handsontable
Version:
Handsontable is a JavaScript Spreadsheet Component available for React, Angular and Vue.
827 lines (700 loc) • 31.5 kB
JavaScript
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import "core-js/modules/es.array.join.js";
import "core-js/modules/es.symbol.js";
import "core-js/modules/es.symbol.description.js";
import "core-js/modules/es.object.to-string.js";
import "core-js/modules/es.symbol.iterator.js";
import "core-js/modules/es.array.iterator.js";
import "core-js/modules/es.string.iterator.js";
import "core-js/modules/web.dom-collections.iterator.js";
import "core-js/modules/es.array.slice.js";
import "core-js/modules/es.function.name.js";
import "core-js/modules/es.array.from.js";
import "core-js/modules/es.regexp.exec.js";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
import { addClass, hasClass, removeClass, getComputedStyle, getTrimmingContainer, innerWidth, innerHeight, offset, outerHeight, outerWidth } from "../../../helpers/dom/element.mjs";
import { stopImmediatePropagation } from "../../../helpers/dom/event.mjs";
import { objectEach } from "../../../helpers/object.mjs";
import { isMobileBrowser } from "../../../helpers/browser.mjs";
/**
*
*/
var Border = /*#__PURE__*/function () {
// TODO As this is an internal class, should be designed for using {Walkontable}. It uses the facade,
// TODO Con. Because the class is created on place where the instance reference comes from external origin.
// TODO Imho, the discrimination for handling both, facade and non-facade should be handled.
/**
* @param {WalkontableFacade} wotInstance The Walkontable instance.
* @param {object} settings The border settings.
*/
function Border(wotInstance, settings) {
_classCallCheck(this, Border);
if (!settings) {
return;
}
this.eventManager = wotInstance.eventManager;
this.instance = wotInstance;
this.wot = wotInstance;
this.settings = settings;
this.mouseDown = false;
this.main = null;
this.top = null;
this.bottom = null;
this.start = null;
this.end = null;
this.topStyle = null;
this.bottomStyle = null;
this.startStyle = null;
this.endStyle = null;
this.cornerDefaultStyle = {
width: '6px',
height: '6px',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: '#FFF'
}; // Offset to moving the corner to be centered relative to the grid.
this.cornerCenterPointOffset = -(parseInt(this.cornerDefaultStyle.width, 10) / 2);
this.corner = null;
this.cornerStyle = null;
this.createBorders(settings);
this.registerListeners();
}
/**
* Register all necessary events.
*/
_createClass(Border, [{
key: "registerListeners",
value: function registerListeners() {
var _this2 = this;
var documentBody = this.wot.rootDocument.body;
this.eventManager.addEventListener(documentBody, 'mousedown', function () {
return _this2.onMouseDown();
});
this.eventManager.addEventListener(documentBody, 'mouseup', function () {
return _this2.onMouseUp();
});
var _loop = function _loop(c, len) {
var element = _this2.main.childNodes[c];
_this2.eventManager.addEventListener(element, 'mouseenter', function (event) {
return _this2.onMouseEnter(event, _this2.main.childNodes[c]);
});
};
for (var c = 0, len = this.main.childNodes.length; c < len; c++) {
_loop(c, len);
}
}
/**
* Mouse down listener.
*
* @private
*/
}, {
key: "onMouseDown",
value: function onMouseDown() {
this.mouseDown = true;
}
/**
* Mouse up listener.
*
* @private
*/
}, {
key: "onMouseUp",
value: function onMouseUp() {
this.mouseDown = false;
}
/**
* Mouse enter listener for fragment selection functionality.
*
* @private
* @param {Event} event Dom event.
* @param {HTMLElement} parentElement Part of border element.
*/
}, {
key: "onMouseEnter",
value: function onMouseEnter(event, parentElement) {
if (!this.mouseDown || !this.wot.getSetting('hideBorderOnMouseDownOver')) {
return;
}
event.preventDefault();
stopImmediatePropagation(event);
var _this = this;
var documentBody = this.wot.rootDocument.body;
var bounds = parentElement.getBoundingClientRect(); // Hide border to prevents selection jumping when fragmentSelection is enabled.
parentElement.style.display = 'none';
/**
* @param {Event} mouseEvent The mouse event object.
* @returns {boolean}
*/
function isOutside(mouseEvent) {
if (mouseEvent.clientY < Math.floor(bounds.top)) {
return true;
}
if (mouseEvent.clientY > Math.ceil(bounds.top + bounds.height)) {
return true;
}
if (mouseEvent.clientX < Math.floor(bounds.left)) {
return true;
}
if (mouseEvent.clientX > Math.ceil(bounds.left + bounds.width)) {
return true;
}
}
/**
* @param {Event} handlerEvent The mouse event object.
*/
function handler(handlerEvent) {
if (isOutside(handlerEvent)) {
_this.eventManager.removeEventListener(documentBody, 'mousemove', handler);
parentElement.style.display = 'block';
}
}
this.eventManager.addEventListener(documentBody, 'mousemove', handler);
}
/**
* Create border elements.
*
* @param {object} settings The border settings.
*/
}, {
key: "createBorders",
value: function createBorders(settings) {
var rootDocument = this.wot.rootDocument;
this.main = rootDocument.createElement('div');
var borderDivs = ['top', 'start', 'bottom', 'end', 'corner'];
var style = this.main.style;
style.position = 'absolute';
style.top = 0;
style.left = 0;
for (var i = 0; i < 5; i++) {
var position = borderDivs[i];
var div = rootDocument.createElement('div');
div.className = "wtBorder ".concat(this.settings.className || ''); // + borderDivs[i];
if (this.settings[position] && this.settings[position].hide) {
div.className += ' hidden';
}
style = div.style;
style.backgroundColor = this.settings[position] && this.settings[position].color ? this.settings[position].color : settings.border.color;
style.height = this.settings[position] && this.settings[position].width ? "".concat(this.settings[position].width, "px") : "".concat(settings.border.width, "px");
style.width = this.settings[position] && this.settings[position].width ? "".concat(this.settings[position].width, "px") : "".concat(settings.border.width, "px");
this.main.appendChild(div);
}
this.top = this.main.childNodes[0];
this.start = this.main.childNodes[1];
this.bottom = this.main.childNodes[2];
this.end = this.main.childNodes[3];
this.topStyle = this.top.style;
this.startStyle = this.start.style;
this.bottomStyle = this.bottom.style;
this.endStyle = this.end.style;
this.corner = this.main.childNodes[4];
this.corner.className += ' corner';
this.cornerStyle = this.corner.style;
this.cornerStyle.width = this.cornerDefaultStyle.width;
this.cornerStyle.height = this.cornerDefaultStyle.height;
this.cornerStyle.border = [this.cornerDefaultStyle.borderWidth, this.cornerDefaultStyle.borderStyle, this.cornerDefaultStyle.borderColor].join(' ');
if (isMobileBrowser()) {
this.createMultipleSelectorHandles();
}
this.disappear();
var wtTable = this.wot.wtTable;
var bordersHolder = wtTable.bordersHolder;
if (!bordersHolder) {
bordersHolder = rootDocument.createElement('div');
bordersHolder.className = 'htBorders';
wtTable.bordersHolder = bordersHolder;
wtTable.spreader.appendChild(bordersHolder);
}
bordersHolder.appendChild(this.main);
}
/**
* Create multiple selector handler for mobile devices.
*/
}, {
key: "createMultipleSelectorHandles",
value: function createMultipleSelectorHandles() {
var _this3 = this;
var rootDocument = this.wot.rootDocument;
this.selectionHandles = {
top: rootDocument.createElement('DIV'),
topHitArea: rootDocument.createElement('DIV'),
bottom: rootDocument.createElement('DIV'),
bottomHitArea: rootDocument.createElement('DIV')
};
var width = 10;
var hitAreaWidth = 40;
this.selectionHandles.top.className = 'topSelectionHandle topLeftSelectionHandle';
this.selectionHandles.topHitArea.className = 'topSelectionHandle-HitArea topLeftSelectionHandle-HitArea';
this.selectionHandles.bottom.className = 'bottomSelectionHandle bottomRightSelectionHandle';
this.selectionHandles.bottomHitArea.className = 'bottomSelectionHandle-HitArea bottomRightSelectionHandle-HitArea';
this.selectionHandles.styles = {
top: this.selectionHandles.top.style,
topHitArea: this.selectionHandles.topHitArea.style,
bottom: this.selectionHandles.bottom.style,
bottomHitArea: this.selectionHandles.bottomHitArea.style
};
var hitAreaStyle = {
position: 'absolute',
height: "".concat(hitAreaWidth, "px"),
width: "".concat(hitAreaWidth, "px"),
'border-radius': "".concat(parseInt(hitAreaWidth / 1.5, 10), "px")
};
objectEach(hitAreaStyle, function (value, key) {
_this3.selectionHandles.styles.bottomHitArea[key] = value;
_this3.selectionHandles.styles.topHitArea[key] = value;
});
var handleStyle = {
position: 'absolute',
height: "".concat(width, "px"),
width: "".concat(width, "px"),
'border-radius': "".concat(parseInt(width / 1.5, 10), "px"),
background: '#F5F5FF',
border: '1px solid #4285c8'
};
objectEach(handleStyle, function (value, key) {
_this3.selectionHandles.styles.bottom[key] = value;
_this3.selectionHandles.styles.top[key] = value;
});
this.main.appendChild(this.selectionHandles.top);
this.main.appendChild(this.selectionHandles.bottom);
this.main.appendChild(this.selectionHandles.topHitArea);
this.main.appendChild(this.selectionHandles.bottomHitArea);
}
/**
* @param {number} row The visual row index.
* @param {number} col The visual column index.
* @returns {boolean}
*/
}, {
key: "isPartRange",
value: function isPartRange(row, col) {
var areaSelection = this.wot.selections.createOrGetArea();
if (areaSelection.cellRange) {
if (row !== areaSelection.cellRange.to.row || col !== areaSelection.cellRange.to.col) {
return true;
}
}
return false;
}
/**
* @param {number} row The visual row index.
* @param {number} col The visual column index.
* @param {number} top The top position of the handler.
* @param {number} left The left position of the handler.
* @param {number} width The width of the handler.
* @param {number} height The height of the handler.
*/
}, {
key: "updateMultipleSelectionHandlesPosition",
value: function updateMultipleSelectionHandlesPosition(row, col, top, left, width, height) {
var isRtl = this.wot.wtSettings.getSetting('rtlMode');
var inlinePosProperty = isRtl ? 'right' : 'left';
var handleWidth = parseInt(this.selectionHandles.styles.top.width, 10);
var hitAreaWidth = parseInt(this.selectionHandles.styles.topHitArea.width, 10);
this.selectionHandles.styles.top.top = "".concat(parseInt(top - handleWidth - 1, 10), "px");
this.selectionHandles.styles.top[inlinePosProperty] = "".concat(parseInt(left - handleWidth - 1, 10), "px");
this.selectionHandles.styles.topHitArea.top = "".concat(parseInt(top - hitAreaWidth / 4 * 3, 10), "px");
this.selectionHandles.styles.topHitArea[inlinePosProperty] = "".concat(parseInt(left - hitAreaWidth / 4 * 3, 10), "px");
this.selectionHandles.styles.bottom.top = "".concat(parseInt(top + height, 10), "px");
this.selectionHandles.styles.bottom[inlinePosProperty] = "".concat(parseInt(left + width, 10), "px");
this.selectionHandles.styles.bottomHitArea.top = "".concat(parseInt(top + height - hitAreaWidth / 4, 10), "px");
this.selectionHandles.styles.bottomHitArea[inlinePosProperty] = "".concat(parseInt(left + width - hitAreaWidth / 4, 10), "px");
if (this.settings.border.cornerVisible && this.settings.border.cornerVisible()) {
this.selectionHandles.styles.top.display = 'block';
this.selectionHandles.styles.topHitArea.display = 'block';
if (this.isPartRange(row, col)) {
this.selectionHandles.styles.bottom.display = 'none';
this.selectionHandles.styles.bottomHitArea.display = 'none';
} else {
this.selectionHandles.styles.bottom.display = 'block';
this.selectionHandles.styles.bottomHitArea.display = 'block';
}
} else {
this.selectionHandles.styles.top.display = 'none';
this.selectionHandles.styles.bottom.display = 'none';
this.selectionHandles.styles.topHitArea.display = 'none';
this.selectionHandles.styles.bottomHitArea.display = 'none';
}
if (row === this.wot.wtSettings.getSetting('fixedRowsTop') || col === this.wot.wtSettings.getSetting('fixedColumnsStart')) {
this.selectionHandles.styles.top.zIndex = '9999';
this.selectionHandles.styles.topHitArea.zIndex = '9999';
} else {
this.selectionHandles.styles.top.zIndex = '';
this.selectionHandles.styles.topHitArea.zIndex = '';
}
}
/**
* Show border around one or many cells.
*
* @param {Array} corners The corner coordinates.
*/
}, {
key: "appear",
value: function appear(corners) {
if (this.disabled) {
return;
}
var _this$wot = this.wot,
wtTable = _this$wot.wtTable,
rootDocument = _this$wot.rootDocument,
rootWindow = _this$wot.rootWindow; // todo refactoring: consider about using internal facade (it is given by external code)
var fromRow;
var toRow;
var fromColumn;
var toColumn;
var rowHeader;
var columnHeader;
var rowsCount = wtTable.getRenderedRowsCount();
for (var i = 0; i < rowsCount; i += 1) {
var s = wtTable.rowFilter.renderedToSource(i);
if (s >= corners[0] && s <= corners[2]) {
fromRow = s;
rowHeader = corners[0];
break;
}
}
for (var _i = rowsCount - 1; _i >= 0; _i -= 1) {
var _s = wtTable.rowFilter.renderedToSource(_i);
if (_s >= corners[0] && _s <= corners[2]) {
toRow = _s;
break;
}
}
var columnsCount = wtTable.getRenderedColumnsCount();
for (var _i2 = 0; _i2 < columnsCount; _i2 += 1) {
var _s2 = wtTable.columnFilter.renderedToSource(_i2);
if (_s2 >= corners[1] && _s2 <= corners[3]) {
fromColumn = _s2;
columnHeader = corners[1];
break;
}
}
for (var _i3 = columnsCount - 1; _i3 >= 0; _i3 -= 1) {
var _s3 = wtTable.columnFilter.renderedToSource(_i3);
if (_s3 >= corners[1] && _s3 <= corners[3]) {
toColumn = _s3;
break;
}
}
if (fromRow === void 0 || fromColumn === void 0) {
this.disappear();
return;
}
var fromTD = wtTable.getCell(this.wot.createCellCoords(fromRow, fromColumn));
var isMultiple = fromRow !== toRow || fromColumn !== toColumn;
var toTD = isMultiple ? wtTable.getCell(this.wot.createCellCoords(toRow, toColumn)) : fromTD;
var fromOffset = offset(fromTD);
var toOffset = isMultiple ? offset(toTD) : fromOffset;
var containerOffset = offset(wtTable.TABLE);
var containerWidth = outerWidth(wtTable.TABLE);
var minTop = fromOffset.top;
var minLeft = fromOffset.left;
var isRtl = this.wot.wtSettings.getSetting('rtlMode');
var inlineStartPos = 0;
var width = 0;
if (isRtl) {
var fromWidth = outerWidth(fromTD);
var gridRightPos = rootWindow.innerWidth - containerOffset.left - containerWidth;
width = minLeft + fromWidth - toOffset.left;
inlineStartPos = rootWindow.innerWidth - minLeft - fromWidth - gridRightPos - 1;
} else {
width = toOffset.left + outerWidth(toTD) - minLeft;
inlineStartPos = minLeft - containerOffset.left - 1;
}
if (this.isEntireColumnSelected(fromRow, toRow)) {
var modifiedValues = this.getDimensionsFromHeader('columns', fromColumn, toColumn, rowHeader, containerOffset);
var fromTH = null;
if (modifiedValues) {
var _modifiedValues = _slicedToArray(modifiedValues, 3);
fromTH = _modifiedValues[0];
inlineStartPos = _modifiedValues[1];
width = _modifiedValues[2];
}
if (fromTH) {
fromTD = fromTH;
}
}
var top = minTop - containerOffset.top - 1;
var height = toOffset.top + outerHeight(toTD) - minTop;
if (this.isEntireRowSelected(fromColumn, toColumn)) {
var _modifiedValues2 = this.getDimensionsFromHeader('rows', fromRow, toRow, columnHeader, containerOffset);
var _fromTH = null;
if (_modifiedValues2) {
var _modifiedValues3 = _slicedToArray(_modifiedValues2, 3);
_fromTH = _modifiedValues3[0];
top = _modifiedValues3[1];
height = _modifiedValues3[2];
}
if (_fromTH) {
fromTD = _fromTH;
}
}
var style = getComputedStyle(fromTD, rootWindow);
if (parseInt(style.borderTopWidth, 10) > 0) {
top += 1;
height = height > 0 ? height - 1 : 0;
}
if (parseInt(style[isRtl ? 'borderRightWidth' : 'borderLeftWidth'], 10) > 0) {
inlineStartPos += 1;
width = width > 0 ? width - 1 : 0;
}
var inlinePosProperty = isRtl ? 'right' : 'left';
this.topStyle.top = "".concat(top, "px");
this.topStyle[inlinePosProperty] = "".concat(inlineStartPos, "px");
this.topStyle.width = "".concat(width, "px");
this.topStyle.display = 'block';
this.startStyle.top = "".concat(top, "px");
this.startStyle[inlinePosProperty] = "".concat(inlineStartPos, "px");
this.startStyle.height = "".concat(height, "px");
this.startStyle.display = 'block';
var delta = Math.floor(this.settings.border.width / 2);
this.bottomStyle.top = "".concat(top + height - delta, "px");
this.bottomStyle[inlinePosProperty] = "".concat(inlineStartPos, "px");
this.bottomStyle.width = "".concat(width, "px");
this.bottomStyle.display = 'block';
this.endStyle.top = "".concat(top, "px");
this.endStyle[inlinePosProperty] = "".concat(inlineStartPos + width - delta, "px");
this.endStyle.height = "".concat(height + 1, "px");
this.endStyle.display = 'block';
var cornerVisibleSetting = this.settings.border.cornerVisible;
cornerVisibleSetting = typeof cornerVisibleSetting === 'function' ? cornerVisibleSetting(this.settings.layerLevel) : cornerVisibleSetting;
var hookResult = this.wot.getSetting('onModifyGetCellCoords', toRow, toColumn);
var checkRow = toRow,
checkCol = toColumn;
if (hookResult && Array.isArray(hookResult)) {
var _hookResult = _slicedToArray(hookResult, 4);
checkRow = _hookResult[2];
checkCol = _hookResult[3];
}
if (isMobileBrowser() || !cornerVisibleSetting || this.isPartRange(checkRow, checkCol)) {
this.cornerStyle.display = 'none';
} else {
this.cornerStyle.top = "".concat(top + height + this.cornerCenterPointOffset - 1, "px");
this.cornerStyle[inlinePosProperty] = "".concat(inlineStartPos + width + this.cornerCenterPointOffset - 1, "px");
this.cornerStyle.borderRightWidth = this.cornerDefaultStyle.borderWidth;
this.cornerStyle.width = this.cornerDefaultStyle.width; // Hide the fill handle, so the possible further adjustments won't force unneeded scrollbars.
this.cornerStyle.display = 'none';
var trimmingContainer = getTrimmingContainer(wtTable.TABLE);
var trimToWindow = trimmingContainer === rootWindow;
if (trimToWindow) {
trimmingContainer = rootDocument.documentElement;
}
if (toColumn === this.wot.getSetting('totalColumns') - 1) {
var toTdOffsetLeft = trimToWindow ? toTD.getBoundingClientRect().left : toTD.offsetLeft;
var cornerOverlappingContainer = false;
var cornerEdge = 0;
if (isRtl) {
cornerEdge = toTdOffsetLeft - parseInt(this.cornerDefaultStyle.width, 10) / 2;
cornerOverlappingContainer = cornerEdge < 0;
} else {
cornerEdge = toTdOffsetLeft + outerWidth(toTD) + parseInt(this.cornerDefaultStyle.width, 10) / 2;
cornerOverlappingContainer = cornerEdge >= innerWidth(trimmingContainer);
}
if (cornerOverlappingContainer) {
this.cornerStyle[inlinePosProperty] = "".concat(Math.floor(inlineStartPos + width + this.cornerCenterPointOffset - parseInt(this.cornerDefaultStyle.width, 10) / 2), "px"); // eslint-disable-line max-len
this.cornerStyle[isRtl ? 'borderLeftWidth' : 'borderRightWidth'] = 0;
}
}
if (toRow === this.wot.getSetting('totalRows') - 1) {
var toTdOffsetTop = trimToWindow ? toTD.getBoundingClientRect().top : toTD.offsetTop;
var cornerBottomEdge = toTdOffsetTop + outerHeight(toTD) + parseInt(this.cornerDefaultStyle.height, 10) / 2;
var _cornerOverlappingContainer = cornerBottomEdge >= innerHeight(trimmingContainer);
if (_cornerOverlappingContainer) {
this.cornerStyle.top = "".concat(Math.floor(top + height + this.cornerCenterPointOffset - parseInt(this.cornerDefaultStyle.height, 10) / 2), "px"); // eslint-disable-line max-len
this.cornerStyle.borderBottomWidth = 0;
}
}
this.cornerStyle.display = 'block';
}
if (isMobileBrowser()) {
this.updateMultipleSelectionHandlesPosition(toRow, toColumn, top, inlineStartPos, width, height);
}
}
/**
* Check whether an entire column of cells is selected.
*
* @private
* @param {number} startRowIndex Start row index.
* @param {number} endRowIndex End row index.
* @returns {boolean}
*/
}, {
key: "isEntireColumnSelected",
value: function isEntireColumnSelected(startRowIndex, endRowIndex) {
return startRowIndex === this.wot.wtTable.getFirstRenderedRow() && endRowIndex === this.wot.wtTable.getLastRenderedRow();
}
/**
* Check whether an entire row of cells is selected.
*
* @private
* @param {number} startColumnIndex Start column index.
* @param {number} endColumnIndex End column index.
* @returns {boolean}
*/
}, {
key: "isEntireRowSelected",
value: function isEntireRowSelected(startColumnIndex, endColumnIndex) {
return startColumnIndex === this.wot.wtTable.getFirstRenderedColumn() && endColumnIndex === this.wot.wtTable.getLastRenderedColumn();
}
/**
* Get left/top index and width/height depending on the `direction` provided.
*
* @private
* @param {string} direction `rows` or `columns`, defines if an entire column or row is selected.
* @param {number} fromIndex Start index of the selection.
* @param {number} toIndex End index of the selection.
* @param {number} headerIndex The header index as negative value.
* @param {number} containerOffset Offset of the container.
* @returns {Array|boolean} Returns an array of [headerElement, left, width] or [headerElement, top, height], depending on `direction` (`false` in case of an error getting the headers).
*/
}, {
key: "getDimensionsFromHeader",
value: function getDimensionsFromHeader(direction, fromIndex, toIndex, headerIndex, containerOffset) {
var wtTable = this.wot.wtTable;
var rootHotElement = wtTable.wtRootElement.parentNode;
var getHeaderFn = null;
var dimensionFn = null;
var entireSelectionClassname = null;
var index = null;
var dimension = null;
var dimensionProperty = null;
var startHeader = null;
var endHeader = null;
switch (direction) {
case 'rows':
getHeaderFn = function getHeaderFn() {
return wtTable.getRowHeader.apply(wtTable, arguments);
};
dimensionFn = function dimensionFn() {
return outerHeight.apply(void 0, arguments);
};
entireSelectionClassname = 'ht__selection--rows';
dimensionProperty = 'top';
break;
case 'columns':
getHeaderFn = function getHeaderFn() {
return wtTable.getColumnHeader.apply(wtTable, arguments);
};
dimensionFn = function dimensionFn() {
return outerWidth.apply(void 0, arguments);
};
entireSelectionClassname = 'ht__selection--columns';
dimensionProperty = 'left';
break;
default:
}
if (rootHotElement.classList.contains(entireSelectionClassname)) {
var columnHeaderLevelCount = this.wot.getSetting('columnHeaders').length;
startHeader = getHeaderFn(fromIndex, columnHeaderLevelCount - headerIndex);
endHeader = getHeaderFn(toIndex, columnHeaderLevelCount - headerIndex);
if (!startHeader || !endHeader) {
return false;
}
var startHeaderOffset = offset(startHeader);
var endOffset = offset(endHeader);
if (startHeader && endHeader) {
index = startHeaderOffset[dimensionProperty] - containerOffset[dimensionProperty] - 1;
dimension = endOffset[dimensionProperty] + dimensionFn(endHeader) - startHeaderOffset[dimensionProperty];
}
return [startHeader, index, dimension];
}
return false;
}
/**
* Change border style.
*
* @private
* @param {string} borderElement Coordinate where add/remove border: top, bottom, start, end.
* @param {object} border The border object descriptor.
*/
}, {
key: "changeBorderStyle",
value: function changeBorderStyle(borderElement, border) {
var style = this[borderElement].style;
var borderStyle = border[borderElement];
if (!borderStyle || borderStyle.hide) {
addClass(this[borderElement], 'hidden');
} else {
if (hasClass(this[borderElement], 'hidden')) {
removeClass(this[borderElement], 'hidden');
}
style.backgroundColor = borderStyle.color;
if (borderElement === 'top' || borderElement === 'bottom') {
style.height = "".concat(borderStyle.width, "px");
}
if (borderElement === 'start' || borderElement === 'end') {
style.width = "".concat(borderStyle.width, "px");
}
}
}
/**
* Change border style to default.
*
* @private
* @param {string} position The position type ("top", "bottom", "start", "end") to change.
*/
}, {
key: "changeBorderToDefaultStyle",
value: function changeBorderToDefaultStyle(position) {
var defaultBorder = {
width: 1,
color: '#000'
};
var style = this[position].style;
style.backgroundColor = defaultBorder.color;
style.width = "".concat(defaultBorder.width, "px");
style.height = "".concat(defaultBorder.width, "px");
}
/**
* Toggle class 'hidden' to element.
*
* @private
* @param {string} borderElement Coordinate where add/remove border: top, bottom, start, end.
* @param {boolean} [remove] Defines type of the action to perform.
*/
}, {
key: "toggleHiddenClass",
value: function toggleHiddenClass(borderElement, remove) {
this.changeBorderToDefaultStyle(borderElement);
if (remove) {
addClass(this[borderElement], 'hidden');
} else {
removeClass(this[borderElement], 'hidden');
}
}
/**
* Hide border.
*/
}, {
key: "disappear",
value: function disappear() {
this.topStyle.display = 'none';
this.bottomStyle.display = 'none';
this.startStyle.display = 'none';
this.endStyle.display = 'none';
this.cornerStyle.display = 'none';
if (isMobileBrowser()) {
this.selectionHandles.styles.top.display = 'none';
this.selectionHandles.styles.bottom.display = 'none';
}
}
/**
* Cleans up all the DOM state related to a Border instance. Call this prior to deleting a Border instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.eventManager.destroyWithOwnEventsOnly();
this.main.parentNode.removeChild(this.main);
}
}]);
return Border;
}();
export default Border;