UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

220 lines (213 loc) 8.57 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.hasMergedCellsWithRowNextToRowIndex = exports.hasMergedCellsWithColumnNextToColumnIndex = exports.hasMergedCellsInSelection = exports.hasMergedCellsInBetween = exports.findDuplicatePosition = exports.checkEdgeHasMergedCells = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _editorTables = require("@atlaskit/editor-tables"); var getRect = function getRect(index, type, map) { if (type === 'column') { var x = Math.max(Math.min(index, map.width - 1), 0); // clamped index return { left: x, right: x === index ? x + 1 : x, top: 0, bottom: map.height }; } else { var y = Math.max(Math.min(index, map.height - 1), 0); // clamped index return { left: 0, right: map.width, top: y, bottom: y === index ? y + 1 : y }; } }; var hasMergedCellsInBetween = exports.hasMergedCellsInBetween = function hasMergedCellsInBetween(indexes, type) { return function (selection) { var table = (0, _editorTables.findTable)(selection); if (!table) { return false; } var map = _editorTables.TableMap.get(table.node); var cellPositions = new Set(); var mergedCells = new Set(); map.map.forEach(function (value) { if (cellPositions.has(value)) { mergedCells.add(value); } else { cellPositions.add(value); } }); if (!mergedCells.size) { return false; } var getMergedCellsInRect = function getMergedCellsInRect(index, type) { var rect = getRect(index, type, map); var isValidRectangle = rect.left < rect.right && rect.top < rect.bottom; if (!isValidRectangle) { return []; } var cells = map.cellsInRect(rect); var allCellsInRect = []; if (type === 'column') { allCellsInRect = map.map.filter(function (_, key) { return key % map.width === index; }); } else { allCellsInRect = map.map.filter(function (_, key) { return Math.floor(key / map.width) === index; }); } var mergedCell = allCellsInRect.filter(function (nodePos) { return !cells.includes(nodePos) // cell exists in Rect but not show in the map.cellsInRect list => merged cell ? true : mergedCells.has(nodePos); // cell includes in mergedCells => merged cell }); return (0, _toConsumableArray2.default)(new Set(mergedCell)); }; var mergedCellsInRectArr = indexes.map(function (index) { return getMergedCellsInRect(index, type); }); // Currently only support 2 indexes, but we can extend this to support more indexes in the future. return mergedCellsInRectArr[0].some(function (cell) { return mergedCellsInRectArr[1].includes(cell); }); }; }; // Checks if any cell in the column with colIndex is merged with a cell in a column to the left or to the right of it. // colIndex is a logical index of the column. It starts at 0 and goes up to tableMap.width - 1. var hasMergedCellsWithColumnNextToColumnIndex = exports.hasMergedCellsWithColumnNextToColumnIndex = function hasMergedCellsWithColumnNextToColumnIndex(colIndex, selection) { var table = (0, _editorTables.findTable)(selection); if (!table) { return false; } var tableMap = _editorTables.TableMap.get(table.node); var width = tableMap.width; if (width <= 1) { return false; } if (colIndex < 0 || colIndex > width - 1) { return false; } var map = tableMap.map; // j is an index in the tableMap.map array. tableMap.map is a flat array. // Each item of this array contains a number. // The number represents the position of the corresponding cell in the tableMap. It exists for each cell. // If there are merged cells, their positions will be represented by the same number. var isFirstColumn = colIndex === 0; var isLastColumn = colIndex === width - 1; for (var j = colIndex; j < map.length; j += width) { if (!isFirstColumn && map[j] === map[j - 1] || // compare with a cell in the column on the left !isLastColumn && map[j] === map[j + 1] // compare with a cell in the column on the right ) { return true; } } return false; }; // Checks if any cell in the row with rowIndex is merged with a cell in a row above or below it. var hasMergedCellsWithRowNextToRowIndex = exports.hasMergedCellsWithRowNextToRowIndex = function hasMergedCellsWithRowNextToRowIndex(rowIndex, selection) { var table = (0, _editorTables.findTable)(selection); if (!table) { return false; } var tableMap = _editorTables.TableMap.get(table.node); var height = tableMap.height; if (height <= 1) { return false; } if (rowIndex < 0 || rowIndex > height - 1) { return false; } var map = tableMap.map, width = tableMap.width; // map is a flat array representing position of each cell in the table. var indexOfFirstCellInTheRow = rowIndex * width; var indexOfLastCellInTheRow = indexOfFirstCellInTheRow + width - 1; var isFirstRow = rowIndex === 0; var isLastRow = rowIndex === height - 1; // j is an index of a cell in a row for (var j = indexOfFirstCellInTheRow; j <= indexOfLastCellInTheRow; j++) { if (!isFirstRow && map[j] === map[j - width] || // compare with a cell in the row above !isLastRow && map[j] === map[j + width] // compare with a cell in the row below ) { return true; } } return false; }; var hasMergedCellsInSelection = exports.hasMergedCellsInSelection = function hasMergedCellsInSelection(indexes, type) { return function (selection) { var table = (0, _editorTables.findTable)(selection); if (!table) { return false; } var map = _editorTables.TableMap.get(table.node); if (!map.hasMergedCells()) { return false; } return checkEdgeHasMergedCells(indexes, map, type); }; }; /** * this check the selection has merged cells with previous/next col or row. * * @param indexes - this get the indexes of the selection,e.g. [0,1] for selecting first two rows or columns. * @param tableMap - this return a TableMap object. * @param direction - check selection is selected by row or column * @returns boolean */ var checkEdgeHasMergedCells = exports.checkEdgeHasMergedCells = function checkEdgeHasMergedCells(indexes, tableMap, direction) { var mapByRow = tableMap.mapByRow, mapByColumn = tableMap.mapByColumn; var map = 'row' === direction ? mapByRow : mapByColumn; var lengthLimiter = direction === 'row' ? tableMap.width : tableMap.height; var minIndex = Math.min.apply(Math, (0, _toConsumableArray2.default)(indexes)); var maxIndex = Math.max.apply(Math, (0, _toConsumableArray2.default)(indexes)); var isTopSideHaveMergedCells = false; var isBottomSideHaveMergedCells = false; /** * this is to check if the cell position from last focused table is overflow. since if you selection from a cell in 6th row and 7th column cell in a 7x8 table to 3x3 table, the cell position will be overflow because new table dont have this cell at all. TODO: ED-22335 this should better called only when hover over the drag handle. */ var isOldMinIndex = !map[minIndex - 1] || !map[minIndex]; var isOldMaxIndex = !map[maxIndex + 1] || !map[maxIndex]; if (minIndex > 0 && !isOldMinIndex) { var prevSelectionSet = map[minIndex - 1]; var minSelectionSet = map[minIndex]; for (var i = 0; i < lengthLimiter; i++) { if (prevSelectionSet[i] === minSelectionSet[i]) { isTopSideHaveMergedCells = true; break; } } } if (maxIndex < map.length - 1 && !isOldMaxIndex) { var afterSelectionSet = map[maxIndex + 1]; var maxSelectionSet = map[maxIndex]; for (var _i = 0; _i < lengthLimiter; _i++) { if (afterSelectionSet[_i] === maxSelectionSet[_i]) { isBottomSideHaveMergedCells = true; break; } } } return isTopSideHaveMergedCells || isBottomSideHaveMergedCells; }; /** * this function will find the duplicate position in the array(table map position array). * * @param array this usually be the array including positions of the table map. * @returns [] */ var findDuplicatePosition = exports.findDuplicatePosition = function findDuplicatePosition(array) { if (!array) { return []; } return array.filter(function (item, index) { return array.indexOf(item) !== index; }); };