UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

237 lines (232 loc) 10.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.deleteColumns = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _customSteps = require("@atlaskit/custom-steps"); var _analytics = require("@atlaskit/editor-common/analytics"); var _state = require("@atlaskit/editor-prosemirror/state"); var _tableMap = require("@atlaskit/editor-tables/table-map"); var _utils = require("@atlaskit/editor-tables/utils"); var _tableAnalytics = require("../table-analytics"); var _columnWidth = require("./column-width"); var _split = require("./split"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var deleteColumnsCustomStep = function deleteColumnsCustomStep(rect) { return function (tr) { var table = (0, _utils.findTable)(tr.selection); if (!table) { return tr; } // Need to split all the merge in the ranges (this is the current behaviour) // Maybe is better to split only the last column? // TODO: ED-26961 - After talking with Roto about this behaviour, he likes when we dont split the columns, I am keeping this for consistency of the current implementation. (0, _split.splitCellsInColumns)(tr, table.pos, rect.left, rect.right); // Delete the columns var mapStart = tr.mapping.maps.length; var originalDoc = tr.doc; var deletedColumns = []; for (var i = rect.left; i < rect.right; i++) { var step = _customSteps.AddColumnStep.create(originalDoc, table.pos, i, true); deletedColumns.push(i); // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion tr.step(step.map(tr.mapping.slice(mapStart))); } var tablePosResult = tr.mapping.mapResult(table.pos); if (tablePosResult.deleted) { var pos = Math.min(tablePosResult.pos, tr.doc.nodeSize - 1); tr.setSelection(_state.Selection.near(tr.doc.resolve(pos))); } else { var newTable = tr.doc.nodeAt(tablePosResult.pos); if (newTable) { var cursorPos = getNextCursorPos(newTable, deletedColumns); tr.setSelection(_state.Selection.near(tr.doc.resolve(table.pos + cursorPos))); } } return tr; }; }; var deleteColumnsLegacy = function deleteColumnsLegacy(rect) { return function (tr) { var table = (0, _utils.findTable)(tr.selection); if (!table) { return tr; } var columnsToDelete = []; for (var i = rect.left; i < rect.right; i++) { columnsToDelete.push(i); } if (!columnsToDelete.length) { return tr; } var map = _tableMap.TableMap.get(table.node); var rows = []; var seen = {}; var deletedCells = {}; for (var rowIndex = 0; rowIndex < map.height; rowIndex++) { var rowCells = []; var row = table.node.child(rowIndex); var _loop = function _loop(colIndex) { var cellPos = map.map[rowIndex * map.width + colIndex]; var cell = table.node.nodeAt(cellPos); if (!cell) { return 0; // continue } var cellsInColumn = map.cellsInRect({ left: colIndex, top: 0, right: colIndex + 1, bottom: map.height }); if (columnsToDelete.indexOf(colIndex) === -1) { // decrement colspans for col-spanning cells that overlap deleted columns if (cellsInColumn.indexOf(cellPos) > -1 && !seen[cellPos]) { var overlappingCols = 0; columnsToDelete.forEach(function (colIndexToDelete) { if (colIndex < colIndexToDelete && cell.attrs.colspan + colIndex - 1 >= colIndexToDelete) { overlappingCols += 1; } }); if (overlappingCols > 0) { var attrs = _objectSpread(_objectSpread({}, cell.attrs), {}, { colspan: cell.attrs.colspan - overlappingCols }); if (cell.attrs.colwidth) { var minColIndex = Math.min.apply(Math, columnsToDelete); var pos = minColIndex > 0 ? minColIndex - map.colCount(cellPos) : 0; var colwidth = cell.attrs.colwidth.slice() || []; colwidth.splice(pos, overlappingCols); attrs.colwidth = colwidth; } var newCell = cell.type.createChecked(attrs, cell.content, cell.marks); rowCells.push(newCell); seen[cellPos] = true; return 0; // continue } } else if (deletedCells[cellPos]) { // if we're removing a col-spanning cell, we need to add missing cells to columns to the right var _attrs = _objectSpread(_objectSpread({}, cell.attrs), {}, { colspan: 1, rowspan: 1 }); if (cell.attrs.colwidth) { var _pos = colIndex > 0 ? colIndex - map.colCount(cellPos) : 0; _attrs.colwidth = cell.attrs.colwidth.slice().splice(_pos, 1); } var _newCell = cell.type.createChecked(_attrs, cell.type.schema.nodes.paragraph.createChecked(), cell.marks); rowCells.push(_newCell); return 0; // continue } // normal cells that we want to keep if (!seen[cellPos]) { seen[cellPos] = true; rowCells.push(cell); } } else if (cellsInColumn.indexOf(cellPos) > -1) { deletedCells[cellPos] = true; } }, _ret; for (var colIndex = 0; colIndex < map.width; colIndex++) { _ret = _loop(colIndex); if (_ret === 0) continue; } if (rowCells.length) { rows.push(row.type.createChecked(row.attrs, rowCells, row.marks)); } } if (!rows.length) { return tr; } var newTable = table.node.type.createChecked(table.node.attrs, rows, table.node.marks); var fixedTable = fixRowSpans(newTable); if (fixedTable === null) { return tr; } var cursorPos = getNextCursorPos(newTable, columnsToDelete); return tr.replaceWith(table.pos, table.pos + table.node.nodeSize, fixedTable) // move cursor to the left of the deleted columns if possible, otherwise - to the first column .setSelection(_state.Selection.near(tr.doc.resolve(table.pos + cursorPos))); }; }; function getNextCursorPos(table, deletedColumns) { var minColumn = Math.min.apply(Math, (0, _toConsumableArray2.default)(deletedColumns)); var nextColumnWithCursor = minColumn > 0 ? minColumn - 1 : 0; var map = _tableMap.TableMap.get(table); return map.map[nextColumnWithCursor]; } // returns an array of numbers, each number indicates the minimum rowSpan in each row function getMinRowSpans(table) { var minRowSpans = []; for (var rowIndex = 0; rowIndex < table.childCount; rowIndex++) { var rowSpans = []; var row = table.child(rowIndex); for (var colIndex = 0; colIndex < row.childCount; colIndex++) { var cell = row.child(colIndex); rowSpans.push(cell.attrs.rowspan); } minRowSpans[rowIndex] = Math.min.apply(Math, rowSpans); } return minRowSpans; } function fixRowSpans(table) { var map = _tableMap.TableMap.get(table); var minRowSpans = getMinRowSpans(table); if (!minRowSpans.some(function (rowspan) { return rowspan > 1; })) { return table; } var rows = []; for (var rowIndex = 0; rowIndex < map.height; rowIndex++) { var row = table.child(rowIndex); if (minRowSpans[rowIndex] === 1) { rows.push(row); } else { var rowCells = []; for (var colIndex = 0; colIndex < row.childCount; colIndex++) { var cell = row.child(colIndex); var rowspan = cell.attrs.rowspan - minRowSpans[rowIndex] + 1; if (rowspan < 1) { return null; } var newCell = cell.type.createChecked(_objectSpread(_objectSpread({}, cell.attrs), {}, { rowspan: rowspan }), cell.content, cell.marks); rowCells.push(newCell); } rows.push(row.type.createChecked(row.attrs, rowCells, row.marks)); } } if (!rows.length) { return null; } return table.type.createChecked(table.attrs, rows, table.marks); } var deleteColumns = exports.deleteColumns = function deleteColumns(rect, allowCustomStep, api, view) { var isTableScalingEnabled = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; var isTableFixedColumnWidthsOptionEnabled = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; var shouldUseIncreasedScalingPercent = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; var isCommentEditor = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false; return function (tr) { var updatedTr = tr; updatedTr.setMeta(_tableAnalytics.META_KEYS.OVERFLOW_TRIGGER, { name: _analytics.TABLE_OVERFLOW_CHANGE_TRIGGER.DELETED_COLUMN }); if (allowCustomStep) { updatedTr = deleteColumnsCustomStep(rect)(updatedTr); } else { updatedTr = deleteColumnsLegacy(rect)(updatedTr); } var table = (0, _utils.findTable)(updatedTr.selection); if (table) { updatedTr = (0, _columnWidth.rescaleColumns)(isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent, api, isCommentEditor)(table, view)(updatedTr); } return updatedTr; }; };