UNPKG

handsontable

Version:

Handsontable is a JavaScript Data Grid available for React, Angular and Vue.

373 lines (350 loc) • 13.1 kB
"use strict"; exports.__esModule = true; require("core-js/modules/es.error.cause.js"); var _templateLiteralTag = require("../../helpers/templateLiteralTag"); function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); } function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); } function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; } function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } /** * The `MergedCellCoords` class represents a single merged cell. * * @private * @class MergedCellCoords */ var _cellRange = /*#__PURE__*/new WeakMap(); class MergedCellCoords { constructor(row, column, rowspan, colspan, cellCoordsFactory, cellRangeFactory) { /** * The index of the topmost merged cell row. * * @type {number} */ _defineProperty(this, "row", void 0); /** * The index of the leftmost column. * * @type {number} */ _defineProperty(this, "col", void 0); /** * The `rowspan` value of the merged cell. * * @type {number} */ _defineProperty(this, "rowspan", void 0); /** * The `colspan` value of the merged cell. * * @type {number} */ _defineProperty(this, "colspan", void 0); /** * `true` only if the merged cell is bound to be removed. * * @type {boolean} */ _defineProperty(this, "removed", false); /** * The CellCoords function factory. * * @type {Function} */ _defineProperty(this, "cellCoordsFactory", void 0); /** * The CellRange function factory. * * @type {Function} */ _defineProperty(this, "cellRangeFactory", void 0); /** * The cached range coordinates of the merged cell. * * @type {CellRange} */ _classPrivateFieldInitSpec(this, _cellRange, null); this.row = row; this.col = column; this.rowspan = rowspan; this.colspan = colspan; this.cellCoordsFactory = cellCoordsFactory; this.cellRangeFactory = cellRangeFactory; } /** * Get a warning message for when the declared merged cell data contains negative values. * * @param {{ row: number, col: number, rowspan: number, colspan: number }} mergedCell Object containing information * about the merged cells that was about to be added. * @returns {string} */ static NEGATIVE_VALUES_WARNING(_ref) { let { row, col, rowspan, colspan } = _ref; return (0, _templateLiteralTag.toSingleLine)`The merged cell declared with {row: ${row}, col: ${col},\x20 rowspan: ${rowspan}, colspan: ${colspan}} contains negative values, which is\x20 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 {{ row: number, col: number, rowspan: number, colspan: number }} mergedCell Object containing information * about the merged cells that was about to be added. * @returns {string} */ static IS_OUT_OF_BOUNDS_WARNING(_ref2) { let { row, col } = _ref2; return (0, _templateLiteralTag.toSingleLine)`The merged cell declared at [${row}, ${col}] is positioned\x20 (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 {{ row: number, col: number, rowspan: number, colspan: number }} mergedCell Object containing information * about the merged cells that was about to be added. * @returns {string} */ static IS_SINGLE_CELL(_ref3) { let { row, col } = _ref3; return (0, _templateLiteralTag.toSingleLine)`The merged cell declared at [${row}, ${col}] has both "rowspan"\x20 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 {{ row: number, col: number, rowspan: number, colspan: number }} mergedCell Object containing information * about the merged cells that was about to be added. * @returns {string} */ static ZERO_SPAN_WARNING(_ref4) { let { row, col } = _ref4; return (0, _templateLiteralTag.toSingleLine)`The merged cell declared at [${row}, ${col}] has "rowspan"\x20 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 {{ row: number, col: number, rowspan: number, colspan: number }} mergedCell Object containing information * about the merged cells that was about to be added. * @returns {boolean} */ static containsNegativeValues(_ref5) { let { row, col, rowspan, colspan } = _ref5; return row < 0 || col < 0 || rowspan < 0 || colspan < 0; } /** * Check whether the provided merged cell information object represents a single cell. * * @private * @param {{ row: number, col: number, rowspan: number, colspan: number }} mergedCell Object containing information * about the merged cells that was about to be added. * @returns {boolean} */ static isSingleCell(_ref6) { let { rowspan, colspan } = _ref6; return colspan === 1 && rowspan === 1; } /** * Check whether the provided merged cell information object contains a rowspan or colspan of 0. * * @private * @param {{ row: number, col: number, rowspan: number, colspan: number }} mergedCell Object containing information * about the merged cells that was about to be added. * @returns {boolean} */ static containsZeroSpan(_ref7) { let { rowspan, colspan } = _ref7; return colspan === 0 || 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. * @returns {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 {Core} hotInstance The Handsontable instance. */ 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; } _classPrivateFieldSet(_cellRange, this, null); } /** * Returns `true` if the provided coordinates are inside the merged cell. * * @param {number} row The row index. * @param {number} column The column index. * @returns {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. * @returns {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. * @returns {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; _classPrivateFieldSet(_cellRange, this, null); 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; } } _classPrivateFieldSet(_cellRange, this, null); 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. * @returns {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. * * @returns {CellRange} */ getRange() { if (!_classPrivateFieldGet(_cellRange, this)) { _classPrivateFieldSet(_cellRange, this, this.cellRangeFactory(this.cellCoordsFactory(this.row, this.col), this.cellCoordsFactory(this.row, this.col), this.cellCoordsFactory(this.getLastRow(), this.getLastColumn()))); } return _classPrivateFieldGet(_cellRange, this); } } var _default = exports.default = MergedCellCoords;