UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

157 lines (150 loc) 6.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.goToNextCellVertical = exports.goToNextCell = void 0; var _analytics = require("@atlaskit/editor-common/analytics"); var _nesting = require("@atlaskit/editor-common/nesting"); var _state = require("@atlaskit/editor-prosemirror/state"); var _utils = require("@atlaskit/editor-prosemirror/utils"); var _tableMap = require("@atlaskit/editor-tables/table-map"); var _utils2 = require("@atlaskit/editor-tables/utils"); var _pluginFactory = require("../plugin-factory"); var _columnResize = require("./column-resize"); var _commandsWithAnalytics = require("./commands-with-analytics"); var TAB_FORWARD_DIRECTION = 1; var TAB_BACKWARD_DIRECTION = -1; var goToNextCell = exports.goToNextCell = function goToNextCell(editorAnalyticsAPI, ariaNotify, getIntl) { return function (direction) { return function (state, dispatch, view) { var _getPluginState; var table = (0, _utils2.findTable)(state.selection); if (!table) { return false; } var isColumnResizing = (_getPluginState = (0, _pluginFactory.getPluginState)(state)) === null || _getPluginState === void 0 ? void 0 : _getPluginState.isKeyboardResize; if (isColumnResizing) { (0, _columnResize.stopKeyboardColumnResizing)({ ariaNotify: ariaNotify, getIntl: getIntl })(state, dispatch, view); return true; } var map = _tableMap.TableMap.get(table.node); var _state$schema$nodes = state.schema.nodes, tableCell = _state$schema$nodes.tableCell, tableHeader = _state$schema$nodes.tableHeader; // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion var cell = (0, _utils.findParentNodeOfType)([tableCell, tableHeader])(state.selection); var firstCellPos = map.positionAt(0, 0, table.node) + table.start; var lastCellPos = map.positionAt(map.height - 1, map.width - 1, table.node) + table.start; // When tabbing backwards at first cell (top left), insert row at the start of table if (firstCellPos === cell.pos && direction === TAB_BACKWARD_DIRECTION) { (0, _commandsWithAnalytics.insertRowWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.KEYBOARD, { index: 0, moveCursorToInsertedRow: true })(state, dispatch); return true; } // When tabbing forwards at last cell (bottom right), insert row at the end of table if (lastCellPos === cell.pos && direction === TAB_FORWARD_DIRECTION) { (0, _commandsWithAnalytics.insertRowWithAnalytics)(editorAnalyticsAPI)(_analytics.INPUT_METHOD.KEYBOARD, { index: map.height, moveCursorToInsertedRow: true })(state, dispatch); return true; } if (dispatch) { return (0, _utils2.goToNextCell)(direction)(state, dispatch); } return true; }; }; }; /** * Moves the cursor vertically from a NodeSelection within a table cell. * - If content exists above/below within the cell, lets ProseMirror handle it. * - Otherwise, moves to the next cell (down to start, up to last line). */ var goToNextCellVertical = exports.goToNextCellVertical = function goToNextCellVertical(direction) { return function (state, dispatch) { var selection = state.selection; var nestedTableSelection = (0, _nesting.isSelectionTableNestedInTable)(state); if (!(selection instanceof _state.NodeSelection) && !nestedTableSelection) { return false; // Let ProseMirror handle other selection types } var table = (0, _utils2.findTable)(selection); var cell = (0, _utils2.findCellClosestToPos)(state.doc.resolve(selection.from)); var selectionPos = selection.from; // Handle when we have nested table fully selected if (table && nestedTableSelection && (0, _utils2.isTableSelected)(selection)) { var parentTablePos = table.pos; table = (0, _utils2.findTableClosestToPos)(state.doc.resolve(parentTablePos)); cell = (0, _utils2.findCellClosestToPos)(state.doc.resolve(parentTablePos)); selectionPos = parentTablePos; } if (!table || !cell || !cell.pos) { return false; } var _state$schema$nodes2 = state.schema.nodes, tableCell = _state$schema$nodes2.tableCell, tableHeader = _state$schema$nodes2.tableHeader; // Let ProseMirror handle movement within the cell if content exists above/below if (cellHasContentInDirection(cell.node, cell.pos, selectionPos, direction)) { return false; } // Move to the next cell vertically var map = _tableMap.TableMap.get(table.node); var nextCellPos = map.nextCell(cell.pos - table.start, 'vert', direction); if (dispatch && nextCellPos) { var _$nextCell$nodeAfter, _$nextCell$nodeAfter2; var nextCellStart = table.start + nextCellPos; var $nextCell = state.doc.resolve(nextCellStart); if ((_$nextCell$nodeAfter = $nextCell.nodeAfter) !== null && _$nextCell$nodeAfter !== void 0 && _$nextCell$nodeAfter.type && [tableCell, tableHeader].includes((_$nextCell$nodeAfter2 = $nextCell.nodeAfter) === null || _$nextCell$nodeAfter2 === void 0 ? void 0 : _$nextCell$nodeAfter2.type)) { var contentPos = getTargetPositionInNextCell($nextCell.nodeAfter, nextCellStart, direction); dispatch(state.tr.setSelection(_state.TextSelection.create(state.doc, contentPos))); return true; } return false; } return false; // No next cell found }; }; function cellHasContentInDirection(cellNode, cellPos, selectionPos, direction) { var hasContent = false; cellNode.content.forEach(function (node, offset) { var nodeStart = cellPos + 1 + offset; var nodeEnd = nodeStart + node.nodeSize; if (direction === 1 && nodeStart > selectionPos && node.isBlock) { hasContent = true; // Content below } else if (direction === -1 && nodeEnd <= selectionPos && node.isBlock) { hasContent = true; // Content above } }); return hasContent; } function getTargetPositionInNextCell(cellNode, nextCellStart, direction) { var contentPos = nextCellStart + 1; // Default: just inside the cell if (cellNode.content.size > 0) { if (direction === 1) { var firstChild = cellNode.firstChild; if (firstChild && firstChild.isBlock) { contentPos = nextCellStart + 1 + (firstChild.isLeaf ? 0 : 1); // Down: Start of first block } } else if (direction === -1) { var lastBlock; var lastOffset = 0; cellNode.content.forEach(function (node, offset) { if (node.isBlock) { lastBlock = node; lastOffset = offset; } }); if (lastBlock) { contentPos = nextCellStart + 1 + lastOffset + (lastBlock.isLeaf ? 0 : lastBlock.nodeSize - 1); } } } return contentPos; }