| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- import { CellCoords, CellRange } from '../../3rdparty/walkontable/src/index';
- import { toSingleLine } from './../../helpers/templateLiteralTag';
- /**
- * The `MergedCellCoords` class represents a single merged cell.
- *
- * @class MergedCellCoords
- * @plugin MergeCells
- */
- class MergedCellCoords {
- constructor(row, column, rowspan, colspan) {
- /**
- * The index of the topmost merged cell row.
- *
- * @type {Number}
- */
- this.row = row;
- /**
- * The index of the leftmost column.
- *
- * @type {Number}
- */
- this.col = column;
- /**
- * The `rowspan` value of the merged cell.
- *
- * @type {Number}
- */
- this.rowspan = rowspan;
- /**
- * The `colspan` value of the merged cell.
- *
- * @type {Number}
- */
- this.colspan = colspan;
- /**
- * `true` only if the merged cell is bound to be removed.
- *
- * @type {Boolean}
- */
- this.removed = false;
- }
- /**
- * Get a warning message for when the declared merged cell data contains negative values.
- *
- * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
- * @return {String}
- */
- static NEGATIVE_VALUES_WARNING(newMergedCell) {
- return toSingleLine`The merged cell declared with {row: ${newMergedCell.row}, col: ${newMergedCell.col}, rowspan:
- ${newMergedCell.rowspan}, colspan: ${newMergedCell.colspan}} contains negative values, which is not supported. It
- will not be added to the collection.`;
- }
- /**
- * Get a warning message for when the declared merged cell data contains values exceeding the table limits.
- *
- * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
- * @return {String}
- */
- static IS_OUT_OF_BOUNDS_WARNING(newMergedCell) {
- return toSingleLine`The merged cell declared at [${newMergedCell.row}, ${newMergedCell.col}] is positioned (or positioned partially)
- outside of the table range. It was not added to the table, please fix your setup.`;
- }
- /**
- * Get a warning message for when the declared merged cell data represents a single cell.
- *
- * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
- * @return {String}
- */
- static IS_SINGLE_CELL(newMergedCell) {
- return toSingleLine`The merged cell declared at [${newMergedCell.row}, ${newMergedCell.col}] has both "rowspan"
- and "colspan" declared as "1", which makes it a single cell. It cannot be added to the collection.`;
- }
- /**
- * Get a warning message for when the declared merged cell data contains "colspan" or "rowspan", that equals 0.
- *
- * @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
- * @return {String}
- */
- static ZERO_SPAN_WARNING(newMergedCell) {
- return toSingleLine`The merged cell declared at [${newMergedCell.row}, ${newMergedCell.col}] has "rowspan" or "colspan" declared as
- "0", which is not supported. It cannot be added to the collection.`;
- }
- /**
- * Check whether the values provided for a merged cell contain any negative values.
- *
- * @param {Object} mergedCellInfo Object containing the `row`, `col`, `rowspan` and `colspan` properties.
- * @return {Boolean}
- */
- static containsNegativeValues(mergedCellInfo) {
- return mergedCellInfo.row < 0 || mergedCellInfo.col < 0 || mergedCellInfo.rowspan < 0 || mergedCellInfo.colspan < 0;
- }
- /**
- * Check whether the provided merged cell information object represents a single cell.
- *
- * @private
- * @param {Object} mergedCellInfo An object with `row`, `col`, `rowspan` and `colspan` properties.
- * @return {Boolean}
- */
- static isSingleCell(mergedCellInfo) {
- return mergedCellInfo.colspan === 1 && mergedCellInfo.rowspan === 1;
- }
- /**
- * Check whether the provided merged cell information object contains a rowspan or colspan of 0.
- *
- * @private
- * @param {Object} mergedCellInfo An object with `row`, `col`, `rowspan` and `colspan` properties.
- * @return {Boolean}
- */
- static containsZeroSpan(mergedCellInfo) {
- return mergedCellInfo.colspan === 0 || mergedCellInfo.rowspan === 0;
- }
- /**
- * Check whether the provided merged cell object is to be declared out of bounds of the table.
- *
- * @param {Object} mergeCell Object containing the `row`, `col`, `rowspan` and `colspan` properties.
- * @param {Number} rowCount Number of rows in the table.
- * @param {Number} columnCount Number of rows in the table.
- * @return {Boolean}
- */
- static isOutOfBounds(mergeCell, rowCount, columnCount) {
- return mergeCell.row < 0 ||
- mergeCell.col < 0 ||
- mergeCell.row >= rowCount ||
- mergeCell.row + mergeCell.rowspan - 1 >= rowCount ||
- mergeCell.col >= columnCount ||
- mergeCell.col + mergeCell.colspan - 1 >= columnCount;
- }
- /**
- * Sanitize (prevent from going outside the boundaries) the merged cell.
- *
- * @param hotInstance
- */
- normalize(hotInstance) {
- const totalRows = hotInstance.countRows();
- const totalColumns = hotInstance.countCols();
- if (this.row < 0) {
- this.row = 0;
- } else if (this.row > totalRows - 1) {
- this.row = totalRows - 1;
- }
- if (this.col < 0) {
- this.col = 0;
- } else if (this.col > totalColumns - 1) {
- this.col = totalColumns - 1;
- }
- if (this.row + this.rowspan > totalRows - 1) {
- this.rowspan = totalRows - this.row;
- }
- if (this.col + this.colspan > totalColumns - 1) {
- this.colspan = totalColumns - this.col;
- }
- }
- /**
- * Returns `true` if the provided coordinates are inside the merged cell.
- *
- * @param {Number} row The row index.
- * @param {Number} column The column index.
- * @return {Boolean}
- */
- includes(row, column) {
- return this.row <= row && this.col <= column && this.row + this.rowspan - 1 >= row && this.col + this.colspan - 1 >= column;
- }
- /**
- * Returns `true` if the provided `column` property is within the column span of the merged cell.
- *
- * @param {Number} column The column index.
- * @return {Boolean}
- */
- includesHorizontally(column) {
- return this.col <= column && this.col + this.colspan - 1 >= column;
- }
- /**
- * Returns `true` if the provided `row` property is within the row span of the merged cell.
- *
- * @param {Number} row Row index.
- * @return {Boolean}
- */
- includesVertically(row) {
- return this.row <= row && this.row + this.rowspan - 1 >= row;
- }
- /**
- * Shift (and possibly resize, if needed) the merged cell.
- *
- * @param {Array} shiftVector 2-element array containing the information on the shifting in the `x` and `y` axis.
- * @param {Number} indexOfChange Index of the preceding change.
- * @returns {Boolean} Returns `false` if the whole merged cell was removed.
- */
- shift(shiftVector, indexOfChange) {
- const shiftValue = shiftVector[0] || shiftVector[1];
- const shiftedIndex = indexOfChange + Math.abs(shiftVector[0] || shiftVector[1]) - 1;
- const span = shiftVector[0] ? 'colspan' : 'rowspan';
- const index = shiftVector[0] ? 'col' : 'row';
- const changeStart = Math.min(indexOfChange, shiftedIndex);
- const changeEnd = Math.max(indexOfChange, shiftedIndex);
- const mergeStart = this[index];
- const mergeEnd = this[index] + this[span] - 1;
- if (mergeStart >= indexOfChange) {
- this[index] += shiftValue;
- }
- // adding rows/columns
- if (shiftValue > 0) {
- if (indexOfChange <= mergeEnd && indexOfChange > mergeStart) {
- this[span] += shiftValue;
- }
- // removing rows/columns
- } else if (shiftValue < 0) {
- // removing the whole merge
- if (changeStart <= mergeStart && changeEnd >= mergeEnd) {
- this.removed = true;
- return false;
- // removing the merge partially, including the beginning
- } else if (mergeStart >= changeStart && mergeStart <= changeEnd) {
- const removedOffset = changeEnd - mergeStart + 1;
- const preRemovedOffset = Math.abs(shiftValue) - removedOffset;
- this[index] -= preRemovedOffset + shiftValue;
- this[span] -= removedOffset;
- // removing the middle part of the merge
- } else if (mergeStart <= changeStart && mergeEnd >= changeEnd) {
- this[span] += shiftValue;
- // removing the end part of the merge
- } else if (mergeStart <= changeStart && mergeEnd >= changeStart && mergeEnd < changeEnd) {
- const removedPart = mergeEnd - changeStart + 1;
- this[span] -= removedPart;
- }
- }
- return true;
- }
- /**
- * Check if the second provided merged cell is "farther" in the provided direction.
- *
- * @param {MergedCellCoords} mergedCell The merged cell to check.
- * @param {String} direction Drag direction.
- * @return {Boolean|null} `true` if the second provided merged cell is "farther".
- */
- isFarther(mergedCell, direction) {
- if (!mergedCell) {
- return true;
- }
- if (direction === 'down') {
- return mergedCell.row + mergedCell.rowspan - 1 < this.row + this.rowspan - 1;
- } else if (direction === 'up') {
- return mergedCell.row > this.row;
- } else if (direction === 'right') {
- return mergedCell.col + mergedCell.colspan - 1 < this.col + this.colspan - 1;
- } else if (direction === 'left') {
- return mergedCell.col > this.col;
- }
- return null;
- }
- /**
- * Get the bottom row index of the merged cell.
- *
- * @returns {Number}
- */
- getLastRow() {
- return this.row + this.rowspan - 1;
- }
- /**
- * Get the rightmost column index of the merged cell.
- *
- * @returns {Number}
- */
- getLastColumn() {
- return this.col + this.colspan - 1;
- }
- /**
- * Get the range coordinates of the merged cell.
- *
- * @return {CellRange}
- */
- getRange() {
- return new CellRange(new CellCoords(this.row, this.col), new CellCoords(this.row, this.col), new CellCoords(this.getLastRow(), this.getLastColumn()));
- }
- }
- export default MergedCellCoords;
|