handsontable
Version:
Handsontable is a JavaScript Data Grid available for React, Angular and Vue.
672 lines (646 loc) • 29 kB
JavaScript
import "core-js/modules/es.error.cause.js";
import "core-js/modules/es.array.push.js";
import "core-js/modules/esnext.iterator.constructor.js";
import "core-js/modules/esnext.iterator.some.js";
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
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 _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
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"); }
import { BasePlugin } from "../base/index.mjs";
import { Hooks } from "../../core/hooks/index.mjs";
import { arrayReduce } from "../../helpers/array.mjs";
import { addClass, removeClass, offset, hasClass, outerWidth } from "../../helpers/dom/element.mjs";
import { offsetRelativeTo } from "../../helpers/dom/event.mjs";
import { rangeEach } from "../../helpers/number.mjs";
import BacklightUI from "./ui/backlight.mjs";
import GuidelineUI from "./ui/guideline.mjs";
Hooks.getSingleton().register('beforeColumnMove');
Hooks.getSingleton().register('afterColumnMove');
export const PLUGIN_KEY = 'manualColumnMove';
export const PLUGIN_PRIORITY = 120;
const CSS_PLUGIN = 'ht__manualColumnMove';
const CSS_SHOW_UI = 'show-ui';
const CSS_ON_MOVING = 'on-moving--columns';
const CSS_AFTER_SELECTION = 'after-selection--columns';
/* eslint-disable jsdoc/require-description-complete-sentence */
/**
* @plugin ManualColumnMove
* @class ManualColumnMove
*
* @description
* This plugin allows to change columns order. To make columns order persistent the {@link Options#persistentState}
* plugin should be enabled.
*
* API:
* - `moveColumn` - move single column to the new position.
* - `moveColumns` - move many columns (as an array of indexes) to the new position.
* - `dragColumn` - drag single column to the new position.
* - `dragColumns` - drag many columns (as an array of indexes) to the new position.
*
* [Documentation](@/guides/columns/column-moving/column-moving.md) explain differences between drag and move actions.
* Please keep in mind that if you want apply visual changes,
* you have to call manually the `render` method on the instance of Handsontable.
*
* The plugin creates additional components to make moving possibly using user interface:
* - backlight - highlight of selected columns.
* - guideline - line which shows where columns has been moved.
*
* @class ManualColumnMove
* @plugin ManualColumnMove
*/
var _backlight = /*#__PURE__*/new WeakMap();
var _guideline = /*#__PURE__*/new WeakMap();
var _columnsToMove = /*#__PURE__*/new WeakMap();
var _countCols = /*#__PURE__*/new WeakMap();
var _pressed = /*#__PURE__*/new WeakMap();
var _target = /*#__PURE__*/new WeakMap();
var _cachedDropIndex = /*#__PURE__*/new WeakMap();
var _hoveredColumn = /*#__PURE__*/new WeakMap();
var _rootElementOffset = /*#__PURE__*/new WeakMap();
var _hasRowHeaders = /*#__PURE__*/new WeakMap();
var _fixedColumnsStart = /*#__PURE__*/new WeakMap();
var _ManualColumnMove_brand = /*#__PURE__*/new WeakSet();
export class ManualColumnMove extends BasePlugin {
constructor() {
super(...arguments);
/**
* Change the behavior of selection / dragging.
*
* @param {MouseEvent} event `mousedown` event properties.
* @param {CellCoords} coords Visual cell coordinates where was fired event.
* @param {HTMLElement} TD Cell represented as HTMLElement.
* @param {object} controller An object with properties `row`, `column` and `cell`. Each property contains
* a boolean value that allows or disallows changing the selection for that particular area.
*/
_classPrivateMethodInitSpec(this, _ManualColumnMove_brand);
/**
* Backlight UI object.
*
* @type {object}
*/
_classPrivateFieldInitSpec(this, _backlight, new BacklightUI(this.hot));
/**
* Guideline UI object.
*
* @type {object}
*/
_classPrivateFieldInitSpec(this, _guideline, new GuidelineUI(this.hot));
/**
* @type {number[]}
*/
_classPrivateFieldInitSpec(this, _columnsToMove, []);
/**
* @type {number}
*/
_classPrivateFieldInitSpec(this, _countCols, 0);
/**
* @type {boolean}
*/
_classPrivateFieldInitSpec(this, _pressed, false);
/**
* @type {object}
*/
_classPrivateFieldInitSpec(this, _target, {});
/**
* @type {number}
*/
_classPrivateFieldInitSpec(this, _cachedDropIndex, void 0);
/**
* @type {number}
*/
_classPrivateFieldInitSpec(this, _hoveredColumn, void 0);
/**
* @type {number}
*/
_classPrivateFieldInitSpec(this, _rootElementOffset, void 0);
/**
* @type {boolean}
*/
_classPrivateFieldInitSpec(this, _hasRowHeaders, void 0);
/**
* @type {number}
*/
_classPrivateFieldInitSpec(this, _fixedColumnsStart, void 0);
}
static get PLUGIN_KEY() {
return PLUGIN_KEY;
}
static get PLUGIN_PRIORITY() {
return PLUGIN_PRIORITY;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` then the {@link ManualColumnMove#enablePlugin} method is called.
*
* @returns {boolean}
*/
isEnabled() {
return !!this.hot.getSettings()[PLUGIN_KEY];
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
enablePlugin() {
var _this = this;
if (this.enabled) {
return;
}
this.addHook('beforeOnCellMouseDown', function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _assertClassBrand(_ManualColumnMove_brand, _this, _onBeforeOnCellMouseDown).call(_this, ...args);
});
this.addHook('beforeOnCellMouseOver', function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return _assertClassBrand(_ManualColumnMove_brand, _this, _onBeforeOnCellMouseOver).call(_this, ...args);
});
this.addHook('afterScrollVertically', () => _assertClassBrand(_ManualColumnMove_brand, this, _onAfterScrollVertically).call(this));
this.addHook('afterLoadData', function () {
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return _assertClassBrand(_ManualColumnMove_brand, _this, _onAfterLoadData).call(_this, ...args);
});
this.buildPluginUI();
this.registerEvents();
// TODO: move adding plugin classname to BasePlugin.
addClass(this.hot.rootElement, CSS_PLUGIN);
super.enablePlugin();
}
/**
* Updates the plugin's state.
*
* This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the following configuration options:
* - [`manualColumnMove`](@/api/options.md#manualcolumnmove)
*/
updatePlugin() {
this.disablePlugin();
this.enablePlugin();
this.moveBySettingsOrLoad();
super.updatePlugin();
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
disablePlugin() {
removeClass(this.hot.rootElement, CSS_PLUGIN);
this.unregisterEvents();
_classPrivateFieldGet(_backlight, this).destroy();
_classPrivateFieldGet(_guideline, this).destroy();
super.disablePlugin();
}
/**
* Moves a single column.
*
* @param {number} column Visual column index to be moved.
* @param {number} finalIndex Visual column index, being a start index for the moved columns. Points to where the elements will be placed after the moving action.
* To check the visualization of the final index, please take a look at [documentation](@/guides/columns/column-moving/column-moving.md#drag-and-move-actions-of-manualcolumnmove-plugin).
* @fires Hooks#beforeColumnMove
* @fires Hooks#afterColumnMove
* @returns {boolean}
*/
moveColumn(column, finalIndex) {
return this.moveColumns([column], finalIndex);
}
/**
* Moves a multiple columns.
*
* @param {Array} columns Array of visual column indexes to be moved.
* @param {number} finalIndex Visual column index, being a start index for the moved columns. Points to where the elements will be placed after the moving action.
* To check the visualization of the final index, please take a look at [documentation](@/guides/columns/column-moving/column-moving.md#drag-and-move-actions-of-manualcolumnmove-plugin).
* @fires Hooks#beforeColumnMove
* @fires Hooks#afterColumnMove
* @returns {boolean}
*/
moveColumns(columns, finalIndex) {
const dropIndex = _classPrivateFieldGet(_cachedDropIndex, this);
const movePossible = this.isMovePossible(columns, finalIndex);
const beforeMoveHook = this.hot.runHooks('beforeColumnMove', columns, finalIndex, dropIndex, movePossible);
_classPrivateFieldSet(_cachedDropIndex, this, undefined);
if (beforeMoveHook === false) {
return;
}
if (movePossible) {
this.hot.columnIndexMapper.moveIndexes(columns, finalIndex);
}
const movePerformed = movePossible && this.isColumnOrderChanged(columns, finalIndex);
this.hot.runHooks('afterColumnMove', columns, finalIndex, dropIndex, movePossible, movePerformed);
return movePerformed;
}
/**
* Drag a single column to drop index position.
*
* @param {number} column Visual column index to be dragged.
* @param {number} dropIndex Visual column index, being a drop index for the moved columns. Points to where we are going to drop the moved elements.
* To check visualization of drop index please take a look at [documentation](@/guides/columns/column-moving/column-moving.md#drag-and-move-actions-of-manualcolumnmove-plugin).
* @fires Hooks#beforeColumnMove
* @fires Hooks#afterColumnMove
* @returns {boolean}
*/
dragColumn(column, dropIndex) {
return this.dragColumns([column], dropIndex);
}
/**
* Drag multiple columns to drop index position.
*
* @param {Array} columns Array of visual column indexes to be dragged.
* @param {number} dropIndex Visual column index, being a drop index for the moved columns. Points to where we are going to drop the moved elements.
* To check visualization of drop index please take a look at [documentation](@/guides/columns/column-moving/column-moving.md#drag-and-move-actions-of-manualcolumnmove-plugin).
* @fires Hooks#beforeColumnMove
* @fires Hooks#afterColumnMove
* @returns {boolean}
*/
dragColumns(columns, dropIndex) {
const finalIndex = this.countFinalIndex(columns, dropIndex);
_classPrivateFieldSet(_cachedDropIndex, this, dropIndex);
return this.moveColumns(columns, finalIndex);
}
/**
* Indicates if it's possible to move columns to the desired position. Some of the actions aren't
* possible, i.e. You can’t move more than one element to the last position.
*
* @param {Array} movedColumns Array of visual column indexes to be moved.
* @param {number} finalIndex Visual column index, being a start index for the moved columns. Points to where the elements will be placed after the moving action.
* To check the visualization of the final index, please take a look at [documentation](@/guides/columns/column-moving/column-moving.md#drag-and-move-actions-of-manualcolumnmove-plugin).
* @returns {boolean}
*/
isMovePossible(movedColumns, finalIndex) {
const length = this.hot.columnIndexMapper.getNotTrimmedIndexesLength();
// An attempt to transfer more columns to start destination than is possible (only when moving from the top to the bottom).
const tooHighDestinationIndex = movedColumns.length + finalIndex > length;
const tooLowDestinationIndex = finalIndex < 0;
const tooLowMovedColumnIndex = movedColumns.some(movedColumn => movedColumn < 0);
const tooHighMovedColumnIndex = movedColumns.some(movedColumn => movedColumn >= length);
if (tooHighDestinationIndex || tooLowDestinationIndex || tooLowMovedColumnIndex || tooHighMovedColumnIndex) {
return false;
}
return true;
}
/**
* Indicates if order of columns was changed.
*
* @private
* @param {Array} movedColumns Array of visual column indexes to be moved.
* @param {number} finalIndex Visual column index, being a start index for the moved columns. Points to where the elements will be placed after the moving action.
* To check the visualization of the final index, please take a look at [documentation](@/guides/columns/column-moving/column-moving.md#drag-and-move-actions-of-manualcolumnmove-plugin).
* @returns {boolean}
*/
isColumnOrderChanged(movedColumns, finalIndex) {
return movedColumns.some((column, nrOfMovedElement) => column - nrOfMovedElement !== finalIndex);
}
/**
* Count the final column index from the drop index.
*
* @private
* @param {Array} movedColumns Array of visual column indexes to be moved.
* @param {number} dropIndex Visual column index, being a drop index for the moved columns.
* @returns {number} Visual column index, being a start index for the moved columns.
*/
countFinalIndex(movedColumns, dropIndex) {
const numberOfColumnsLowerThanDropIndex = arrayReduce(movedColumns, (numberOfColumns, currentColumnIndex) => {
if (currentColumnIndex < dropIndex) {
numberOfColumns += 1;
}
return numberOfColumns;
}, 0);
return dropIndex - numberOfColumnsLowerThanDropIndex;
}
/**
* Gets the sum of the widths of columns in the provided range.
*
* @private
* @param {number} fromColumn Visual column index.
* @param {number} toColumn Visual column index.
* @returns {number}
*/
getColumnsWidth(fromColumn, toColumn) {
const columnMapper = this.hot.columnIndexMapper;
let columnsWidth = 0;
for (let visualColumnIndex = fromColumn; visualColumnIndex <= toColumn; visualColumnIndex += 1) {
const renderableIndex = columnMapper.getRenderableFromVisualIndex(visualColumnIndex);
if (visualColumnIndex < 0) {
columnsWidth += this.hot.view._wt.wtViewport.getRowHeaderWidth() || 0;
} else if (renderableIndex !== null) {
columnsWidth += this.hot.view._wt.wtTable.getColumnWidth(renderableIndex) || 0;
}
}
return columnsWidth;
}
/**
* Loads initial settings when persistent state is saved or when plugin was initialized as an array.
*
* @private
*/
moveBySettingsOrLoad() {
const pluginSettings = this.hot.getSettings()[PLUGIN_KEY];
if (Array.isArray(pluginSettings)) {
this.moveColumns(pluginSettings, 0);
} else if (pluginSettings !== undefined) {
const persistentState = this.persistentStateLoad();
if (persistentState.length) {
this.moveColumns(persistentState, 0);
}
}
}
/**
* Checks if the provided column is in the fixedColumnsTop section.
*
* @private
* @param {number} column Visual column index to check.
* @returns {boolean}
*/
isFixedColumnsStart(column) {
return column < this.hot.getSettings().fixedColumnsStart;
}
/**
* Saves the manual column positions to the persistent state (the {@link Options#persistentState} option has to be enabled).
*
* @private
* @fires Hooks#persistentStateSave
*/
persistentStateSave() {
this.hot.runHooks('persistentStateSave', 'manualColumnMove', this.hot.columnIndexMapper.getIndexesSequence()); // The `PersistentState` plugin should be refactored.
}
/**
* Loads the manual column positions from the persistent state (the {@link Options#persistentState} option has to be enabled).
*
* @private
* @fires Hooks#persistentStateLoad
* @returns {Array} Stored state.
*/
persistentStateLoad() {
const storedState = {};
this.hot.runHooks('persistentStateLoad', 'manualColumnMove', storedState);
return storedState.value ? storedState.value : [];
}
/**
* Prepares an array of indexes based on actual selection.
*
* @private
* @param {number} start The start index.
* @param {number} end The end index.
* @returns {Array}
*/
prepareColumnsToMoving(start, end) {
const selectedColumns = [];
rangeEach(start, end, i => {
selectedColumns.push(i);
});
return selectedColumns;
}
/**
* Update the UI visual position.
*
* @private
*/
refreshPositions() {
const firstVisible = this.hot.view.getFirstFullyVisibleColumn();
if (this.isFixedColumnsStart(_classPrivateFieldGet(_hoveredColumn, this)) && firstVisible > 0) {
this.hot.scrollViewportTo({
col: this.hot.columnIndexMapper.getNearestNotHiddenIndex(firstVisible - 1, -1)
});
}
const wtTable = this.hot.view._wt.wtTable;
const scrollableElement = this.hot.view._wt.wtOverlays.scrollableElement;
const scrollStart = typeof scrollableElement.scrollX === 'number' ? scrollableElement.scrollX : scrollableElement.scrollLeft;
let tdOffsetStart = this.hot.view.THEAD.offsetLeft + this.getColumnsWidth(0, _classPrivateFieldGet(_hoveredColumn, this) - 1);
const hiderWidth = wtTable.hider.offsetWidth;
const tbodyOffsetLeft = wtTable.TBODY.offsetLeft;
const backlightElemMarginStart = _classPrivateFieldGet(_backlight, this).getOffset().start;
const backlightElemWidth = _classPrivateFieldGet(_backlight, this).getSize().width;
let rowHeaderWidth = 0;
let mouseOffsetStart = 0;
if (this.hot.isRtl()) {
const rootWindow = this.hot.rootWindow;
const containerWidth = outerWidth(this.hot.rootElement);
const gridMostRightPos = rootWindow.innerWidth - _classPrivateFieldGet(_rootElementOffset, this) - containerWidth;
mouseOffsetStart = rootWindow.innerWidth - _classPrivateFieldGet(_target, this).eventPageX - gridMostRightPos - (scrollableElement.scrollX === undefined ? scrollStart : 0);
} else {
mouseOffsetStart = _classPrivateFieldGet(_target, this).eventPageX - (_classPrivateFieldGet(_rootElementOffset, this) - (scrollableElement.scrollX === undefined ? scrollStart : 0));
}
if (_classPrivateFieldGet(_hasRowHeaders, this)) {
rowHeaderWidth = this.hot.view._wt.wtOverlays.inlineStartOverlay.clone.wtTable.getColumnHeader(-1).offsetWidth;
}
if (this.isFixedColumnsStart(_classPrivateFieldGet(_hoveredColumn, this))) {
tdOffsetStart += scrollStart;
}
tdOffsetStart += rowHeaderWidth;
if (_classPrivateFieldGet(_hoveredColumn, this) < 0) {
// if hover on rowHeader
if (_classPrivateFieldGet(_fixedColumnsStart, this) > 0) {
_classPrivateFieldGet(_target, this).col = 0;
} else {
_classPrivateFieldGet(_target, this).col = firstVisible > 0 ? firstVisible - 1 : firstVisible;
}
} else if (_classPrivateFieldGet(_target, this).TD.offsetWidth / 2 + tdOffsetStart <= mouseOffsetStart) {
const newCoordsCol = _classPrivateFieldGet(_hoveredColumn, this) >= _classPrivateFieldGet(_countCols, this) ? _classPrivateFieldGet(_countCols, this) - 1 : _classPrivateFieldGet(_hoveredColumn, this);
// if hover on right part of TD
_classPrivateFieldGet(_target, this).col = newCoordsCol + 1;
// unfortunately first column is bigger than rest
tdOffsetStart += _classPrivateFieldGet(_target, this).TD.offsetWidth;
} else {
// elsewhere on table
_classPrivateFieldGet(_target, this).col = _classPrivateFieldGet(_hoveredColumn, this);
}
let backlightStart = mouseOffsetStart;
let guidelineStart = tdOffsetStart;
if (mouseOffsetStart + backlightElemWidth + backlightElemMarginStart >= hiderWidth) {
// prevent display backlight on the right side of the table
backlightStart = hiderWidth - backlightElemWidth - backlightElemMarginStart;
} else if (mouseOffsetStart + backlightElemMarginStart < tbodyOffsetLeft + rowHeaderWidth) {
// prevent display backlight on the left side of the table
backlightStart = tbodyOffsetLeft + rowHeaderWidth + Math.abs(backlightElemMarginStart);
}
if (tdOffsetStart >= hiderWidth - 1) {
// prevent display guideline outside the table
guidelineStart = hiderWidth - 1;
} else if (guidelineStart === 0) {
// guideline has got `margin-left: -1px` as default
guidelineStart = 1;
} else if (scrollableElement.scrollX !== undefined && _classPrivateFieldGet(_hoveredColumn, this) < _classPrivateFieldGet(_fixedColumnsStart, this)) {
guidelineStart -= _classPrivateFieldGet(_rootElementOffset, this) <= scrollableElement.scrollX ? _classPrivateFieldGet(_rootElementOffset, this) : 0;
}
_classPrivateFieldGet(_backlight, this).setPosition(null, backlightStart);
_classPrivateFieldGet(_guideline, this).setPosition(null, guidelineStart);
}
/**
* Binds the events used by the plugin.
*
* @private
*/
registerEvents() {
const {
documentElement
} = this.hot.rootDocument;
this.eventManager.addEventListener(documentElement, 'mousemove', event => _assertClassBrand(_ManualColumnMove_brand, this, _onMouseMove).call(this, event));
this.eventManager.addEventListener(documentElement, 'mouseup', () => _assertClassBrand(_ManualColumnMove_brand, this, _onMouseUp).call(this));
}
/**
* Unbinds the events used by the plugin.
*
* @private
*/
unregisterEvents() {
this.eventManager.clear();
}
/**
* Builds the plugin's UI.
*
* @private
*/
buildPluginUI() {
_classPrivateFieldGet(_backlight, this).build();
_classPrivateFieldGet(_guideline, this).build();
}
/**
* Callback for the `afterLoadData` hook.
*
* @private
*/
/**
* Destroys the plugin instance.
*/
destroy() {
_classPrivateFieldGet(_backlight, this).destroy();
_classPrivateFieldGet(_guideline, this).destroy();
super.destroy();
}
}
function _onBeforeOnCellMouseDown(event, coords, TD, controller) {
const wtTable = this.hot.view._wt.wtTable;
const isHeaderSelection = this.hot.selection.isSelectedByColumnHeader();
const selection = this.hot.getSelectedRangeActive();
// This block action shouldn't be handled below.
const isSortingElement = hasClass(event.target, 'sortAction');
if (!selection || !isHeaderSelection || _classPrivateFieldGet(_pressed, this) || event.button !== 0 || isSortingElement) {
_classPrivateFieldSet(_pressed, this, false);
_classPrivateFieldGet(_columnsToMove, this).length = 0;
removeClass(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]);
return;
}
const guidelineIsNotReady = _classPrivateFieldGet(_guideline, this).isBuilt() && !_classPrivateFieldGet(_guideline, this).isAppended();
const backlightIsNotReady = _classPrivateFieldGet(_backlight, this).isBuilt() && !_classPrivateFieldGet(_backlight, this).isAppended();
if (guidelineIsNotReady && backlightIsNotReady) {
_classPrivateFieldGet(_guideline, this).appendTo(wtTable.hider);
_classPrivateFieldGet(_backlight, this).appendTo(wtTable.hider);
}
const {
from,
to
} = selection;
const start = Math.min(from.col, to.col);
const end = Math.max(from.col, to.col);
if (coords.row < 0 && coords.col >= start && coords.col <= end) {
controller.column = true;
_classPrivateFieldSet(_pressed, this, true);
const eventOffsetX = TD.firstChild ? offsetRelativeTo(event, TD.firstChild).x : event.offsetX;
_classPrivateFieldGet(_target, this).eventPageX = event.pageX;
_classPrivateFieldSet(_hoveredColumn, this, coords.col);
_classPrivateFieldGet(_target, this).TD = TD;
_classPrivateFieldGet(_target, this).col = coords.col;
_classPrivateFieldSet(_columnsToMove, this, this.prepareColumnsToMoving(start, end));
_classPrivateFieldSet(_hasRowHeaders, this, !!this.hot.getSettings().rowHeaders);
_classPrivateFieldSet(_countCols, this, this.hot.countCols());
_classPrivateFieldSet(_fixedColumnsStart, this, this.hot.getSettings().fixedColumnsStart);
_classPrivateFieldSet(_rootElementOffset, this, offset(this.hot.rootElement).left);
const countColumnsFrom = _classPrivateFieldGet(_hasRowHeaders, this) ? -1 : 0;
const topPos = wtTable.holder.scrollTop + wtTable.getColumnHeaderHeight(0) + 1;
const fixedColumnsStart = coords.col < _classPrivateFieldGet(_fixedColumnsStart, this);
const horizontalScrollPosition = this.hot.view._wt.wtOverlays.inlineStartOverlay.getOverlayOffset();
const offsetX = Math.abs(eventOffsetX - (this.hot.isRtl() ? TD.offsetWidth : 0));
const inlineOffset = this.getColumnsWidth(start, coords.col - 1) + offsetX;
const inlinePos = this.getColumnsWidth(countColumnsFrom, start - 1) + (fixedColumnsStart ? horizontalScrollPosition : 0) + inlineOffset;
_classPrivateFieldGet(_backlight, this).setPosition(topPos, inlinePos);
_classPrivateFieldGet(_backlight, this).setSize(this.getColumnsWidth(start, end), wtTable.hider.offsetHeight - topPos);
_classPrivateFieldGet(_backlight, this).setOffset(null, -inlineOffset);
addClass(this.hot.rootElement, CSS_ON_MOVING);
} else {
removeClass(this.hot.rootElement, CSS_AFTER_SELECTION);
_classPrivateFieldSet(_pressed, this, false);
_classPrivateFieldGet(_columnsToMove, this).length = 0;
}
}
/**
* 'mouseMove' event callback. Fired when pointer move on document.documentElement.
*
* @param {MouseEvent} event `mousemove` event properties.
*/
function _onMouseMove(event) {
if (!_classPrivateFieldGet(_pressed, this)) {
return;
}
_classPrivateFieldGet(_target, this).eventPageX = event.pageX;
this.refreshPositions();
}
/**
* 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell.
*
* @param {MouseEvent} event `mouseover` event properties.
* @param {CellCoords} coords Visual cell coordinates where was fired event.
* @param {HTMLElement} TD Cell represented as HTMLElement.
* @param {object} controller An object with properties `row`, `column` and `cell`. Each property contains
* a boolean value that allows or disallows changing the selection for that particular area.
*/
function _onBeforeOnCellMouseOver(event, coords, TD, controller) {
const selectedRange = this.hot.getSelectedRangeActive();
if (!selectedRange || !_classPrivateFieldGet(_pressed, this)) {
return;
}
if (_classPrivateFieldGet(_columnsToMove, this).indexOf(coords.col) > -1) {
removeClass(this.hot.rootElement, CSS_SHOW_UI);
} else {
addClass(this.hot.rootElement, CSS_SHOW_UI);
}
controller.row = true;
controller.column = true;
controller.cell = true;
_classPrivateFieldSet(_hoveredColumn, this, coords.col);
_classPrivateFieldGet(_target, this).TD = TD;
}
/**
* `onMouseUp` hook callback.
*/
function _onMouseUp() {
const target = _classPrivateFieldGet(_target, this).col;
const columnsLen = _classPrivateFieldGet(_columnsToMove, this).length;
_classPrivateFieldSet(_hoveredColumn, this, undefined);
_classPrivateFieldSet(_pressed, this, false);
removeClass(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]);
if (this.hot.selection.isSelectedByColumnHeader()) {
addClass(this.hot.rootElement, CSS_AFTER_SELECTION);
}
if (columnsLen < 1 || target === undefined) {
return;
}
const firstMovedVisualColumn = _classPrivateFieldGet(_columnsToMove, this)[0];
const firstMovedPhysicalColumn = this.hot.toPhysicalColumn(firstMovedVisualColumn);
const movePerformed = this.dragColumns(_classPrivateFieldGet(_columnsToMove, this), target);
_classPrivateFieldGet(_columnsToMove, this).length = 0;
if (movePerformed === true) {
this.persistentStateSave();
this.hot.view.adjustElementsSize();
this.hot.render();
const selectionStart = this.hot.toVisualColumn(firstMovedPhysicalColumn);
const selectionEnd = selectionStart + columnsLen - 1;
this.hot.selectColumns(selectionStart, selectionEnd);
}
}
/**
* `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally.
*/
function _onAfterScrollVertically() {
const wtTable = this.hot.view._wt.wtTable;
const headerHeight = wtTable.getColumnHeaderHeight(0) + 1;
const scrollTop = wtTable.holder.scrollTop;
const posTop = headerHeight + scrollTop;
_classPrivateFieldGet(_backlight, this).setPosition(posTop);
_classPrivateFieldGet(_backlight, this).setSize(null, wtTable.hider.offsetHeight - posTop);
}
function _onAfterLoadData() {
this.moveBySettingsOrLoad();
}