You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.7 KiB

// This file defines a plugin that handles the drawing of cell
// selections and the basic user interactions for creating and working
// with such selections. It also makes sure that, after each
// transaction, the shapes of tables are normalized to be rectangular
// and not contain overlapping cells.
import { Plugin } from 'prosemirror-state';
import { drawCellSelection, normalizeSelection } from './cellselection';
import { fixTables, fixTablesKey } from './fixtables';
import {
handleKeyDown,
handleMouseDown,
handlePaste,
handleTripleClick,
} from './input';
import { tableEditingKey } from './util';
export { CellBookmark, CellSelection } from './cellselection';
export type { CellSelectionJSON } from './cellselection';
export {
columnResizing,
columnResizingPluginKey,
ResizeState,
} from './columnresizing';
export type { ColumnResizingOptions, Dragging } from './columnresizing';
export * from './commands';
export {
clipCells as __clipCells,
insertCells as __insertCells,
pastedCells as __pastedCells,
} from './copypaste';
export type { Area as __Area } from './copypaste';
export type { Direction } from './input';
export { tableNodes, tableNodeTypes } from './schema';
export type {
CellAttributes,
getFromDOM,
setDOMAttr,
TableNodes,
TableNodesOptions,
TableRoles,
} from './schema';
export { TableMap } from './tablemap';
export type { ColWidths, Problem, Rect } from './tablemap';
export { TableView, updateColumnsOnResize } from './tableview';
export {
addColSpan,
cellAround,
colCount,
columnIsHeader,
findCell,
inSameTable,
isInTable,
moveCellForward,
nextCell,
pointsAtCell,
removeColSpan,
selectionCell,
} from './util';
export type { MutableAttrs } from './util';
export { fixTables, handlePaste, fixTablesKey };
export { tableEditingKey };
/**
* @public
*/
export type TableEditingOptions = {
allowTableNodeSelection?: boolean;
};
/**
* Creates a [plugin](http://prosemirror.net/docs/ref/#state.Plugin)
* that, when added to an editor, enables cell-selection, handles
* cell-based copy/paste, and makes sure tables stay well-formed (each
* row has the same width, and cells don't overlap).
*
* You should probably put this plugin near the end of your array of
* plugins, since it handles mouse and arrow key events in tables
* rather broadly, and other plugins, like the gap cursor or the
* column-width dragging plugin, might want to get a turn first to
* perform more specific behavior.
*
* @public
*/
export function tableEditing({
allowTableNodeSelection = false,
}: TableEditingOptions = {}): Plugin {
return new Plugin({
key: tableEditingKey,
// This piece of state is used to remember when a mouse-drag
// cell-selection is happening, so that it can continue even as
// transactions (which might move its anchor cell) come in.
state: {
init() {
return null;
},
apply(tr, cur) {
const set = tr.getMeta(tableEditingKey);
if (set != null) return set == -1 ? null : set;
if (cur == null || !tr.docChanged) return cur;
const { deleted, pos } = tr.mapping.mapResult(cur);
return deleted ? null : pos;
},
},
props: {
decorations: drawCellSelection,
handleDOMEvents: {
mousedown: handleMouseDown,
},
createSelectionBetween(view) {
if (tableEditingKey.getState(view.state) != null)
return view.state.selection;
},
handleTripleClick,
handleKeyDown,
handlePaste,
},
appendTransaction(_, oldState, state) {
return normalizeSelection(
state,
fixTables(state, oldState),
allowTableNodeSelection,
);
},
});
}