@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
220 lines (213 loc) • 8.57 kB
JavaScript
"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;
});
};