/*!
* Copyright (c) HANDSONCODE sp. z o. o.
*
* HANDSONTABLE is a software distributed by HANDSONCODE sp. z o. o.,
* a Polish corporation, based in Gdynia, Poland, at 96/98 Aleja Zwycięstwa,
* registered with the National Court Register under number 538651,
* EU tax ID number: PL5862294002, share capital: PLN 62,800.00.
*
* This software is protected by applicable copyright laws, including
* international treaties, and dual-licensed – depending on whether
* your use is intended for or may result in commercial advantage
* or monetary compensation (commercial purposes), or not.
*
* If your use involves only such purposes as research, private study,
* evaluation and the like, you agree to be bound by the terms included
* in the “handsontable-non-commercial-license.pdf” file, available
* in the main directory of this software repository.
*
* By installing, copying, or otherwise using this software for
* commercial purposes, you agree to be bound by the terms included
* in the “handsontable-general-terms.pdf” file, available in the main
* directory of this software repository.
*
* HANDSONCODE PROVIDES THIS SOFTWARE ON AN “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND. IN NO EVENT
* AND UNDER NO LEGAL THEORY, SHALL HANDSONCODE BE LIABLE
* TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL,
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING
* FROM USE OR INABILITY TO USE THIS SOFTWARE.
*
* Version: 7.0.1
* Release date: 08/04/2019 (built at 29/03/2019 11:28:56)
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("moment"), require("hot-formula-parser"), require("pikaday"), require("numbro"));
else if(typeof define === 'function' && define.amd)
define("Handsontable", ["moment", "hot-formula-parser", "pikaday", "numbro"], factory);
else if(typeof exports === 'object')
exports["Handsontable"] = factory(require("moment"), require("hot-formula-parser"), require("pikaday"), require("numbro"));
else
root["Handsontable"] = factory(root["moment"], root["formulaParser"], root["Pikaday"], root["numbro"]);
})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE__66__, __WEBPACK_EXTERNAL_MODULE__111__, __WEBPACK_EXTERNAL_MODULE__290__, __WEBPACK_EXTERNAL_MODULE__301__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 257);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
"default": obj
};
}
module.exports = _interopRequireDefault;
/***/ }),
/* 1 */
/***/ (function(module, exports) {
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
module.exports = _classCallCheck;
/***/ }),
/* 2 */
/***/ (function(module, exports) {
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);
return Constructor;
}
module.exports = _createClass;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
__webpack_require__(18);
__webpack_require__(59);
__webpack_require__(12);
__webpack_require__(14);
exports.__esModule = true;
exports.to2dArray = to2dArray;
exports.extendArray = extendArray;
exports.pivot = pivot;
exports.arrayReduce = arrayReduce;
exports.arrayFilter = arrayFilter;
exports.arrayMap = arrayMap;
exports.arrayEach = arrayEach;
exports.arraySum = arraySum;
exports.arrayMax = arrayMax;
exports.arrayMin = arrayMin;
exports.arrayAvg = arrayAvg;
exports.arrayFlatten = arrayFlatten;
exports.arrayUnique = arrayUnique;
function to2dArray(arr) {
var ilen = arr.length;
var i = 0;
while (i < ilen) {
arr[i] = [arr[i]];
i += 1;
}
}
function extendArray(arr, extension) {
var ilen = extension.length;
var i = 0;
while (i < ilen) {
arr.push(extension[i]);
i += 1;
}
}
function pivot(arr) {
var pivotedArr = [];
if (!arr || arr.length === 0 || !arr[0] || arr[0].length === 0) {
return pivotedArr;
}
var rowCount = arr.length;
var colCount = arr[0].length;
for (var i = 0; i < rowCount; i++) {
for (var j = 0; j < colCount; j++) {
if (!pivotedArr[j]) {
pivotedArr[j] = [];
}
pivotedArr[j][i] = arr[i][j];
}
}
return pivotedArr;
}
/**
* A specialized version of `.reduce` for arrays without support for callback
* shorthands and `this` binding.
*
* {@link https://github.com/lodash/lodash/blob/master/lodash.js}
*
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {Boolean} [initFromArray] Specify using the first element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initFromArray) {
var index = -1;
var iterable = array;
var result = accumulator;
if (!Array.isArray(array)) {
iterable = Array.from(array);
}
var length = iterable.length;
if (initFromArray && length) {
index += 1;
result = iterable[index];
}
index += 1;
while (index < length) {
result = iteratee(result, iterable[index], index, iterable);
index += 1;
}
return result;
}
/**
* A specialized version of `.filter` for arrays without support for callback
* shorthands and `this` binding.
*
* {@link https://github.com/lodash/lodash/blob/master/lodash.js}
*
* @param {Array} array The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
*/
function arrayFilter(array, predicate) {
var index = 0;
var iterable = array;
if (!Array.isArray(array)) {
iterable = Array.from(array);
}
var length = iterable.length;
var result = [];
var resIndex = -1;
while (index < length) {
var value = iterable[index];
if (predicate(value, index, iterable)) {
resIndex += 1;
result[resIndex] = value;
}
index += 1;
}
return result;
}
/**
* A specialized version of `.map` for arrays without support for callback
* shorthands and `this` binding.
*
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
*/
function arrayMap(array, iteratee) {
var index = 0;
var iterable = array;
if (!Array.isArray(array)) {
iterable = Array.from(array);
}
var length = iterable.length;
var result = [];
var resIndex = -1;
while (index < length) {
var value = iterable[index];
resIndex += 1;
result[resIndex] = iteratee(value, index, iterable);
index += 1;
}
return result;
}
/**
* A specialized version of `.forEach` for arrays without support for callback
* shorthands and `this` binding.
*
* {@link https://github.com/lodash/lodash/blob/master/lodash.js}
*
* @param {Array|*} array The array to iterate over or an any element with implemented iterator protocol.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEach(array, iteratee) {
var index = 0;
var iterable = array;
if (!Array.isArray(array)) {
iterable = Array.from(array);
}
var length = iterable.length;
while (index < length) {
if (iteratee(iterable[index], index, iterable) === false) {
break;
}
index += 1;
}
return array;
}
/**
* Calculate sum value for each item of the array.
*
* @param {Array} array The array to process.
* @returns {Number} Returns calculated sum value.
*/
function arraySum(array) {
return arrayReduce(array, function (a, b) {
return a + b;
}, 0);
}
/**
* Returns the highest value from an array. Can be array of numbers or array of strings.
* NOTICE: Mixed values is not supported.
*
* @param {Array} array The array to process.
* @returns {Number} Returns the highest value from an array.
*/
function arrayMax(array) {
return arrayReduce(array, function (a, b) {
return a > b ? a : b;
}, Array.isArray(array) ? array[0] : void 0);
}
/**
* Returns the lowest value from an array. Can be array of numbers or array of strings.
* NOTICE: Mixed values is not supported.
*
* @param {Array} array The array to process.
* @returns {Number} Returns the lowest value from an array.
*/
function arrayMin(array) {
return arrayReduce(array, function (a, b) {
return a < b ? a : b;
}, Array.isArray(array) ? array[0] : void 0);
}
/**
* Calculate average value for each item of the array.
*
* @param {Array} array The array to process.
* @returns {Number} Returns calculated average value.
*/
function arrayAvg(array) {
if (!array.length) {
return 0;
}
return arraySum(array) / array.length;
}
/**
* Flatten multidimensional array.
*
* @param {Array} array Array of Arrays
* @returns {Array}
*/
function arrayFlatten(array) {
return arrayReduce(array, function (initial, value) {
return initial.concat(Array.isArray(value) ? arrayFlatten(value) : value);
}, []);
}
/**
* Unique values in the array.
*
* @param {Array} array The array to process.
* @returns {Array}
*/
function arrayUnique(array) {
var unique = [];
arrayEach(array, function (value) {
if (unique.indexOf(value) === -1) {
unique.push(value);
}
});
return unique;
}
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(46);
exports.__esModule = true;
exports.duckSchema = duckSchema;
exports.inherit = inherit;
exports.extend = extend;
exports.deepExtend = deepExtend;
exports.deepClone = deepClone;
exports.clone = clone;
exports.mixin = mixin;
exports.isObjectEqual = isObjectEqual;
exports.isObject = isObject;
exports.defineGetter = defineGetter;
exports.objectEach = objectEach;
exports.getProperty = getProperty;
exports.deepObjectSize = deepObjectSize;
exports.createObjectPropListener = createObjectPropListener;
exports.hasOwnProperty = hasOwnProperty;
var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
var _array = __webpack_require__(3);
/**
* Generate schema for passed object.
*
* @param {Array|Object} object
* @returns {Array|Object}
*/
function duckSchema(object) {
var schema;
if (Array.isArray(object)) {
schema = [];
} else {
schema = {};
objectEach(object, function (value, key) {
if (key === '__children') {
return;
}
if (value && (0, _typeof2.default)(value) === 'object' && !Array.isArray(value)) {
schema[key] = duckSchema(value);
} else if (Array.isArray(value)) {
if (value.length && (0, _typeof2.default)(value[0]) === 'object' && !Array.isArray(value[0])) {
schema[key] = [duckSchema(value[0])];
} else {
schema[key] = [];
}
} else {
schema[key] = null;
}
});
}
return schema;
}
/**
* Inherit without without calling parent constructor, and setting `Child.prototype.constructor` to `Child` instead of `Parent`.
* Creates temporary dummy function to call it as constructor.
* Described in ticket: https://github.com/handsontable/handsontable/pull/516
*
* @param {Object} Child child class
* @param {Object} Parent parent class
* @return {Object} extended Child
*/
function inherit(Child, Parent) {
Parent.prototype.constructor = Parent;
Child.prototype = new Parent();
Child.prototype.constructor = Child;
return Child;
}
/**
* Perform shallow extend of a target object with extension's own properties.
*
* @param {Object} target An object that will receive the new properties.
* @param {Object} extension An object containing additional properties to merge into the target.
*/
function extend(target, extension) {
objectEach(extension, function (value, key) {
target[key] = value;
});
return target;
}
/**
* Perform deep extend of a target object with extension's own properties.
*
* @param {Object} target An object that will receive the new properties.
* @param {Object} extension An object containing additional properties to merge into the target.
*/
function deepExtend(target, extension) {
objectEach(extension, function (value, key) {
if (extension[key] && (0, _typeof2.default)(extension[key]) === 'object') {
if (!target[key]) {
if (Array.isArray(extension[key])) {
target[key] = [];
} else if (Object.prototype.toString.call(extension[key]) === '[object Date]') {
target[key] = extension[key];
} else {
target[key] = {};
}
}
deepExtend(target[key], extension[key]);
} else {
target[key] = extension[key];
}
});
}
/**
* Perform deep clone of an object.
* WARNING! Only clones JSON properties. Will cause error when `obj` contains a function, Date, etc.
*
* @param {Object} obj An object that will be cloned
* @return {Object}
*/
function deepClone(obj) {
if ((0, _typeof2.default)(obj) === 'object') {
return JSON.parse(JSON.stringify(obj));
}
return obj;
}
/**
* Shallow clone object.
*
* @param {Object} object
* @returns {Object}
*/
function clone(object) {
var result = {};
objectEach(object, function (value, key) {
result[key] = value;
});
return result;
}
/**
* Extend the Base object (usually prototype) of the functionality the `mixins` objects.
*
* @param {Object} Base Base object which will be extended.
* @param {Object} mixins The object of the functionality will be "copied".
* @returns {Object}
*/
function mixin(Base) {
if (!Base.MIXINS) {
Base.MIXINS = [];
}
for (var _len = arguments.length, mixins = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
mixins[_key - 1] = arguments[_key];
}
(0, _array.arrayEach)(mixins, function (mixinItem) {
Base.MIXINS.push(mixinItem.MIXIN_NAME);
objectEach(mixinItem, function (value, key) {
if (Base.prototype[key] !== void 0) {
throw new Error("Mixin conflict. Property '".concat(key, "' already exist and cannot be overwritten."));
}
if (typeof value === 'function') {
Base.prototype[key] = value;
} else {
var getter = function _getter(property, initialValue) {
var propertyName = "_".concat(property);
var initValue = function initValue(newValue) {
var result = newValue;
if (Array.isArray(result) || isObject(result)) {
result = deepClone(result);
}
return result;
};
return function () {
if (this[propertyName] === void 0) {
this[propertyName] = initValue(initialValue);
}
return this[propertyName];
};
};
var setter = function _setter(property) {
var propertyName = "_".concat(property);
return function (newValue) {
this[propertyName] = newValue;
};
};
Object.defineProperty(Base.prototype, key, {
get: getter(key, value),
set: setter(key),
configurable: true
});
}
});
});
return Base;
}
/**
* Checks if two objects or arrays are (deep) equal
*
* @param {Object|Array} object1
* @param {Object|Array} object2
* @returns {Boolean}
*/
function isObjectEqual(object1, object2) {
return JSON.stringify(object1) === JSON.stringify(object2);
}
/**
* Determines whether given object is a plain Object.
* Note: String and Array are not plain Objects
* @param {*} obj
* @returns {boolean}
*/
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
function defineGetter(object, property, value, options) {
options.value = value;
options.writable = options.writable !== false;
options.enumerable = options.enumerable !== false;
options.configurable = options.configurable !== false;
Object.defineProperty(object, property, options);
}
/**
* A specialized version of `.forEach` for objects.
*
* @param {Object} object The object to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Object} Returns `object`.
*/
function objectEach(object, iteratee) {
// eslint-disable-next-line no-restricted-syntax
for (var key in object) {
if (!object.hasOwnProperty || object.hasOwnProperty && Object.prototype.hasOwnProperty.call(object, key)) {
if (iteratee(object[key], key, object) === false) {
break;
}
}
}
return object;
}
/**
* Get object property by its name. Access to sub properties can be achieved by dot notation (e.q. `'foo.bar.baz'`).
*
* @param {Object} object Object which value will be exported.
* @param {String} name Object property name.
* @returns {*}
*/
function getProperty(object, name) {
var names = name.split('.');
var result = object;
objectEach(names, function (nameItem) {
result = result[nameItem];
if (result === void 0) {
result = void 0;
return false;
}
});
return result;
}
/**
* Return object length (recursively).
*
* @param {*} object Object for which we want get length.
* @returns {Number}
*/
function deepObjectSize(object) {
if (!isObject(object)) {
return 0;
}
var recursObjLen = function recursObjLen(obj) {
var result = 0;
if (isObject(obj)) {
objectEach(obj, function (key) {
result += recursObjLen(key);
});
} else {
result += 1;
}
return result;
};
return recursObjLen(object);
}
/**
* Create object with property where its value change will be observed.
*
* @param {*} [defaultValue=undefined] Default value.
* @param {String} [propertyToListen='value'] Property to listen.
* @returns {Object}
*/
function createObjectPropListener(defaultValue) {
var _holder;
var propertyToListen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'value';
var privateProperty = "_".concat(propertyToListen);
var holder = (_holder = {
_touched: false
}, (0, _defineProperty2.default)(_holder, privateProperty, defaultValue), (0, _defineProperty2.default)(_holder, "isTouched", function isTouched() {
return this._touched;
}), _holder);
Object.defineProperty(holder, propertyToListen, {
get: function get() {
return this[privateProperty];
},
set: function set(value) {
this._touched = true;
this[privateProperty] = value;
},
enumerable: true,
configurable: true
});
return holder;
}
/**
* Check if at specified `key` there is any value for `object`.
*
* @param {Object} object Object to search value at specyfic key.
* @param {String} key String key to check.
*/
function hasOwnProperty(object, key) {
return Object.prototype.hasOwnProperty.call(object, key);
}
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(34);
__webpack_require__(12);
__webpack_require__(54);
__webpack_require__(40);
__webpack_require__(10);
__webpack_require__(130);
__webpack_require__(36);
__webpack_require__(39);
__webpack_require__(37);
__webpack_require__(46);
__webpack_require__(105);
exports.__esModule = true;
exports.getParent = getParent;
exports.closest = closest;
exports.closestDown = closestDown;
exports.isChildOf = isChildOf;
exports.isChildOfWebComponentTable = isChildOfWebComponentTable;
exports.polymerWrap = polymerWrap;
exports.polymerUnwrap = polymerUnwrap;
exports.index = index;
exports.overlayContainsElement = overlayContainsElement;
exports.hasClass = hasClass;
exports.addClass = addClass;
exports.removeClass = removeClass;
exports.removeTextNodes = removeTextNodes;
exports.empty = empty;
exports.fastInnerHTML = fastInnerHTML;
exports.fastInnerText = fastInnerText;
exports.isVisible = isVisible;
exports.offset = offset;
exports.getWindowScrollTop = getWindowScrollTop;
exports.getWindowScrollLeft = getWindowScrollLeft;
exports.getScrollTop = getScrollTop;
exports.getScrollLeft = getScrollLeft;
exports.getScrollableElement = getScrollableElement;
exports.getTrimmingContainer = getTrimmingContainer;
exports.getStyle = getStyle;
exports.getComputedStyle = getComputedStyle;
exports.outerWidth = outerWidth;
exports.outerHeight = outerHeight;
exports.innerHeight = innerHeight;
exports.innerWidth = innerWidth;
exports.addEvent = addEvent;
exports.removeEvent = removeEvent;
exports.getCaretPosition = getCaretPosition;
exports.getSelectionEndPosition = getSelectionEndPosition;
exports.getSelectionText = getSelectionText;
exports.clearTextSelection = clearTextSelection;
exports.setCaretPosition = setCaretPosition;
exports.getScrollbarWidth = getScrollbarWidth;
exports.hasVerticalScrollbar = hasVerticalScrollbar;
exports.hasHorizontalScrollbar = hasHorizontalScrollbar;
exports.setOverlayPosition = setOverlayPosition;
exports.getCssTransform = getCssTransform;
exports.resetCssTransform = resetCssTransform;
exports.isInput = isInput;
exports.isOutsideInput = isOutsideInput;
exports.selectElementIfAllowed = selectElementIfAllowed;
exports.HTML_CHARACTERS = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _browser = __webpack_require__(72);
var _feature = __webpack_require__(73);
/**
* Get the parent of the specified node in the DOM tree.
*
* @param {HTMLElement} element Element from which traversing is started.
* @param {Number} [level=0] Traversing deep level.
* @return {HTMLElement|null}
*/
function getParent(element) {
var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var iteration = -1;
var parent = null;
var elementToCheck = element;
while (elementToCheck !== null) {
if (iteration === level) {
parent = elementToCheck;
break;
}
if (elementToCheck.host && elementToCheck.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
elementToCheck = elementToCheck.host;
} else {
iteration += 1;
elementToCheck = elementToCheck.parentNode;
}
}
return parent;
}
/**
* Goes up the DOM tree (including given element) until it finds an element that matches the nodes or nodes name.
* This method goes up through web components.
*
* @param {HTMLElement} element Element from which traversing is started
* @param {Array} nodes Array of elements or Array of elements name
* @param {HTMLElement} [until]
* @returns {HTMLElement|null}
*/
function closest(element, nodes, until) {
var elementToCheck = element;
while (elementToCheck !== null && elementToCheck !== until) {
if (elementToCheck.nodeType === Node.ELEMENT_NODE && (nodes.indexOf(elementToCheck.nodeName) > -1 || nodes.indexOf(elementToCheck) > -1)) {
return elementToCheck;
}
if (elementToCheck.host && elementToCheck.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
elementToCheck = elementToCheck.host;
} else {
elementToCheck = elementToCheck.parentNode;
}
}
return null;
}
/**
* Goes "down" the DOM tree (including given element) until it finds an element that matches the nodes or nodes name.
*
* @param {HTMLElement} element Element from which traversing is started
* @param {Array} nodes Array of elements or Array of elements name
* @param {HTMLElement} [until]
* @returns {HTMLElement|null}
*/
function closestDown(element, nodes, until) {
var matched = [];
var elementToCheck = element;
while (elementToCheck) {
elementToCheck = closest(elementToCheck, nodes, until);
if (!elementToCheck || until && !until.contains(elementToCheck)) {
break;
}
matched.push(elementToCheck);
if (elementToCheck.host && elementToCheck.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
elementToCheck = elementToCheck.host;
} else {
elementToCheck = elementToCheck.parentNode;
}
}
var length = matched.length;
return length ? matched[length - 1] : null;
}
/**
* Goes up the DOM tree and checks if element is child of another element.
*
* @param child Child element
* @param {Object|String} parent Parent element OR selector of the parent element.
* If string provided, function returns `true` for the first occurrence of element with that class.
* @returns {Boolean}
*/
function isChildOf(child, parent) {
var node = child.parentNode;
var queriedParents = [];
if (typeof parent === 'string') {
queriedParents = Array.prototype.slice.call(child.ownerDocument.querySelectorAll(parent), 0);
} else {
queriedParents.push(parent);
}
while (node !== null) {
if (queriedParents.indexOf(node) > -1) {
return true;
}
node = node.parentNode;
}
return false;
}
/**
* Check if an element is part of `hot-table` web component.
*
* @param {Element} element
* @returns {Boolean}
*/
function isChildOfWebComponentTable(element) {
var hotTableName = 'hot-table';
var result = false;
var parentNode = polymerWrap(element);
function isHotTable(testElement) {
return testElement.nodeType === Node.ELEMENT_NODE && testElement.nodeName === hotTableName.toUpperCase();
}
while (parentNode !== null) {
if (isHotTable(parentNode)) {
result = true;
break;
} else if (parentNode.host && parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
result = isHotTable(parentNode.host);
if (result) {
break;
}
parentNode = parentNode.host;
}
parentNode = parentNode.parentNode;
}
return result;
}
/* global Polymer wrap unwrap */
/**
* Wrap element into polymer/webcomponent container if exists
*
* @param element
* @returns {*}
*/
function polymerWrap(element) {
return typeof Polymer !== 'undefined' && typeof wrap === 'function' ? wrap(element) : element;
}
/**
* Unwrap element from polymer/webcomponent container if exists
*
* @param element
* @returns {*}
*/
function polymerUnwrap(element) {
return typeof Polymer !== 'undefined' && typeof unwrap === 'function' ? unwrap(element) : element;
}
/**
* Counts index of element within its parent
* WARNING: for performance reasons, assumes there are only element nodes (no text nodes). This is true for Walkotnable
* Otherwise would need to check for nodeType or use previousElementSibling
*
* @see http://jsperf.com/sibling-index/10
* @param {Element} element
* @return {Number}
*/
function index(element) {
var i = 0;
var elementToCheck = element;
if (elementToCheck.previousSibling) {
/* eslint-disable no-cond-assign */
while (elementToCheck = elementToCheck.previousSibling) {
i += 1;
}
}
return i;
}
/**
* Check if the provided overlay contains the provided element
*
* @param {String} overlay
* @param {HTMLElement} element
* @returns {boolean}
*/
function overlayContainsElement(overlayType, element) {
var overlayElement = element.ownerDocument.querySelector(".ht_clone_".concat(overlayType));
return overlayElement ? overlayElement.contains(element) : null;
}
var _hasClass;
var _addClass;
var _removeClass;
function filterEmptyClassNames(classNames) {
var result = [];
if (!classNames || !classNames.length) {
return result;
}
var len = 0;
while (classNames[len]) {
result.push(classNames[len]);
len += 1;
}
return result;
}
if ((0, _feature.isClassListSupported)()) {
var isSupportMultipleClassesArg = function isSupportMultipleClassesArg(rootDocument) {
var element = rootDocument.createElement('div');
element.classList.add('test', 'test2');
return element.classList.contains('test2');
};
_hasClass = function _hasClass(element, className) {
if (element.classList === void 0 || typeof className !== 'string' || className === '') {
return false;
}
return element.classList.contains(className);
};
_addClass = function _addClass(element, classes) {
var rootDocument = element.ownerDocument;
var className = classes;
if (typeof className === 'string') {
className = className.split(' ');
}
className = filterEmptyClassNames(className);
if (className.length > 0) {
if (isSupportMultipleClassesArg(rootDocument)) {
var _element$classList;
(_element$classList = element.classList).add.apply(_element$classList, (0, _toConsumableArray2.default)(className));
} else {
var len = 0;
while (className && className[len]) {
element.classList.add(className[len]);
len += 1;
}
}
}
};
_removeClass = function _removeClass(element, classes) {
var className = classes;
if (typeof className === 'string') {
className = className.split(' ');
}
className = filterEmptyClassNames(className);
if (className.length > 0) {
if (isSupportMultipleClassesArg) {
var _element$classList2;
(_element$classList2 = element.classList).remove.apply(_element$classList2, (0, _toConsumableArray2.default)(className));
} else {
var len = 0;
while (className && className[len]) {
element.classList.remove(className[len]);
len += 1;
}
}
}
};
} else {
var createClassNameRegExp = function createClassNameRegExp(className) {
return new RegExp("(\\s|^)".concat(className, "(\\s|$)"));
};
_hasClass = function _hasClass(element, className) {
// http://snipplr.com/view/3561/addclass-removeclass-hasclass/
return element.className !== void 0 && createClassNameRegExp(className).test(element.className);
};
_addClass = function _addClass(element, classes) {
var len = 0;
var _className = element.className;
var className = classes;
if (typeof className === 'string') {
className = className.split(' ');
}
if (_className === '') {
_className = className.join(' ');
} else {
while (className && className[len]) {
if (!createClassNameRegExp(className[len]).test(_className)) {
_className += " ".concat(className[len]);
}
len += 1;
}
}
element.className = _className;
};
_removeClass = function _removeClass(element, classes) {
var len = 0;
var _className = element.className;
var className = classes;
if (typeof className === 'string') {
className = className.split(' ');
}
while (className && className[len]) {
// String.prototype.trim is defined in polyfill.js
_className = _className.replace(createClassNameRegExp(className[len]), ' ').trim();
len += 1;
}
if (element.className !== _className) {
element.className = _className;
}
};
}
/**
* Checks if element has class name
*
* @param {HTMLElement} element
* @param {String} className Class name to check
* @returns {Boolean}
*/
function hasClass(element, className) {
return _hasClass(element, className);
}
/**
* Add class name to an element
*
* @param {HTMLElement} element
* @param {String|Array} className Class name as string or array of strings
*/
function addClass(element, className) {
return _addClass(element, className);
}
/**
* Remove class name from an element
*
* @param {HTMLElement} element
* @param {String|Array} className Class name as string or array of strings
*/
function removeClass(element, className) {
return _removeClass(element, className);
}
function removeTextNodes(element, parent) {
if (element.nodeType === 3) {
parent.removeChild(element); // bye text nodes!
} else if (['TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TR'].indexOf(element.nodeName) > -1) {
var childs = element.childNodes;
for (var i = childs.length - 1; i >= 0; i--) {
removeTextNodes(childs[i], element);
}
}
}
/**
* Remove childs function
* WARNING - this doesn't unload events and data attached by jQuery
* http://jsperf.com/jquery-html-vs-empty-vs-innerhtml/9
* http://jsperf.com/jquery-html-vs-empty-vs-innerhtml/11 - no siginificant improvement with Chrome remove() method
*
* @param element
* @returns {void}
*/
//
function empty(element) {
var child;
/* eslint-disable no-cond-assign */
while (child = element.lastChild) {
element.removeChild(child);
}
}
var HTML_CHARACTERS = /(<(.*)>|&(.*);)/;
/**
* Insert content into element trying avoid innerHTML method.
* @return {void}
*/
exports.HTML_CHARACTERS = HTML_CHARACTERS;
function fastInnerHTML(element, content) {
if (HTML_CHARACTERS.test(content)) {
element.innerHTML = content;
} else {
fastInnerText(element, content);
}
}
/**
* Insert text content into element
* @return {Boolean}
*/
function fastInnerText(element, content) {
var child = element.firstChild;
if (child && child.nodeType === 3 && child.nextSibling === null) {
// fast lane - replace existing text node
if (_feature.isTextContentSupported) {
// http://jsperf.com/replace-text-vs-reuse
child.textContent = content;
} else {
// http://jsperf.com/replace-text-vs-reuse
child.data = content;
}
} else {
// slow lane - empty element and insert a text node
empty(element);
element.appendChild(element.ownerDocument.createTextNode(content));
}
}
/**
* Returns true if element is attached to the DOM and visible, false otherwise
* @param elem
* @returns {boolean}
*/
function isVisible(elem) {
var documentElement = elem.ownerDocument.documentElement;
var next = elem;
while (polymerUnwrap(next) !== documentElement) {
// until reached
if (next === null) {
// parent detached from DOM
return false;
} else if (next.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
if (next.host) {
// this is Web Components Shadow DOM
// see: http://w3c.github.io/webcomponents/spec/shadow/#encapsulation
// according to spec, should be if (next.ownerDocument !== window.document), but that doesn't work yet
if (next.host.impl) {
// Chrome 33.0.1723.0 canary (2013-11-29) Web Platform features disabled
return isVisible(next.host.impl);
} else if (next.host) {
// Chrome 33.0.1723.0 canary (2013-11-29) Web Platform features enabled
return isVisible(next.host);
}
throw new Error('Lost in Web Components world');
} else {
return false; // this is a node detached from document in IE8
}
} else if (next.style && next.style.display === 'none') {
return false;
}
next = next.parentNode;
}
return true;
}
/**
* Returns elements top and left offset relative to the document. Function is not compatible with jQuery offset.
*
* @param {HTMLElement} elem
* @return {Object} Returns object with `top` and `left` props
*/
function offset(elem) {
var rootDocument = elem.ownerDocument;
var rootWindow = rootDocument.defaultView;
var documentElement = rootDocument.documentElement;
var elementToCheck = elem;
var offsetLeft;
var offsetTop;
var lastElem;
var box;
if ((0, _feature.hasCaptionProblem)() && elementToCheck.firstChild && elementToCheck.firstChild.nodeName === 'CAPTION') {
// fixes problem with Firefox ignoring
in TABLE offset (see also export outerHeight)
// http://jsperf.com/offset-vs-getboundingclientrect/8
box = elementToCheck.getBoundingClientRect();
return {
top: box.top + (rootWindow.pageYOffset || documentElement.scrollTop) - (documentElement.clientTop || 0),
left: box.left + (rootWindow.pageXOffset || documentElement.scrollLeft) - (documentElement.clientLeft || 0)
};
}
offsetLeft = elementToCheck.offsetLeft;
offsetTop = elementToCheck.offsetTop;
lastElem = elementToCheck;
/* eslint-disable no-cond-assign */
while (elementToCheck = elementToCheck.offsetParent) {
// from my observation, document.body always has scrollLeft/scrollTop == 0
if (elementToCheck === rootDocument.body) {
break;
}
offsetLeft += elementToCheck.offsetLeft;
offsetTop += elementToCheck.offsetTop;
lastElem = elementToCheck;
} // slow - http://jsperf.com/offset-vs-getboundingclientrect/6
if (lastElem && lastElem.style.position === 'fixed') {
// if(lastElem !== document.body) { //faster but does gives false positive in Firefox
offsetLeft += rootWindow.pageXOffset || documentElement.scrollLeft;
offsetTop += rootWindow.pageYOffset || documentElement.scrollTop;
}
return {
left: offsetLeft,
top: offsetTop
};
}
/**
* Returns the document's scrollTop property.
*
* @param {Window} rootWindow
* @returns {Number}
*/
// eslint-disable-next-line no-restricted-globals
function getWindowScrollTop() {
var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
var res = rootWindow.scrollY;
if (res === void 0) {
// IE8-11
res = rootWindow.document.documentElement.scrollTop;
}
return res;
}
/**
* Returns the document's scrollLeft property.
*
* @param {Window} rootWindow
* @returns {Number}
*/
// eslint-disable-next-line no-restricted-globals
function getWindowScrollLeft() {
var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
var res = rootWindow.scrollX;
if (res === void 0) {
// IE8-11
res = rootWindow.document.documentElement.scrollLeft;
}
return res;
}
/**
* Returns the provided element's scrollTop property.
*
* @param element
* @param {Window} rootWindow
* @returns {Number}
*/
// eslint-disable-next-line no-restricted-globals
function getScrollTop(element) {
var rootWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;
if (element === rootWindow) {
return getWindowScrollTop(rootWindow);
}
return element.scrollTop;
}
/**
* Returns the provided element's scrollLeft property.
*
* @param element
* @param {Window} rootWindow
* @returns {Number}
*/
// eslint-disable-next-line no-restricted-globals
function getScrollLeft(element) {
var rootWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;
if (element === rootWindow) {
return getWindowScrollLeft(rootWindow);
}
return element.scrollLeft;
}
/**
* Returns a DOM element responsible for scrolling of the provided element.
*
* @param {HTMLElement} element
* @returns {HTMLElement} Element's scrollable parent
*/
function getScrollableElement(element) {
var rootDocument = element.ownerDocument;
var rootWindow = rootDocument ? rootDocument.defaultView : void 0;
if (!rootDocument) {
rootDocument = element.document ? element.document : element;
rootWindow = rootDocument.defaultView;
}
var props = ['auto', 'scroll'];
var supportedGetComputedStyle = (0, _feature.isGetComputedStyleSupported)();
var el = element.parentNode;
while (el && el.style && rootDocument.body !== el) {
var _el$style = el.style,
overflow = _el$style.overflow,
overflowX = _el$style.overflowX,
overflowY = _el$style.overflowY;
if ([overflow, overflowX, overflowY].includes('scroll')) {
return el;
} else if (supportedGetComputedStyle) {
var _rootWindow$getComput = rootWindow.getComputedStyle(el);
overflow = _rootWindow$getComput.overflow;
overflowX = _rootWindow$getComput.overflowX;
overflowY = _rootWindow$getComput.overflowY;
if (props.includes(overflow) || props.includes(overflowX) || props.includes(overflowY)) {
return el;
}
} // The '+ 1' after the scrollHeight/scrollWidth is to prevent problems with zoomed out Chrome.
if (el.clientHeight <= el.scrollHeight + 1 && (props.includes(overflowY) || props.includes(overflow))) {
return el;
}
if (el.clientWidth <= el.scrollWidth + 1 && (props.includes(overflowX) || props.includes(overflow))) {
return el;
}
el = el.parentNode;
}
return rootWindow;
}
/**
* Returns a DOM element responsible for trimming the provided element.
*
* @param {HTMLElement} base Base element
* @returns {HTMLElement} Base element's trimming parent
*/
function getTrimmingContainer(base) {
var rootDocument = base.ownerDocument;
var rootWindow = rootDocument.defaultView;
var el = base.parentNode;
while (el && el.style && rootDocument.body !== el) {
if (el.style.overflow !== 'visible' && el.style.overflow !== '') {
return el;
}
var computedStyle = getComputedStyle(el, rootWindow);
var allowedProperties = ['scroll', 'hidden', 'auto'];
var property = computedStyle.getPropertyValue('overflow');
var propertyY = computedStyle.getPropertyValue('overflow-y');
var propertyX = computedStyle.getPropertyValue('overflow-x');
if (allowedProperties.includes(property) || allowedProperties.includes(propertyY) || allowedProperties.includes(propertyX)) {
return el;
}
el = el.parentNode;
}
return rootWindow;
}
/**
* Returns a style property for the provided element. (Be it an inline or external style).
*
* @param {HTMLElement} element
* @param {String} prop Wanted property
* @param {Window} rootWindow
* @returns {String|undefined} Element's style property
*/
// eslint-disable-next-line no-restricted-globals
function getStyle(element, prop) {
var rootWindow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window;
if (!element) {
return;
} else if (element === rootWindow) {
if (prop === 'width') {
return "".concat(rootWindow.innerWidth, "px");
} else if (prop === 'height') {
return "".concat(rootWindow.innerHeight, "px");
}
return;
}
var styleProp = element.style[prop];
if (styleProp !== '' && styleProp !== void 0) {
return styleProp;
}
var computedStyle = getComputedStyle(element, rootWindow);
if (computedStyle[prop] !== '' && computedStyle[prop] !== void 0) {
return computedStyle[prop];
}
}
/**
* Returns a computed style object for the provided element. (Needed if style is declared in external stylesheet).
*
* @param element
* @param {Window} rootWindow
* @returns {IEElementStyle|CssStyle} Elements computed style object
*/
// eslint-disable-next-line no-restricted-globals
function getComputedStyle(element) {
var rootWindow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;
return element.currentStyle || rootWindow.getComputedStyle(element);
}
/**
* Returns the element's outer width.
*
* @param element
* @returns {number} Element's outer width
*/
function outerWidth(element) {
return element.offsetWidth;
}
/**
* Returns the element's outer height
*
* @param elem
* @returns {number} Element's outer height
*/
function outerHeight(elem) {
if ((0, _feature.hasCaptionProblem)() && elem.firstChild && elem.firstChild.nodeName === 'CAPTION') {
// fixes problem with Firefox ignoring
in TABLE.offsetHeight
// jQuery (1.10.1) still has this unsolved
// may be better to just switch to getBoundingClientRect
// http://bililite.com/blog/2009/03/27/finding-the-size-of-a-table/
// http://lists.w3.org/Archives/Public/www-style/2009Oct/0089.html
// http://bugs.jquery.com/ticket/2196
// http://lists.w3.org/Archives/Public/www-style/2009Oct/0140.html#start140
return elem.offsetHeight + elem.firstChild.offsetHeight;
}
return elem.offsetHeight;
}
/**
* Returns the element's inner height.
*
* @param element
* @returns {number} Element's inner height
*/
function innerHeight(element) {
return element.clientHeight || element.innerHeight;
}
/**
* Returns the element's inner width.
*
* @param element
* @returns {number} Element's inner width
*/
function innerWidth(element) {
return element.clientWidth || element.innerWidth;
}
function addEvent(element, event, callback) {
var rootWindow = element.defaultView;
if (!rootWindow) {
rootWindow = element.document ? element : element.ownerDocument.defaultView;
}
if (rootWindow.addEventListener) {
element.addEventListener(event, callback, false);
} else {
element.attachEvent("on".concat(event), callback);
}
}
function removeEvent(element, event, callback) {
var rootWindow = element.defaultView;
if (!rootWindow) {
rootWindow = element.document ? element : element.ownerDocument.defaultView;
}
if (rootWindow.removeEventListener) {
element.removeEventListener(event, callback, false);
} else {
element.detachEvent("on".concat(event), callback);
}
}
/**
* Returns caret position in text input
*
* @author https://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
* @return {Number}
*/
function getCaretPosition(el) {
var rootDocument = el.ownerDocument;
if (el.selectionStart) {
return el.selectionStart;
} else if (rootDocument.selection) {
// IE8
el.focus();
var r = rootDocument.selection.createRange();
if (r === null) {
return 0;
}
var re = el.createTextRange();
var rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
/**
* Returns end of the selection in text input
*
* @return {Number}
*/
function getSelectionEndPosition(el) {
var rootDocument = el.ownerDocument;
if (el.selectionEnd) {
return el.selectionEnd;
} else if (rootDocument.selection) {
// IE8
var r = rootDocument.selection.createRange();
if (r === null) {
return 0;
}
var re = el.createTextRange();
return re.text.indexOf(r.text) + r.text.length;
}
return 0;
}
/**
* Returns text under selection.
*
* @param {Window} rootWindow
* @returns {String}
*/
// eslint-disable-next-line no-restricted-globals
function getSelectionText() {
var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
var rootDocument = rootWindow.document;
var text = '';
if (rootWindow.getSelection) {
text = rootWindow.getSelection().toString();
} else if (rootDocument.selection && rootDocument.selection.type !== 'Control') {
text = rootDocument.selection.createRange().text;
}
return text;
}
/**
* Cross-platform helper to clear text selection.
*
* @param {Window} rootWindow
*/
// eslint-disable-next-line no-restricted-globals
function clearTextSelection() {
var rootWindow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
var rootDocument = rootWindow.document; // http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript
if (rootWindow.getSelection) {
if (rootWindow.getSelection().empty) {
// Chrome
rootWindow.getSelection().empty();
} else if (rootWindow.getSelection().removeAllRanges) {
// Firefox
rootWindow.getSelection().removeAllRanges();
}
} else if (rootDocument.selection) {
// IE?
rootDocument.selection.empty();
}
}
/**
* Sets caret position in text input.
*
* @author http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/
* @param {Element} element
* @param {Number} pos
* @param {Number} endPos
*/
function setCaretPosition(element, pos, endPos) {
if (endPos === void 0) {
endPos = pos;
}
if (element.setSelectionRange) {
element.focus();
try {
element.setSelectionRange(pos, endPos);
} catch (err) {
var elementParent = element.parentNode;
var parentDisplayValue = elementParent.style.display;
elementParent.style.display = 'block';
element.setSelectionRange(pos, endPos);
elementParent.style.display = parentDisplayValue;
}
} else if (element.createTextRange) {
// IE8
var range = element.createTextRange();
range.collapse(true);
range.moveEnd('character', endPos);
range.moveStart('character', pos);
range.select();
}
}
var cachedScrollbarWidth;
/**
* Helper to calculate scrollbar width.
* Source: https://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes
*
* @private
* @param {Document} rootDocument
*/
// eslint-disable-next-line no-restricted-globals
function walkontableCalculateScrollbarWidth() {
var rootDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
var inner = rootDocument.createElement('div');
inner.style.height = '200px';
inner.style.width = '100%';
var outer = rootDocument.createElement('div');
outer.style.boxSizing = 'content-box';
outer.style.height = '150px';
outer.style.left = '0px';
outer.style.overflow = 'hidden';
outer.style.position = 'absolute';
outer.style.top = '0px';
outer.style.width = '200px';
outer.style.visibility = 'hidden';
outer.appendChild(inner);
(rootDocument.body || rootDocument.documentElement).appendChild(outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 === w2) {
w2 = outer.clientWidth;
}
(rootDocument.body || rootDocument.documentElement).removeChild(outer);
return w1 - w2;
}
/**
* Returns the computed width of the native browser scroll bar.
*
* @param {Document} rootDocument
* @return {Number} width
*/
// eslint-disable-next-line no-restricted-globals
function getScrollbarWidth() {
var rootDocument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document;
if (cachedScrollbarWidth === void 0) {
cachedScrollbarWidth = walkontableCalculateScrollbarWidth(rootDocument);
}
return cachedScrollbarWidth;
}
/**
* Checks if the provided element has a vertical scrollbar.
*
* @param {HTMLElement} element
* @returns {Boolean}
*/
function hasVerticalScrollbar(element) {
return element.offsetWidth !== element.clientWidth;
}
/**
* Checks if the provided element has a vertical scrollbar.
*
* @param {HTMLElement} element
* @returns {Boolean}
*/
function hasHorizontalScrollbar(element) {
return element.offsetHeight !== element.clientHeight;
}
/**
* Sets overlay position depending on it's type and used browser
*/
function setOverlayPosition(overlayElem, left, top) {
if ((0, _browser.isIE8)() || (0, _browser.isIE9)()) {
overlayElem.style.top = top;
overlayElem.style.left = left;
} else if ((0, _browser.isSafari)()) {
overlayElem.style['-webkit-transform'] = "translate3d(".concat(left, ",").concat(top, ",0)");
overlayElem.style['-webkit-transform'] = "translate3d(".concat(left, ",").concat(top, ",0)");
} else {
overlayElem.style.transform = "translate3d(".concat(left, ",").concat(top, ",0)");
}
}
function getCssTransform(element) {
var transform;
if (element.style.transform && (transform = element.style.transform) !== '') {
return ['transform', transform];
} else if (element.style['-webkit-transform'] && (transform = element.style['-webkit-transform']) !== '') {
return ['-webkit-transform', transform];
}
return -1;
}
function resetCssTransform(element) {
if (element.style.transform && element.style.transform !== '') {
element.style.transform = '';
} else if (element.style['-webkit-transform'] && element.style['-webkit-transform'] !== '') {
element.style['-webkit-transform'] = '';
}
}
/**
* Determines if the given DOM element is an input field.
* Notice: By 'input' we mean input, textarea and select nodes
*
* @param {HTMLElement} element - DOM element
* @returns {Boolean}
*/
function isInput(element) {
var inputs = ['INPUT', 'SELECT', 'TEXTAREA'];
return element && (inputs.indexOf(element.nodeName) > -1 || element.contentEditable === 'true');
}
/**
* Determines if the given DOM element is an input field placed OUTSIDE of HOT.
* Notice: By 'input' we mean input, textarea and select nodes
*
* @param {HTMLElement} element - DOM element
* @returns {Boolean}
*/
function isOutsideInput(element) {
return isInput(element) && element.className.indexOf('handsontableInput') === -1 && element.className.indexOf('copyPaste') === -1;
}
/**
* Check if the given DOM element can be focused (by using "select" method).
*
* @param {HTMLElement} element - DOM element
*/
function selectElementIfAllowed(element) {
var activeElement = element.ownerDocument.activeElement;
if (!isOutsideInput(activeElement)) {
element.select();
}
}
/***/ }),
/* 6 */
/***/ (function(module, exports) {
function _getPrototypeOf(o) {
module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
module.exports = _getPrototypeOf;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
var _typeof = __webpack_require__(44);
var assertThisInitialized = __webpack_require__(26);
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
}
return assertThisInitialized(self);
}
module.exports = _possibleConstructorReturn;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
var setPrototypeOf = __webpack_require__(274);
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) setPrototypeOf(subClass, superClass);
}
module.exports = _inherits;
/***/ }),
/* 9 */
/***/ (function(module, exports) {
function _interopRequireWildcard(obj) {
if (obj && obj.__esModule) {
return obj;
} else {
var newObj = {};
if (obj != null) {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
if (desc.get || desc.set) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
}
newObj["default"] = obj;
return newObj;
}
}
module.exports = _interopRequireWildcard;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
var toString = __webpack_require__(266);
var ObjectPrototype = Object.prototype;
// `Object.prototype.toString` method
// https://tc39.github.io/ecma262/#sec-object.prototype.tostring
if (toString !== ObjectPrototype.toString) {
__webpack_require__(64)(ObjectPrototype, 'toString', toString, { unsafe: true });
}
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE = exports.FILTERS_BUTTONS_PLACEHOLDER_VALUE = exports.FILTERS_BUTTONS_PLACEHOLDER_SEARCH = exports.FILTERS_BUTTONS_CANCEL = exports.FILTERS_BUTTONS_OK = exports.FILTERS_BUTTONS_CLEAR = exports.FILTERS_BUTTONS_SELECT_ALL = exports.FILTERS_VALUES_BLANK_CELLS = exports.FILTERS_LABELS_DISJUNCTION = exports.FILTERS_LABELS_CONJUNCTION = exports.FILTERS_DIVS_FILTER_BY_VALUE = exports.FILTERS_DIVS_FILTER_BY_CONDITION = exports.FILTERS_CONDITIONS_YESTERDAY = exports.FILTERS_CONDITIONS_TOMORROW = exports.FILTERS_CONDITIONS_TODAY = exports.FILTERS_CONDITIONS_BEFORE = exports.FILTERS_CONDITIONS_AFTER = exports.FILTERS_CONDITIONS_NOT_BETWEEN = exports.FILTERS_CONDITIONS_BETWEEN = exports.FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL = exports.FILTERS_CONDITIONS_LESS_THAN = exports.FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL = exports.FILTERS_CONDITIONS_GREATER_THAN = exports.FILTERS_CONDITIONS_BY_VALUE = exports.FILTERS_CONDITIONS_NOT_CONTAIN = exports.FILTERS_CONDITIONS_CONTAINS = exports.FILTERS_CONDITIONS_ENDS_WITH = exports.FILTERS_CONDITIONS_BEGINS_WITH = exports.FILTERS_CONDITIONS_NOT_EQUAL = exports.FILTERS_CONDITIONS_EQUAL = exports.FILTERS_CONDITIONS_NOT_EMPTY = exports.FILTERS_CONDITIONS_EMPTY = exports.FILTERS_CONDITIONS_NONE = exports.FILTERS_CONDITIONS_NAMESPACE = exports.FILTERS_NAMESPACE = exports.CONTEXTMENU_ITEMS_SHOW_ROW = exports.CONTEXTMENU_ITEMS_HIDE_ROW = exports.CONTEXTMENU_ITEMS_SHOW_COLUMN = exports.CONTEXTMENU_ITEMS_HIDE_COLUMN = exports.CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD = exports.CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD = exports.CONTEXTMENU_ITEMS_REMOVE_BORDERS = exports.CONTEXTMENU_ITEMS_BORDERS_LEFT = exports.CONTEXTMENU_ITEMS_BORDERS_BOTTOM = exports.CONTEXTMENU_ITEMS_BORDERS_RIGHT = exports.CONTEXTMENU_ITEMS_BORDERS_TOP = exports.CONTEXTMENU_ITEMS_BORDERS = exports.CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM = exports.CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE = exports.CONTEXTMENU_ITEMS_ALIGNMENT_TOP = exports.CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY = exports.CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT = exports.CONTEXTMENU_ITEMS_ALIGNMENT_CENTER = exports.CONTEXTMENU_ITEMS_ALIGNMENT_LEFT = exports.CONTEXTMENU_ITEMS_ALIGNMENT = exports.CONTEXTMENU_ITEMS_READ_ONLY_COMMENT = exports.CONTEXTMENU_ITEMS_REMOVE_COMMENT = exports.CONTEXTMENU_ITEMS_EDIT_COMMENT = exports.CONTEXTMENU_ITEMS_ADD_COMMENT = exports.CONTEXTMENU_ITEMS_UNMERGE_CELLS = exports.CONTEXTMENU_ITEMS_MERGE_CELLS = exports.CONTEXTMENU_ITEMS_UNFREEZE_COLUMN = exports.CONTEXTMENU_ITEMS_FREEZE_COLUMN = exports.CONTEXTMENU_ITEMS_CUT = exports.CONTEXTMENU_ITEMS_COPY = exports.CONTEXTMENU_ITEMS_CLEAR_COLUMN = exports.CONTEXTMENU_ITEMS_READ_ONLY = exports.CONTEXTMENU_ITEMS_REDO = exports.CONTEXTMENU_ITEMS_UNDO = exports.CONTEXTMENU_ITEMS_REMOVE_COLUMN = exports.CONTEXTMENU_ITEMS_REMOVE_ROW = exports.CONTEXTMENU_ITEMS_INSERT_RIGHT = exports.CONTEXTMENU_ITEMS_INSERT_LEFT = exports.CONTEXTMENU_ITEMS_ROW_BELOW = exports.CONTEXTMENU_ITEMS_ROW_ABOVE = exports.CONTEXTMENU_ITEMS_NO_ITEMS = exports.CONTEXT_MENU_ITEMS_NAMESPACE = void 0;
/**
* Constants for parts of translation.
*/
var CONTEXT_MENU_ITEMS_NAMESPACE = 'ContextMenu:items';
exports.CONTEXT_MENU_ITEMS_NAMESPACE = CONTEXT_MENU_ITEMS_NAMESPACE;
var CONTEXTMENU_ITEMS_NO_ITEMS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".noItems");
exports.CONTEXTMENU_ITEMS_NO_ITEMS = CONTEXTMENU_ITEMS_NO_ITEMS;
var CONTEXTMENU_ITEMS_ROW_ABOVE = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertRowAbove");
exports.CONTEXTMENU_ITEMS_ROW_ABOVE = CONTEXTMENU_ITEMS_ROW_ABOVE;
var CONTEXTMENU_ITEMS_ROW_BELOW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertRowBelow");
exports.CONTEXTMENU_ITEMS_ROW_BELOW = CONTEXTMENU_ITEMS_ROW_BELOW;
var CONTEXTMENU_ITEMS_INSERT_LEFT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertColumnOnTheLeft");
exports.CONTEXTMENU_ITEMS_INSERT_LEFT = CONTEXTMENU_ITEMS_INSERT_LEFT;
var CONTEXTMENU_ITEMS_INSERT_RIGHT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".insertColumnOnTheRight");
exports.CONTEXTMENU_ITEMS_INSERT_RIGHT = CONTEXTMENU_ITEMS_INSERT_RIGHT;
var CONTEXTMENU_ITEMS_REMOVE_ROW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".removeRow");
exports.CONTEXTMENU_ITEMS_REMOVE_ROW = CONTEXTMENU_ITEMS_REMOVE_ROW;
var CONTEXTMENU_ITEMS_REMOVE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".removeColumn");
exports.CONTEXTMENU_ITEMS_REMOVE_COLUMN = CONTEXTMENU_ITEMS_REMOVE_COLUMN;
var CONTEXTMENU_ITEMS_UNDO = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".undo");
exports.CONTEXTMENU_ITEMS_UNDO = CONTEXTMENU_ITEMS_UNDO;
var CONTEXTMENU_ITEMS_REDO = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".redo");
exports.CONTEXTMENU_ITEMS_REDO = CONTEXTMENU_ITEMS_REDO;
var CONTEXTMENU_ITEMS_READ_ONLY = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".readOnly");
exports.CONTEXTMENU_ITEMS_READ_ONLY = CONTEXTMENU_ITEMS_READ_ONLY;
var CONTEXTMENU_ITEMS_CLEAR_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".clearColumn");
exports.CONTEXTMENU_ITEMS_CLEAR_COLUMN = CONTEXTMENU_ITEMS_CLEAR_COLUMN;
var CONTEXTMENU_ITEMS_COPY = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".copy");
exports.CONTEXTMENU_ITEMS_COPY = CONTEXTMENU_ITEMS_COPY;
var CONTEXTMENU_ITEMS_CUT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".cut");
exports.CONTEXTMENU_ITEMS_CUT = CONTEXTMENU_ITEMS_CUT;
var CONTEXTMENU_ITEMS_FREEZE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".freezeColumn");
exports.CONTEXTMENU_ITEMS_FREEZE_COLUMN = CONTEXTMENU_ITEMS_FREEZE_COLUMN;
var CONTEXTMENU_ITEMS_UNFREEZE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".unfreezeColumn");
exports.CONTEXTMENU_ITEMS_UNFREEZE_COLUMN = CONTEXTMENU_ITEMS_UNFREEZE_COLUMN;
var CONTEXTMENU_ITEMS_MERGE_CELLS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".mergeCells");
exports.CONTEXTMENU_ITEMS_MERGE_CELLS = CONTEXTMENU_ITEMS_MERGE_CELLS;
var CONTEXTMENU_ITEMS_UNMERGE_CELLS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".unmergeCells");
exports.CONTEXTMENU_ITEMS_UNMERGE_CELLS = CONTEXTMENU_ITEMS_UNMERGE_CELLS;
var CONTEXTMENU_ITEMS_ADD_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".addComment");
exports.CONTEXTMENU_ITEMS_ADD_COMMENT = CONTEXTMENU_ITEMS_ADD_COMMENT;
var CONTEXTMENU_ITEMS_EDIT_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".editComment");
exports.CONTEXTMENU_ITEMS_EDIT_COMMENT = CONTEXTMENU_ITEMS_EDIT_COMMENT;
var CONTEXTMENU_ITEMS_REMOVE_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".removeComment");
exports.CONTEXTMENU_ITEMS_REMOVE_COMMENT = CONTEXTMENU_ITEMS_REMOVE_COMMENT;
var CONTEXTMENU_ITEMS_READ_ONLY_COMMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".readOnlyComment");
exports.CONTEXTMENU_ITEMS_READ_ONLY_COMMENT = CONTEXTMENU_ITEMS_READ_ONLY_COMMENT;
var CONTEXTMENU_ITEMS_ALIGNMENT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align");
exports.CONTEXTMENU_ITEMS_ALIGNMENT = CONTEXTMENU_ITEMS_ALIGNMENT;
var CONTEXTMENU_ITEMS_ALIGNMENT_LEFT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.left");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_LEFT = CONTEXTMENU_ITEMS_ALIGNMENT_LEFT;
var CONTEXTMENU_ITEMS_ALIGNMENT_CENTER = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.center");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_CENTER = CONTEXTMENU_ITEMS_ALIGNMENT_CENTER;
var CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.right");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT = CONTEXTMENU_ITEMS_ALIGNMENT_RIGHT;
var CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.justify");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY = CONTEXTMENU_ITEMS_ALIGNMENT_JUSTIFY;
var CONTEXTMENU_ITEMS_ALIGNMENT_TOP = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.top");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_TOP = CONTEXTMENU_ITEMS_ALIGNMENT_TOP;
var CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.middle");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE = CONTEXTMENU_ITEMS_ALIGNMENT_MIDDLE;
var CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".align.bottom");
exports.CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM = CONTEXTMENU_ITEMS_ALIGNMENT_BOTTOM;
var CONTEXTMENU_ITEMS_BORDERS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders");
exports.CONTEXTMENU_ITEMS_BORDERS = CONTEXTMENU_ITEMS_BORDERS;
var CONTEXTMENU_ITEMS_BORDERS_TOP = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.top");
exports.CONTEXTMENU_ITEMS_BORDERS_TOP = CONTEXTMENU_ITEMS_BORDERS_TOP;
var CONTEXTMENU_ITEMS_BORDERS_RIGHT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.right");
exports.CONTEXTMENU_ITEMS_BORDERS_RIGHT = CONTEXTMENU_ITEMS_BORDERS_RIGHT;
var CONTEXTMENU_ITEMS_BORDERS_BOTTOM = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.bottom");
exports.CONTEXTMENU_ITEMS_BORDERS_BOTTOM = CONTEXTMENU_ITEMS_BORDERS_BOTTOM;
var CONTEXTMENU_ITEMS_BORDERS_LEFT = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.left");
exports.CONTEXTMENU_ITEMS_BORDERS_LEFT = CONTEXTMENU_ITEMS_BORDERS_LEFT;
var CONTEXTMENU_ITEMS_REMOVE_BORDERS = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".borders.remove");
exports.CONTEXTMENU_ITEMS_REMOVE_BORDERS = CONTEXTMENU_ITEMS_REMOVE_BORDERS;
var CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".nestedHeaders.insertChildRow");
exports.CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD = CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD;
var CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".nestedHeaders.detachFromParent");
exports.CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD = CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD;
var CONTEXTMENU_ITEMS_HIDE_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".hideColumn");
exports.CONTEXTMENU_ITEMS_HIDE_COLUMN = CONTEXTMENU_ITEMS_HIDE_COLUMN;
var CONTEXTMENU_ITEMS_SHOW_COLUMN = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".showColumn");
exports.CONTEXTMENU_ITEMS_SHOW_COLUMN = CONTEXTMENU_ITEMS_SHOW_COLUMN;
var CONTEXTMENU_ITEMS_HIDE_ROW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".hideRow");
exports.CONTEXTMENU_ITEMS_HIDE_ROW = CONTEXTMENU_ITEMS_HIDE_ROW;
var CONTEXTMENU_ITEMS_SHOW_ROW = "".concat(CONTEXT_MENU_ITEMS_NAMESPACE, ".showRow");
exports.CONTEXTMENU_ITEMS_SHOW_ROW = CONTEXTMENU_ITEMS_SHOW_ROW;
var FILTERS_NAMESPACE = 'Filters:';
exports.FILTERS_NAMESPACE = FILTERS_NAMESPACE;
var FILTERS_CONDITIONS_NAMESPACE = "".concat(FILTERS_NAMESPACE, "conditions");
exports.FILTERS_CONDITIONS_NAMESPACE = FILTERS_CONDITIONS_NAMESPACE;
var FILTERS_CONDITIONS_NONE = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".none");
exports.FILTERS_CONDITIONS_NONE = FILTERS_CONDITIONS_NONE;
var FILTERS_CONDITIONS_EMPTY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isEmpty");
exports.FILTERS_CONDITIONS_EMPTY = FILTERS_CONDITIONS_EMPTY;
var FILTERS_CONDITIONS_NOT_EMPTY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isNotEmpty");
exports.FILTERS_CONDITIONS_NOT_EMPTY = FILTERS_CONDITIONS_NOT_EMPTY;
var FILTERS_CONDITIONS_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isEqualTo");
exports.FILTERS_CONDITIONS_EQUAL = FILTERS_CONDITIONS_EQUAL;
var FILTERS_CONDITIONS_NOT_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isNotEqualTo");
exports.FILTERS_CONDITIONS_NOT_EQUAL = FILTERS_CONDITIONS_NOT_EQUAL;
var FILTERS_CONDITIONS_BEGINS_WITH = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".beginsWith");
exports.FILTERS_CONDITIONS_BEGINS_WITH = FILTERS_CONDITIONS_BEGINS_WITH;
var FILTERS_CONDITIONS_ENDS_WITH = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".endsWith");
exports.FILTERS_CONDITIONS_ENDS_WITH = FILTERS_CONDITIONS_ENDS_WITH;
var FILTERS_CONDITIONS_CONTAINS = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".contains");
exports.FILTERS_CONDITIONS_CONTAINS = FILTERS_CONDITIONS_CONTAINS;
var FILTERS_CONDITIONS_NOT_CONTAIN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".doesNotContain");
exports.FILTERS_CONDITIONS_NOT_CONTAIN = FILTERS_CONDITIONS_NOT_CONTAIN;
var FILTERS_CONDITIONS_BY_VALUE = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".byValue");
exports.FILTERS_CONDITIONS_BY_VALUE = FILTERS_CONDITIONS_BY_VALUE;
var FILTERS_CONDITIONS_GREATER_THAN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".greaterThan");
exports.FILTERS_CONDITIONS_GREATER_THAN = FILTERS_CONDITIONS_GREATER_THAN;
var FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".greaterThanOrEqualTo");
exports.FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL = FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL;
var FILTERS_CONDITIONS_LESS_THAN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".lessThan");
exports.FILTERS_CONDITIONS_LESS_THAN = FILTERS_CONDITIONS_LESS_THAN;
var FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".lessThanOrEqualTo");
exports.FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL = FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL;
var FILTERS_CONDITIONS_BETWEEN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isBetween");
exports.FILTERS_CONDITIONS_BETWEEN = FILTERS_CONDITIONS_BETWEEN;
var FILTERS_CONDITIONS_NOT_BETWEEN = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".isNotBetween");
exports.FILTERS_CONDITIONS_NOT_BETWEEN = FILTERS_CONDITIONS_NOT_BETWEEN;
var FILTERS_CONDITIONS_AFTER = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".after");
exports.FILTERS_CONDITIONS_AFTER = FILTERS_CONDITIONS_AFTER;
var FILTERS_CONDITIONS_BEFORE = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".before");
exports.FILTERS_CONDITIONS_BEFORE = FILTERS_CONDITIONS_BEFORE;
var FILTERS_CONDITIONS_TODAY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".today");
exports.FILTERS_CONDITIONS_TODAY = FILTERS_CONDITIONS_TODAY;
var FILTERS_CONDITIONS_TOMORROW = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".tomorrow");
exports.FILTERS_CONDITIONS_TOMORROW = FILTERS_CONDITIONS_TOMORROW;
var FILTERS_CONDITIONS_YESTERDAY = "".concat(FILTERS_CONDITIONS_NAMESPACE, ".yesterday");
exports.FILTERS_CONDITIONS_YESTERDAY = FILTERS_CONDITIONS_YESTERDAY;
var FILTERS_DIVS_FILTER_BY_CONDITION = "".concat(FILTERS_NAMESPACE, "labels.filterByCondition");
exports.FILTERS_DIVS_FILTER_BY_CONDITION = FILTERS_DIVS_FILTER_BY_CONDITION;
var FILTERS_DIVS_FILTER_BY_VALUE = "".concat(FILTERS_NAMESPACE, "labels.filterByValue");
exports.FILTERS_DIVS_FILTER_BY_VALUE = FILTERS_DIVS_FILTER_BY_VALUE;
var FILTERS_LABELS_CONJUNCTION = "".concat(FILTERS_NAMESPACE, "labels.conjunction");
exports.FILTERS_LABELS_CONJUNCTION = FILTERS_LABELS_CONJUNCTION;
var FILTERS_LABELS_DISJUNCTION = "".concat(FILTERS_NAMESPACE, "labels.disjunction");
exports.FILTERS_LABELS_DISJUNCTION = FILTERS_LABELS_DISJUNCTION;
var FILTERS_VALUES_BLANK_CELLS = "".concat(FILTERS_NAMESPACE, "values.blankCells");
exports.FILTERS_VALUES_BLANK_CELLS = FILTERS_VALUES_BLANK_CELLS;
var FILTERS_BUTTONS_SELECT_ALL = "".concat(FILTERS_NAMESPACE, "buttons.selectAll");
exports.FILTERS_BUTTONS_SELECT_ALL = FILTERS_BUTTONS_SELECT_ALL;
var FILTERS_BUTTONS_CLEAR = "".concat(FILTERS_NAMESPACE, "buttons.clear");
exports.FILTERS_BUTTONS_CLEAR = FILTERS_BUTTONS_CLEAR;
var FILTERS_BUTTONS_OK = "".concat(FILTERS_NAMESPACE, "buttons.ok");
exports.FILTERS_BUTTONS_OK = FILTERS_BUTTONS_OK;
var FILTERS_BUTTONS_CANCEL = "".concat(FILTERS_NAMESPACE, "buttons.cancel");
exports.FILTERS_BUTTONS_CANCEL = FILTERS_BUTTONS_CANCEL;
var FILTERS_BUTTONS_PLACEHOLDER_SEARCH = "".concat(FILTERS_NAMESPACE, "buttons.placeholder.search");
exports.FILTERS_BUTTONS_PLACEHOLDER_SEARCH = FILTERS_BUTTONS_PLACEHOLDER_SEARCH;
var FILTERS_BUTTONS_PLACEHOLDER_VALUE = "".concat(FILTERS_NAMESPACE, "buttons.placeholder.value");
exports.FILTERS_BUTTONS_PLACEHOLDER_VALUE = FILTERS_BUTTONS_PLACEHOLDER_VALUE;
var FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE = "".concat(FILTERS_NAMESPACE, "buttons.placeholder.secondValue");
exports.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE = FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var internalIndexOf = __webpack_require__(140)(false);
var nativeIndexOf = [].indexOf;
var NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;
var SLOPPY_METHOD = __webpack_require__(126)('indexOf');
// `Array.prototype.indexOf` method
// https://tc39.github.io/ecma262/#sec-array.prototype.indexof
__webpack_require__(22)({ target: 'Array', proto: true, forced: NEGATIVE_ZERO || SLOPPY_METHOD }, {
indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
return NEGATIVE_ZERO
// convert -0 to +0
? nativeIndexOf.apply(this, arguments) || 0
: internalIndexOf(this, searchElement, arguments[1]);
}
});
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
var getPrototypeOf = __webpack_require__(6);
var superPropBase = __webpack_require__(286);
function _get(target, property, receiver) {
if (typeof Reflect !== "undefined" && Reflect.get) {
module.exports = _get = Reflect.get;
} else {
module.exports = _get = function _get(target, property, receiver) {
var base = superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(receiver);
}
return desc.value;
};
}
return _get(target, property, receiver || target);
}
module.exports = _get;
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var codePointAt = __webpack_require__(146);
var InternalStateModule = __webpack_require__(87);
var defineIterator = __webpack_require__(144);
var STRING_ITERATOR = 'String Iterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(STRING_ITERATOR);
// `String.prototype[@@iterator]` method
// https://tc39.github.io/ecma262/#sec-string.prototype-@@iterator
defineIterator(String, 'String', function (iterated) {
setInternalState(this, {
type: STRING_ITERATOR,
string: String(iterated),
index: 0
});
// `%StringIteratorPrototype%.next` method
// https://tc39.github.io/ecma262/#sec-%stringiteratorprototype%.next
}, function next() {
var state = getInternalState(this);
var string = state.string;
var index = state.index;
var point;
if (index >= string.length) return { value: undefined, done: true };
point = codePointAt(string, index, true);
state.index += point.length;
return { value: point, done: false };
});
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(37);
exports.__esModule = true;
exports.isNumeric = isNumeric;
exports.rangeEach = rangeEach;
exports.rangeEachReverse = rangeEachReverse;
exports.valueAccordingPercent = valueAccordingPercent;
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
/**
* Checks if value of n is a numeric one
* http://jsperf.com/isnan-vs-isnumeric/4
* @param n
* @returns {boolean}
*/
function isNumeric(n) {
/* eslint-disable */
var t = (0, _typeof2.default)(n);
return t == 'number' ? !isNaN(n) && isFinite(n) : t == 'string' ? !n.length ? false : n.length == 1 ? /\d/.test(n) : /^\s*[+-]?\s*(?:(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?)|(?:0x[a-f\d]+))\s*$/i.test(n) : t == 'object' ? !!n && typeof n.valueOf() == 'number' && !(n instanceof Date) : false;
}
/**
* A specialized version of `.forEach` defined by ranges.
*
* @param {Number} rangeFrom The number from start iterate.
* @param {Number|Function} rangeTo The number where finish iterate or function as a iteratee.
* @param {Function} [iteratee] The function invoked per iteration.
*/
function rangeEach(rangeFrom, rangeTo, iteratee) {
var index = -1;
if (typeof rangeTo === 'function') {
iteratee = rangeTo;
rangeTo = rangeFrom;
} else {
index = rangeFrom - 1;
}
while (++index <= rangeTo) {
if (iteratee(index) === false) {
break;
}
}
}
/**
* A specialized version of `.forEach` defined by ranges iterable in reverse order.
*
* @param {Number} rangeFrom The number from start iterate.
* @param {Number|Function} rangeTo The number where finish iterate or function as a iteratee.
* @param {Function} [iteratee] The function invoked per iteration.
*/
function rangeEachReverse(rangeFrom, rangeTo, iteratee) {
var index = rangeFrom + 1;
if (typeof rangeTo === 'function') {
iteratee = rangeTo;
rangeTo = 0;
}
while (--index >= rangeTo) {
if (iteratee(index) === false) {
break;
}
}
}
/**
* Calculate value from percent.
*
* @param {Number} value Base value from percent will be calculated.
* @param {String|Number} percent Can be Number or String (eq. `'33%'`).
* @returns {Number}
*/
function valueAccordingPercent(value, percent) {
percent = parseInt(percent.toString().replace('%', ''), 10);
percent = parseInt(value * percent / 100, 10);
return percent;
}
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var toIndexedObject = __webpack_require__(69);
var addToUnscopables = __webpack_require__(121);
var Iterators = __webpack_require__(100);
var InternalStateModule = __webpack_require__(87);
var defineIterator = __webpack_require__(144);
var ARRAY_ITERATOR = 'Array Iterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(ARRAY_ITERATOR);
// `Array.prototype.entries` method
// https://tc39.github.io/ecma262/#sec-array.prototype.entries
// `Array.prototype.keys` method
// https://tc39.github.io/ecma262/#sec-array.prototype.keys
// `Array.prototype.values` method
// https://tc39.github.io/ecma262/#sec-array.prototype.values
// `Array.prototype[@@iterator]` method
// https://tc39.github.io/ecma262/#sec-array.prototype-@@iterator
// `CreateArrayIterator` internal method
// https://tc39.github.io/ecma262/#sec-createarrayiterator
module.exports = defineIterator(Array, 'Array', function (iterated, kind) {
setInternalState(this, {
type: ARRAY_ITERATOR,
target: toIndexedObject(iterated), // target
index: 0, // next index
kind: kind // kind
});
// `%ArrayIteratorPrototype%.next` method
// https://tc39.github.io/ecma262/#sec-%arrayiteratorprototype%.next
}, function () {
var state = getInternalState(this);
var target = state.target;
var kind = state.kind;
var index = state.index++;
if (!target || index >= target.length) {
state.target = undefined;
return { value: undefined, done: true };
}
if (kind == 'keys') return { value: index, done: false };
if (kind == 'values') return { value: target[index], done: false };
return { value: [index, target[index]], done: false };
}, 'values');
// argumentsList[@@iterator] is %ArrayProto_values%
// https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject
// https://tc39.github.io/ecma262/#sec-createmappedargumentsobject
Iterators.Arguments = Iterators.Array;
// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
var DOMIterables = __webpack_require__(191);
var ArrayIteratorMethods = __webpack_require__(16);
var global = __webpack_require__(32);
var hide = __webpack_require__(61);
var wellKnownSymbol = __webpack_require__(35);
var ITERATOR = wellKnownSymbol('iterator');
var TO_STRING_TAG = wellKnownSymbol('toStringTag');
var ArrayValues = ArrayIteratorMethods.values;
for (var COLLECTION_NAME in DOMIterables) {
var Collection = global[COLLECTION_NAME];
var CollectionPrototype = Collection && Collection.prototype;
if (CollectionPrototype) {
// some Chrome versions have non-configurable methods on DOMTokenList
if (CollectionPrototype[ITERATOR] !== ArrayValues) try {
hide(CollectionPrototype, ITERATOR, ArrayValues);
} catch (e) {
CollectionPrototype[ITERATOR] = ArrayValues;
}
if (!CollectionPrototype[TO_STRING_TAG]) hide(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME);
if (DOMIterables[COLLECTION_NAME]) for (var METHOD_NAME in ArrayIteratorMethods) {
// some Chrome versions have non-configurable methods on DOMTokenList
if (CollectionPrototype[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try {
hide(CollectionPrototype, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]);
} catch (e) {
CollectionPrototype[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME];
}
}
}
}
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var isArray = __webpack_require__(124);
var isObject = __webpack_require__(42);
var toObject = __webpack_require__(62);
var toLength = __webpack_require__(48);
var createProperty = __webpack_require__(127);
var arraySpeciesCreate = __webpack_require__(151);
var IS_CONCAT_SPREADABLE = __webpack_require__(35)('isConcatSpreadable');
var MAX_SAFE_INTEGER = 0x1fffffffffffff;
var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
var IS_CONCAT_SPREADABLE_SUPPORT = !__webpack_require__(29)(function () {
var array = [];
array[IS_CONCAT_SPREADABLE] = false;
return array.concat()[0] !== array;
});
var SPECIES_SUPPORT = __webpack_require__(103)('concat');
var isConcatSpreadable = function (O) {
if (!isObject(O)) return false;
var spreadable = O[IS_CONCAT_SPREADABLE];
return spreadable !== undefined ? !!spreadable : isArray(O);
};
var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
// `Array.prototype.concat` method
// https://tc39.github.io/ecma262/#sec-array.prototype.concat
// with adding support of @@isConcatSpreadable and @@species
__webpack_require__(22)({ target: 'Array', proto: true, forced: FORCED }, {
concat: function concat(arg) { // eslint-disable-line no-unused-vars
var O = toObject(this);
var A = arraySpeciesCreate(O, 0);
var n = 0;
var i, k, length, len, E;
for (i = -1, length = arguments.length; i < length; i++) {
E = i === -1 ? O : arguments[i];
if (isConcatSpreadable(E)) {
len = toLength(E.length);
if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
} else {
if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
createProperty(A, n++, E);
}
}
A.length = n;
return A;
}
});
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
var arrayWithHoles = __webpack_require__(212);
var iterableToArrayLimit = __webpack_require__(278);
var nonIterableRest = __webpack_require__(213);
function _slicedToArray(arr, i) {
return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
}
module.exports = _slicedToArray;
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(76);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.registerPlugin = registerPlugin;
exports.getPlugin = getPlugin;
exports.getRegistredPluginNames = getRegistredPluginNames;
exports.getPluginName = getPluginName;
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _object = __webpack_require__(4);
var _string = __webpack_require__(68);
/**
* Utility to register plugins and common namespace for keeping reference to all plugins classes
*/
var registeredPlugins = new WeakMap();
/**
* Registers plugin under given name
*
* @param {String} pluginName
* @param {Function} PluginClass
*/
function registerPlugin(pluginName, PluginClass) {
var correctedPluginName = (0, _string.toUpperCaseFirst)(pluginName);
_pluginHooks.default.getSingleton().add('construct', function () {
if (!registeredPlugins.has(this)) {
registeredPlugins.set(this, {});
}
var holder = registeredPlugins.get(this);
if (!holder[correctedPluginName]) {
holder[correctedPluginName] = new PluginClass(this);
}
});
_pluginHooks.default.getSingleton().add('afterDestroy', function () {
if (registeredPlugins.has(this)) {
var pluginsHolder = registeredPlugins.get(this);
(0, _object.objectEach)(pluginsHolder, function (plugin) {
return plugin.destroy();
});
registeredPlugins.delete(this);
}
});
}
/**
* @param {Object} instance
* @param {String|Function} pluginName
* @returns {Function} pluginClass Returns plugin instance if exists or `undefined` if not exists.
*/
function getPlugin(instance, pluginName) {
if (typeof pluginName !== 'string') {
throw Error('Only strings can be passed as "plugin" parameter');
}
var _pluginName = (0, _string.toUpperCaseFirst)(pluginName);
if (!registeredPlugins.has(instance) || !registeredPlugins.get(instance)[_pluginName]) {
return void 0;
}
return registeredPlugins.get(instance)[_pluginName];
}
/**
* Get all registred plugins names for concrete Handsontable instance.
*
* @param {Object} hotInstance
* @returns {Array}
*/
function getRegistredPluginNames(hotInstance) {
return registeredPlugins.has(hotInstance) ? Object.keys(registeredPlugins.get(hotInstance)) : [];
}
/**
* Get plugin name.
*
* @param {Object} hotInstance
* @param {Object} plugin
* @returns {String|null}
*/
function getPluginName(hotInstance, plugin) {
var pluginName = null;
if (registeredPlugins.has(hotInstance)) {
(0, _object.objectEach)(registeredPlugins.get(hotInstance), function (pluginInstance, name) {
if (pluginInstance === plugin) {
pluginName = name;
}
});
}
return pluginName;
}
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(33);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _object = __webpack_require__(4);
var _array = __webpack_require__(3);
var _recordTranslator = __webpack_require__(90);
var _plugins = __webpack_require__(20);
var privatePool = new WeakMap();
var initializedPlugins = null;
/**
* @util
*/
var BasePlugin =
/*#__PURE__*/
function () {
/**
* @param {Object} hotInstance Handsontable instance.
*/
function BasePlugin(hotInstance) {
var _this = this;
(0, _classCallCheck2.default)(this, BasePlugin);
/**
* Handsontable instance.
*
* @type {Core}
*/
(0, _object.defineGetter)(this, 'hot', hotInstance, {
writable: false
});
(0, _object.defineGetter)(this, 't', (0, _recordTranslator.getTranslator)(hotInstance), {
writable: false
});
privatePool.set(this, {
hooks: {}
});
initializedPlugins = null;
this.pluginName = null;
this.pluginsInitializedCallbacks = [];
this.isPluginsReady = false;
this.enabled = false;
this.initialized = false;
this.hot.addHook('afterPluginsInitialized', function () {
return _this.onAfterPluginsInitialized();
});
this.hot.addHook('afterUpdateSettings', function (newSettings) {
return _this.onUpdateSettings(newSettings);
});
this.hot.addHook('beforeInit', function () {
return _this.init();
});
}
(0, _createClass2.default)(BasePlugin, [{
key: "init",
value: function init() {
this.pluginName = (0, _plugins.getPluginName)(this.hot, this);
if (this.isEnabled && this.isEnabled()) {
this.enablePlugin();
}
if (!initializedPlugins) {
initializedPlugins = (0, _plugins.getRegistredPluginNames)(this.hot);
}
if (initializedPlugins.indexOf(this.pluginName) >= 0) {
initializedPlugins.splice(initializedPlugins.indexOf(this.pluginName), 1);
}
if (!initializedPlugins.length) {
this.hot.runHooks('afterPluginsInitialized');
}
this.initialized = true;
}
/**
* Enable plugin for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
this.enabled = true;
}
/**
* Disable plugin for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
if (this.eventManager) {
this.eventManager.clear();
}
this.clearHooks();
this.enabled = false;
}
/**
* Add listener to plugin hooks system.
*
* @param {String} name
* @param {Function} callback
*/
}, {
key: "addHook",
value: function addHook(name, callback) {
privatePool.get(this).hooks[name] = privatePool.get(this).hooks[name] || [];
var hooks = privatePool.get(this).hooks[name];
this.hot.addHook(name, callback);
hooks.push(callback);
privatePool.get(this).hooks[name] = hooks;
}
/**
* Remove all hooks listeners by hook name.
*
* @param {String} name
*/
}, {
key: "removeHooks",
value: function removeHooks(name) {
var _this2 = this;
(0, _array.arrayEach)(privatePool.get(this).hooks[name] || [], function (callback) {
_this2.hot.removeHook(name, callback);
});
}
/**
* Clear all hooks.
*/
}, {
key: "clearHooks",
value: function clearHooks() {
var _this3 = this;
var hooks = privatePool.get(this).hooks;
(0, _object.objectEach)(hooks, function (callbacks, name) {
return _this3.removeHooks(name);
});
hooks.length = 0;
}
/**
* Register function which will be immediately called after all plugins initialized.
*
* @param {Function} callback
*/
}, {
key: "callOnPluginsReady",
value: function callOnPluginsReady(callback) {
if (this.isPluginsReady) {
callback();
} else {
this.pluginsInitializedCallbacks.push(callback);
}
}
/**
* On after plugins initialized listener.
*
* @private
*/
}, {
key: "onAfterPluginsInitialized",
value: function onAfterPluginsInitialized() {
(0, _array.arrayEach)(this.pluginsInitializedCallbacks, function (callback) {
return callback();
});
this.pluginsInitializedCallbacks.length = 0;
this.isPluginsReady = true;
}
/**
* On update settings listener.
*
* @private
*/
}, {
key: "onUpdateSettings",
value: function onUpdateSettings() {
if (this.isEnabled) {
if (this.enabled && !this.isEnabled()) {
this.disablePlugin();
}
if (!this.enabled && this.isEnabled()) {
this.enablePlugin();
}
if (this.enabled && this.isEnabled()) {
this.updatePlugin();
}
}
}
/**
* Updates the plugin to use the latest options you have specified.
*
* @private
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {}
/**
* Destroy plugin.
*/
}, {
key: "destroy",
value: function destroy() {
var _this4 = this;
if (this.eventManager) {
this.eventManager.destroy();
}
this.clearHooks();
(0, _object.objectEach)(this, function (value, property) {
if (property !== 'hot' && property !== 't') {
_this4[property] = null;
}
});
delete this.t;
delete this.hot;
}
}]);
return BasePlugin;
}();
var _default = BasePlugin;
exports.default = _default;
/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {
var global = __webpack_require__(32);
var getOwnPropertyDescriptor = __webpack_require__(115).f;
var hide = __webpack_require__(61);
var redefine = __webpack_require__(64);
var setGlobal = __webpack_require__(143);
var copyConstructorProperties = __webpack_require__(179);
var isForced = __webpack_require__(120);
/*
options.target - name of the target object
options.global - target is the global object
options.stat - export as static methods of target
options.proto - export as prototype methods of target
options.real - real prototype method for the `pure` version
options.forced - export even if the native feature is available
options.bind - bind methods to the target, required for the `pure` version
options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
options.unsafe - use the simple assignment of property instead of delete + defineProperty
options.sham - add a flag to not completely full polyfills
options.enumerable - export as enumerable property
options.noTargetGet - prevent calling a getter on target
*/
module.exports = function (options, source) {
var TARGET = options.target;
var GLOBAL = options.global;
var STATIC = options.stat;
var FORCED, target, key, targetProperty, sourceProperty, descriptor;
if (GLOBAL) {
target = global;
} else if (STATIC) {
target = global[TARGET] || setGlobal(TARGET, {});
} else {
target = (global[TARGET] || {}).prototype;
}
if (target) for (key in source) {
sourceProperty = source[key];
if (options.noTargetGet) {
descriptor = getOwnPropertyDescriptor(target, key);
targetProperty = descriptor && descriptor.value;
} else targetProperty = target[key];
FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
// contained in target
if (!FORCED && targetProperty !== undefined) {
if (typeof sourceProperty === typeof targetProperty) continue;
copyConstructorProperties(sourceProperty, targetProperty);
}
// add a flag to not completely full polyfills
if (options.sham || (targetProperty && targetProperty.sham)) {
hide(sourceProperty, 'sham', true);
}
// extend global
redefine(target, key, sourceProperty, options);
}
};
/***/ }),
/* 23 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(33);
exports.__esModule = true;
exports.getListenersCounter = getListenersCounter;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _element = __webpack_require__(5);
var _object = __webpack_require__(4);
var _feature = __webpack_require__(73);
var _event = __webpack_require__(31);
/**
* Counter which tracks unregistered listeners (useful for detecting memory leaks).
*
* @type {Number}
*/
var listenersCounter = 0;
/**
* Event DOM manager for internal use in Handsontable.
*
* @class EventManager
* @util
*/
var EventManager =
/*#__PURE__*/
function () {
/**
* @param {Object} [context=null]
* @private
*/
function EventManager() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
(0, _classCallCheck2.default)(this, EventManager);
this.context = context || this;
if (!this.context.eventListeners) {
this.context.eventListeners = [];
}
}
/**
* Register specified listener (`eventName`) to the element.
*
* @param {Element} element Target element.
* @param {String} eventName Event name.
* @param {Function} callback Function which will be called after event occur.
* @param {AddEventListenerOptions|Boolean} [options] Listener options if object or useCapture if boolean.
* @returns {Function} Returns function which you can easily call to remove that event
*/
(0, _createClass2.default)(EventManager, [{
key: "addEventListener",
value: function addEventListener(element, eventName, callback) {
var _this = this;
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var context = this.context;
function callbackProxy(event) {
callback.call(this, extendEvent(context, event));
}
if (typeof options !== 'boolean' && !(0, _feature.isPassiveEventSupported)()) {
options = false;
}
this.context.eventListeners.push({
element: element,
event: eventName,
callback: callback,
callbackProxy: callbackProxy,
options: options
});
element.addEventListener(eventName, callbackProxy, options);
listenersCounter += 1;
return function () {
_this.removeEventListener(element, eventName, callback);
};
}
/**
* Remove the event listener previously registered.
*
* @param {Element} element Target element.
* @param {String} eventName Event name.
* @param {Function} callback Function to remove from the event target. It must be the same as during registration listener.
*/
}, {
key: "removeEventListener",
value: function removeEventListener(element, eventName, callback) {
var len = this.context.eventListeners.length;
var tmpEvent;
while (len) {
len -= 1;
tmpEvent = this.context.eventListeners[len];
if (tmpEvent.event === eventName && tmpEvent.element === element) {
if (callback && callback !== tmpEvent.callback) {
/* eslint-disable no-continue */
continue;
}
this.context.eventListeners.splice(len, 1);
tmpEvent.element.removeEventListener(tmpEvent.event, tmpEvent.callbackProxy, tmpEvent.options);
listenersCounter -= 1;
}
}
}
/**
* Clear all previously registered events.
*
* @private
* @since 0.15.0-beta3
*/
}, {
key: "clearEvents",
value: function clearEvents() {
if (!this.context) {
return;
}
var len = this.context.eventListeners.length;
while (len) {
len -= 1;
var event = this.context.eventListeners[len];
if (event) {
this.removeEventListener(event.element, event.event, event.callback);
}
}
}
/**
* Clear all previously registered events.
*/
}, {
key: "clear",
value: function clear() {
this.clearEvents();
}
/**
* Destroy instance of EventManager.
*/
}, {
key: "destroy",
value: function destroy() {
this.clearEvents();
this.context = null;
}
/**
* Trigger event at the specified target element.
*
* @param {Element} element Target element.
* @param {String} eventName Event name.
*/
}, {
key: "fireEvent",
value: function fireEvent(element, eventName) {
var rootDocument = element.document;
var rootWindow = element;
if (!rootDocument) {
rootDocument = element.ownerDocument ? element.ownerDocument : element;
rootWindow = rootDocument.defaultView;
}
var options = {
bubbles: true,
cancelable: eventName !== 'mousemove',
view: rootWindow,
detail: 0,
screenX: 0,
screenY: 0,
clientX: 1,
clientY: 1,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
button: 0,
relatedTarget: undefined
};
var event;
if (rootDocument.createEvent) {
event = rootDocument.createEvent('MouseEvents');
event.initMouseEvent(eventName, options.bubbles, options.cancelable, options.view, options.detail, options.screenX, options.screenY, options.clientX, options.clientY, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, options.relatedTarget || rootDocument.body.parentNode);
} else {
event = rootDocument.createEventObject();
}
if (element.dispatchEvent) {
element.dispatchEvent(event);
} else {
element.fireEvent("on".concat(eventName), event);
}
}
}]);
return EventManager;
}();
/**
* @param {Object} context
* @param {Event} event
* @private
* @returns {*}
*/
function extendEvent(context, event) {
var componentName = 'HOT-TABLE';
var isHotTableSpotted;
var fromElement;
var realTarget;
var target;
var len;
event.isTargetWebComponent = false;
event.realTarget = event.target;
var nativeStopImmediatePropagation = event.stopImmediatePropagation;
event.stopImmediatePropagation = function () {
nativeStopImmediatePropagation.apply(this);
(0, _event.stopImmediatePropagation)(this);
};
if (!EventManager.isHotTableEnv) {
return event;
} // eslint-disable-next-line no-param-reassign
event = (0, _element.polymerWrap)(event);
len = event.path ? event.path.length : 0;
while (len) {
len -= 1;
if (event.path[len].nodeName === componentName) {
isHotTableSpotted = true;
} else if (isHotTableSpotted && event.path[len].shadowRoot) {
target = event.path[len];
break;
}
if (len === 0 && !target) {
target = event.path[len];
}
}
if (!target) {
target = event.target;
}
event.isTargetWebComponent = true;
if ((0, _feature.isWebComponentSupportedNatively)()) {
event.realTarget = event.srcElement || event.toElement;
} else if ((0, _object.hasOwnProperty)(context, 'hot') || context.isHotTableEnv || context.wtTable) {
// Polymer doesn't support `event.target` property properly we must emulate it ourselves
if ((0, _object.hasOwnProperty)(context, 'hot')) {
// Custom element
fromElement = context.hot ? context.hot.view.wt.wtTable.TABLE : null;
} else if (context.isHotTableEnv) {
// Handsontable.Core
fromElement = context.view.activeWt.wtTable.TABLE.parentNode.parentNode;
} else if (context.wtTable) {
// Walkontable
fromElement = context.wtTable.TABLE.parentNode.parentNode;
}
realTarget = (0, _element.closest)(event.target, [componentName], fromElement);
if (realTarget) {
event.realTarget = fromElement.querySelector(componentName) || event.target;
} else {
event.realTarget = event.target;
}
}
Object.defineProperty(event, 'target', {
get: function get() {
return (0, _element.polymerWrap)(target);
},
enumerable: true,
configurable: true
});
return event;
}
var _default = EventManager;
exports.default = _default;
function getListenersCounter() {
return listenersCounter;
}
/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var global = __webpack_require__(32);
var redefineAll = __webpack_require__(147);
var InternalMetadataModule = __webpack_require__(123);
var weak = __webpack_require__(186);
var isObject = __webpack_require__(42);
var enforceIternalState = __webpack_require__(87).enforce;
var NATIVE_WEAK_MAP = __webpack_require__(178);
var IS_IE11 = !global.ActiveXObject && 'ActiveXObject' in global;
var isExtensible = Object.isExtensible;
var InternalWeakMap;
var wrapper = function (get) {
return function WeakMap() {
return get(this, arguments.length > 0 ? arguments[0] : undefined);
};
};
// `WeakMap` constructor
// https://tc39.github.io/ecma262/#sec-weakmap-constructor
var $WeakMap = module.exports = __webpack_require__(125)('WeakMap', wrapper, weak, true, true);
// IE11 WeakMap frozen keys fix
// We can't use feature detection because it crash some old IE builds
// https://github.com/zloirock/core-js/issues/485
if (NATIVE_WEAK_MAP && IS_IE11) {
InternalWeakMap = weak.getConstructor(wrapper, 'WeakMap', true);
InternalMetadataModule.REQUIRED = true;
var WeakMapPrototype = $WeakMap.prototype;
var nativeDelete = WeakMapPrototype['delete'];
var nativeHas = WeakMapPrototype.has;
var nativeGet = WeakMapPrototype.get;
var nativeSet = WeakMapPrototype.set;
redefineAll(WeakMapPrototype, {
'delete': function (key) {
if (isObject(key) && !isExtensible(key)) {
var state = enforceIternalState(this);
if (!state.frozen) state.frozen = new InternalWeakMap();
return nativeDelete.call(this, key) || state.frozen['delete'](key);
} return nativeDelete.call(this, key);
},
has: function has(key) {
if (isObject(key) && !isExtensible(key)) {
var state = enforceIternalState(this);
if (!state.frozen) state.frozen = new InternalWeakMap();
return nativeHas.call(this, key) || state.frozen.has(key);
} return nativeHas.call(this, key);
},
get: function get(key) {
if (isObject(key) && !isExtensible(key)) {
var state = enforceIternalState(this);
if (!state.frozen) state.frozen = new InternalWeakMap();
return nativeHas.call(this, key) ? nativeGet.call(this, key) : state.frozen.get(key);
} return nativeGet.call(this, key);
},
set: function set(key, value) {
if (isObject(key) && !isExtensible(key)) {
var state = enforceIternalState(this);
if (!state.frozen) state.frozen = new InternalWeakMap();
nativeHas.call(this, key) ? nativeSet.call(this, key, value) : state.frozen.set(key, value);
} else nativeSet.call(this, key, value);
return this;
}
});
}
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
var _viewportColumns = _interopRequireDefault(__webpack_require__(198));
exports.ViewportColumnsCalculator = _viewportColumns.default;
var _viewportRows = _interopRequireDefault(__webpack_require__(199));
exports.ViewportRowsCalculator = _viewportRows.default;
var _coords = _interopRequireDefault(__webpack_require__(106));
exports.CellCoords = _coords.default;
var _range = _interopRequireDefault(__webpack_require__(200));
exports.CellRange = _range.default;
var _column = _interopRequireDefault(__webpack_require__(201));
exports.ColumnFilter = _column.default;
var _row = _interopRequireDefault(__webpack_require__(202));
exports.RowFilter = _row.default;
var _debug = _interopRequireDefault(__webpack_require__(275));
exports.DebugOverlay = _debug.default;
var _left = _interopRequireDefault(__webpack_require__(279));
exports.LeftOverlay = _left.default;
var _top = _interopRequireDefault(__webpack_require__(280));
exports.TopOverlay = _top.default;
var _topLeftCorner = _interopRequireDefault(__webpack_require__(281));
exports.TopLeftCornerOverlay = _topLeftCorner.default;
var _bottom = _interopRequireDefault(__webpack_require__(282));
exports.BottomOverlay = _bottom.default;
var _bottomLeftCorner = _interopRequireDefault(__webpack_require__(283));
exports.BottomLeftCornerOverlay = _bottomLeftCorner.default;
var _border = _interopRequireDefault(__webpack_require__(216));
exports.Border = _border.default;
var _core = _interopRequireDefault(__webpack_require__(206));
exports.default = _core.default;
exports.Core = _core.default;
var _event = _interopRequireDefault(__webpack_require__(207));
exports.Event = _event.default;
var _overlays = _interopRequireDefault(__webpack_require__(208));
exports.Overlays = _overlays.default;
var _scroll = _interopRequireDefault(__webpack_require__(209));
exports.Scroll = _scroll.default;
var _selection = _interopRequireDefault(__webpack_require__(284));
exports.Selection = _selection.default;
var _settings = _interopRequireDefault(__webpack_require__(210));
exports.Settings = _settings.default;
var _table = _interopRequireDefault(__webpack_require__(211));
exports.Table = _table.default;
var _tableRenderer = _interopRequireDefault(__webpack_require__(214));
exports.TableRenderer = _tableRenderer.default;
var _viewport = _interopRequireDefault(__webpack_require__(215));
exports.Viewport = _viewport.default;
/***/ }),
/* 26 */
/***/ (function(module, exports) {
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
module.exports = _assertThisInitialized;
/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(276);
__webpack_require__(204);
__webpack_require__(37);
__webpack_require__(46);
exports.__esModule = true;
exports.stringify = stringify;
exports.isDefined = isDefined;
exports.isUndefined = isUndefined;
exports.isEmpty = isEmpty;
exports.isRegExp = isRegExp;
exports._injectProductInfo = _injectProductInfo;
var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(65));
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
var _moment = _interopRequireDefault(__webpack_require__(66));
var _templateLiteralTag = __webpack_require__(67);
function _templateObject6() {
var data = (0, _taggedTemplateLiteral2.default)(["\n The license key for Handsontable is missing. Use your purchased key to activate the product. \n Alternatively, you can activate Handsontable to use for non-commercial purposes by \n passing the key: 'non-commercial-and-evaluation'. \n Read more about it in \n the documentation or contact us at support@handsontable.com."], ["\n The license key for Handsontable is missing. Use your purchased key to activate the product.\\x20\n Alternatively, you can activate Handsontable to use for non-commercial purposes by\\x20\n passing the key: 'non-commercial-and-evaluation'.\\x20\n Read more about it in\\x20\n the documentation or contact us at support@handsontable.com."]);
_templateObject6 = function _templateObject6() {
return data;
};
return data;
}
function _templateObject5() {
var data = (0, _taggedTemplateLiteral2.default)(["\n The license key for Handsontable expired on ", ", and is not valid for the installed \n version ", ". Renew your \n license key or downgrade to a version released prior to ", ". If you need any \n help, contact us at sales@handsontable.com."], ["\n The license key for Handsontable expired on ", ", and is not valid for the installed\\x20\n version ", ". Renew your\\x20\n license key or downgrade to a version released prior to ", ". If you need any\\x20\n help, contact us at sales@handsontable.com."]);
_templateObject5 = function _templateObject5() {
return data;
};
return data;
}
function _templateObject4() {
var data = (0, _taggedTemplateLiteral2.default)(["\n The license key for Handsontable is invalid. \n Read more on how to \n install it properly or contact us at support@handsontable.com."], ["\n The license key for Handsontable is invalid.\\x20\n Read more on how to\\x20\n install it properly or contact us at support@handsontable.com."]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = (0, _taggedTemplateLiteral2.default)(["\n The license key for Handsontable is missing. Use your purchased key to activate the product. \n Alternatively, you can activate Handsontable to use for non-commercial purposes by \n passing the key: 'non-commercial-and-evaluation'. If you need any help, contact \n us at support@handsontable.com."], ["\n The license key for Handsontable is missing. Use your purchased key to activate the product.\\x20\n Alternatively, you can activate Handsontable to use for non-commercial purposes by\\x20\n passing the key: 'non-commercial-and-evaluation'. If you need any help, contact\\x20\n us at support@handsontable.com."]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = (0, _taggedTemplateLiteral2.default)(["\n The license key for Handsontable expired on ", ", and is not valid for the installed \n version ", ". Renew your license key at handsontable.com or downgrade to a version released prior \n to ", ". If you need any help, contact us at sales@handsontable.com."], ["\n The license key for Handsontable expired on ", ", and is not valid for the installed\\x20\n version ", ". Renew your license key at handsontable.com or downgrade to a version released prior\\x20\n to ", ". If you need any help, contact us at sales@handsontable.com."]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = (0, _taggedTemplateLiteral2.default)(["\n The license key for Handsontable is invalid. \n If you need any help, contact us at support@handsontable.com."], ["\n The license key for Handsontable is invalid.\\x20\n If you need any help, contact us at support@handsontable.com."]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
/**
* Converts any value to string.
*
* @param {*} value
* @returns {String}
*/
function stringify(value) {
var result;
switch ((0, _typeof2.default)(value)) {
case 'string':
case 'number':
result = "".concat(value);
break;
case 'object':
result = value === null ? '' : value.toString();
break;
case 'undefined':
result = '';
break;
default:
result = value.toString();
break;
}
return result;
}
/**
* Checks if given variable is defined.
*
* @param {*} variable Variable to check.
* @returns {Boolean}
*/
function isDefined(variable) {
return typeof variable !== 'undefined';
}
/**
* Checks if given variable is undefined.
*
* @param {*} variable Variable to check.
* @returns {Boolean}
*/
function isUndefined(variable) {
return typeof variable === 'undefined';
}
/**
* Check if given variable is null, empty string or undefined.
*
* @param {*} variable Variable to check.
* @returns {Boolean}
*/
function isEmpty(variable) {
return variable === null || variable === '' || isUndefined(variable);
}
/**
* Check if given variable is a regular expression.
*
* @param {*} variable Variable to check.
* @returns {Boolean}
*/
function isRegExp(variable) {
return Object.prototype.toString.call(variable) === '[object RegExp]';
}
/* eslint-disable */
var _m = '\x6C\x65\x6E\x67\x74\x68';
var _hd = function _hd(v) {
return parseInt(v, 16);
};
var _pi = function _pi(v) {
return parseInt(v, 10);
};
var _ss = function _ss(v, s, l) {
return v['\x73\x75\x62\x73\x74\x72'](s, l);
};
var _cp = function _cp(v) {
return v['\x63\x6F\x64\x65\x50\x6F\x69\x6E\x74\x41\x74'](0) - 65;
};
var _norm = function _norm(v) {
return "".concat(v).replace(/\-/g, '');
};
var _extractTime = function _extractTime(v) {
return _hd(_ss(_norm(v), _hd('12'), _cp('\x46'))) / (_hd(_ss(_norm(v), _cp('\x42'), ~~![][_m])) || 9);
};
var _ignored = function _ignored() {
return typeof location !== 'undefined' && /^([a-z0-9\-]+\.)?\x68\x61\x6E\x64\x73\x6F\x6E\x74\x61\x62\x6C\x65\x2E\x63\x6F\x6D$/i.test(location.host);
};
var _notified = false;
var consoleMessages = {
invalid: function invalid() {
return (0, _templateLiteralTag.toSingleLine)(_templateObject());
},
expired: function expired(_ref) {
var keyValidityDate = _ref.keyValidityDate,
hotVersion = _ref.hotVersion;
return (0, _templateLiteralTag.toSingleLine)(_templateObject2(), keyValidityDate, hotVersion, keyValidityDate);
},
missing: function missing() {
return (0, _templateLiteralTag.toSingleLine)(_templateObject3());
},
non_commercial: function non_commercial() {
return '';
}
};
var domMessages = {
invalid: function invalid() {
return (0, _templateLiteralTag.toSingleLine)(_templateObject4());
},
expired: function expired(_ref2) {
var keyValidityDate = _ref2.keyValidityDate,
hotVersion = _ref2.hotVersion;
return (0, _templateLiteralTag.toSingleLine)(_templateObject5(), keyValidityDate, hotVersion, keyValidityDate);
},
missing: function missing() {
return (0, _templateLiteralTag.toSingleLine)(_templateObject6());
},
non_commercial: function non_commercial() {
return '';
}
};
function _injectProductInfo(key, element) {
var hasValidType = !isEmpty(key);
var isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
var hotVersion = "7.0.1";
var keyValidityDate;
var consoleMessageState = 'invalid';
var domMessageState = 'invalid';
key = _norm(key || '');
var schemaValidity = _checkKeySchema(key);
if (hasValidType || isNonCommercial || schemaValidity) {
if (schemaValidity) {
var releaseDate = (0, _moment.default)("08/04/2019", 'DD/MM/YYYY');
var releaseDays = Math.floor(releaseDate.toDate().getTime() / 8.64e7);
var keyValidityDays = _extractTime(key);
keyValidityDate = (0, _moment.default)((keyValidityDays + 1) * 8.64e7, 'x').format('MMMM DD, YYYY');
if (releaseDays > keyValidityDays) {
var daysAfterRelease = (0, _moment.default)().diff(releaseDate, 'days');
consoleMessageState = daysAfterRelease <= 1 ? 'valid' : 'expired';
domMessageState = daysAfterRelease <= 15 ? 'valid' : 'expired';
} else {
consoleMessageState = 'valid';
domMessageState = 'valid';
}
} else if (isNonCommercial) {
consoleMessageState = 'non_commercial';
domMessageState = 'valid';
} else {
consoleMessageState = 'invalid';
domMessageState = 'invalid';
}
} else {
consoleMessageState = 'missing';
domMessageState = 'missing';
}
if (_ignored()) {
consoleMessageState = 'valid';
domMessageState = 'valid';
}
if (!_notified && consoleMessageState !== 'valid') {
var message = consoleMessages[consoleMessageState]({
keyValidityDate: keyValidityDate,
hotVersion: hotVersion
});
if (message) {
console[consoleMessageState === 'non_commercial' ? 'info' : 'warn'](consoleMessages[consoleMessageState]({
keyValidityDate: keyValidityDate,
hotVersion: hotVersion
}));
}
_notified = true;
}
if (domMessageState !== 'valid' && element.parentNode) {
var _message = domMessages[domMessageState]({
keyValidityDate: keyValidityDate,
hotVersion: hotVersion
});
if (_message) {
var messageNode = document.createElement('div');
messageNode.id = 'hot-display-license-info';
messageNode.innerHTML = domMessages[domMessageState]({
keyValidityDate: keyValidityDate,
hotVersion: hotVersion
});
element.parentNode.insertBefore(messageNode, element.nextSibling);
}
}
}
function _checkKeySchema(v) {
var z = [][_m];
var p = z;
if (v[_m] !== _cp('\x5A')) {
return false;
}
for (var c = '', i = '\x42\x3C\x48\x34\x50\x2B'.split(''), j = _cp(i.shift()); j; j = _cp(i.shift() || 'A')) {
--j < ''[_m] ? p = p | (_pi("".concat(_pi(_hd(c) + (_hd(_ss(v, Math.abs(j), 2)) + []).padStart(2, '0')))) % 97 || 2) >> 1 : c = _ss(v, j, !j ? 6 : i[_m] === 1 ? 9 : 8);
}
return p === z;
}
/* eslint-enable */
/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
__webpack_require__(18);
exports.__esModule = true;
exports.getCondition = getCondition;
exports.getConditionDescriptor = getConditionDescriptor;
exports.registerCondition = registerCondition;
exports.conditions = void 0;
var conditions = {};
/**
* Get condition closure with pre-bound arguments.
*
* @param {String} name Condition name.
* @param {Array} args Condition arguments.
* @returns {Function}
*/
exports.conditions = conditions;
function getCondition(name, args) {
if (!conditions[name]) {
throw Error("Filter condition \"".concat(name, "\" does not exist."));
}
var _conditions$name = conditions[name],
condition = _conditions$name.condition,
descriptor = _conditions$name.descriptor;
var conditionArguments = args;
if (descriptor.inputValuesDecorator) {
conditionArguments = descriptor.inputValuesDecorator(conditionArguments);
}
return function (dataRow) {
return condition.apply(dataRow.meta.instance, [].concat([dataRow], [conditionArguments]));
};
}
/**
* Get condition object descriptor which defines some additional informations about this condition.
*
* @param {String} name Condition name.
* @returns {Object}
*/
function getConditionDescriptor(name) {
if (!conditions[name]) {
throw Error("Filter condition \"".concat(name, "\" does not exist."));
}
return conditions[name].descriptor;
}
/**
* Condition registerer.
*
* @param {String} name Condition name.
* @param {Function} condition Condition function
* @param {Object} descriptor Condition descriptor
*/
function registerCondition(name, condition, descriptor) {
descriptor.key = name;
conditions[name] = {
condition: condition,
descriptor: descriptor
};
}
/***/ }),
/* 29 */
/***/ (function(module, exports) {
module.exports = function (exec) {
try {
return !!exec();
} catch (e) {
return true;
}
};
/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {
// ie9- setTimeout & setInterval additional parameters fix
var global = __webpack_require__(32);
var userAgent = __webpack_require__(203);
var slice = [].slice;
var MSIE = /MSIE .\./.test(userAgent); // <- dirty ie9- check
var wrap = function (set) {
return function (fn, time /* , ...args */) {
var boundArgs = arguments.length > 2;
var args = boundArgs ? slice.call(arguments, 2) : false;
return set(boundArgs ? function () {
// eslint-disable-next-line no-new-func
(typeof fn == 'function' ? fn : Function(fn)).apply(this, args);
} : fn, time);
};
};
__webpack_require__(22)({ global: true, bind: true, forced: MSIE }, {
setTimeout: wrap(global.setTimeout),
setInterval: wrap(global.setInterval)
});
/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.stopImmediatePropagation = stopImmediatePropagation;
exports.isImmediatePropagationStopped = isImmediatePropagationStopped;
exports.stopPropagation = stopPropagation;
exports.pageX = pageX;
exports.pageY = pageY;
exports.isRightClick = isRightClick;
exports.isLeftClick = isLeftClick;
var _element = __webpack_require__(5);
/**
* Prevent other listeners of the same event from being called.
*
* @param {Event} event
*/
function stopImmediatePropagation(event) {
event.isImmediatePropagationEnabled = false;
event.cancelBubble = true;
}
/**
* Check if event was stopped by `stopImmediatePropagation`.
*
* @param event {Event}
* @returns {Boolean}
*/
function isImmediatePropagationStopped(event) {
return event.isImmediatePropagationEnabled === false;
}
/**
* Prevent further propagation of the current event (prevent bubbling).
*
* @param event {Event}
*/
function stopPropagation(event) {
// ie8
// http://msdn.microsoft.com/en-us/library/ie/ff975462(v=vs.85).aspx
if (typeof event.stopPropagation === 'function') {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
/**
* Get horizontal coordinate of the event object relative to the whole document.
*
* @param {Event} event
* @returns {Number}
*/
function pageX(event) {
if (event.pageX) {
return event.pageX;
}
var rootWindow = event.target.ownerDocument.defaultView;
return event.clientX + (0, _element.getWindowScrollLeft)(rootWindow);
}
/**
* Get vertical coordinate of the event object relative to the whole document.
*
* @param {Event} event
* @returns {Number}
*/
function pageY(event) {
if (event.pageY) {
return event.pageY;
}
var rootWindow = event.target.ownerDocument.defaultView;
return event.clientY + (0, _element.getWindowScrollTop)(rootWindow);
}
/**
* Check if provided event was triggered by clicking the right mouse button.
*
* @param {Event} event DOM Event.
* @returns {Boolean}
*/
function isRightClick(event) {
return event.button === 2;
}
/**
* Check if provided event was triggered by clicking the left mouse button.
*
* @param {Event} event DOM Event.
* @returns {Boolean}
*/
function isLeftClick(event) {
return event.button === 0;
}
/***/ }),
/* 32 */
/***/ (function(module, exports) {
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
module.exports = typeof window == 'object' && window && window.Math == Math ? window
: typeof self == 'object' && self && self.Math == Math ? self
// eslint-disable-next-line no-new-func
: Function('return this')();
/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var toAbsoluteIndex = __webpack_require__(114);
var toInteger = __webpack_require__(86);
var toLength = __webpack_require__(48);
var toObject = __webpack_require__(62);
var arraySpeciesCreate = __webpack_require__(151);
var createProperty = __webpack_require__(127);
var max = Math.max;
var min = Math.min;
var MAX_SAFE_INTEGER = 0x1fffffffffffff;
var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';
var SPECIES_SUPPORT = __webpack_require__(103)('splice');
// `Array.prototype.splice` method
// https://tc39.github.io/ecma262/#sec-array.prototype.splice
// with adding support of @@species
__webpack_require__(22)({ target: 'Array', proto: true, forced: !SPECIES_SUPPORT }, {
splice: function splice(start, deleteCount /* , ...items */) {
var O = toObject(this);
var len = toLength(O.length);
var actualStart = toAbsoluteIndex(start, len);
var argumentsLength = arguments.length;
var insertCount, actualDeleteCount, A, k, from, to;
if (argumentsLength === 0) {
insertCount = actualDeleteCount = 0;
} else if (argumentsLength === 1) {
insertCount = 0;
actualDeleteCount = len - actualStart;
} else {
insertCount = argumentsLength - 2;
actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart);
}
if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {
throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
}
A = arraySpeciesCreate(O, actualDeleteCount);
for (k = 0; k < actualDeleteCount; k++) {
from = actualStart + k;
if (from in O) createProperty(A, k, O[from]);
}
A.length = actualDeleteCount;
if (insertCount < actualDeleteCount) {
for (k = actualStart; k < len - actualDeleteCount; k++) {
from = k + actualDeleteCount;
to = k + insertCount;
if (from in O) O[to] = O[from];
else delete O[to];
}
for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
} else if (insertCount > actualDeleteCount) {
for (k = len - actualDeleteCount; k > actualStart; k--) {
from = k + actualDeleteCount - 1;
to = k + insertCount - 1;
if (from in O) O[to] = O[from];
else delete O[to];
}
}
for (k = 0; k < insertCount; k++) {
O[k + actualStart] = arguments[k + 2];
}
O.length = len - actualDeleteCount + insertCount;
return A;
}
});
/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var internalIncludes = __webpack_require__(140)(true);
// `Array.prototype.includes` method
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
__webpack_require__(22)({ target: 'Array', proto: true }, {
includes: function includes(el /* , fromIndex = 0 */) {
return internalIncludes(this, el, arguments.length > 1 ? arguments[1] : undefined);
}
});
// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables
__webpack_require__(121)('includes');
/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {
var store = __webpack_require__(98)('wks');
var uid = __webpack_require__(118);
var Symbol = __webpack_require__(32).Symbol;
var NATIVE_SYMBOL = __webpack_require__(180);
module.exports = function (name) {
return store[name] || (store[name] = NATIVE_SYMBOL && Symbol[name]
|| (NATIVE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};
/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var anObject = __webpack_require__(45);
var fails = __webpack_require__(29);
var flags = __webpack_require__(153);
var DESCRIPTORS = __webpack_require__(52);
var TO_STRING = 'toString';
var nativeToString = /./[TO_STRING];
var NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });
// FF44- RegExp#toString has a wrong name
var INCORRECT_NAME = nativeToString.name != TO_STRING;
// `RegExp.prototype.toString` method
// https://tc39.github.io/ecma262/#sec-regexp.prototype.tostring
if (NOT_GENERIC || INCORRECT_NAME) {
__webpack_require__(64)(RegExp.prototype, TO_STRING, function toString() {
var R = anObject(this);
return '/'.concat(R.source, '/',
'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? flags.call(R) : undefined);
}, { unsafe: true });
}
/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var anObject = __webpack_require__(45);
var toObject = __webpack_require__(62);
var toLength = __webpack_require__(48);
var toInteger = __webpack_require__(86);
var requireObjectCoercible = __webpack_require__(58);
var advanceStringIndex = __webpack_require__(155);
var regExpExec = __webpack_require__(128);
var max = Math.max;
var min = Math.min;
var floor = Math.floor;
var SUBSTITUTION_SYMBOLS = /\$([$&`']|\d\d?|<[^>]*>)/g;
var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&`']|\d\d?)/g;
var maybeToString = function (it) {
return it === undefined ? it : String(it);
};
// @@replace logic
__webpack_require__(129)(
'replace',
2,
function (REPLACE, nativeReplace, maybeCallNative) {
return [
// `String.prototype.replace` method
// https://tc39.github.io/ecma262/#sec-string.prototype.replace
function replace(searchValue, replaceValue) {
var O = requireObjectCoercible(this);
var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
return replacer !== undefined
? replacer.call(searchValue, O, replaceValue)
: nativeReplace.call(String(O), searchValue, replaceValue);
},
// `RegExp.prototype[@@replace]` method
// https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace
function (regexp, replaceValue) {
var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
if (res.done) return res.value;
var rx = anObject(regexp);
var S = String(this);
var functionalReplace = typeof replaceValue === 'function';
if (!functionalReplace) replaceValue = String(replaceValue);
var global = rx.global;
if (global) {
var fullUnicode = rx.unicode;
rx.lastIndex = 0;
}
var results = [];
while (true) {
var result = regExpExec(rx, S);
if (result === null) break;
results.push(result);
if (!global) break;
var matchStr = String(result[0]);
if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
}
var accumulatedResult = '';
var nextSourcePosition = 0;
for (var i = 0; i < results.length; i++) {
result = results[i];
var matched = String(result[0]);
var position = max(min(toInteger(result.index), S.length), 0);
var captures = [];
// NOTE: This is equivalent to
// captures = result.slice(1).map(maybeToString)
// but for some reason `nativeSlice.call(result, 1, result.length)` (called in
// the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
// causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
var namedCaptures = result.groups;
if (functionalReplace) {
var replacerArgs = [matched].concat(captures, position, S);
if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
var replacement = String(replaceValue.apply(undefined, replacerArgs));
} else {
replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
}
if (position >= nextSourcePosition) {
accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
nextSourcePosition = position + matched.length;
}
}
return accumulatedResult + S.slice(nextSourcePosition);
}
];
// https://tc39.github.io/ecma262/#sec-getsubstitution
function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
var tailPos = position + matched.length;
var m = captures.length;
var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
if (namedCaptures !== undefined) {
namedCaptures = toObject(namedCaptures);
symbols = SUBSTITUTION_SYMBOLS;
}
return nativeReplace.call(replacement, symbols, function (match, ch) {
var capture;
switch (ch.charAt(0)) {
case '$': return '$';
case '&': return matched;
case '`': return str.slice(0, position);
case "'": return str.slice(tailPos);
case '<':
capture = namedCaptures[ch.slice(1, -1)];
break;
default: // \d\d?
var n = +ch;
if (n === 0) return match;
if (n > m) {
var f = floor(n / 10);
if (f === 0) return match;
if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
return match;
}
capture = captures[n - 1];
}
return capture === undefined ? '' : capture;
});
}
}
);
/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {
var arrayWithoutHoles = __webpack_require__(269);
var iterableToArray = __webpack_require__(195);
var nonIterableSpread = __webpack_require__(270);
function _toConsumableArray(arr) {
return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
}
module.exports = _toConsumableArray;
/***/ }),
/* 39 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var validateArguments = __webpack_require__(157);
var INCLUDES = 'includes';
var CORRECT_IS_REGEXP_LOGIC = __webpack_require__(158)(INCLUDES);
// `String.prototype.includes` method
// https://tc39.github.io/ecma262/#sec-string.prototype.includes
__webpack_require__(22)({ target: 'String', proto: true, forced: !CORRECT_IS_REGEXP_LOGIC }, {
includes: function includes(searchString /* , position = 0 */) {
return !!~validateArguments(this, searchString, INCLUDES)
.indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
}
});
/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var isObject = __webpack_require__(42);
var isArray = __webpack_require__(124);
var toAbsoluteIndex = __webpack_require__(114);
var toLength = __webpack_require__(48);
var toIndexedObject = __webpack_require__(69);
var createProperty = __webpack_require__(127);
var SPECIES = __webpack_require__(35)('species');
var nativeSlice = [].slice;
var max = Math.max;
var SPECIES_SUPPORT = __webpack_require__(103)('slice');
// `Array.prototype.slice` method
// https://tc39.github.io/ecma262/#sec-array.prototype.slice
// fallback for not array-like ES3 strings and DOM objects
__webpack_require__(22)({ target: 'Array', proto: true, forced: !SPECIES_SUPPORT }, {
slice: function slice(start, end) {
var O = toIndexedObject(this);
var length = toLength(O.length);
var k = toAbsoluteIndex(start, length);
var fin = toAbsoluteIndex(end === undefined ? length : end, length);
// inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
var Constructor, result, n;
if (isArray(O)) {
Constructor = O.constructor;
// cross-realm fallback
if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {
Constructor = undefined;
} else if (isObject(Constructor)) {
Constructor = Constructor[SPECIES];
if (Constructor === null) Constructor = undefined;
}
if (Constructor === Array || Constructor === undefined) {
return nativeSlice.call(O, k, fin);
}
}
result = new (Constructor === undefined ? Array : Constructor)(max(fin - k, 0));
for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);
result.length = n;
return result;
}
});
/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.getRenderer = _getItem;
exports.getRegisteredRenderers = exports.getRegisteredRendererNames = exports.hasRenderer = exports.registerRenderer = void 0;
var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));
var _cellDecorator = _interopRequireDefault(__webpack_require__(296));
var _autocompleteRenderer = _interopRequireDefault(__webpack_require__(297));
var _checkboxRenderer = _interopRequireDefault(__webpack_require__(298));
var _htmlRenderer = _interopRequireDefault(__webpack_require__(299));
var _numericRenderer = _interopRequireDefault(__webpack_require__(300));
var _passwordRenderer = _interopRequireDefault(__webpack_require__(302));
var _textRenderer = _interopRequireDefault(__webpack_require__(303));
var _staticRegister = (0, _staticRegister2.default)('renderers'),
register = _staticRegister.register,
getItem = _staticRegister.getItem,
hasItem = _staticRegister.hasItem,
getNames = _staticRegister.getNames,
getValues = _staticRegister.getValues;
exports.getRegisteredRenderers = getValues;
exports.getRegisteredRendererNames = getNames;
exports.hasRenderer = hasItem;
exports.registerRenderer = register;
register('base', _cellDecorator.default);
register('autocomplete', _autocompleteRenderer.default);
register('checkbox', _checkboxRenderer.default);
register('html', _htmlRenderer.default);
register('numeric', _numericRenderer.default);
register('password', _passwordRenderer.default);
register('text', _textRenderer.default);
/**
* Retrieve renderer function.
*
* @param {String} name Renderer identification.
* @returns {Function} Returns renderer function.
*/
function _getItem(name) {
if (typeof name === 'function') {
return name;
}
if (!hasItem(name)) {
throw Error("No registered renderer found under \"".concat(name, "\" name"));
}
return getItem(name);
}
/***/ }),
/* 42 */
/***/ (function(module, exports) {
module.exports = function (it) {
return typeof it === 'object' ? it !== null : typeof it === 'function';
};
/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(33);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
/**
* @description
* Handsontable events are the common interface that function in 2 ways: as __callbacks__ and as __hooks__.
*
* @example
*
* ```js
* // Using events as callbacks:
* ...
* const hot1 = new Handsontable(document.getElementById('example1'), {
* afterChange: function(changes, source) {
* $.ajax({
* url: "save.php',
* data: change
* });
* }
* });
* ...
* ```
*
* ```js
* // Using events as plugin hooks:
* ...
* const hot1 = new Handsontable(document.getElementById('example1'), {
* myPlugin: true
* });
*
* const hot2 = new Handsontable(document.getElementById('example2'), {
* myPlugin: false
* });
*
* // global hook
* Handsontable.hooks.add('afterChange', function() {
* // Fired twice - for hot1 and hot2
* if (this.getSettings().myPlugin) {
* // function body - will only run for hot1
* }
* });
*
* // local hook (has same effect as a callback)
* hot2.addHook('afterChange', function() {
* // function body - will only run in #example2
* });
* ```
* ...
*/
// @TODO: Move plugin description hooks to plugin?
var REGISTERED_HOOKS = [
/**
* Fired after resetting a cell's meta. This happens when the {@link Core#updateSettings} method is called.
*
* @event Hooks#afterCellMetaReset
*/
'afterCellMetaReset',
/**
* Fired after one or more cells has been changed. The changes are triggered in any situation when the
* value is entered using an editor or changed using API (e.q setDataAtCell)
*
* __Note:__ For performance reasons, the `changes` array is null for `"loadData"` source.
*
* @event Hooks#afterChange
* @param {Array} changes 2D array containing information about each of the edited cells `[[row, prop, oldVal, newVal], ...]`.
* @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
* @example
* ```js
* new Handsontable(element, {
* afterChange: (changes) => {
* changes.forEach(([row, prop, oldValue, newValue]) => {
* // Some logic...
* });
* }
* })
* ```
*/
'afterChange',
/**
* Fired by {@link ObserveChanges} plugin after detecting changes in the data source. This hook is fired when
* {@link Options#observeChanges} option is enabled.
*
* @event Hooks#afterChangesObserved
*/
'afterChangesObserved',
/**
* Fired each time user opens {@link ContextMenu} and after setting up the Context Menu's default options. These options are a collection
* which user can select by setting an array of keys or an array of objects in {@link Options#contextMenu} option.
*
* @event Hooks#afterContextMenuDefaultOptions
* @param {Array} predefinedItems An array of objects containing information about the pre-defined Context Menu items.
*/
'afterContextMenuDefaultOptions',
/**
* Fired each time user opens {@link ContextMenu} plugin before setting up the Context Menu's items but after filtering these options by
* user (`contextMenu` option). This hook can by helpful to determine if user use specified menu item or to set up
* one of the menu item to by always visible.
*
* @event Hooks#beforeContextMenuSetItems
* @param {Object[]} menuItems An array of objects containing information about to generated Context Menu items.
*/
'beforeContextMenuSetItems',
/**
* Fired by {@link DropdownMenu} plugin after setting up the Dropdown Menu's default options. These options are a
* collection which user can select by setting an array of keys or an array of objects in {@link Options#dropdownMenu}
* option.
*
* @event Hooks#afterDropdownMenuDefaultOptions
* @param {Object[]} predefinedItems An array of objects containing information about the pre-defined Context Menu items.
*/
'afterDropdownMenuDefaultOptions',
/**
* Fired by {@link DropdownMenu} plugin before setting up the Dropdown Menu's items but after filtering these options
* by user (`dropdownMenu` option). This hook can by helpful to determine if user use specified menu item or to set
* up one of the menu item to by always visible.
*
* @event Hooks#beforeDropdownMenuSetItems
* @param {Object[]} menuItems An array of objects containing information about to generated Dropdown Menu items.
*/
'beforeDropdownMenuSetItems',
/**
* Fired by {@link ContextMenu} plugin after hiding the Context Menu. This hook is fired when {@link Options#contextMenu}
* option is enabled.
*
* @event Hooks#afterContextMenuHide
* @param {Object} context The Context Menu plugin instance.
*/
'afterContextMenuHide',
/**
* Fired by {@link ContextMenu} plugin before opening the Context Menu. This hook is fired when {@link Options#contextMenu}
* option is enabled.
*
* @event Hooks#beforeContextMenuShow
* @param {Object} context The Context Menu instance.
*/
'beforeContextMenuShow',
/**
* Fired by {@link ContextMenu} plugin after opening the Context Menu. This hook is fired when {@link Options#contextMenu}
* option is enabled.
*
* @event Hooks#afterContextMenuShow
* @param {Object} context The Context Menu plugin instance.
*/
'afterContextMenuShow',
/**
* Fired by {@link CopyPaste} plugin after reaching the copy limit while copying data. This hook is fired when
* {@link Options#copyPaste} option is enabled.
*
* @event Hooks#afterCopyLimit
* @param {Number} selectedRows Count of selected copyable rows.
* @param {Number} selectedColumns Count of selected copyable columns.
* @param {Number} copyRowsLimit Current copy rows limit.
* @param {Number} copyColumnsLimit Current copy columns limit.
*/
'afterCopyLimit',
/**
* Fired before created a new column.
*
* @event Hooks#beforeCreateCol
* @param {Number} index Represents the visual index of first newly created column in the data source array.
* @param {Number} amount Number of newly created columns in the data source array.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'beforeCreateCol',
/**
* Fired after created a new column.
*
* @event Hooks#afterCreateCol
* @param {Number} index Represents the visual index of first newly created column in the data source.
* @param {Number} amount Number of newly created columns in the data source.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'afterCreateCol',
/**
* Fired before created a new row.
*
* @event Hooks#beforeCreateRow
* @param {Number} index Represents the visual index of first newly created row in the data source array.
* @param {Number} amount Number of newly created rows in the data source array.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'beforeCreateRow',
/**
* Fired after created a new row.
*
* @event Hooks#afterCreateRow
* @param {Number} index Represents the visual index of first newly created row in the data source array.
* @param {Number} amount Number of newly created rows in the data source array.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'afterCreateRow',
/**
* Fired after the current cell is deselected.
*
* @event Hooks#afterDeselect
*/
'afterDeselect',
/**
* Fired after destroying the Handsontable instance.
*
* @event Hooks#afterDestroy
*/
'afterDestroy',
/**
* General hook which captures `keydown` events attached to the document body. These events are delegated to the
* hooks system and consumed by Core and internal modules (e.g plugins, editors).
*
* @event Hooks#afterDocumentKeyDown
* @param {Event} event A native `keydown` event object.
*/
'afterDocumentKeyDown',
/**
* Fired inside the Walkontable's selection `draw` method. Can be used to add additional class names to cells, depending on the current selection.
*
* @event Hooks#afterDrawSelection
* @param {Number} currentRow Row index of the currently processed cell.
* @param {Number} currentColumn Column index of the currently cell.
* @param {Number[]} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
* @param {Number|undefined} layerLevel Number indicating which layer of selection is currently processed.
* @since 0.38.1
* @returns {String|undefined} Can return a `String`, which will act as an additional `className` to be added to the currently processed cell.
*/
'afterDrawSelection',
/**
* Fired inside the Walkontable's `refreshSelections` method. Can be used to remove additional class names from all cells in the table.
*
* @event Hooks#beforeRemoveCellClassNames
* @since 0.38.1
* @returns {String[]|undefined} Can return an `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
*/
'beforeRemoveCellClassNames',
/**
* Fired after getting the cell settings.
*
* @event Hooks#afterGetCellMeta
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {Object} cellProperties Object containing the cell properties.
*/
'afterGetCellMeta',
/**
* Fired after retrieving information about a column header and appending it to the table header.
*
* @event Hooks#afterGetColHeader
* @param {Number} column Visual column index.
* @param {HTMLTableCellElement} TH Header's TH element.
*/
'afterGetColHeader',
/**
* Fired after retrieving information about a row header and appending it to the table header.
*
* @event Hooks#afterGetRowHeader
* @param {Number} row Visual row index.
* @param {HTMLTableCellElement} TH Header's TH element.
*/
'afterGetRowHeader',
/**
* Fired after the Handsontable instance is initiated.
*
* @event Hooks#afterInit
*/
'afterInit',
/**
* Fired after new data is loaded (by `loadData` or `updateSettings` method) into the data source array.
*
* @event Hooks#afterLoadData
* @param {Boolean} initialLoad flag that determines whether the data has been loaded during the initialization.
*/
'afterLoadData',
/**
* Fired after a scroll event, which is identified as a momentum scroll (e.g. on an iPad).
*
* @event Hooks#afterMomentumScroll
*/
'afterMomentumScroll',
/**
* Fired after a `mousedown` event is triggered on the cell corner (the drag handle).
*
* @event Hooks#afterOnCellCornerMouseDown
* @param {Event} event `mousedown` event object.
*/
'afterOnCellCornerMouseDown',
/**
* Fired after a `dblclick` event is triggered on the cell corner (the drag handle).
*
* @event Hooks#afterOnCellCornerDblClick
* @param {Event} event `dblclick` event object.
*/
'afterOnCellCornerDblClick',
/**
* Fired after clicking on a cell or row/column header. In case the row/column header was clicked, the coordinate
* indexes are negative.
*
* For example clicking on the row header of cell (0, 0) results with `afterOnCellMouseDown` called
* with coordinates `{row: 0, col: -1}`.
*
* @event Hooks#afterOnCellMouseDown
* @param {Event} event `mousedown` event object.
* @param {CellCoords} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
* @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
*/
'afterOnCellMouseDown',
/**
* Fired after clicking on a cell or row/column header. In case the row/column header was clicked, the coordinate
* indexes are negative.
*
* For example clicking on the row header of cell (0, 0) results with `afterOnCellMouseUp` called
* with coordinates `{row: 0, col: -1}`.
*
* @event Hooks#afterOnCellMouseUp
* @param {Event} event `mouseup` event object.
* @param {CellCoords} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
* @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
*/
'afterOnCellMouseUp',
/**
* Fired after clicking right mouse button on a cell or row/column header.
*
* For example clicking on the row header of cell (0, 0) results with `afterOnCellContextMenu` called
* with coordinates `{row: 0, col: -1}`.
*
* @event Hooks#afterOnCellContextMenu
* @since 4.1.0
* @param {Event} event `contextmenu` event object.
* @param {CellCoords} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
* @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
*/
'afterOnCellContextMenu',
/**
* Fired after hovering a cell or row/column header with the mouse cursor. In case the row/column header was
* hovered, the index is negative.
*
* For example, hovering over the row header of cell (0, 0) results with `afterOnCellMouseOver` called
* with coords `{row: 0, col: -1}`.
*
* @event Hooks#afterOnCellMouseOver
* @param {Event} event `mouseover` event object.
* @param {CellCoords} coords Hovered cell's visual coordinate object.
* @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
*/
'afterOnCellMouseOver',
/**
* Fired after leaving a cell or row/column header with the mouse cursor.
*
* @event Hooks#afterOnCellMouseOut
* @param {Event} event `mouseout` event object.
* @param {CellCoords} coords Leaved cell's visual coordinate object.
* @param {HTMLTableCellElement} TD Cell's TD (or TH) element.
*/
'afterOnCellMouseOut',
/**
* Fired after one or more columns are removed.
*
* @event Hooks#afterRemoveCol
* @param {Number} index Visual index of starter column.
* @param {Number} amount An amount of removed columns.
* @param {Number[]} physicalColumns An array of physical columns removed from the data source.
* @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'afterRemoveCol',
/**
* Fired after one or more rows are removed.
*
* @event Hooks#afterRemoveRow
* @param {Number} index Visual index of starter row.
* @param {Number} amount An amount of removed rows.
* @param {Number[]} physicalRows An array of physical rows removed from the data source.
* @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'afterRemoveRow',
/**
* Fired after the Handsontable table is rendered.
*
* @event Hooks#afterRender
* @param {Boolean} isForced Is `true` if rendering was triggered by a change of settings or data; or `false` if
* rendering was triggered by scrolling or moving selection.
*/
'afterRender',
/**
* Fired before starting rendering the cell.
*
* @event Hooks#beforeRenderer
* @param {HTMLTableCellElement} TD Currently rendered cell's TD element.
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {String|Number} prop Column property name or a column index, if datasource is an array of arrays.
* @param {*} value Value of the rendered cell.
* @param {Object} cellProperties Object containing the cell's properties.
*/
'beforeRenderer',
/**
* Fired after finishing rendering the cell (after the renderer finishes).
*
* @event Hooks#afterRenderer
* @param {HTMLTableCellElement} TD Currently rendered cell's TD element.
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {String|Number} prop Column property name or a column index, if datasource is an array of arrays.
* @param {*} value Value of the rendered cell.
* @param {Object} cellProperties Object containing the cell's properties.
*/
'afterRenderer',
/**
* Fired after the horizontal scroll event.
*
* @event Hooks#afterScrollHorizontally
*/
'afterScrollHorizontally',
/**
* Fired after the vertical scroll event.
*
* @event Hooks#afterScrollVertically
*/
'afterScrollVertically',
/**
* Fired after one or more cells are selected (e.g. during mouse move).
*
* @event Hooks#afterSelection
* @param {Number} row Selection start visual row index.
* @param {Number} column Selection start visual column index.
* @param {Number} row2 Selection end visual row index.
* @param {Number} column2 Selection end visual column index.
* @param {Object} preventScrolling Object with `value` property where its value change will be observed.
* @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
* @example
* ```js
* new Handsontable(element, {
* afterSelection: (row, column, row2, column2, preventScrolling, selectionLayerLevel) => {
* // setting if prevent scrolling after selection
* preventScrolling.value = true;
* }
* })
* ```
*/
'afterSelection',
/**
* Fired after one or more cells are selected.
*
* The `prop` and `prop2` arguments represent the source object property name instead of the column number.
*
* @event Hooks#afterSelectionByProp
* @param {Number} row Selection start visual row index.
* @param {String} prop Selection start data source object property name.
* @param {Number} row2 Selection end visual row index.
* @param {String} prop2 Selection end data source object property name.
* @param {Object} preventScrolling Object with `value` property where its value change will be observed.
* @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
* @example
* ```js
* new Handsontable(element, {
* afterSelectionByProp: (row, column, row2, column2, preventScrolling, selectionLayerLevel) => {
* // setting if prevent scrolling after selection
* preventScrolling.value = true;
* }
* })
* ```
*/
'afterSelectionByProp',
/**
* Fired after one or more cells are selected (e.g. on mouse up).
*
* @event Hooks#afterSelectionEnd
* @param {Number} row Selection start visual row index.
* @param {Number} column Selection start visual column index.
* @param {Number} row2 Selection end visual row index.
* @param {Number} column2 Selection end visual column index.
* @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
*/
'afterSelectionEnd',
/**
* Fired after one or more cells are selected (e.g. on mouse up).
*
* The `prop` and `prop2` arguments represent the source object property name instead of the column number.
*
* @event Hooks#afterSelectionEndByProp
* @param {Number} row Selection start visual row index.
* @param {String} prop Selection start data source object property index.
* @param {Number} row2 Selection end visual row index.
* @param {String} prop2 Selection end data source object property index.
* @param {Number} selectionLayerLevel The number which indicates what selection layer is currently modified.
*/
'afterSelectionEndByProp',
/**
* Fired after cell meta is changed.
*
* @event Hooks#afterSetCellMeta
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {String} key The updated meta key.
* @param {*} value The updated meta value.
*/
'afterSetCellMeta',
/**
* Fired after cell meta is removed.
*
* @event Hooks#afterRemoveCellMeta
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {String} key The removed meta key.
* @param {*} value Value which was under removed key of cell meta.
*/
'afterRemoveCellMeta',
/**
* Fired after cell data was changed.
*
* @event Hooks#afterSetDataAtCell
* @param {Array} changes An array of changes in format `[[row, column, oldValue, value], ...]`.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'afterSetDataAtCell',
/**
* Fired after cell data was changed.
*
* @event Hooks#afterSetDataAtRowProp
* @param {Array} changes An array of changes in format `[[row, prop, oldValue, value], ...]`.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'afterSetDataAtRowProp',
/**
* Fired after calling the `updateSettings` method.
*
* @event Hooks#afterUpdateSettings
* @param {Object} newSettings New settings object.
*/
'afterUpdateSettings',
/**
* @description
* A plugin hook executed after validator function, only if validator function is defined.
* Validation result is the first parameter. This can be used to determinate if validation passed successfully or not.
*
* __Returning false from the callback will mark the cell as invalid.__
*
* @event Hooks#afterValidate
* @param {Boolean} isValid `true` if valid, `false` if not.
* @param {*} value The value in question.
* @param {Number} row Visual row index.
* @param {String|Number} prop Property name / visual column index.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'afterValidate',
/**
* Fired before successful change of language (when proper language code was set)
*
* @event Hooks#beforeLanguageChange
* @since 0.35.0
* @param {String} languageCode New language code.
*/
'beforeLanguageChange',
/**
* Fired after successful change of language (when proper language code was set).
*
* @event Hooks#afterLanguageChange
* @since 0.35.0
* @param {String} languageCode New language code.
*/
'afterLanguageChange',
/**
* Fired by {@link Autofill} plugin before populating the data in the autofill feature. This hook is fired when
* {@link Options#fillHandle} option is enabled.
*
* @event Hooks#beforeAutofill
* @param {CellCoords} start Object containing information about first filled cell: `{row: 2, col: 0}`.
* @param {CellCoords} end Object containing information about last filled cell: `{row: 4, col: 1}`.
* @param {Array[]} data 2D array containing information about fill pattern: `[["1", "Ted"], ["1", "John"]]`.
*/
'beforeAutofill',
/**
* Fired before aligning the cell contents.
*
* @event Hooks#beforeCellAlignment
* @param {Object} stateBefore An object with class names defining the cell alignment.
* @param {CellRange[]} range An array of CellRange coordinates where the alignment will be applied.
* @param {String} type Type of the alignment - either `horizontal` or `vertical`.
* @param {String} alignmentClass String defining the alignment class added to the cell.
* Possible values:
* * `htLeft`
* * `htCenter`
* * `htRight`
* * `htJustify`
* * `htTop`
* * `htMiddle`
* * `htBottom`
*/
'beforeCellAlignment',
/**
* Fired before one or more cells is changed. Its main purpose is to alter changes silently after input and before
* table rendering.
*
* @event Hooks#beforeChange
* @param {Array[]} changes 2D array containing information about each of the edited cells.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
* @example
* ```js
* // To disregard a single change, set changes[i] to null or remove it from array using changes.splice(i, 1).
* new Handsontable(element, {
* beforeChange: (changes, source) => {
* // [[row, prop, oldVal, newVal], ...]
* changes[0] = null;
* }
* });
* // To alter a single change, overwrite the desired value to changes[i][3].
* new Handsontable(element, {
* beforeChange: (changes, source) => {
* // [[row, prop, oldVal, newVal], ...]
* changes[0][3] = 10;
* }
* });
* // To cancel all edit, return false from the callback or set array length to 0 (changes.length = 0).
* new Handsontable(element, {
* beforeChange: (changes, source) => {
* // [[row, prop, oldVal, newVal], ...]
* return false;
* }
* });
* ```
*/
'beforeChange',
/**
* Fired right before rendering the changes.
*
* @event Hooks#beforeChangeRender
* @param {Array[]} changes Array in form of `[row, prop, oldValue, newValue]`.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'beforeChangeRender',
/**
* Fired before drawing the borders.
*
* @event Hooks#beforeDrawBorders
* @param {Array} corners Array specifying the current selection borders.
* @param {String} borderClassName Specifies the border class name.
*/
'beforeDrawBorders',
/**
* Fired before getting cell settings.
*
* @event Hooks#beforeGetCellMeta
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {Object} cellProperties Object containing the cell's properties.
*/
'beforeGetCellMeta',
/**
* Fired before cell meta is removed.
*
* @event Hooks#beforeRemoveCellMeta
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {String} key The removed meta key.
* @param {*} value Value which is under removed key of cell meta.
*/
'beforeRemoveCellMeta',
/**
* Fired before the Handsontable instance is initiated.
*
* @event Hooks#beforeInit
*/
'beforeInit',
/**
* Fired before the Walkontable instance is initiated.
*
* @event Hooks#beforeInitWalkontable
* @param {Object} walkontableConfig Walkontable configuration object.
*/
'beforeInitWalkontable',
/**
* Fired before keydown event is handled. It can be used to overwrite default key bindings.
*
* __Note__: To prevent default behavior you need to call `event.stopImmediatePropagation()` in your `beforeKeyDown`
* handler.
*
* @event Hooks#beforeKeyDown
* @param {Event} event Original DOM event.
*/
'beforeKeyDown',
/**
* Fired after the user clicked a cell, but before all the calculations related with it.
*
* @event Hooks#beforeOnCellMouseDown
* @param {Event} event The `mousedown` event object.
* @param {CellCoords} coords Cell coords object containing the visual coordinates of the clicked cell.
* @param {HTMLTableCellElement} TD TD element.
* @param {Object} controller An object with keys `row`, `column` and `cells` which contains boolean values. This
* object allows or disallows changing the selection for the particular axies.
*/
'beforeOnCellMouseDown',
/**
* Fired after the user clicked a cell.
*
* @event Hooks#beforeOnCellMouseUp
* @param {Event} event The `mouseup` event object.
* @param {CellCoords} coords Cell coords object containing the visual coordinates of the clicked cell.
* @param {HTMLTableCellElement} TD TD element.
* @param {Object} controller An object with keys `row`, `column` and `cells` which contains boolean values. This
* object allows or disallows changing the selection for the particular axies.
*/
'beforeOnCellMouseUp',
/**
* Fired after the user clicked a cell, but before all the calculations related with it.
*
* @event Hooks#beforeOnCellContextMenu
* @since 4.1.0
* @param {Event} event The `contextmenu` event object.
* @param {CellCoords} coords Cell coords object containing the visual coordinates of the clicked cell.
* @param {HTMLTableCellElement} TD TD element.
*/
'beforeOnCellContextMenu',
/**
* Fired after the user moved cursor over a cell, but before all the calculations related with it.
*
* @event Hooks#beforeOnCellMouseOver
* @param {Event} event The `mouseover` event object.
* @param {CellCoords} coords CellCoords object containing the visual coordinates of the clicked cell.
* @param {HTMLTableCellElement} TD TD element.
* @param {Object} controller An object with keys `row`, `column` and `cells` which contains boolean values. This
* object allows or disallows changing the selection for the particular axies.
*/
'beforeOnCellMouseOver',
/**
* Fired after the user moved cursor out from a cell, but before all the calculations related with it.
*
* @event Hooks#beforeOnCellMouseOut
* @param {Event} event The `mouseout` event object.
* @param {CellCoords} coords CellCoords object containing the visual coordinates of the leaved cell.
* @param {HTMLTableCellElement} TD TD element.
*/
'beforeOnCellMouseOut',
/**
* Fired before one or more columns are about to be removed.
*
* @event Hooks#beforeRemoveCol
* @param {Number} index Visual index of starter column.
* @param {Number} amount Amount of columns to be removed.
* @param {Number[]} physicalColumns An array of physical columns removed from the data source.
* @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'beforeRemoveCol',
/**
* Fired when one or more rows are about to be removed.
*
* @event Hooks#beforeRemoveRow
* @param {Number} index Visual index of starter column.
* @param {Number} amount Amount of columns to be removed.
* @param {Number[]} physicalRows An array of physical rows removed from the data source.
* @param {String} [source] String that identifies source of hook call ([list of all available sources]{@link https://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'beforeRemoveRow',
/**
* Fired before the Handsontable table is rendered.
*
* @event Hooks#beforeRender
* @param {Boolean} isForced If `true` rendering was triggered by a change of settings or data; or `false` if
* rendering was triggered by scrolling or moving selection.
*/
'beforeRender',
/**
* Fired before setting range is started but not finished yet.
*
* @event Hooks#beforeSetRangeStartOnly
* @param {CellCoords} coords CellCoords instance.
*/
'beforeSetRangeStartOnly',
/**
* Fired before setting range is started.
*
* @event Hooks#beforeSetRangeStart
* @param {CellCoords} coords CellCoords instance.
*/
'beforeSetRangeStart',
/**
* Fired before setting range is ended.
*
* @event Hooks#beforeSetRangeEnd
* @param {CellCoords} coords CellCoords instance.
*/
'beforeSetRangeEnd',
/**
* Fired before the logic of handling a touch scroll, when user started scrolling on a touch-enabled device.
*
* @event Hooks#beforeTouchScroll
*/
'beforeTouchScroll',
/**
* Fired before cell validation, only if validator function is defined. This can be used to manipulate the value
* of changed cell before it is applied to the validator function.
*
* __Note:__ this will not affect values of changes. This will change value *ONLY* for validation
*
* @event Hooks#beforeValidate
* @param {*} value Value of the cell.
* @param {Number} row Visual row index.
* @param {String|Number} prop Property name / column index.
* @param {String} [source] String that identifies source of hook call
* ([list of all available sources]{@link http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
*/
'beforeValidate',
/**
* Fired before cell value is rendered into the DOM (through renderer function). This can be used to manipulate the
* value which is passed to the renderer without modifying the renderer itself.
*
* @event Hooks#beforeValueRender
* @param {*} value Cell value to render.
* @param {Object} cellProperties An object containing the cell properties.
*/
'beforeValueRender',
/**
* Fired after Handsontable instance is constructed (using `new` operator).
*
* @event Hooks#construct
*/
'construct',
/**
* Fired after Handsontable instance is initiated but before table is rendered.
*
* @event Hooks#init
*/
'init',
/**
* Fired when a column index is about to be modified by a callback function.
*
* @event Hooks#modifyCol
* @param {Number} column Visual column index.
*/
'modifyCol',
/**
* Fired when a column index is about to be de-modified by a callback function.
*
* @event Hooks#unmodifyCol
* @param {Number} column Physical column index.
*/
'unmodifyCol',
/**
* Fired when a physical row index is about to be de-modified by a callback function.
*
* @event Hooks#unmodifyRow
* @param {Number} row Physical row index.
*/
'unmodifyRow',
/**
* Fired when a column header index is about to be modified by a callback function.
*
* @event Hooks#modifyColHeader
* @param {Number} column Visual column header index.
*/
'modifyColHeader',
/**
* Fired when a column width is about to be modified by a callback function.
*
* @event Hooks#modifyColWidth
* @param {Number} width Current column width.
* @param {Number} column Visual column index.
*/
'modifyColWidth',
/**
* Fired when a row index is about to be modified by a callback function.
*
* @event Hooks#modifyRow
* @param {Number} row Visual row index.
*/
'modifyRow',
/**
* Fired when a row header index is about to be modified by a callback function.
*
* @event Hooks#modifyRowHeader
* @param {Number} row Visual row header index.
*/
'modifyRowHeader',
/**
* Fired when a row height is about to be modified by a callback function.
*
* @event Hooks#modifyRowHeight
* @param {Number} height Row height.
* @param {Number} row Visual row index.
*/
'modifyRowHeight',
/**
* Fired when a data was retrieved or modified.
*
* @event Hooks#modifyData
* @param {Number} row Row height.
* @param {Number} column Column index.
* @param {Object} valueHolder Object which contains original value which can be modified by overwriting `.value` property.
* @param {String} ioMode String which indicates for what operation hook is fired (`get` or `set`).
*/
'modifyData',
/**
* Fired when a data was retrieved or modified.
*
* @event Hooks#modifyRowData
* @param {Number} row Physical row index.
*/
'modifyRowData',
/**
* Used to modify the cell coordinates when using the `getCell` method.
*
* @event Hooks#modifyGetCellCoords
* @since 0.36.0
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {Boolean} topmost If set to `true`, it returns the TD element from the topmost overlay. For example,
* if the wanted cell is in the range of fixed rows, it will return a TD element
* from the `top` overlay.
*/
'modifyGetCellCoords',
/**
* Fired by {@link PersistentState} plugin, after loading value, saved under given key, from browser local storage. This hook is fired when
* {@link Options#persistentState} option is enabled.
*
* @event Hooks#persistentStateLoad
* @param {String} key Key.
* @param {Object} valuePlaceholder Object containing the loaded value under `valuePlaceholder.value` (if no value have been saved, `value` key will be undefined).
*/
'persistentStateLoad',
/**
* Fired by {@link PersistentState} plugin after resetting data from local storage. If no key is given, all values associated with table will be cleared.
* This hook is fired when {@link Options#persistentState} option is enabled.
*
* @event Hooks#persistentStateReset
* @param {String} [key] Key.
*/
'persistentStateReset',
/**
* Fired by {@link PersistentState} plugin, after saving value under given key in browser local storage. This hook is fired when
* {@link Options#persistentState} option is enabled.
*
* @event Hooks#persistentStateSave
* @param {String} key Key.
* @param {Mixed} value Value to save.
*/
'persistentStateSave',
/**
* Fired by {@link ColumnSorting} and {@link MultiColumnSorting} plugins before sorting the column. If you return `false` value inside callback for hook, then sorting
* will be not applied by the Handsontable (useful for server-side sorting).
*
* This hook is fired when {@link Options#columnSorting} or {@link Options#multiColumnSorting} option is enabled.
*
* @event Hooks#beforeColumnSort
* @param {Array} currentSortConfig Current sort configuration (for all sorted columns).
* @param {Array} destinationSortConfigs Destination sort configuration (for all sorted columns).
*/
'beforeColumnSort',
/**
* Fired by {@link ColumnSorting} and {@link MultiColumnSorting} plugins after sorting the column. This hook is fired when {@link Options#columnSorting}
* or {@link Options#multiColumnSorting} option is enabled.
*
* @event Hooks#afterColumnSort
* @param {Array} currentSortConfig Current sort configuration (for all sorted columns).
* @param {Array} destinationSortConfigs Destination sort configuration (for all sorted columns).
*/
'afterColumnSort',
/**
* Fired by {@link Autofill} plugin after setting range of autofill. This hook is fired when {@link Options#fillHandle}
* option is enabled.
*
* @event Hooks#modifyAutofillRange
* @param {Array} startArea Array of visual coordinates of the starting point for the drag-down operation (`[startRow, startColumn, endRow, endColumn]`).
* @param {Array} entireArea Array of visual coordinates of the entire area of the drag-down operation (`[startRow, startColumn, endRow, endColumn]`).
*/
'modifyAutofillRange',
/**
* Fired to allow modifying the copyable range with a callback function.
*
* @event Hooks#modifyCopyableRange
* @param {Array[]} copyableRanges Array of objects defining copyable cells.
*/
'modifyCopyableRange',
/**
* Fired by {@link CopyPaste} plugin before copying the values into clipboard and before clearing values of
* the selected cells. This hook is fired when {@link Options#copyPaste} option is enabled.
*
* @event Hooks#beforeCut
* @param {Array[]} data An array of arrays which contains data to cut.
* @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
* which will be cut out.
* @returns {*} If returns `false` then operation of the cutting out is canceled.
* @example
* ```js
* // To disregard a single row, remove it from the array using data.splice(i, 1).
* new Handsontable(element, {
* beforeCut: function(data, coords) {
* // data -> [[1, 2, 3], [4, 5, 6]]
* data.splice(0, 1);
* // data -> [[4, 5, 6]]
* // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
* }
* });
* // To cancel a cutting action, just return `false`.
* new Handsontable(element, {
* beforeCut: function(data, coords) {
* return false;
* }
* });
* ```
*/
'beforeCut',
/**
* Fired by {@link CopyPaste} plugin after data was cut out from the table. This hook is fired when
* {@link Options#copyPaste} option is enabled.
*
* @event Hooks#afterCut
* @param {Array[]} data An array of arrays which contains the cutted out data.
* @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
* which was cut out.
*/
'afterCut',
/**
* Fired before values are copied into clipboard.
*
* @event Hooks#beforeCopy
* @param {Array[]} data An array of arrays which contains data to copied.
* @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
* which will copied.
* @returns {*} If returns `false` then copying is canceled.
*
* @example
* ```js
* // To disregard a single row, remove it from array using data.splice(i, 1).
* ...
* new Handsontable(document.getElementById('example'), {
* beforeCopy: (data, coords) => {
* // data -> [[1, 2, 3], [4, 5, 6]]
* data.splice(0, 1);
* // data -> [[4, 5, 6]]
* // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
* }
* });
* ...
*
* // To cancel copying, return false from the callback.
* ...
* new Handsontable(document.getElementById('example'), {
* beforeCopy: (data, coords) => {
* return false;
* }
* });
* ...
* ```
*/
'beforeCopy',
/**
* Fired by {@link CopyPaste} plugin after data are pasted into table. This hook is fired when {@link Options#copyPaste}
* option is enabled.
*
* @event Hooks#afterCopy
* @param {Array[]} data An array of arrays which contains the copied data.
* @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
* which was copied.
*/
'afterCopy',
/**
* Fired by {@link CopyPaste} plugin before values are pasted into table. This hook is fired when
* {@link Options#copyPaste} option is enabled.
*
* @event Hooks#beforePaste
* @param {Array[]} data An array of arrays which contains data to paste.
* @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
* that correspond to the previously selected area.
* @returns {*} If returns `false` then pasting is canceled.
* @example
* ```js
* // To disregard a single row, remove it from array using data.splice(i, 1).
* new Handsontable(example, {
* beforePaste: (data, coords) => {
* // data -> [[1, 2, 3], [4, 5, 6]]
* data.splice(0, 1);
* // data -> [[4, 5, 6]]
* // coords -> [{startRow: 0, startCol: 0, endRow: 1, endCol: 2}]
* }
* });
* // To cancel pasting, return false from the callback.
* new Handsontable(example, {
* beforePaste: (data, coords) => {
* return false;
* }
* });
* ```
*/
'beforePaste',
/**
* Fired by {@link CopyPaste} plugin after values are pasted into table. This hook is fired when
* {@link Options#copyPaste} option is enabled.
*
* @event Hooks#afterPaste
* @param {Array[]} data An array of arrays which contains the pasted data.
* @param {Object[]} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
* that correspond to the previously selected area.
*/
'afterPaste',
/**
* Fired by {@link ManualColumnMove} plugin before change order of the visual indexes. This hook is fired when
* {@link Options#manualColumnMove} option is enabled.
*
* @event Hooks#beforeColumnMove
* @param {Number[]} columns Array of visual column indexes to be moved.
* @param {Number} target Visual column index being a target for moved columns.
*/
'beforeColumnMove',
/**
* Fired by {@link ManualColumnMove} plugin after changing order of the visual indexes. This hook is fired when
* {@link Options#manualColumnMove} option is enabled.
*
* @event Hooks#afterColumnMove
* @param {Number[]} columns Array of visual column indexes that were moved.
* @param {Number} target Visual column index being a target for moved columns.
*/
'afterColumnMove',
/**
* Fired by {@link ManualRowMove} plugin before change order of the visual indexes. This hook is fired when
* {@link Options#manualRowMove} option is enabled.
*
* @event Hooks#beforeRowMove
* @param {Number[]} rows An array of visual row indexes to be moved.
* @param {Number} target Visual row index being a target for moved rows.
*/
'beforeRowMove',
/**
* Fired by {@link ManualRowMove} plugin after change order of the visual indexes. This hook is fired when
* {@link Options#manualRowMove} option is enabled.
*
* @event Hooks#afterRowMove
* @param {Number[]} rows An array of visual row indexes that were moved.
* @param {Number} target Visual row index being a target for moved rows.
*/
'afterRowMove',
/**
* Fired by {@link ManualColumnResize} plugin before rendering the table with modified column sizes. This hook is
* fired when {@link Options#manualColumnResize} option is enabled.
*
* @event Hooks#beforeColumnResize
* @param {Number} currentColumn Visual index of the resized column.
* @param {Number} newSize Calculated new column width.
* @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
* @returns {Number} Returns a new column size or `undefined`, if column size should be calculated automatically.
*/
'beforeColumnResize',
/**
* Fired by {@link ManualColumnResize} plugin after rendering the table with modified column sizes. This hook is
* fired when {@link Options#manualColumnResize} option is enabled.
*
* @event Hooks#afterColumnResize
* @param {Number} currentColumn Visual index of the resized column.
* @param {Number} newSize Calculated new column width.
* @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
*/
'afterColumnResize',
/**
* Fired by {@link ManualRowResize} plugin before rendering the table with modified row sizes. This hook is
* fired when {@link Options#manualRowResize} option is enabled.
*
* @event Hooks#beforeRowResize
* @param {Number} currentRow Visual index of the resized row.
* @param {Number} newSize Calculated new row height.
* @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
* @returns {Number} Returns the new row size or `undefined` if row size should be calculated automatically.
*/
'beforeRowResize',
/**
* Fired by {@link ManualRowResize} plugin after rendering the table with modified row sizes. This hook is
* fired when {@link Options#manualRowResize} option is enabled.
*
* @event Hooks#afterRowResize
* @param {Number} currentRow Visual index of the resized row.
* @param {Number} newSize Calculated new row height.
* @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
*/
'afterRowResize',
/**
* Fired after getting the column header renderers.
*
* @event Hooks#afterGetColumnHeaderRenderers
* @param {Function[]} renderers An array of the column header renderers.
*/
'afterGetColumnHeaderRenderers',
/**
* Fired after getting the row header renderers.
*
* @event Hooks#afterGetRowHeaderRenderers
* @param {Function[]} renderers An array of the row header renderers.
*/
'afterGetRowHeaderRenderers',
/**
* Fired before applying stretched column width to column.
*
* @event Hooks#beforeStretchingColumnWidth
* @param {Number} stretchedWidth Calculated width.
* @param {Number} column Visual column index.
* @returns {Number} Returns new width which will be applied to the column element.
*/
'beforeStretchingColumnWidth',
/**
* Fired by {@link Filters} plugin before applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}. This hook is fired when
* {@link Options#filters} option is enabled.
*
* @event Hooks#beforeFilter
* @param {Object[]} conditionsStack An array of objects with added formulas.
* ```js
* // Example format of the conditionsStack argument:
* [
* {
* column: 2,
* conditions: [
* {name: 'begins_with', args: [['S']]}
* ],
* operation: 'conjunction'
* },
* {
* column: 4,
* conditions: [
* {name: 'not_empty', args: []}
* ],
* operation: 'conjunction'
* },
* ]
* ```
* @returns {Boolean} If hook returns `false` value then filtering won't be applied on the UI side (server-side filtering).
*/
'beforeFilter',
/**
* Fired by {@link Filters} plugin after applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}. This hook is fired when
* {@link Options#filters} option is enabled.
*
* @event Hooks#afterFilter
* @param {Object[]} conditionsStack An array of objects with added conditions.
* ```js
* // Example format of the conditionsStack argument:
* [
* {
* column: 2,
* conditions: [
* {name: 'begins_with', args: [['S']]}
* ],
* operation: 'conjunction'
* },
* {
* column: 4,
* conditions: [
* {name: 'not_empty', args: []}
* ],
* operation: 'conjunction'
* },
* ]
* ```
*/
'afterFilter',
/**
* Fired while retrieving the column header height.
*
* @event Hooks#modifyColumnHeaderHeight
*/
'modifyColumnHeaderHeight',
/**
* Fired by {@link UndoRedo} plugin before the undo action. Contains information about the action that is being undone.
* This hook is fired when {@link Options#undo} option is enabled.
*
* @event Hooks#beforeUndo
* @param {Object} action The action object. Contains information about the action being undone. The `actionType`
* property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
*/
'beforeUndo',
/**
* Fired by {@link UndoRedo} plugin after the undo action. Contains information about the action that is being undone.
* This hook is fired when {@link Options#undo} option is enabled.
*
* @event Hooks#afterUndo
* @param {Object} action The action object. Contains information about the action being undone. The `actionType`
* property of the object specifies the type of the action in a String format. (e.g. `'remove_row'`).
*/
'afterUndo',
/**
* Fired by {@link UndoRedo} plugin before the redo action. Contains information about the action that is being redone.
* This hook is fired when {@link Options#undo} option is enabled.
*
* @event Hooks#beforeRedo
* @param {Object} action The action object. Contains information about the action being redone. The `actionType`
* property of the object specifies the type of the action in a String format (e.g. `'remove_row'`).
*/
'beforeRedo',
/**
* Fired by {@link UndoRedo} plugin after the redo action. Contains information about the action that is being redone.
* This hook is fired when {@link Options#undo} option is enabled.
*
* @event Hooks#afterRedo
* @param {Object} action The action object. Contains information about the action being redone. The `actionType`
* property of the object specifies the type of the action in a String format (e.g. `'remove_row'`).
*/
'afterRedo',
/**
* Fired while retrieving the row header width.
*
* @event Hooks#modifyRowHeaderWidth
* @param {Number} rowHeaderWidth Row header width.
*/
'modifyRowHeaderWidth',
/**
* Fired from the `populateFromArray` method during the `autofill` process. Fired for each "autofilled" cell individually.
*
* @event Hooks#beforeAutofillInsidePopulate
* @param {Object} index Object containing `row` and `col` properties, defining the number of rows/columns from the initial cell of the autofill.
* @param {String} direction Declares the direction of the autofill. Possible values: `up`, `down`, `left`, `right`.
* @param {Array[]} input Contains an array of rows with data being used in the autofill.
* @param {Array} deltas The deltas array passed to the `populateFromArray` method.
*/
'beforeAutofillInsidePopulate',
/**
* Fired when the start of the selection is being modified (e.g. moving the selection with the arrow keys).
*
* @event Hooks#modifyTransformStart
* @param {CellCoords} delta Cell coords object declaring the delta of the new selection relative to the previous one.
*/
'modifyTransformStart',
/**
* Fired when the end of the selection is being modified (e.g. moving the selection with the arrow keys).
*
* @event Hooks#modifyTransformEnd
* @param {CellCoords} delta Cell coords object declaring the delta of the new selection relative to the previous one.
*/
'modifyTransformEnd',
/**
* Fired after the start of the selection is being modified (e.g. moving the selection with the arrow keys).
*
* @event Hooks#afterModifyTransformStart
* @param {CellCoords} coords Coords of the freshly selected cell.
* @param {Number} rowTransformDir `-1` if trying to select a cell with a negative row index. `0` otherwise.
* @param {Number} colTransformDir `-1` if trying to select a cell with a negative column index. `0` otherwise.
*/
'afterModifyTransformStart',
/**
* Fired after the end of the selection is being modified (e.g. moving the selection with the arrow keys).
*
* @event Hooks#afterModifyTransformEnd
* @param {CellCoords} coords Visual coords of the freshly selected cell.
* @param {Number} rowTransformDir `-1` if trying to select a cell with a negative row index. `0` otherwise.
* @param {Number} colTransformDir `-1` if trying to select a cell with a negative column index. `0` otherwise.
*/
'afterModifyTransformEnd',
/**
* Fired inside the `viewportRowCalculatorOverride` method. Allows modifying the row calculator parameters.
*
* @event Hooks#afterViewportRowCalculatorOverride
* @param {Object} calc The row calculator.
*/
'afterViewportRowCalculatorOverride',
/**
* Fired inside the `viewportColumnCalculatorOverride` method. Allows modifying the row calculator parameters.
*
* @event Hooks#afterViewportColumnCalculatorOverride
* @param {Object} calc The row calculator.
*/
'afterViewportColumnCalculatorOverride',
/**
* Fired after initializing all the plugins.
*
* @event Hooks#afterPluginsInitialized
*/
'afterPluginsInitialized',
/**
* Used to skip the length cache calculation for a defined period of time.
*
* @event Hooks#skipLengthCache
* @param {Number} delay The delay in milliseconds.
*/
'skipLengthCache',
/**
* Fired by {@link HiddenRows} plugin before marking the rows as hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
* Returning `false` in the callback will prevent the hiding action from completing.
*
* @event Hooks#beforeHideRows
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
* @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the hiding action will not be completed.
*/
'beforeHideRows',
/**
* Fired by {@link HiddenRows} plugin after marking the rows as hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
*
* @event Hooks#afterHideRows
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
* @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
* @param {Boolean} stateChanged `true`, if the action affected any non-hidden rows, `false` otherwise.
*/
'afterHideRows',
/**
* Fired by {@link HiddenRows} plugin before marking the rows as not hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
* Returning `false` in the callback will prevent the row revealing action from completing.
*
* @event Hooks#beforeUnhideRows
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
* @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the revealing action will not be completed.
*/
'beforeUnhideRows',
/**
* Fired by {@link HiddenRows} plugin after marking the rows as not hidden. Fired only if the {@link Options#hiddenRows} option is enabled.
*
* @event Hooks#afterUnhideRows
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical row indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical row indexes.
* @param {Boolean} actionPossible `true`, if provided row indexes are valid, `false` otherwise.
* @param {Boolean} stateChanged `true`, if the action affected any hidden rows, `false` otherwise.
*/
'afterUnhideRows',
/**
* Fired by {@link HiddenColumns} plugin before marking the columns as hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
* Returning `false` in the callback will prevent the hiding action from completing.
*
* @event Hooks#beforeHideColumns
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
* @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the hiding action will not be completed.
*/
'beforeHideColumns',
/**
* Fired by {@link HiddenColumns} plugin after marking the columns as hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
*
* @event Hooks#afterHideColumns
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
* @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
* @param {Boolean} stateChanged `true`, if the action affected any non-hidden columns, `false` otherwise.
*/
'afterHideColumns',
/**
* Fired by {@link HiddenColumns} plugin before marking the columns as not hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
* Returning `false` in the callback will prevent the column revealing action from completing.
*
* @event Hooks#beforeUnhideColumns
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
* @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the hiding action will not be completed.
*/
'beforeUnhideColumns',
/**
* Fired by {@link HiddenColumns} plugin after marking the columns as not hidden. Fired only if the {@link Options#hiddenColumns} option is enabled.
*
* @event Hooks#afterUnhideColumns
* @param {Array} currentHideConfig Current hide configuration - a list of hidden physical column indexes.
* @param {Array} destinationHideConfig Destination hide configuration - a list of hidden physical column indexes.
* @param {Boolean} actionPossible `true`, if the provided column indexes are valid, `false` otherwise.
* @param {Boolean} stateChanged `true`, if the action affected any hidden columns, `false` otherwise.
*/
'afterUnhideColumns',
/**
* Fired by {@link TrimRows} plugin before trimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
*
* @event Hooks#beforeTrimRow
* @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
* @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
* @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the trimming action will not be completed.
*/
'beforeTrimRow',
/**
* Fired by {@link TrimRows} plugin after trimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
*
* @event Hooks#afterTrimRow
* @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
* @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
* @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
* @param {Boolean} stateChanged `true`, if the action affected any non-trimmed rows, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the trimming action will not be completed.
*/
'afterTrimRow',
/**
* Fired by {@link TrimRows} plugin before untrimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
*
* @event Hooks#beforeUntrimRow
* @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
* @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
* @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the untrimming action will not be completed.
*/
'beforeUntrimRow',
/**
* Fired by {@link TrimRows} plugin after untrimming rows. This hook is fired when {@link Options#trimRows} option is enabled.
*
* @event Hooks#afterUntrimRow
* @param {Array} currentTrimConfig Current trim configuration - a list of trimmed physical row indexes.
* @param {Array} destinationTrimConfig Destination trim configuration - a list of trimmed physical row indexes.
* @param {Boolean} actionPossible `true`, if all of the row indexes are withing the bounds of the table, `false` otherwise.
* @param {Boolean} stateChanged `true`, if the action affected any trimmed rows, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the untrimming action will not be completed.
*/
'afterUntrimRow',
/**
* Fired by {@link DropdownMenu} plugin before opening the dropdown menu. This hook is fired when {@link Options#dropdownMenu}
* option is enabled.
*
* @event Hooks#beforeDropdownMenuShow
* @param {DropdownMenu} dropdownMenu The DropdownMenu instance.
*/
'beforeDropdownMenuShow',
/**
* Fired by {@link DropdownMenu} plugin after opening the Dropdown Menu. This hook is fired when {@link Options#dropdownMenu}
* option is enabled.
*
* @event Hooks#afterDropdownMenuShow
* @param {DropdownMenu} dropdownMenu The DropdownMenu instance.
*/
'afterDropdownMenuShow',
/**
* Fired by {@link DropdownMenu} plugin after hiding the Dropdown Menu. This hook is fired when {@link Options#dropdownMenu}
* option is enabled.
*
* @event Hooks#afterDropdownMenuHide
* @param {DropdownMenu} instance The DropdownMenu instance.
*/
'afterDropdownMenuHide',
/**
* Fired by {@link HiddenRows} plugin to check whether the provided row index is hidden. This hook is fired when
* {@link Options#hiddenRows} option is enabled.
*
* @event Hooks#hiddenRow
* @param {Number} row The visual row index in question.
*/
'hiddenRow',
/**
* Fired by {@link HiddenColumns} plugin to check whether the provided column index is hidden. This hook is fired when
* {@link Options#hiddenColumns} option is enabled.
*
* @event Hooks#hiddenColumn
* @param {Number} column The visual column index in question.
*/
'hiddenColumn',
/**
* Fired by {@link NestedRows} plugin before adding a children to the NestedRows structure. This hook is fired when
* {@link Options#nestedRows} option is enabled.
*
* @event Hooks#beforeAddChild
* @param {Object} parent The parent object.
* @param {Object|undefined} element The element added as a child. If `undefined`, a blank child was added.
* @param {Number|undefined} index The index within the parent where the new child was added. If `undefined`, the element was added as the last child.
*/
'beforeAddChild',
/**
* Fired by {@link NestedRows} plugin after adding a children to the NestedRows structure. This hook is fired when
* {@link Options#nestedRows} option is enabled.
*
* @event Hooks#afterAddChild
* @param {Object} parent The parent object.
* @param {Object|undefined} element The element added as a child. If `undefined`, a blank child was added.
* @param {Number|undefined} index The index within the parent where the new child was added. If `undefined`, the element was added as the last child.
*/
'afterAddChild',
/**
* Fired by {@link NestedRows} plugin before detaching a child from its parent. This hook is fired when
* {@link Options#nestedRows} option is enabled.
*
* @event Hooks#beforeDetachChild
* @param {Object} parent An object representing the parent from which the element is to be detached.
* @param {Object} element The detached element.
*/
'beforeDetachChild',
/**
* Fired by {@link NestedRows} plugin after detaching a child from its parent. This hook is fired when
* {@link Options#nestedRows} option is enabled.
*
* @event Hooks#afterDetachChild
* @param {Object} parent An object representing the parent from which the element was detached.
* @param {Object} element The detached element.
*/
'afterDetachChild',
/**
* Fired after the editor is opened and rendered.
*
* @event Hooks#afterBeginEditing
* @param {Number} row Visual row index of the edited cell.
* @param {Number} column Visual column index of the edited cell.
*/
'afterBeginEditing',
/**
* Fired by {@link MergeCells} plugin before cell merging. This hook is fired when {@link Options#mergeCells}
* option is enabled.
*
* @event Hooks#beforeMergeCells
* @param {CellRange} cellRange Selection cell range.
* @param {Boolean} [auto=false] `true` if called automatically by the plugin.
*/
'beforeMergeCells',
/**
* Fired by {@link MergeCells} plugin after cell merging. This hook is fired when {@link Options#mergeCells}
* option is enabled.
*
* @event Hooks#afterMergeCells
* @param {CellRange} cellRange Selection cell range.
* @param {Object} mergeParent The parent collection of the provided cell range.
* @param {Boolean} [auto=false] `true` if called automatically by the plugin.
*/
'afterMergeCells',
/**
* Fired by {@link MergeCells} plugin before unmerging the cells. This hook is fired when {@link Options#mergeCells}
* option is enabled.
*
* @event Hooks#beforeUnmergeCells
* @param {CellRange} cellRange Selection cell range.
* @param {Boolean} [auto=false] `true` if called automatically by the plugin.
*/
'beforeUnmergeCells',
/**
* Fired by {@link MergeCells} plugin after unmerging the cells. This hook is fired when {@link Options#mergeCells}
* option is enabled.
*
* @event Hooks#afterUnmergeCells
* @param {CellRange} cellRange Selection cell range.
* @param {Boolean} [auto=false] `true` if called automatically by the plugin.
*/
'afterUnmergeCells',
/**
* Fired after the table was switched into listening mode. This allows Handsontable to capture keyboard events and
* respond in the right way.
*
* @event Hooks#afterListen
*/
'afterListen',
/**
* Fired after the table was switched off from the listening mode. This makes the Handsontable inert for any
* keyboard events.
*
* @event Hooks#afterUnlisten
*/
'afterUnlisten',
/**
* Fired after the window was resized.
*
* @event Hooks#afterRefreshDimensions
* @param {Object} previousDimensions Previous dimensions of the container.
* @param {Object} currentDimensions Current dimensions of the container.
* @param {Boolean} stateChanged `true`, if the container was re-render, `false` otherwise.
*/
'afterRefreshDimensions',
/**
* Cancellable hook, called after resizing a window, but before redrawing a table.
*
* @event Hooks#beforeRefreshDimensions
* @param {Object} previousDimensions Previous dimensions of the container.
* @param {Object} currentDimensions Current dimensions of the container.
* @param {Boolean} actionPossible `true`, if current and previous dimensions are different, `false` otherwise.
* @returns {undefined|Boolean} If the callback returns `false`, the refresh action will not be completed.
*/
'beforeRefreshDimensions'];
var Hooks =
/*#__PURE__*/
function () {
(0, _createClass2.default)(Hooks, null, [{
key: "getSingleton",
value: function getSingleton() {
return getGlobalSingleton();
}
/**
*
*/
}]);
function Hooks() {
(0, _classCallCheck2.default)(this, Hooks);
this.globalBucket = this.createEmptyBucket();
}
/**
* Returns a new object with empty handlers related to every registered hook name.
*
* @returns {Object} The empty bucket object.
*
* @example
* ```js
* Handsontable.hooks.createEmptyBucket();
* // Results:
* {
* ...
* afterCreateCol: [],
* afterCreateRow: [],
* beforeInit: [],
* ...
* }
* ```
*/
(0, _createClass2.default)(Hooks, [{
key: "createEmptyBucket",
value: function createEmptyBucket() {
var bucket = Object.create(null); // eslint-disable-next-line no-return-assign
(0, _array.arrayEach)(REGISTERED_HOOKS, function (hook) {
return bucket[hook] = [];
});
return bucket;
}
/**
* Get hook bucket based on the context of the object or if argument is `undefined`, get the global hook bucket.
*
* @param {Object} [context=null] A Handsontable instance.
* @returns {Object} Returns a global or Handsontable instance bucket.
*/
}, {
key: "getBucket",
value: function getBucket() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
if (context) {
if (!context.pluginHookBucket) {
context.pluginHookBucket = this.createEmptyBucket();
}
return context.pluginHookBucket;
}
return this.globalBucket;
}
/**
* Adds a listener (globally or locally) to a specified hook name.
* If the `context` parameter is provided, the hook will be added only to the instance it references.
* Otherwise, the callback will be used everytime the hook fires on any Handsontable instance.
* You can provide an array of callback functions as the `callback` argument, this way they will all be fired
* once the hook is triggered.
*
* @see Core#addHook
* @param {String} key Hook name.
* @param {Function|Array} callback Callback function or an array of functions.
* @param {Object} [context=null] The context for the hook callback to be added - a Handsontable instance or leave empty.
* @returns {Hooks} Instance of Hooks.
*
* @example
* ```js
* // single callback, added locally
* Handsontable.hooks.add('beforeInit', myCallback, hotInstance);
*
* // single callback, added globally
* Handsontable.hooks.add('beforeInit', myCallback);
*
* // multiple callbacks, added locally
* Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback], hotInstance);
*
* // multiple callbacks, added globally
* Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback]);
* ```
*/
}, {
key: "add",
value: function add(key, callback) {
var _this = this;
var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (Array.isArray(callback)) {
(0, _array.arrayEach)(callback, function (c) {
return _this.add(key, c, context);
});
} else {
var bucket = this.getBucket(context);
if (typeof bucket[key] === 'undefined') {
this.register(key);
bucket[key] = [];
}
callback.skip = false;
if (bucket[key].indexOf(callback) === -1) {
// only add a hook if it has not already been added (adding the same hook twice is now silently ignored)
var foundInitialHook = false;
if (callback.initialHook) {
(0, _array.arrayEach)(bucket[key], function (cb, i) {
if (cb.initialHook) {
bucket[key][i] = callback;
foundInitialHook = true;
return false;
}
});
}
if (!foundInitialHook) {
bucket[key].push(callback);
}
}
}
return this;
}
/**
* Adds a listener to a specified hook. After the hook runs this listener will be automatically removed from the bucket.
*
* @see Core#addHookOnce
* @param {String} key Hook/Event name.
* @param {Function|Array} callback Callback function.
* @param {Object} [context=null] A Handsontable instance.
*
* @example
* ```js
* Handsontable.hooks.once('beforeInit', myCallback, hotInstance);
* ```
*/
}, {
key: "once",
value: function once(key, callback) {
var _this2 = this;
var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (Array.isArray(callback)) {
(0, _array.arrayEach)(callback, function (c) {
return _this2.once(key, c, context);
});
} else {
callback.runOnce = true;
this.add(key, callback, context);
}
}
/**
* Removes a listener from a hook with a given name. If the `context` argument is provided, it removes a listener from a local hook assigned to the given Handsontable instance.
*
* @see Core#removeHook
* @param {String} key Hook/Event name.
* @param {Function} callback Callback function (needs the be the function that was previously added to the hook).
* @param {Object} [context=null] Handsontable instance.
* @return {Boolean} Returns `true` if hook was removed, `false` otherwise.
*
* @example
* ```js
* Handsontable.hooks.remove('beforeInit', myCallback);
* ```
*/
}, {
key: "remove",
value: function remove(key, callback) {
var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var bucket = this.getBucket(context);
if (typeof bucket[key] !== 'undefined') {
if (bucket[key].indexOf(callback) >= 0) {
callback.skip = true;
return true;
}
}
return false;
}
/**
* Checks whether there are any registered listeners for the provided hook name.
* If the `context` parameter is provided, it only checks for listeners assigned to the given Handsontable instance.
*
* @param {String} key Hook name.
* @param {Object} [context=null] A Handsontable instance.
* @returns {Boolean} `true` for success, `false` otherwise.
*/
}, {
key: "has",
value: function has(key) {
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var bucket = this.getBucket(context);
return !!(bucket[key] !== void 0 && bucket[key].length);
}
/**
* Runs all local and global callbacks assigned to the hook identified by the `key` parameter.
* It returns either a return value from the last called callback or the first parameter (`p1`) passed to the `run` function.
*
* @see Core#runHooks
* @param {Object} context Handsontable instance.
* @param {String} key Hook/Event name.
* @param {*} [p1] Parameter to be passed as an argument to the callback function.
* @param {*} [p2] Parameter to be passed as an argument to the callback function.
* @param {*} [p3] Parameter to be passed as an argument to the callback function.
* @param {*} [p4] Parameter to be passed as an argument to the callback function.
* @param {*} [p5] Parameter to be passed as an argument to the callback function.
* @param {*} [p6] Parameter to be passed as an argument to the callback function.
* @returns {*} Either a return value from the last called callback or `p1`.
*
* @example
* ```js
* Handsontable.hooks.run(hot, 'beforeInit');
* ```
*/
}, {
key: "run",
value: function run(context, key, p1, p2, p3, p4, p5, p6) {
{
var globalHandlers = this.globalBucket[key];
var length = globalHandlers ? globalHandlers.length : 0;
var index = 0;
if (length) {
// Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
while (index < length) {
if (!globalHandlers[index] || globalHandlers[index].skip) {
index += 1;
/* eslint-disable no-continue */
continue;
} // performance considerations - http://jsperf.com/call-vs-apply-for-a-plugin-architecture
var res = globalHandlers[index].call(context, p1, p2, p3, p4, p5, p6);
if (res !== void 0) {
// eslint-disable-next-line no-param-reassign
p1 = res;
}
if (globalHandlers[index] && globalHandlers[index].runOnce) {
this.remove(key, globalHandlers[index]);
}
index += 1;
}
}
}
{
var localHandlers = this.getBucket(context)[key];
var _length = localHandlers ? localHandlers.length : 0;
var _index = 0;
if (_length) {
// Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
while (_index < _length) {
if (!localHandlers[_index] || localHandlers[_index].skip) {
_index += 1;
/* eslint-disable no-continue */
continue;
} // performance considerations - http://jsperf.com/call-vs-apply-for-a-plugin-architecture
var _res = localHandlers[_index].call(context, p1, p2, p3, p4, p5, p6);
if (_res !== void 0) {
// eslint-disable-next-line no-param-reassign
p1 = _res;
}
if (localHandlers[_index] && localHandlers[_index].runOnce) {
this.remove(key, localHandlers[_index], context);
}
_index += 1;
}
}
}
return p1;
}
/**
* Destroy all listeners connected to the context. If no context is provided, the global listeners will be destroyed.
*
* @param {Object} [context=null] A Handsontable instance.
* @example
* ```js
* // destroy the global listeners
* Handsontable.hooks.destroy();
*
* // destroy the local listeners
* Handsontable.hooks.destroy(hotInstance);
* ```
*/
}, {
key: "destroy",
value: function destroy() {
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
// eslint-disable-next-line no-return-assign
(0, _object.objectEach)(this.getBucket(context), function (value, key, bucket) {
return bucket[key].length = 0;
});
}
/**
* Registers a hook name (adds it to the list of the known hook names). Used by plugins.
* It is not necessary to call register, but if you use it, your plugin hook will be used returned by
* the `getRegistered` method. (which itself is used in the demo http://docs.handsontable.com/tutorial-callbacks.html).
*
* @param key {String} The hook name.
*
* @example
* ```js
* Handsontable.hooks.register('myHook');
* ```
*/
}, {
key: "register",
value: function register(key) {
if (!this.isRegistered(key)) {
REGISTERED_HOOKS.push(key);
}
}
/**
* Deregisters a hook name (removes it from the list of known hook names).
*
* @param key {String} Hook name.
*
* @example
* ```js
* Handsontable.hooks.deregister('myHook');
* ```
*/
}, {
key: "deregister",
value: function deregister(key) {
if (this.isRegistered(key)) {
REGISTERED_HOOKS.splice(REGISTERED_HOOKS.indexOf(key), 1);
}
}
/**
* Returns a boolean depending on if a hook by such name has been registered.
*
* @param key {String} Hook name.
* @returns {Boolean} `true` for success, `false` otherwise.
*
* @example
* ```js
* Handsontable.hooks.isRegistered('beforeInit');
*
* // Results:
* true
* ```
*/
}, {
key: "isRegistered",
value: function isRegistered(key) {
return REGISTERED_HOOKS.indexOf(key) >= 0;
}
/**
* Returns an array of registered hooks.
*
* @returns {Array} An array of registered hooks.
*
* @example
* ```js
* Handsontable.hooks.getRegistered();
*
* // Results:
* [
* ...
* 'beforeInit',
* 'beforeRender',
* 'beforeSetRangeEnd',
* 'beforeDrawBorders',
* 'beforeChange',
* ...
* ]
* ```
*/
}, {
key: "getRegistered",
value: function getRegistered() {
return REGISTERED_HOOKS;
}
}]);
return Hooks;
}();
var globalSingleton = new Hooks();
function getGlobalSingleton() {
return globalSingleton;
}
var _default = Hooks;
exports.default = _default;
/***/ }),
/* 44 */
/***/ (function(module, exports) {
function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }
function _typeof(obj) {
if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
module.exports = _typeof = function _typeof(obj) {
return _typeof2(obj);
};
} else {
module.exports = _typeof = function _typeof(obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
};
}
return _typeof(obj);
}
module.exports = _typeof;
/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {
var isObject = __webpack_require__(42);
module.exports = function (it) {
if (!isObject(it)) {
throw TypeError(String(it) + ' is not an object');
} return it;
};
/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var isRegExp = __webpack_require__(154);
var anObject = __webpack_require__(45);
var requireObjectCoercible = __webpack_require__(58);
var speciesConstructor = __webpack_require__(272);
var advanceStringIndex = __webpack_require__(155);
var toLength = __webpack_require__(48);
var callRegExpExec = __webpack_require__(128);
var regexpExec = __webpack_require__(156);
var fails = __webpack_require__(29);
var arrayPush = [].push;
var min = Math.min;
var MAX_UINT32 = 0xffffffff;
// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });
// @@split logic
__webpack_require__(129)(
'split',
2,
function (SPLIT, nativeSplit, maybeCallNative) {
var internalSplit;
if (
'abbc'.split(/(b)*/)[1] == 'c' ||
'test'.split(/(?:)/, -1).length != 4 ||
'ab'.split(/(?:ab)*/).length != 2 ||
'.'.split(/(.?)(.?)/).length != 4 ||
'.'.split(/()()/).length > 1 ||
''.split(/.?/).length
) {
// based on es5-shim implementation, need to rework it
internalSplit = function (separator, limit) {
var string = String(requireObjectCoercible(this));
var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
if (lim === 0) return [];
if (separator === undefined) return [string];
// If `separator` is not a regex, use native split
if (!isRegExp(separator)) {
return nativeSplit.call(string, separator, lim);
}
var output = [];
var flags = (separator.ignoreCase ? 'i' : '') +
(separator.multiline ? 'm' : '') +
(separator.unicode ? 'u' : '') +
(separator.sticky ? 'y' : '');
var lastLastIndex = 0;
// Make `global` and avoid `lastIndex` issues by working with a copy
var separatorCopy = new RegExp(separator.source, flags + 'g');
var match, lastIndex, lastLength;
while (match = regexpExec.call(separatorCopy, string)) {
lastIndex = separatorCopy.lastIndex;
if (lastIndex > lastLastIndex) {
output.push(string.slice(lastLastIndex, match.index));
if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= lim) break;
}
if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
}
if (lastLastIndex === string.length) {
if (lastLength || !separatorCopy.test('')) output.push('');
} else output.push(string.slice(lastLastIndex));
return output.length > lim ? output.slice(0, lim) : output;
};
// Chakra, V8
} else if ('0'.split(undefined, 0).length) {
internalSplit = function (separator, limit) {
return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
};
} else internalSplit = nativeSplit;
return [
// `String.prototype.split` method
// https://tc39.github.io/ecma262/#sec-string.prototype.split
function split(separator, limit) {
var O = requireObjectCoercible(this);
var splitter = separator == undefined ? undefined : separator[SPLIT];
return splitter !== undefined
? splitter.call(separator, O, limit)
: internalSplit.call(String(O), separator, limit);
},
// `RegExp.prototype[@@split]` method
// https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split
//
// NOTE: This cannot be properly polyfilled in engines that don't support
// the 'y' flag.
function (regexp, limit) {
var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
if (res.done) return res.value;
var rx = anObject(regexp);
var S = String(this);
var C = speciesConstructor(rx, RegExp);
var unicodeMatching = rx.unicode;
var flags = (rx.ignoreCase ? 'i' : '') +
(rx.multiline ? 'm' : '') +
(rx.unicode ? 'u' : '') +
(SUPPORTS_Y ? 'y' : 'g');
// ^(? + rx + ) is needed, in combination with some S slicing, to
// simulate the 'y' flag.
var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
if (lim === 0) return [];
if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];
var p = 0;
var q = 0;
var A = [];
while (q < S.length) {
splitter.lastIndex = SUPPORTS_Y ? q : 0;
var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));
var e;
if (
z === null ||
(e = min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p
) {
q = advanceStringIndex(S, q, unicodeMatching);
} else {
A.push(S.slice(p, q));
if (A.length === lim) return A;
for (var i = 1; i <= z.length - 1; i++) {
A.push(z[i]);
if (A.length === lim) return A;
}
q = p = e;
}
}
A.push(S.slice(p));
return A;
}
];
},
!SUPPORTS_Y
);
/***/ }),
/* 47 */
/***/ (function(module, exports) {
var hasOwnProperty = {}.hasOwnProperty;
module.exports = function (it, key) {
return hasOwnProperty.call(it, key);
};
/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {
var toInteger = __webpack_require__(86);
var min = Math.min;
// `ToLength` abstract operation
// https://tc39.github.io/ecma262/#sec-tolength
module.exports = function (argument) {
return argument > 0 ? min(toInteger(argument), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};
/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {
var DESCRIPTORS = __webpack_require__(52);
var IE8_DOM_DEFINE = __webpack_require__(176);
var anObject = __webpack_require__(45);
var toPrimitive = __webpack_require__(97);
var nativeDefineProperty = Object.defineProperty;
exports.f = DESCRIPTORS ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
anObject(O);
P = toPrimitive(P, true);
anObject(Attributes);
if (IE8_DOM_DEFINE) try {
return nativeDefineProperty(O, P, Attributes);
} catch (e) { /* empty */ }
if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
if ('value' in Attributes) O[P] = Attributes.value;
return O;
};
/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
__webpack_require__(34);
__webpack_require__(12);
__webpack_require__(39);
__webpack_require__(46);
exports.__esModule = true;
exports.isPrintableChar = isPrintableChar;
exports.isMetaKey = isMetaKey;
exports.isCtrlKey = isCtrlKey;
exports.isCtrlMetaKey = isCtrlMetaKey;
exports.isKey = isKey;
exports.KEY_CODES = void 0;
var _array = __webpack_require__(3);
var KEY_CODES = {
MOUSE_LEFT: 1,
MOUSE_RIGHT: 3,
MOUSE_MIDDLE: 2,
BACKSPACE: 8,
COMMA: 188,
INSERT: 45,
DELETE: 46,
END: 35,
ENTER: 13,
ESCAPE: 27,
CONTROL: 17,
COMMAND_LEFT: 91,
COMMAND_RIGHT: 93,
COMMAND_FIREFOX: 224,
ALT: 18,
HOME: 36,
PAGE_DOWN: 34,
PAGE_UP: 33,
PERIOD: 190,
SPACE: 32,
SHIFT: 16,
CAPS_LOCK: 20,
TAB: 9,
ARROW_RIGHT: 39,
ARROW_LEFT: 37,
ARROW_UP: 38,
ARROW_DOWN: 40,
F1: 112,
F2: 113,
F3: 114,
F4: 115,
F5: 116,
F6: 117,
F7: 118,
F8: 119,
F9: 120,
F10: 121,
F11: 122,
F12: 123,
A: 65,
C: 67,
D: 68,
F: 70,
L: 76,
O: 79,
P: 80,
S: 83,
V: 86,
X: 88
};
/**
* Returns true if keyCode represents a printable character.
*
* @param {Number} keyCode
* @returns {Boolean}
*/
exports.KEY_CODES = KEY_CODES;
function isPrintableChar(keyCode) {
return keyCode === 32 || // space
keyCode >= 48 && keyCode <= 57 || // 0-9
keyCode >= 96 && keyCode <= 111 || // numpad
keyCode >= 186 && keyCode <= 192 || // ;=,-./`
keyCode >= 219 && keyCode <= 222 || // []{}\|"'
keyCode >= 226 || // special chars (229 for Asian chars)
keyCode >= 65 && keyCode <= 90; // a-z
}
/**
* @param {Number} keyCode
* @returns {Boolean}
*/
function isMetaKey(keyCode) {
var metaKeys = [KEY_CODES.ARROW_DOWN, KEY_CODES.ARROW_UP, KEY_CODES.ARROW_LEFT, KEY_CODES.ARROW_RIGHT, KEY_CODES.HOME, KEY_CODES.END, KEY_CODES.DELETE, KEY_CODES.BACKSPACE, KEY_CODES.F1, KEY_CODES.F2, KEY_CODES.F3, KEY_CODES.F4, KEY_CODES.F5, KEY_CODES.F6, KEY_CODES.F7, KEY_CODES.F8, KEY_CODES.F9, KEY_CODES.F10, KEY_CODES.F11, KEY_CODES.F12, KEY_CODES.TAB, KEY_CODES.PAGE_DOWN, KEY_CODES.PAGE_UP, KEY_CODES.ENTER, KEY_CODES.ESCAPE, KEY_CODES.SHIFT, KEY_CODES.CAPS_LOCK, KEY_CODES.ALT];
return metaKeys.indexOf(keyCode) !== -1;
}
/**
* Checks if passed key code is ctrl or cmd key. Depends on what OS the code runs it check key code based on
* different meta key codes.
*
* @param {Number} keyCode Key code to check.
* @returns {Boolean}
*/
function isCtrlKey(keyCode) {
var keys = [];
if (navigator.platform.includes('Mac')) {
keys.push(KEY_CODES.COMMAND_LEFT, KEY_CODES.COMMAND_RIGHT, KEY_CODES.COMMAND_FIREFOX);
} else {
keys.push(KEY_CODES.CONTROL);
}
return keys.includes(keyCode);
}
/**
* Checks if passed key code is ctrl or cmd key. This helper checks if the key code matches to meta keys
* regardless of the OS on which it is running.
*
* @param {Number} keyCode Key code to check.
* @returns {Boolean}
*/
function isCtrlMetaKey(keyCode) {
return [KEY_CODES.CONTROL, KEY_CODES.COMMAND_LEFT, KEY_CODES.COMMAND_RIGHT, KEY_CODES.COMMAND_FIREFOX].includes(keyCode);
}
/**
* @param {Number} keyCode
* @param {String} baseCode
* @returns {Boolean}
*/
function isKey(keyCode, baseCode) {
var keys = baseCode.split('|');
var result = false;
(0, _array.arrayEach)(keys, function (key) {
if (keyCode === KEY_CODES[key]) {
result = true;
return false;
}
});
return result;
}
/***/ }),
/* 51 */
/***/ (function(module, exports, __webpack_require__) {
var DESCRIPTORS = __webpack_require__(52);
var defineProperty = __webpack_require__(49).f;
var FunctionPrototype = Function.prototype;
var FunctionPrototypeToString = FunctionPrototype.toString;
var nameRE = /^\s*function ([^ (]*)/;
var NAME = 'name';
// Function instances `.name` property
// https://tc39.github.io/ecma262/#sec-function-instances-name
if (DESCRIPTORS && !(NAME in FunctionPrototype)) {
defineProperty(FunctionPrototype, NAME, {
configurable: true,
get: function () {
try {
return FunctionPrototypeToString.call(this).match(nameRE)[1];
} catch (e) {
return '';
}
}
});
}
/***/ }),
/* 52 */
/***/ (function(module, exports, __webpack_require__) {
// Thank's IE8 for his funny defineProperty
module.exports = !__webpack_require__(29)(function () {
return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
});
/***/ }),
/* 53 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.RegisteredEditor = RegisteredEditor;
exports.getEditorInstance = exports._getEditorInstance = _getEditorInstance;
exports.registerEditor = _register;
exports.getEditor = _getItem;
exports.getRegisteredEditors = exports.getRegisteredEditorNames = exports.hasEditor = void 0;
var _staticRegister2 = _interopRequireDefault(__webpack_require__(78));
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _baseEditor = _interopRequireDefault(__webpack_require__(104));
var _autocompleteEditor = _interopRequireDefault(__webpack_require__(217));
var _checkboxEditor = _interopRequireDefault(__webpack_require__(288));
var _dateEditor = _interopRequireDefault(__webpack_require__(289));
var _dropdownEditor = _interopRequireDefault(__webpack_require__(292));
var _handsontableEditor = _interopRequireDefault(__webpack_require__(218));
var _numericEditor = _interopRequireDefault(__webpack_require__(293));
var _passwordEditor = _interopRequireDefault(__webpack_require__(294));
var _selectEditor = _interopRequireDefault(__webpack_require__(295));
var _textEditor = _interopRequireDefault(__webpack_require__(107));
/**
* Utility to register editors and common namespace for keeping reference to all editor classes
*/
var registeredEditorClasses = new WeakMap();
var _staticRegister = (0, _staticRegister2.default)('editors'),
register = _staticRegister.register,
getItem = _staticRegister.getItem,
hasItem = _staticRegister.hasItem,
getNames = _staticRegister.getNames,
getValues = _staticRegister.getValues;
exports.getRegisteredEditors = getValues;
exports.getRegisteredEditorNames = getNames;
exports.hasEditor = hasItem;
_register('base', _baseEditor.default);
_register('autocomplete', _autocompleteEditor.default);
_register('checkbox', _checkboxEditor.default);
_register('date', _dateEditor.default);
_register('dropdown', _dropdownEditor.default);
_register('handsontable', _handsontableEditor.default);
_register('numeric', _numericEditor.default);
_register('password', _passwordEditor.default);
_register('select', _selectEditor.default);
_register('text', _textEditor.default);
function RegisteredEditor(editorClass) {
var instances = {};
var Clazz = editorClass;
this.getConstructor = function () {
return editorClass;
};
this.getInstance = function (hotInstance) {
if (!(hotInstance.guid in instances)) {
instances[hotInstance.guid] = new Clazz(hotInstance);
}
return instances[hotInstance.guid];
};
_pluginHooks.default.getSingleton().add('afterDestroy', function () {
instances[this.guid] = null;
});
}
/**
* Returns instance (singleton) of editor class.
*
* @param {String} name Name of an editor under which it has been stored.
* @param {Object} hotInstance Instance of Handsontable.
* @returns {Function} Returns instance of editor.
*/
function _getEditorInstance(name, hotInstance) {
var editor;
if (typeof name === 'function') {
if (!registeredEditorClasses.get(name)) {
_register(null, name);
}
editor = registeredEditorClasses.get(name);
} else if (typeof name === 'string') {
editor = getItem(name);
} else {
throw Error('Only strings and functions can be passed as "editor" parameter');
}
if (!editor) {
throw Error("No editor registered under name \"".concat(name, "\""));
}
return editor.getInstance(hotInstance);
}
/**
* Retrieve editor class.
*
* @param {String} name Editor identification.
* @returns {Function} Returns editor class.
*/
function _getItem(name) {
if (!hasItem(name)) {
throw Error("No registered editor found under \"".concat(name, "\" name"));
}
return getItem(name).getConstructor();
}
/**
* Register editor class under specified name.
*
* @param {String} name Editor identification.
* @param {Function} editorClass Editor class.
*/
function _register(name, editorClass) {
var editorWrapper = new RegisteredEditor(editorClass);
if (typeof name === 'string') {
register(name, editorWrapper);
}
registeredEditorClasses.set(editorClass, editorWrapper);
}
/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var toIndexedObject = __webpack_require__(69);
var nativeJoin = [].join;
var ES3_STRINGS = __webpack_require__(113) != Object;
var SLOPPY_METHOD = __webpack_require__(126)('join', ',');
// `Array.prototype.join` method
// https://tc39.github.io/ecma262/#sec-array.prototype.join
__webpack_require__(22)({ target: 'Array', proto: true, forced: ES3_STRINGS || SLOPPY_METHOD }, {
join: function join(separator) {
return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
}
});
/***/ }),
/* 55 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.log = log;
exports.warn = warn;
exports.info = info;
exports.error = error;
var _mixed = __webpack_require__(27);
/* eslint-disable no-console */
/* eslint-disable no-restricted-globals */
/**
* "In Internet Explorer 9 (and 8), the console object is only exposed when the developer tools are opened
* for a particular tab."
*
* Source: https://stackoverflow.com/a/5473193
*/
/**
* Logs message to the console if the `console` object is exposed.
*
* @param {...*} args Values which will be logged.
*/
function log() {
if ((0, _mixed.isDefined)(console)) {
var _console;
(_console = console).log.apply(_console, arguments);
}
}
/**
* Logs warn to the console if the `console` object is exposed.
*
* @param {...*} args Values which will be logged.
*/
function warn() {
if ((0, _mixed.isDefined)(console)) {
var _console2;
(_console2 = console).warn.apply(_console2, arguments);
}
}
/**
* Logs info to the console if the `console` object is exposed.
*
* @param {...*} args Values which will be logged.
*/
function info() {
if ((0, _mixed.isDefined)(console)) {
var _console3;
(_console3 = console).info.apply(_console3, arguments);
}
}
/**
* Logs error to the console if the `console` object is exposed.
*
* @param {...*} args Values which will be logged.
*/
function error() {
if ((0, _mixed.isDefined)(console)) {
var _console4;
(_console4 = console).error.apply(_console4, arguments);
}
}
/***/ }),
/* 56 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var internalFilter = __webpack_require__(102)(2);
var SPECIES_SUPPORT = __webpack_require__(103)('filter');
// `Array.prototype.filter` method
// https://tc39.github.io/ecma262/#sec-array.prototype.filter
// with adding support of @@species
__webpack_require__(22)({ target: 'Array', proto: true, forced: !SPECIES_SUPPORT }, {
filter: function filter(callbackfn /* , thisArg */) {
return internalFilter(this, callbackfn, arguments[1]);
}
});
/***/ }),
/* 57 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var MIXIN_NAME = 'localHooks';
/**
* Mixin object to extend objects functionality for local hooks.
*
* @type {Object}
*/
var localHooks = {
/**
* Internal hooks storage.
*/
_localHooks: Object.create(null),
/**
* Add hook to the collection.
*
* @param {String} key Hook name.
* @param {Function} callback Hook callback
* @returns {Object}
*/
addLocalHook: function addLocalHook(key, callback) {
if (!this._localHooks[key]) {
this._localHooks[key] = [];
}
this._localHooks[key].push(callback);
return this;
},
/**
* Run hooks.
*
* @param {String} key Hook name.
* @param {*} params
*/
runLocalHooks: function runLocalHooks(key) {
var _this = this;
for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
params[_key - 1] = arguments[_key];
}
if (this._localHooks[key]) {
(0, _array.arrayEach)(this._localHooks[key], function (callback) {
return callback.apply(_this, params);
});
}
},
/**
* Clear all added hooks.
*
* @returns {Object}
*/
clearLocalHooks: function clearLocalHooks() {
this._localHooks = {};
return this;
}
};
(0, _object.defineGetter)(localHooks, 'MIXIN_NAME', MIXIN_NAME, {
writable: false,
enumerable: false
});
var _default = localHooks;
exports.default = _default;
/***/ }),
/* 58 */
/***/ (function(module, exports) {
// `RequireObjectCoercible` abstract operation
// https://tc39.github.io/ecma262/#sec-requireobjectcoercible
module.exports = function (it) {
if (it == undefined) throw TypeError("Can't call method on " + it);
return it;
};
/***/ }),
/* 59 */
/***/ (function(module, exports, __webpack_require__) {
var INCORRECT_ITERATION = !__webpack_require__(190)(function (iterable) {
Array.from(iterable);
});
// `Array.from` method
// https://tc39.github.io/ecma262/#sec-array.from
__webpack_require__(22)({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, {
from: __webpack_require__(271)
});
/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
__webpack_require__(18);
__webpack_require__(12);
__webpack_require__(40);
__webpack_require__(51);
__webpack_require__(37);
exports.__esModule = true;
exports.normalizeSelection = normalizeSelection;
exports.isSeparator = isSeparator;
exports.hasSubMenu = hasSubMenu;
exports.isDisabled = isDisabled;
exports.isSelectionDisabled = isSelectionDisabled;
exports.getValidSelection = getValidSelection;
exports.prepareVerticalAlignClass = prepareVerticalAlignClass;
exports.prepareHorizontalAlignClass = prepareHorizontalAlignClass;
exports.getAlignmentClasses = getAlignmentClasses;
exports.align = align;
exports.checkSelectionConsistency = checkSelectionConsistency;
exports.markLabelAsSelected = markLabelAsSelected;
exports.isItemHidden = isItemHidden;
exports.filterSeparators = filterSeparators;
var _array = __webpack_require__(3);
var _element = __webpack_require__(5);
var _separator = __webpack_require__(166);
function normalizeSelection(selRanges) {
return (0, _array.arrayMap)(selRanges, function (range) {
return {
start: range.getTopLeftCorner(),
end: range.getBottomRightCorner()
};
});
}
function isSeparator(cell) {
return (0, _element.hasClass)(cell, 'htSeparator');
}
function hasSubMenu(cell) {
return (0, _element.hasClass)(cell, 'htSubmenu');
}
function isDisabled(cell) {
return (0, _element.hasClass)(cell, 'htDisabled');
}
function isSelectionDisabled(cell) {
return (0, _element.hasClass)(cell, 'htSelectionDisabled');
}
function getValidSelection(hot) {
var selected = hot.getSelected();
if (!selected) {
return null;
}
if (selected[0] < 0) {
return null;
}
return selected;
}
function prepareVerticalAlignClass(className, alignment) {
if (className.indexOf(alignment) !== -1) {
return className;
}
var replacedClassName = className.replace('htTop', '').replace('htMiddle', '').replace('htBottom', '').replace(' ', '');
return "".concat(replacedClassName, " ").concat(alignment);
}
function prepareHorizontalAlignClass(className, alignment) {
if (className.indexOf(alignment) !== -1) {
return className;
}
var replacedClassName = className.replace('htLeft', '').replace('htCenter', '').replace('htRight', '').replace('htJustify', '').replace(' ', '');
return "".concat(replacedClassName, " ").concat(alignment);
}
function getAlignmentClasses(ranges, callback) {
var classes = {};
(0, _array.arrayEach)(ranges, function (_ref) {
var from = _ref.from,
to = _ref.to;
for (var row = from.row; row <= to.row; row++) {
for (var col = from.col; col <= to.col; col++) {
if (!classes[row]) {
classes[row] = [];
}
classes[row][col] = callback(row, col);
}
}
});
return classes;
}
function align(ranges, type, alignment, cellDescriptor, propertySetter) {
(0, _array.arrayEach)(ranges, function (_ref2) {
var from = _ref2.from,
to = _ref2.to;
if (from.row === to.row && from.col === to.col) {
applyAlignClassName(from.row, from.col, type, alignment, cellDescriptor, propertySetter);
} else {
for (var row = from.row; row <= to.row; row++) {
for (var col = from.col; col <= to.col; col++) {
applyAlignClassName(row, col, type, alignment, cellDescriptor, propertySetter);
}
}
}
});
}
function applyAlignClassName(row, col, type, alignment, cellDescriptor, propertySetter) {
var cellMeta = cellDescriptor(row, col);
var className = alignment;
if (cellMeta.className) {
if (type === 'vertical') {
className = prepareVerticalAlignClass(cellMeta.className, alignment);
} else {
className = prepareHorizontalAlignClass(cellMeta.className, alignment);
}
}
propertySetter(row, col, 'className', className);
}
function checkSelectionConsistency(ranges, comparator) {
var result = false;
if (Array.isArray(ranges)) {
(0, _array.arrayEach)(ranges, function (range) {
range.forAll(function (row, col) {
if (comparator(row, col)) {
result = true;
return false;
}
});
return result;
});
}
return result;
}
function markLabelAsSelected(label) {
// workaround for https://github.com/handsontable/handsontable/issues/1946
return "".concat(String.fromCharCode(10003), "").concat(label);
}
function isItemHidden(item, instance) {
return !item.hidden || !(typeof item.hidden === 'function' && item.hidden.call(instance));
}
function shiftSeparators(items, separator) {
var result = items.slice(0);
for (var i = 0; i < result.length;) {
if (result[i].name === separator) {
result.shift();
} else {
break;
}
}
return result;
}
function popSeparators(items, separator) {
var result = items.slice(0);
result.reverse();
result = shiftSeparators(result, separator);
result.reverse();
return result;
}
function removeDuplicatedSeparators(items) {
var result = [];
(0, _array.arrayEach)(items, function (value, index) {
if (index > 0) {
if (result[result.length - 1].name !== value.name) {
result.push(value);
}
} else {
result.push(value);
}
});
return result;
}
function filterSeparators(items) {
var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _separator.KEY;
var result = items.slice(0);
result = shiftSeparators(result, separator);
result = popSeparators(result, separator);
result = removeDuplicatedSeparators(result);
return result;
}
/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {
var definePropertyModule = __webpack_require__(49);
var createPropertyDescriptor = __webpack_require__(96);
module.exports = __webpack_require__(52) ? function (object, key, value) {
return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
} : function (object, key, value) {
object[key] = value;
return object;
};
/***/ }),
/* 62 */
/***/ (function(module, exports, __webpack_require__) {
var requireObjectCoercible = __webpack_require__(58);
// `ToObject` abstract operation
// https://tc39.github.io/ecma262/#sec-toobject
module.exports = function (argument) {
return Object(requireObjectCoercible(argument));
};
/***/ }),
/* 63 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var aFunction = __webpack_require__(150);
var toObject = __webpack_require__(62);
var fails = __webpack_require__(29);
var nativeSort = [].sort;
var test = [1, 2, 3];
// IE8-
var FAILS_ON_UNDEFINED = fails(function () {
test.sort(undefined);
});
// V8 bug
var FAILS_ON_NULL = fails(function () {
test.sort(null);
});
// Old WebKit
var SLOPPY_METHOD = __webpack_require__(126)('sort');
var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || SLOPPY_METHOD;
// `Array.prototype.sort` method
// https://tc39.github.io/ecma262/#sec-array.prototype.sort
__webpack_require__(22)({ target: 'Array', proto: true, forced: FORCED }, {
sort: function sort(comparefn) {
return comparefn === undefined
? nativeSort.call(toObject(this))
: nativeSort.call(toObject(this), aFunction(comparefn));
}
});
/***/ }),
/* 64 */
/***/ (function(module, exports, __webpack_require__) {
var global = __webpack_require__(32);
var hide = __webpack_require__(61);
var has = __webpack_require__(47);
var setGlobal = __webpack_require__(143);
var nativeFunctionToString = __webpack_require__(177);
var InternalStateModule = __webpack_require__(87);
var getInternalState = InternalStateModule.get;
var enforceInternalState = InternalStateModule.enforce;
var TEMPLATE = String(nativeFunctionToString).split('toString');
__webpack_require__(98)('inspectSource', function (it) {
return nativeFunctionToString.call(it);
});
(module.exports = function (O, key, value, options) {
var unsafe = options ? !!options.unsafe : false;
var simple = options ? !!options.enumerable : false;
var noTargetGet = options ? !!options.noTargetGet : false;
if (typeof value == 'function') {
if (typeof key == 'string' && !has(value, 'name')) hide(value, 'name', key);
enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');
}
if (O === global) {
if (simple) O[key] = value;
else setGlobal(key, value);
return;
} else if (!unsafe) {
delete O[key];
} else if (!noTargetGet && O[key]) {
simple = true;
}
if (simple) O[key] = value;
else hide(O, key, value);
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, 'toString', function toString() {
return typeof this == 'function' && getInternalState(this).source || nativeFunctionToString.call(this);
});
/***/ }),
/* 65 */
/***/ (function(module, exports) {
function _taggedTemplateLiteral(strings, raw) {
if (!raw) {
raw = strings.slice(0);
}
return Object.freeze(Object.defineProperties(strings, {
raw: {
value: Object.freeze(raw)
}
}));
}
module.exports = _taggedTemplateLiteral;
/***/ }),
/* 66 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__66__;
/***/ }),
/* 67 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
__webpack_require__(37);
__webpack_require__(105);
exports.__esModule = true;
exports.toSingleLine = toSingleLine;
var _array = __webpack_require__(3);
/* eslint-disable import/prefer-default-export */
/**
* Tags a multiline string and return new one without line break characters and following spaces.
*
* @param {Array} strings Parts of the entire string without expressions.
* @param {...String} expressions Expressions converted to strings, which are added to the entire string.
* @returns {String}
*/
function toSingleLine(strings) {
for (var _len = arguments.length, expressions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
expressions[_key - 1] = arguments[_key];
}
var result = (0, _array.arrayReduce)(strings, function (previousValue, currentValue, index) {
var valueWithoutWhiteSpaces = currentValue.replace(/(?:\r?\n\s+)/g, '');
var expressionForIndex = expressions[index] ? expressions[index] : '';
return previousValue + valueWithoutWhiteSpaces + expressionForIndex;
}, '');
return result.trim();
}
/***/ }),
/* 68 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
__webpack_require__(12);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(37);
exports.__esModule = true;
exports.toUpperCaseFirst = toUpperCaseFirst;
exports.equalsIgnoreCase = equalsIgnoreCase;
exports.randomString = randomString;
exports.isPercentValue = isPercentValue;
exports.substitute = substitute;
exports.stripTags = stripTags;
var _mixed = __webpack_require__(27);
/**
* Convert string to upper case first letter.
*
* @param {String} string String to convert.
* @returns {String}
*/
function toUpperCaseFirst(string) {
return string[0].toUpperCase() + string.substr(1);
}
/**
* Compare strings case insensitively.
*
* @param {...String} strings Strings to compare.
* @returns {Boolean}
*/
function equalsIgnoreCase() {
var unique = [];
for (var _len = arguments.length, strings = new Array(_len), _key = 0; _key < _len; _key++) {
strings[_key] = arguments[_key];
}
var length = strings.length;
while (length) {
length -= 1;
var string = (0, _mixed.stringify)(strings[length]).toLowerCase();
if (unique.indexOf(string) === -1) {
unique.push(string);
}
}
return unique.length === 1;
}
/**
* Generates a random hex string. Used as namespace for Handsontable instance events.
*
* @return {String} Returns 16-long character random string (eq. `'92b1bfc74ec4'`).
*/
function randomString() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + s4() + s4();
}
/**
* Checks if value is valid percent.
*
* @param {String} value
* @returns {Boolean}
*/
function isPercentValue(value) {
return /^([0-9][0-9]?%$)|(^100%$)/.test(value);
}
/**
* Substitute strings placed beetwen square brackets into value defined in `variables` object. String names defined in
* square brackets must be the same as property name of `variables` object.
*
* @param {String} template Template string.
* @param {Object} variables Object which contains all available values which can be injected into template.
* @returns {String}
*/
function substitute(template) {
var variables = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return "".concat(template).replace(/(?:\\)?\[([^[\]]+)]/g, function (match, name) {
if (match.charAt(0) === '\\') {
return match.substr(1, match.length - 1);
}
return variables[name] === void 0 ? '' : variables[name];
});
}
var STRIP_TAGS_REGEX = /<\/?\w+\/?>|<\w+[\s|/][^>]*>/gi;
/**
* Strip any HTML tag from the string.
*
* @param {String} string String to cut HTML from.
* @return {String}
*/
function stripTags(string) {
return "".concat(string).replace(STRIP_TAGS_REGEX, '');
}
/***/ }),
/* 69 */
/***/ (function(module, exports, __webpack_require__) {
// toObject with fallback for non-array-like ES3 strings
var IndexedObject = __webpack_require__(113);
var requireObjectCoercible = __webpack_require__(58);
module.exports = function (it) {
return IndexedObject(requireObjectCoercible(it));
};
/***/ }),
/* 70 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// `Map` constructor
// https://tc39.github.io/ecma262/#sec-map-objects
module.exports = __webpack_require__(125)('Map', function (get) {
return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, __webpack_require__(192), true);
/***/ }),
/* 71 */
/***/ (function(module, exports) {
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
module.exports = _defineProperty;
/***/ }),
/* 72 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.setBrowserMeta = setBrowserMeta;
exports.isChrome = isChrome;
exports.isEdge = isEdge;
exports.isIE = isIE;
exports.isIE8 = isIE8;
exports.isIE9 = isIE9;
exports.isMSBrowser = isMSBrowser;
exports.isMobileBrowser = isMobileBrowser;
exports.isSafari = isSafari;
var _object = __webpack_require__(4);
var tester = function tester(testerFunc) {
var result = {
value: false
};
result.test = function (ua, vendor) {
result.value = testerFunc(ua, vendor);
};
return result;
};
var browsers = {
chrome: tester(function (ua, vendor) {
return /Chrome/.test(ua) && /Google/.test(vendor);
}),
edge: tester(function (ua) {
return /Edge/.test(ua);
}),
ie: tester(function (ua) {
return /Trident/.test(ua);
}),
// eslint-disable-next-line no-restricted-globals
ie8: tester(function () {
return !document.createTextNode('test').textContent;
}),
// eslint-disable-next-line no-restricted-globals
ie9: tester(function () {
return !!document.documentMode;
}),
mobile: tester(function (ua) {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
}),
safari: tester(function (ua, vendor) {
return /Safari/.test(ua) && /Apple Computer/.test(vendor);
})
};
function setBrowserMeta() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$userAgent = _ref.userAgent,
userAgent = _ref$userAgent === void 0 ? navigator.userAgent : _ref$userAgent,
_ref$vendor = _ref.vendor,
vendor = _ref$vendor === void 0 ? navigator.vendor : _ref$vendor;
(0, _object.objectEach)(browsers, function (_ref2) {
var test = _ref2.test;
return void test(userAgent, vendor);
});
}
setBrowserMeta();
function isChrome() {
return browsers.chrome.value;
}
function isEdge() {
return browsers.edge.value;
}
function isIE() {
return browsers.ie.value;
}
function isIE8() {
return browsers.ie8.value;
}
function isIE9() {
return browsers.ie9.value;
}
function isMSBrowser() {
return browsers.ie.value || browsers.edge.value;
}
function isMobileBrowser() {
return browsers.mobile.value;
}
function isSafari() {
return browsers.safari.value;
}
/***/ }),
/* 73 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(131);
__webpack_require__(30);
exports.__esModule = true;
exports.requestAnimationFrame = requestAnimationFrame;
exports.isClassListSupported = isClassListSupported;
exports.isTextContentSupported = isTextContentSupported;
exports.isGetComputedStyleSupported = isGetComputedStyleSupported;
exports.cancelAnimationFrame = cancelAnimationFrame;
exports.isTouchSupported = isTouchSupported;
exports.isWebComponentSupportedNatively = isWebComponentSupportedNatively;
exports.hasCaptionProblem = hasCaptionProblem;
exports.getComparisonFunction = getComparisonFunction;
exports.isPassiveEventSupported = isPassiveEventSupported;
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
// https://gist.github.com/paulirish/1579671
/* eslint-disable no-restricted-globals */
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
var _requestAnimationFrame = window.requestAnimationFrame;
var _cancelAnimationFrame = window.cancelAnimationFrame;
for (var x = 0; x < vendors.length && !_requestAnimationFrame; ++x) {
_requestAnimationFrame = window["".concat(vendors[x], "RequestAnimationFrame")];
_cancelAnimationFrame = window["".concat(vendors[x], "CancelAnimationFrame")] || window["".concat(vendors[x], "CancelRequestAnimationFrame")];
}
if (!_requestAnimationFrame) {
_requestAnimationFrame = function _requestAnimationFrame(callback) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function () {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!_cancelAnimationFrame) {
_cancelAnimationFrame = function _cancelAnimationFrame(id) {
clearTimeout(id);
};
}
/**
* Polyfill for requestAnimationFrame
*
* @param {Function} callback
* @returns {Number}
*/
function requestAnimationFrame(callback) {
return _requestAnimationFrame.call(window, callback);
}
function isClassListSupported() {
return !!document.documentElement.classList;
}
function isTextContentSupported() {
return !!document.createTextNode('test').textContent;
}
function isGetComputedStyleSupported() {
return !!window.getComputedStyle;
}
/**
* Polyfill for cancelAnimationFrame
*
* @param {Number} id
*/
function cancelAnimationFrame(id) {
_cancelAnimationFrame.call(window, id);
}
function isTouchSupported() {
return 'ontouchstart' in window;
}
/**
* Checks if browser is support web components natively
*
* @returns {Boolean}
*/
function isWebComponentSupportedNatively() {
var test = document.createElement('div');
return !!(test.createShadowRoot && test.createShadowRoot.toString().match(/\[native code\]/));
}
var _hasCaptionProblem;
function detectCaptionProblem() {
var TABLE = document.createElement('TABLE');
TABLE.style.borderSpacing = '0';
TABLE.style.borderWidth = '0';
TABLE.style.padding = '0';
var TBODY = document.createElement('TBODY');
TABLE.appendChild(TBODY);
TBODY.appendChild(document.createElement('TR'));
TBODY.firstChild.appendChild(document.createElement('TD'));
TBODY.firstChild.firstChild.innerHTML = '
');
return result.join('');
}
/**
* Helper to verify if DOM element is an HTMLTable element.
*
* @param {Element} element Node element to verify if it's an HTMLTable.
*/
function isHTMLTable(element) {
return (element && element.nodeName || '').toLowerCase() === 'table';
}
/**
* Converts HTMLTable or string into array.
*
* @param {Element|String} element Node element or string, which should contain `
...
`.
*/
function tableToArray(element, rootDocument) {
var result = [];
var checkElement = element;
if (typeof checkElement === 'string') {
var tempElem = rootDocument.createElement('div');
tempElem.innerHTML = checkElement.replace(/\n/g, '');
checkElement = tempElem.querySelector('table');
}
if (checkElement && isHTMLTable(checkElement)) {
var rows = checkElement.rows;
var rowsLen = rows && rows.length;
var tempArray = [];
for (var row = 0; row < rowsLen; row += 1) {
var cells = rows[row].cells;
var cellsLen = cells.length;
var newRow = [];
for (var column = 0; column < cellsLen; column += 1) {
var cell = cells[column];
cell.innerHTML = cell.innerHTML.trim().replace(/ (\n?)/, '\n');
var cellText = cell.innerText;
newRow.push(cellText);
}
tempArray.push(newRow);
}
result.push.apply(result, tempArray);
}
return result;
}
/***/ }),
/* 391 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 392 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(33);
__webpack_require__(237);
__webpack_require__(76);
__webpack_require__(393);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _plugins = __webpack_require__(20);
var _object = __webpack_require__(4);
var _number = __webpack_require__(15);
var _array = __webpack_require__(3);
var _src = __webpack_require__(25);
var C = _interopRequireWildcard(__webpack_require__(11));
var _contextMenuItem = __webpack_require__(395);
var _utils = __webpack_require__(92);
var _selection = __webpack_require__(230);
/**
* @class CustomBorders
* @plugin CustomBorders
*
* @description
* This plugin enables an option to apply custom borders through the context menu (configurable with context menu key
* `borders`).
*
* To initialize Handsontable with predefined custom borders, provide cell coordinates and border styles in a form
* of an array.
*
* See [Custom Borders](http://docs.handsontable.com/demo-custom-borders.html) demo for more examples.
*
* @example
* ```js
* customBorders: [
* {
* range: {
* from: {
* row: 1,
* col: 1
* },
* to: {
* row: 3,
* col: 4
* },
* },
* left: {},
* right: {},
* top: {},
* bottom: {},
* },
* ],
*
* // or
* customBorders: [
* { row: 2,
* col: 2,
* left: {
* width: 2,
* color: 'red',
* },
* right: {
* width: 1,
* color: 'green',
* },
* top: '',
* bottom: '',
* }
* ],
* ```
*/
var CustomBorders =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(CustomBorders, _BasePlugin);
function CustomBorders(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, CustomBorders);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CustomBorders).call(this, hotInstance));
/**
* Saved borders.
*
* @private
* @type {Array}
*/
_this.savedBorders = [];
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link CustomBorders#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(CustomBorders, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().customBorders;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.addHook('afterContextMenuDefaultOptions', function (options) {
return _this2.onAfterContextMenuDefaultOptions(options);
});
this.addHook('afterInit', function () {
return _this2.onAfterInit();
});
(0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.hideBorders();
(0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "disablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
this.changeBorderSettings();
(0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "updatePlugin", this).call(this);
}
/**
* Set custom borders.
*
* @example
* ```js
* const customBordersPlugin = hot.getPlugin('customBorders');
*
* // Using an array of arrays (produced by `.getSelected()` method).
* customBordersPlugin.setBorders([[1, 1, 2, 2], [6, 2, 0, 2]], {left: {width: 2, color: 'blue'}});
* // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
* customBordersPlugin.setBorders(hot.getSelectedRange(), {left: {hide: false, width: 2, color: 'blue'}});
* ```
*
* @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
* @param {Object} borderObject Object with `top`, `right`, `bottom` and `left` properties.
*/
}, {
key: "setBorders",
value: function setBorders(selectionRanges, borderObject) {
var _this3 = this;
var defaultBorderKeys = ['top', 'right', 'bottom', 'left'];
var borderKeys = borderObject ? Object.keys(borderObject) : defaultBorderKeys;
var selectionType = (0, _selection.detectSelectionType)(selectionRanges);
var selectionSchemaNormalizer = (0, _selection.normalizeSelectionFactory)(selectionType);
(0, _array.arrayEach)(selectionRanges, function (selection) {
var _selectionSchemaNorma = selectionSchemaNormalizer(selection),
_selectionSchemaNorma2 = (0, _slicedToArray2.default)(_selectionSchemaNorma, 4),
rowStart = _selectionSchemaNorma2[0],
columnStart = _selectionSchemaNorma2[1],
rowEnd = _selectionSchemaNorma2[2],
columnEnd = _selectionSchemaNorma2[3];
var _loop = function _loop(row) {
var _loop2 = function _loop2(col) {
(0, _array.arrayEach)(borderKeys, function (borderKey) {
_this3.prepareBorderFromCustomAdded(row, col, borderObject, borderKey);
});
};
for (var col = columnStart; col <= columnEnd; col += 1) {
_loop2(col);
}
};
for (var row = rowStart; row <= rowEnd; row += 1) {
_loop(row);
}
});
}
/**
* Get custom borders.
*
* @example
* ```js
* const customBordersPlugin = hot.getPlugin('customBorders');
*
* // Using an array of arrays (produced by `.getSelected()` method).
* customBordersPlugin.getBorders([[1, 1, 2, 2], [6, 2, 0, 2]]);
* // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
* customBordersPlugin.getBorders(hot.getSelectedRange());
* // Using without param - return all customBorders.
* customBordersPlugin.getBorders();
* ```
*
* @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
* @return {Object[]} Returns array of border objects.
*/
}, {
key: "getBorders",
value: function getBorders(selectionRanges) {
var _this4 = this;
if (!Array.isArray(selectionRanges)) {
return this.savedBorders;
}
var selectionType = (0, _selection.detectSelectionType)(selectionRanges);
var selectionSchemaNormalizer = (0, _selection.normalizeSelectionFactory)(selectionType);
var selectedBorders = [];
(0, _array.arrayEach)(selectionRanges, function (selection) {
var _selectionSchemaNorma3 = selectionSchemaNormalizer(selection),
_selectionSchemaNorma4 = (0, _slicedToArray2.default)(_selectionSchemaNorma3, 4),
rowStart = _selectionSchemaNorma4[0],
columnStart = _selectionSchemaNorma4[1],
rowEnd = _selectionSchemaNorma4[2],
columnEnd = _selectionSchemaNorma4[3];
var _loop3 = function _loop3(row) {
var _loop4 = function _loop4(col) {
(0, _array.arrayEach)(_this4.savedBorders, function (border) {
if (border.row === row && border.col === col) {
selectedBorders.push(border);
}
});
};
for (var col = columnStart; col <= columnEnd; col += 1) {
_loop4(col);
}
};
for (var row = rowStart; row <= rowEnd; row += 1) {
_loop3(row);
}
});
return selectedBorders;
}
/**
* Clear custom borders.
*
* @example
* ```js
* const customBordersPlugin = hot.getPlugin('customBorders');
*
* // Using an array of arrays (produced by `.getSelected()` method).
* customBordersPlugin.clearBorders([[1, 1, 2, 2], [6, 2, 0, 2]]);
* // Using an array of CellRange objects (produced by `.getSelectedRange()` method).
* customBordersPlugin.clearBorders(hot.getSelectedRange());
* // Using without param - clear all customBorders.
* customBordersPlugin.clearBorders();
* ```
*
* @param {Array[]|CellRange[]} selectionRanges Array of selection ranges.
*/
}, {
key: "clearBorders",
value: function clearBorders(selectionRanges) {
var _this5 = this;
if (selectionRanges) {
this.setBorders(selectionRanges);
} else {
(0, _array.arrayEach)(this.savedBorders, function (border) {
_this5.clearBordersFromSelectionSettings(border.id);
_this5.clearNullCellRange();
_this5.hot.removeCellMeta(border.row, border.col, 'borders');
});
this.savedBorders.length = 0;
}
}
/**
* Insert WalkontableSelection instance into Walkontable settings.
*
* @private
* @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
* @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right`.
*/
}, {
key: "insertBorderIntoSettings",
value: function insertBorderIntoSettings(border, place) {
var hasSavedBorders = this.checkSavedBorders(border);
if (!hasSavedBorders) {
this.savedBorders.push(border);
}
var coordinates = {
row: border.row,
col: border.col
};
var cellRange = new _src.CellRange(coordinates, coordinates, coordinates);
var hasCustomSelections = this.checkCustomSelections(border, cellRange, place);
if (!hasCustomSelections) {
this.hot.selection.highlight.addCustomSelection({
border: border,
cellRange: cellRange
});
this.hot.view.wt.draw(true);
}
}
/**
* Prepare borders from setting (single cell).
*
* @private
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {Object} borderDescriptor Object with `row` and `col`, `left`, `right`, `top` and `bottom` properties.
* @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right`.
*/
}, {
key: "prepareBorderFromCustomAdded",
value: function prepareBorderFromCustomAdded(row, column, borderDescriptor, place) {
var border = (0, _utils.createEmptyBorders)(row, column);
if (borderDescriptor) {
border = (0, _utils.extendDefaultBorder)(border, borderDescriptor);
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection) {
if (border.id === customSelection.settings.id) {
Object.assign(customSelection.settings, borderDescriptor);
border = customSelection.settings;
return false; // breaks forAll
}
});
}
this.hot.setCellMeta(row, column, 'borders', border);
this.insertBorderIntoSettings(border, place);
}
/**
* Prepare borders from setting (object).
*
* @private
* @param {Object} rowDecriptor Object with `range`, `left`, `right`, `top` and `bottom` properties.
*/
}, {
key: "prepareBorderFromCustomAddedRange",
value: function prepareBorderFromCustomAddedRange(rowDecriptor) {
var _this6 = this;
var range = rowDecriptor.range;
(0, _number.rangeEach)(range.from.row, range.to.row, function (rowIndex) {
(0, _number.rangeEach)(range.from.col, range.to.col, function (colIndex) {
var border = (0, _utils.createEmptyBorders)(rowIndex, colIndex);
var add = 0;
if (rowIndex === range.from.row) {
add += 1;
if ((0, _object.hasOwnProperty)(rowDecriptor, 'top')) {
border.top = rowDecriptor.top;
}
}
if (rowIndex === range.to.row) {
add += 1;
if ((0, _object.hasOwnProperty)(rowDecriptor, 'bottom')) {
border.bottom = rowDecriptor.bottom;
}
}
if (colIndex === range.from.col) {
add += 1;
if ((0, _object.hasOwnProperty)(rowDecriptor, 'left')) {
border.left = rowDecriptor.left;
}
}
if (colIndex === range.to.col) {
add += 1;
if ((0, _object.hasOwnProperty)(rowDecriptor, 'right')) {
border.right = rowDecriptor.right;
}
}
if (add > 0) {
_this6.hot.setCellMeta(rowIndex, colIndex, 'borders', border);
_this6.insertBorderIntoSettings(border);
}
});
});
}
/**
* Remove border (triggered from context menu).
*
* @private
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
*/
}, {
key: "removeAllBorders",
value: function removeAllBorders(row, column) {
var borderId = (0, _utils.createId)(row, column);
this.spliceBorder(borderId);
this.clearBordersFromSelectionSettings(borderId);
this.clearNullCellRange();
this.hot.removeCellMeta(row, column, 'borders');
}
/**
* Set borders for each cell re. to border position.
*
* @private
* @param {Number} row Visual row index.
* @param {Number} column Visual column index.
* @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right` and `noBorders`.
* @param {Boolean} remove True when remove borders, and false when add borders.
*/
}, {
key: "setBorder",
value: function setBorder(row, column, place, remove) {
var bordersMeta = this.hot.getCellMeta(row, column).borders;
if (!bordersMeta || bordersMeta.border === void 0) {
bordersMeta = (0, _utils.createEmptyBorders)(row, column);
}
if (remove) {
bordersMeta[place] = (0, _utils.createSingleEmptyBorder)();
var hideCount = this.countHide(bordersMeta);
if (hideCount === 4) {
this.removeAllBorders(row, column);
} else {
var customSelectionsChecker = this.checkCustomSelectionsFromContextMenu(bordersMeta, place, remove);
if (!customSelectionsChecker) {
this.insertBorderIntoSettings(bordersMeta);
}
this.hot.setCellMeta(row, column, 'borders', bordersMeta);
}
} else {
bordersMeta[place] = (0, _utils.createDefaultCustomBorder)();
var _customSelectionsChecker = this.checkCustomSelectionsFromContextMenu(bordersMeta, place, remove);
if (!_customSelectionsChecker) {
this.insertBorderIntoSettings(bordersMeta);
}
this.hot.setCellMeta(row, column, 'borders', bordersMeta);
}
}
/**
* Prepare borders based on cell and border position.
*
* @private
* @param {Object} selected
* @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right` and `noBorders`.
* @param {Boolean} remove True when remove borders, and false when add borders.
*/
}, {
key: "prepareBorder",
value: function prepareBorder(selected, place, remove) {
var _this7 = this;
(0, _array.arrayEach)(selected, function (_ref) {
var start = _ref.start,
end = _ref.end;
if (start.row === end.row && start.col === end.col) {
if (place === 'noBorders') {
_this7.removeAllBorders(start.row, start.col);
} else {
_this7.setBorder(start.row, start.col, place, remove);
}
} else {
switch (place) {
case 'noBorders':
(0, _number.rangeEach)(start.col, end.col, function (colIndex) {
(0, _number.rangeEach)(start.row, end.row, function (rowIndex) {
_this7.removeAllBorders(rowIndex, colIndex);
});
});
break;
case 'top':
(0, _number.rangeEach)(start.col, end.col, function (topCol) {
_this7.setBorder(start.row, topCol, place, remove);
});
break;
case 'right':
(0, _number.rangeEach)(start.row, end.row, function (rowRight) {
_this7.setBorder(rowRight, end.col, place, remove);
});
break;
case 'bottom':
(0, _number.rangeEach)(start.col, end.col, function (bottomCol) {
_this7.setBorder(end.row, bottomCol, place, remove);
});
break;
case 'left':
(0, _number.rangeEach)(start.row, end.row, function (rowLeft) {
_this7.setBorder(rowLeft, start.col, place, remove);
});
break;
default:
break;
}
}
});
}
/**
* Create borders from settings.
*
* @private
* @param {Array} customBorders Object with `row` and `col`, `left`, `right`, `top` and `bottom` properties.
*/
}, {
key: "createCustomBorders",
value: function createCustomBorders(customBorders) {
var _this8 = this;
(0, _array.arrayEach)(customBorders, function (customBorder) {
if (customBorder.range) {
_this8.prepareBorderFromCustomAddedRange(customBorder);
} else {
_this8.prepareBorderFromCustomAdded(customBorder.row, customBorder.col, customBorder);
}
});
}
/**
* Count hide property in border object.
*
* @private
* @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
*/
}, {
key: "countHide",
value: function countHide(border) {
var values = Object.values(border);
return (0, _array.arrayReduce)(values, function (accumulator, value) {
var result = accumulator;
if (value.hide) {
result += 1;
}
return result;
}, 0);
}
/**
* Clear borders settings from custom selections.
*
* @private
* @param {String} borderId Border id name as string.
*/
}, {
key: "clearBordersFromSelectionSettings",
value: function clearBordersFromSelectionSettings(borderId) {
var index = (0, _array.arrayMap)(this.hot.selection.highlight.customSelections, function (customSelection) {
return customSelection.settings.id;
}).indexOf(borderId);
if (index > -1) {
this.hot.selection.highlight.customSelections[index].clear();
}
this.hot.view.wt.draw(true);
}
/**
* Clear cellRange with null value.
*
* @private
*/
}, {
key: "clearNullCellRange",
value: function clearNullCellRange() {
var _this9 = this;
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection, index) {
if (customSelection.cellRange === null) {
_this9.hot.selection.highlight.customSelections.splice(index, 1);
return false; // breaks forAll
}
});
}
/**
* Hide custom borders.
*
* @private
*/
}, {
key: "hideBorders",
value: function hideBorders() {
var _this10 = this;
(0, _array.arrayEach)(this.savedBorders, function (border) {
_this10.clearBordersFromSelectionSettings(border.id);
});
}
/**
* Splice border from savedBorders.
*
* @private
* @param {String} borderId Border id name as string.
*/
}, {
key: "spliceBorder",
value: function spliceBorder(borderId) {
var index = (0, _array.arrayMap)(this.savedBorders, function (border) {
return border.id;
}).indexOf(borderId);
if (index > -1) {
this.savedBorders.splice(index, 1);
}
}
/**
* Check if an border already exists in the savedBorders array, and if true update border in savedBorders.
*
* @private
* @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
*
* @return {Boolean}
*/
}, {
key: "checkSavedBorders",
value: function checkSavedBorders(border) {
var _this11 = this;
var check = false;
var hideCount = this.countHide(border);
if (hideCount === 4) {
this.spliceBorder(border.id);
check = true;
} else {
(0, _array.arrayEach)(this.savedBorders, function (savedBorder, index) {
if (border.id === savedBorder.id) {
_this11.savedBorders[index] = border;
check = true;
return false; // breaks forAll
}
});
}
return check;
}
/**
* Check if an border already exists in the customSelections, and if true call toggleHiddenClass method.
*
* @private
* @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
* @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right` and `noBorders`.
* @param {Boolean} remove True when remove borders, and false when add borders.
*
* @return {Boolean}
*/
}, {
key: "checkCustomSelectionsFromContextMenu",
value: function checkCustomSelectionsFromContextMenu(border, place, remove) {
var check = false;
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection) {
if (border.id === customSelection.settings.id) {
(0, _object.objectEach)(customSelection.instanceBorders, function (borderObject) {
borderObject.toggleHiddenClass(place, remove);
});
check = true;
return false; // breaks forAll
}
});
return check;
}
/**
* Check if an border already exists in the customSelections, and if true reset cellRange.
*
* @private
* @param {Object} border Object with `row` and `col`, `left`, `right`, `top` and `bottom`, `id` and `border` ({Object} with `color`, `width` and `cornerVisible` property) properties.
* @param {CellRange} cellRange
* @param {String} place Coordinate where add/remove border - `top`, `bottom`, `left`, `right`.
*
* @return {Boolean}
*/
}, {
key: "checkCustomSelections",
value: function checkCustomSelections(border, cellRange, place) {
var hideCount = this.countHide(border);
var check = false;
if (hideCount === 4) {
this.removeAllBorders(border.row, border.col);
this.clearBordersFromSelectionSettings(border.id);
this.clearNullCellRange();
check = true;
} else {
(0, _array.arrayEach)(this.hot.selection.highlight.customSelections, function (customSelection) {
if (border.id === customSelection.settings.id) {
customSelection.cellRange = cellRange;
if (place) {
(0, _object.objectEach)(customSelection.instanceBorders, function (borderObject) {
borderObject.changeBorderStyle(place, border);
});
}
check = true;
return false; // breaks forAll
}
});
}
return check;
}
/**
* Change borders from settings.
*
* @private
*/
}, {
key: "changeBorderSettings",
value: function changeBorderSettings() {
var customBorders = this.hot.getSettings().customBorders;
if (Array.isArray(customBorders)) {
if (!customBorders.length) {
this.savedBorders = customBorders;
}
this.createCustomBorders(customBorders);
} else if (customBorders !== void 0) {
this.createCustomBorders(this.savedBorders);
}
}
/**
* Add border options to context menu.
*
* @private
* @param {Object} defaultOptions Context menu items.
*/
}, {
key: "onAfterContextMenuDefaultOptions",
value: function onAfterContextMenuDefaultOptions(defaultOptions) {
if (!this.hot.getSettings().customBorders) {
return;
}
defaultOptions.items.push({
name: '---------'
}, {
key: 'borders',
name: function name() {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS);
},
disabled: function disabled() {
return this.selection.isSelectedByCorner();
},
submenu: {
items: [(0, _contextMenuItem.top)(this), (0, _contextMenuItem.right)(this), (0, _contextMenuItem.bottom)(this), (0, _contextMenuItem.left)(this), (0, _contextMenuItem.noBorders)(this)]
}
});
}
/**
* `afterInit` hook callback.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
this.changeBorderSettings();
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
(0, _get2.default)((0, _getPrototypeOf2.default)(CustomBorders.prototype), "destroy", this).call(this);
}
}]);
return CustomBorders;
}(_base.default);
(0, _plugins.registerPlugin)('customBorders', CustomBorders);
var _default = CustomBorders;
exports.default = _default;
/***/ }),
/* 393 */
/***/ (function(module, exports, __webpack_require__) {
var objectToArray = __webpack_require__(394);
// `Object.values` method
// https://tc39.github.io/ecma262/#sec-object.values
__webpack_require__(22)({ target: 'Object', stat: true }, {
values: function values(O) {
return objectToArray(O);
}
});
/***/ }),
/* 394 */
/***/ (function(module, exports, __webpack_require__) {
var objectKeys = __webpack_require__(89);
var toIndexedObject = __webpack_require__(69);
var propertyIsEnumerable = __webpack_require__(95).f;
// TO_ENTRIES: true -> Object.entries
// TO_ENTRIES: false -> Object.values
module.exports = function (it, TO_ENTRIES) {
var O = toIndexedObject(it);
var keys = objectKeys(O);
var length = keys.length;
var i = 0;
var result = [];
var key;
while (length > i) if (propertyIsEnumerable.call(O, key = keys[i++])) {
result.push(TO_ENTRIES ? [key, O[key]] : O[key]);
} return result;
};
/***/ }),
/* 395 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
var _bottom = _interopRequireDefault(__webpack_require__(396));
exports.bottom = _bottom.default;
var _left = _interopRequireDefault(__webpack_require__(397));
exports.left = _left.default;
var _noBorders = _interopRequireDefault(__webpack_require__(398));
exports.noBorders = _noBorders.default;
var _right = _interopRequireDefault(__webpack_require__(399));
exports.right = _right.default;
var _top = _interopRequireDefault(__webpack_require__(400));
exports.top = _top.default;
/***/ }),
/* 396 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.default = bottom;
var C = _interopRequireWildcard(__webpack_require__(11));
var _utils = __webpack_require__(92);
function bottom(customBordersPlugin) {
return {
key: 'borders:bottom',
name: function name() {
var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_BOTTOM);
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'bottom');
if (hasBorder) {
label = (0, _utils.markSelected)(label);
}
return label;
},
callback: function callback(key, selected) {
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'bottom');
customBordersPlugin.prepareBorder(selected, 'bottom', hasBorder);
}
};
}
/***/ }),
/* 397 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.default = left;
var C = _interopRequireWildcard(__webpack_require__(11));
var _utils = __webpack_require__(92);
function left(customBordersPlugin) {
return {
key: 'borders:left',
name: function name() {
var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_LEFT);
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'left');
if (hasBorder) {
label = (0, _utils.markSelected)(label);
}
return label;
},
callback: function callback(key, selected) {
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'left');
customBordersPlugin.prepareBorder(selected, 'left', hasBorder);
}
};
}
/***/ }),
/* 398 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.default = noBorders;
var C = _interopRequireWildcard(__webpack_require__(11));
var _utils = __webpack_require__(92);
function noBorders(customBordersPlugin) {
return {
key: 'borders:no_borders',
name: function name() {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_REMOVE_BORDERS);
},
callback: function callback(key, selected) {
customBordersPlugin.prepareBorder(selected, 'noBorders');
},
disabled: function disabled() {
return !(0, _utils.checkSelectionBorders)(this);
}
};
}
/***/ }),
/* 399 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.default = right;
var C = _interopRequireWildcard(__webpack_require__(11));
var _utils = __webpack_require__(92);
function right(customBordersPlugin) {
return {
key: 'borders:right',
name: function name() {
var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_RIGHT);
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'right');
if (hasBorder) {
label = (0, _utils.markSelected)(label);
}
return label;
},
callback: function callback(key, selected) {
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'right');
customBordersPlugin.prepareBorder(selected, 'right', hasBorder);
}
};
}
/***/ }),
/* 400 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.default = top;
var C = _interopRequireWildcard(__webpack_require__(11));
var _utils = __webpack_require__(92);
function top(customBordersPlugin) {
return {
key: 'borders:top',
name: function name() {
var label = this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_BORDERS_TOP);
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'top');
if (hasBorder) {
label = (0, _utils.markSelected)(label);
}
return label;
},
callback: function callback(key, selected) {
var hasBorder = (0, _utils.checkSelectionBorders)(this, 'top');
customBordersPlugin.prepareBorder(selected, 'top', hasBorder);
}
};
}
/***/ }),
/* 401 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _plugins = __webpack_require__(20);
/**
* @description
* Plugin used to scroll Handsontable by selecting a cell and dragging outside of the visible viewport.
*
*
* @class DragToScroll
* @plugin DragToScroll
*/
var DragToScroll =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(DragToScroll, _BasePlugin);
function DragToScroll(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, DragToScroll);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(DragToScroll).call(this, hotInstance));
/**
* Instance of {@link EventManager}.
*
* @private
* @type {EventManager}
*/
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
/**
* Size of an element and its position relative to the viewport,
* e.g. {bottom: 449, height: 441, left: 8, right: 814, top: 8, width: 806, x: 8, y:8}.
*
* @type {DOMRect}
*/
_this.boundaries = null;
/**
* Callback function.
*
* @private
* @type {Function}
*/
_this.callback = null;
/**
* Flag indicates mouseDown/mouseUp.
*
* @private
* @type {Boolean}
*/
_this.listening = false;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link DragToScroll#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(DragToScroll, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().dragToScroll;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.addHook('afterOnCellMouseDown', function () {
return _this2.setupListening();
});
this.addHook('afterOnCellCornerMouseDown', function () {
return _this2.setupListening();
});
this.registerEvents();
(0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.unregisterEvents();
(0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "disablePlugin", this).call(this);
}
/**
* Sets the value of the visible element.
*
* @param boundaries {DOMRect} An object with coordinates compatible with DOMRect.
*/
}, {
key: "setBoundaries",
value: function setBoundaries(boundaries) {
this.boundaries = boundaries;
}
/**
* Changes callback function.
*
* @param callback {Function}
*/
}, {
key: "setCallback",
value: function setCallback(callback) {
this.callback = callback;
}
/**
* Checks if the mouse position (X, Y) is outside of the viewport and fires a callback with calculated X an Y diffs
* between passed boundaries.
*
* @param {Number} x Mouse X coordinate to check.
* @param {Number} y Mouse Y coordinate to check.
*/
}, {
key: "check",
value: function check(x, y) {
var diffX = 0;
var diffY = 0;
if (y < this.boundaries.top) {
// y is less than top
diffY = y - this.boundaries.top;
} else if (y > this.boundaries.bottom) {
// y is more than bottom
diffY = y - this.boundaries.bottom;
}
if (x < this.boundaries.left) {
// x is less than left
diffX = x - this.boundaries.left;
} else if (x > this.boundaries.right) {
// x is more than right
diffX = x - this.boundaries.right;
}
this.callback(diffX, diffY);
}
/**
* Registers dom listeners.
*
* @private
*/
}, {
key: "registerEvents",
value: function registerEvents() {
var _this3 = this;
var rootDocument = this.hot.rootDocument;
this.eventManager.addEventListener(rootDocument, 'mouseup', function () {
return _this3.onMouseUp();
});
this.eventManager.addEventListener(rootDocument, 'mousemove', function (event) {
return _this3.onMouseMove(event);
});
}
/**
* Unbinds the events used by the plugin.
*
* @private
*/
}, {
key: "unregisterEvents",
value: function unregisterEvents() {
this.eventManager.clear();
}
/**
* On after on cell/cellCorner mouse down listener.
*
* @private
*/
}, {
key: "setupListening",
value: function setupListening() {
var scrollHandler = this.hot.view.wt.wtTable.holder; // native scroll
if (scrollHandler === this.hot.rootWindow) {
// not much we can do currently
return;
}
this.setBoundaries(scrollHandler.getBoundingClientRect());
this.setCallback(function (scrollX, scrollY) {
if (scrollX < 0) {
scrollHandler.scrollLeft -= 50;
} else if (scrollX > 0) {
scrollHandler.scrollLeft += 50;
}
if (scrollY < 0) {
scrollHandler.scrollTop -= 20;
} else if (scrollY > 0) {
scrollHandler.scrollTop += 20;
}
});
this.listening = true;
}
/**
* 'mouseMove' event callback.
*
* @private
* @param {MouseEvent} event `mousemove` event properties.
*/
}, {
key: "onMouseMove",
value: function onMouseMove(event) {
if (this.listening) {
this.check(event.clientX, event.clientY);
}
}
/**
* `onMouseUp` hook callback.
*
* @private
*/
}, {
key: "onMouseUp",
value: function onMouseUp() {
this.listening = false;
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
(0, _get2.default)((0, _getPrototypeOf2.default)(DragToScroll.prototype), "destroy", this).call(this);
}
}]);
return DragToScroll;
}(_base.default);
(0, _plugins.registerPlugin)('dragToScroll', DragToScroll);
var _default = DragToScroll;
exports.default = _default;
/***/ }),
/* 402 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _plugins = __webpack_require__(20);
var _array = __webpack_require__(3);
var _freezeColumn = _interopRequireDefault(__webpack_require__(403));
var _unfreezeColumn = _interopRequireDefault(__webpack_require__(404));
__webpack_require__(405);
var privatePool = new WeakMap();
/**
* This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu or using API.
* You can turn it on by setting a {@link Options#manualColumnFreeze} property to `true`.
*
* @example
* ```js
* // Enables the plugin
* manualColumnFreeze: true,
* ```
*
* @plugin ManualColumnFreeze
* @dependencies ManualColumnMove
*/
var ManualColumnFreeze =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ManualColumnFreeze, _BasePlugin);
function ManualColumnFreeze(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ManualColumnFreeze);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualColumnFreeze).call(this, hotInstance));
privatePool.set((0, _assertThisInitialized2.default)(_this), {
moveByFreeze: false,
afterFirstUse: false
});
/**
* Original column positions
*
* @private
* @type {Array}
*/
_this.frozenColumnsBasePositions = [];
/**
* Reference to the `ManualColumnMove` plugin.
*
* @private
* @type {ManualColumnMove}
*/
_this.manualColumnMovePlugin = void 0;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ManualColumnFreeze#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(ManualColumnFreeze, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().manualColumnFreeze;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.addHook('afterContextMenuDefaultOptions', function (options) {
return _this2.addContextMenuEntry(options);
});
this.addHook('afterInit', function () {
return _this2.onAfterInit();
});
this.addHook('beforeColumnMove', function (rows, target) {
return _this2.onBeforeColumnMove(rows, target);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
var priv = privatePool.get(this);
priv.afterFirstUse = false;
priv.moveByFreeze = false;
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "disablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "updatePlugin", this).call(this);
}
/**
* Freezes the given column (add it to fixed columns).
*
* @param {Number} column Visual column index.
*/
}, {
key: "freezeColumn",
value: function freezeColumn(column) {
var priv = privatePool.get(this);
var settings = this.hot.getSettings();
if (!priv.afterFirstUse) {
priv.afterFirstUse = true;
}
if (settings.fixedColumnsLeft === this.hot.countCols() || column <= settings.fixedColumnsLeft - 1) {
return; // already fixed
}
priv.moveByFreeze = true;
if (column !== this.getMovePlugin().columnsMapper.getValueByIndex(column)) {
this.frozenColumnsBasePositions[settings.fixedColumnsLeft] = column;
}
this.getMovePlugin().moveColumn(column, settings.fixedColumnsLeft);
settings.fixedColumnsLeft += 1;
}
/**
* Unfreezes the given column (remove it from fixed columns and bring to it's previous position).
*
* @param {Number} column Visual column index.
*/
}, {
key: "unfreezeColumn",
value: function unfreezeColumn(column) {
var priv = privatePool.get(this);
var settings = this.hot.getSettings();
if (!priv.afterFirstUse) {
priv.afterFirstUse = true;
}
if (settings.fixedColumnsLeft <= 0 || column > settings.fixedColumnsLeft - 1) {
return; // not fixed
}
var returnCol = this.getBestColumnReturnPosition(column);
priv.moveByFreeze = true;
settings.fixedColumnsLeft -= 1;
this.getMovePlugin().moveColumn(column, returnCol + 1);
}
/**
* Gets the reference to the ManualColumnMove plugin.
*
* @private
* @returns {Object}
*/
}, {
key: "getMovePlugin",
value: function getMovePlugin() {
if (!this.manualColumnMovePlugin) {
this.manualColumnMovePlugin = this.hot.getPlugin('manualColumnMove');
}
return this.manualColumnMovePlugin;
}
/**
* Estimates the most fitting return position for unfrozen column.
*
* @private
* @param {Number} column Visual column index.
*/
}, {
key: "getBestColumnReturnPosition",
value: function getBestColumnReturnPosition(column) {
var movePlugin = this.getMovePlugin();
var settings = this.hot.getSettings();
var i = settings.fixedColumnsLeft;
var j = movePlugin.columnsMapper.getValueByIndex(i);
var initialCol;
if (this.frozenColumnsBasePositions[column] === null || this.frozenColumnsBasePositions[column] === void 0) {
initialCol = movePlugin.columnsMapper.getValueByIndex(column);
while (j !== null && j <= initialCol) {
i += 1;
j = movePlugin.columnsMapper.getValueByIndex(i);
}
} else {
initialCol = this.frozenColumnsBasePositions[column];
this.frozenColumnsBasePositions[column] = void 0;
while (j !== null && j <= initialCol) {
i += 1;
j = movePlugin.columnsMapper.getValueByIndex(i);
}
i = j;
}
return i - 1;
}
/**
* Adds the manualColumnFreeze context menu entries.
*
* @private
* @param {Object} options Context menu options.
*/
}, {
key: "addContextMenuEntry",
value: function addContextMenuEntry(options) {
options.items.push({
name: '---------'
}, (0, _freezeColumn.default)(this), (0, _unfreezeColumn.default)(this));
}
/**
* Enables `manualColumnMove` plugin on `afterInit` hook.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
if (!this.getMovePlugin().isEnabled()) {
this.getMovePlugin().enablePlugin();
}
}
/**
* Prevents moving the rows from/to fixed area.
*
* @private
* @param {Array} rows
* @param {Number} target
*/
}, {
key: "onBeforeColumnMove",
value: function onBeforeColumnMove(rows, target) {
var priv = privatePool.get(this);
if (priv.afterFirstUse && !priv.moveByFreeze) {
var frozenLen = this.hot.getSettings().fixedColumnsLeft;
var disallowMoving = target < frozenLen;
if (!disallowMoving) {
(0, _array.arrayEach)(rows, function (value) {
if (value < frozenLen) {
disallowMoving = true;
return false;
}
});
}
if (disallowMoving) {
return false;
}
}
if (priv.moveByFreeze) {
priv.moveByFreeze = false;
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnFreeze.prototype), "destroy", this).call(this);
}
}]);
return ManualColumnFreeze;
}(_base.default);
(0, _plugins.registerPlugin)('manualColumnFreeze', ManualColumnFreeze);
var _default = ManualColumnFreeze;
exports.default = _default;
/***/ }),
/* 403 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = freezeColumnItem;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
function freezeColumnItem(manualColumnFreezePlugin) {
return {
key: 'freeze_column',
name: function name() {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_FREEZE_COLUMN);
},
callback: function callback(key, selected) {
var _selected = (0, _slicedToArray2.default)(selected, 1),
selectedColumn = _selected[0].start.col;
manualColumnFreezePlugin.freezeColumn(selectedColumn);
this.render();
this.view.wt.wtOverlays.adjustElementsSize(true);
},
hidden: function hidden() {
var selection = this.getSelectedRange();
var hide = false;
if (selection === void 0) {
hide = true;
} else if (selection.length > 1) {
hide = true;
} else if (selection[0].from.col !== selection[0].to.col || selection[0].from.col <= this.getSettings().fixedColumnsLeft - 1) {
hide = true;
}
return hide;
}
};
}
/***/ }),
/* 404 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = unfreezeColumnItem;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
function unfreezeColumnItem(manualColumnFreezePlugin) {
return {
key: 'unfreeze_column',
name: function name() {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_UNFREEZE_COLUMN);
},
callback: function callback(key, selected) {
var _selected = (0, _slicedToArray2.default)(selected, 1),
selectedColumn = _selected[0].start.col;
manualColumnFreezePlugin.unfreezeColumn(selectedColumn);
this.render();
this.view.wt.wtOverlays.adjustElementsSize(true);
},
hidden: function hidden() {
var selection = this.getSelectedRange();
var hide = false;
if (selection === void 0) {
hide = true;
} else if (selection.length > 1) {
hide = true;
} else if (selection[0].from.col !== selection[0].to.col || selection[0].from.col >= this.getSettings().fixedColumnsLeft) {
hide = true;
}
return hide;
}
};
}
/***/ }),
/* 405 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 406 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _array = __webpack_require__(3);
var _element = __webpack_require__(5);
var _number = __webpack_require__(15);
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _plugins = __webpack_require__(20);
var _columnsMapper = _interopRequireDefault(__webpack_require__(407));
var _backlight = _interopRequireDefault(__webpack_require__(408));
var _guideline = _interopRequireDefault(__webpack_require__(409));
__webpack_require__(410);
_pluginHooks.default.getSingleton().register('beforeColumnMove');
_pluginHooks.default.getSingleton().register('afterColumnMove');
_pluginHooks.default.getSingleton().register('unmodifyCol');
var privatePool = new WeakMap();
var CSS_PLUGIN = 'ht__manualColumnMove';
var CSS_SHOW_UI = 'show-ui';
var CSS_ON_MOVING = 'on-moving--columns';
var CSS_AFTER_SELECTION = 'after-selection--columns';
/**
* @plugin 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.
*
* 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 rows has been moved.
*
* @class ManualColumnMove
* @plugin ManualColumnMove
*/
var ManualColumnMove =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ManualColumnMove, _BasePlugin);
function ManualColumnMove(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ManualColumnMove);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualColumnMove).call(this, hotInstance));
/**
* Set up WeakMap of plugin to sharing private parameters;
*/
privatePool.set((0, _assertThisInitialized2.default)(_this), {
columnsToMove: [],
countCols: 0,
fixedColumns: 0,
pressed: void 0,
disallowMoving: void 0,
target: {
eventPageX: void 0,
coords: void 0,
TD: void 0,
col: void 0
}
});
/**
* List of last removed row indexes.
*
* @private
* @type {Array}
*/
_this.removedColumns = [];
/**
* Object containing visual row indexes mapped to data source indexes.
*
* @private
* @type {RowsMapper}
*/
_this.columnsMapper = new _columnsMapper.default((0, _assertThisInitialized2.default)(_this));
/**
* Event Manager object.
*
* @private
* @type {Object}
*/
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
/**
* Backlight UI object.
*
* @private
* @type {Object}
*/
_this.backlight = new _backlight.default(hotInstance);
/**
* Guideline UI object.
*
* @private
* @type {Object}
*/
_this.guideline = new _guideline.default(hotInstance);
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ManualColumnMove#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(ManualColumnMove, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().manualColumnMove;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) {
return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations);
});
this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) {
return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations);
});
this.addHook('afterScrollVertically', function () {
return _this2.onAfterScrollVertically();
});
this.addHook('modifyCol', function (row, source) {
return _this2.onModifyCol(row, source);
});
this.addHook('beforeRemoveCol', function (index, amount) {
return _this2.onBeforeRemoveCol(index, amount);
});
this.addHook('afterRemoveCol', function () {
return _this2.onAfterRemoveCol();
});
this.addHook('afterCreateCol', function (index, amount) {
return _this2.onAfterCreateCol(index, amount);
});
this.addHook('afterLoadData', function () {
return _this2.onAfterLoadData();
});
this.addHook('unmodifyCol', function (column) {
return _this2.onUnmodifyCol(column);
});
this.registerEvents(); // TODO: move adding plugin classname to BasePlugin.
(0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN);
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
this.onAfterPluginsInitialized();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
var pluginSettings = this.hot.getSettings().manualColumnMove;
if (Array.isArray(pluginSettings)) {
this.columnsMapper.clearMap();
}
(0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN);
this.unregisterEvents();
this.backlight.destroy();
this.guideline.destroy();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "disablePlugin", this).call(this);
}
/**
* Moves a single column.
*
* @param {Number} column Visual column index to be moved.
* @param {Number} target Visual column index being a target for the moved column.
* @fires Hooks#beforeColumnMove
* @fires Hooks#afterColumnMove
*/
}, {
key: "moveColumn",
value: function moveColumn(column, target) {
this.moveColumns([column], target);
}
/**
* Moves a multiple columns.
*
* @param {Array} columns Array of visual column indexes to be moved.
* @param {Number} target Visual column index being a target for the moved columns.
* @fires Hooks#beforeColumnMove
* @fires Hooks#afterColumnMove
*/
}, {
key: "moveColumns",
value: function moveColumns(columns, target) {
var _this3 = this;
var visualColumns = (0, _toConsumableArray2.default)(columns);
var priv = privatePool.get(this);
var beforeColumnHook = this.hot.runHooks('beforeColumnMove', visualColumns, target);
priv.disallowMoving = !beforeColumnHook;
if (beforeColumnHook !== false) {
// first we need to rewrite an visual indexes to physical for save reference after move
(0, _array.arrayEach)(columns, function (column, index, array) {
array[index] = _this3.columnsMapper.getValueByIndex(column);
}); // next, when we have got an physical indexes, we can move columns
(0, _array.arrayEach)(columns, function (column, index) {
var actualPosition = _this3.columnsMapper.getIndexByValue(column);
if (actualPosition !== target) {
_this3.columnsMapper.moveColumn(actualPosition, target + index);
}
}); // after moving we have to clear columnsMapper from null entries
this.columnsMapper.clearNull();
}
this.hot.runHooks('afterColumnMove', visualColumns, target);
}
/**
* Correct the cell selection after the move action. Fired only when action was made with a mouse.
* That means that changing the column order using the API won't correct the selection.
*
* @private
* @param {Number} startColumn Visual column index for the start of the selection.
* @param {Number} endColumn Visual column index for the end of the selection.
*/
}, {
key: "changeSelection",
value: function changeSelection(startColumn, endColumn) {
this.hot.selectColumns(startColumn, endColumn);
}
/**
* Gets the sum of the widths of columns in the provided range.
*
* @private
* @param {Number} from Visual column index.
* @param {Number} to Visual column index.
* @returns {Number}
*/
}, {
key: "getColumnsWidth",
value: function getColumnsWidth(from, to) {
var width = 0;
for (var i = from; i < to; i++) {
var columnWidth = 0;
if (i < 0) {
columnWidth = this.hot.view.wt.wtViewport.getRowHeaderWidth() || 0;
} else {
columnWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(i) || 0;
}
width += columnWidth;
}
return width;
}
/**
* Loads initial settings when persistent state is saved or when plugin was initialized as an array.
*
* @private
*/
}, {
key: "initialSettings",
value: function initialSettings() {
var pluginSettings = this.hot.getSettings().manualColumnMove;
if (Array.isArray(pluginSettings)) {
this.moveColumns(pluginSettings, 0);
} else if (pluginSettings !== void 0) {
this.persistentStateLoad();
}
}
/**
* Checks if the provided column is in the fixedColumnsLeft section.
*
* @private
* @param {Number} column Visual column index to check.
* @returns {Boolean}
*/
}, {
key: "isFixedColumnsLeft",
value: function isFixedColumnsLeft(column) {
return column < this.hot.getSettings().fixedColumnsLeft;
}
/**
* Saves the manual column positions to the persistent state (the {@link Options#persistentState} option has to be enabled).
*/
}, {
key: "persistentStateSave",
value: function persistentStateSave() {
this.hot.runHooks('persistentStateSave', 'manualColumnMove', this.columnsMapper._arrayMap);
}
/**
* Loads the manual column positions from the persistent state (the {@link Options#persistentState} option has to be enabled).
*/
}, {
key: "persistentStateLoad",
value: function persistentStateLoad() {
var storedState = {};
this.hot.runHooks('persistentStateLoad', 'manualColumnMove', storedState);
if (storedState.value) {
this.columnsMapper._arrayMap = storedState.value;
}
}
/**
* Prepares an array of indexes based on actual selection.
*
* @private
* @returns {Array}
*/
}, {
key: "prepareColumnsToMoving",
value: function prepareColumnsToMoving(start, end) {
var selectedColumns = [];
(0, _number.rangeEach)(start, end, function (i) {
selectedColumns.push(i);
});
return selectedColumns;
}
/**
* Updates the UI visual position.
*
* @private
*/
}, {
key: "refreshPositions",
value: function refreshPositions() {
var priv = privatePool.get(this);
var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleColumn();
var lastVisible = this.hot.view.wt.wtTable.getLastVisibleColumn();
var wtTable = this.hot.view.wt.wtTable;
var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement;
var scrollLeft = typeof scrollableElement.scrollX === 'number' ? scrollableElement.scrollX : scrollableElement.scrollLeft;
var tdOffsetLeft = this.hot.view.THEAD.offsetLeft + this.getColumnsWidth(0, priv.coordsColumn);
var mouseOffsetLeft = priv.target.eventPageX - (priv.rootElementOffset - (scrollableElement.scrollX === void 0 ? scrollLeft : 0));
var hiderWidth = wtTable.hider.offsetWidth;
var tbodyOffsetLeft = wtTable.TBODY.offsetLeft;
var backlightElemMarginLeft = this.backlight.getOffset().left;
var backlightElemWidth = this.backlight.getSize().width;
var rowHeaderWidth = 0;
if (priv.rootElementOffset + wtTable.holder.offsetWidth + scrollLeft < priv.target.eventPageX) {
if (priv.coordsColumn < priv.countCols) {
priv.coordsColumn += 1;
}
}
if (priv.hasRowHeaders) {
rowHeaderWidth = this.hot.view.wt.wtOverlays.leftOverlay.clone.wtTable.getColumnHeader(-1).offsetWidth;
}
if (this.isFixedColumnsLeft(priv.coordsColumn)) {
tdOffsetLeft += scrollLeft;
}
tdOffsetLeft += rowHeaderWidth;
if (priv.coordsColumn < 0) {
// if hover on rowHeader
if (priv.fixedColumns > 0) {
priv.target.col = 0;
} else {
priv.target.col = firstVisible > 0 ? firstVisible - 1 : firstVisible;
}
} else if (priv.target.TD.offsetWidth / 2 + tdOffsetLeft <= mouseOffsetLeft) {
var newCoordsCol = priv.coordsColumn >= priv.countCols ? priv.countCols - 1 : priv.coordsColumn; // if hover on right part of TD
priv.target.col = newCoordsCol + 1; // unfortunately first column is bigger than rest
tdOffsetLeft += priv.target.TD.offsetWidth;
if (priv.target.col > lastVisible && lastVisible < priv.countCols) {
this.hot.scrollViewportTo(void 0, lastVisible + 1, void 0, true);
}
} else {
// elsewhere on table
priv.target.col = priv.coordsColumn;
if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns && firstVisible > 0) {
this.hot.scrollViewportTo(void 0, firstVisible - 1);
}
}
if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns && firstVisible > 0) {
this.hot.scrollViewportTo(void 0, firstVisible - 1);
}
var backlightLeft = mouseOffsetLeft;
var guidelineLeft = tdOffsetLeft;
if (mouseOffsetLeft + backlightElemWidth + backlightElemMarginLeft >= hiderWidth) {
// prevent display backlight on the right side of the table
backlightLeft = hiderWidth - backlightElemWidth - backlightElemMarginLeft;
} else if (mouseOffsetLeft + backlightElemMarginLeft < tbodyOffsetLeft + rowHeaderWidth) {
// prevent display backlight on the left side of the table
backlightLeft = tbodyOffsetLeft + rowHeaderWidth + Math.abs(backlightElemMarginLeft);
}
if (tdOffsetLeft >= hiderWidth - 1) {
// prevent display guideline outside the table
guidelineLeft = hiderWidth - 1;
} else if (guidelineLeft === 0) {
// guideline has got `margin-left: -1px` as default
guidelineLeft = 1;
} else if (scrollableElement.scrollX !== void 0 && priv.coordsColumn < priv.fixedColumns) {
guidelineLeft -= priv.rootElementOffset <= scrollableElement.scrollX ? priv.rootElementOffset : 0;
}
this.backlight.setPosition(null, backlightLeft);
this.guideline.setPosition(null, guidelineLeft);
}
/**
* This method checks arrayMap from columnsMapper and updates the columnsMapper if it's necessary.
*
* @private
*/
}, {
key: "updateColumnsMapper",
value: function updateColumnsMapper() {
var countCols = this.hot.countSourceCols();
var columnsMapperLen = this.columnsMapper._arrayMap.length;
if (columnsMapperLen === 0) {
this.columnsMapper.createMap(countCols || this.hot.getSettings().startCols);
} else if (columnsMapperLen < countCols) {
var diff = countCols - columnsMapperLen;
this.columnsMapper.insertItems(columnsMapperLen, diff);
} else if (columnsMapperLen > countCols) {
var maxIndex = countCols - 1;
var columnsToRemove = [];
(0, _array.arrayEach)(this.columnsMapper._arrayMap, function (value, index) {
if (value > maxIndex) {
columnsToRemove.push(index);
}
});
this.columnsMapper.removeItems(columnsToRemove);
}
}
/**
* Binds the events used by the plugin.
*
* @private
*/
}, {
key: "registerEvents",
value: function registerEvents() {
var _this4 = this;
var documentElement = this.hot.rootDocument.documentElement;
this.eventManager.addEventListener(documentElement, 'mousemove', function (event) {
return _this4.onMouseMove(event);
});
this.eventManager.addEventListener(documentElement, 'mouseup', function () {
return _this4.onMouseUp();
});
}
/**
* Unbinds the events used by the plugin.
*
* @private
*/
}, {
key: "unregisterEvents",
value: function unregisterEvents() {
this.eventManager.clear();
}
/**
* Changes the behavior of selection / dragging.
*
* @private
* @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} blockCalculations Object which contains information about blockCalculation for row, column or cells.
*/
}, {
key: "onBeforeOnCellMouseDown",
value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) {
var wtTable = this.hot.view.wt.wtTable;
var isHeaderSelection = this.hot.selection.isSelectedByColumnHeader();
var selection = this.hot.getSelectedRangeLast();
var priv = privatePool.get(this); // This block action shouldn't be handled below.
var isSortingElement = event.realTarget.className.indexOf('sortAction') > -1;
if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0 || isSortingElement) {
priv.pressed = false;
priv.columnsToMove.length = 0;
(0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]);
return;
}
var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended();
var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended();
if (guidelineIsNotReady && backlightIsNotReady) {
this.guideline.appendTo(wtTable.hider);
this.backlight.appendTo(wtTable.hider);
}
var from = selection.from,
to = selection.to;
var start = Math.min(from.col, to.col);
var end = Math.max(from.col, to.col);
if (coords.row < 0 && coords.col >= start && coords.col <= end) {
blockCalculations.column = true;
priv.pressed = true;
priv.target.eventPageX = event.pageX;
priv.coordsColumn = coords.col;
priv.target.TD = TD;
priv.target.col = coords.col;
priv.columnsToMove = this.prepareColumnsToMoving(start, end);
priv.hasRowHeaders = !!this.hot.getSettings().rowHeaders;
priv.countCols = this.hot.countCols();
priv.fixedColumns = this.hot.getSettings().fixedColumnsLeft;
priv.rootElementOffset = (0, _element.offset)(this.hot.rootElement).left;
var countColumnsFrom = priv.hasRowHeaders ? -1 : 0;
var topPos = wtTable.holder.scrollTop + wtTable.getColumnHeaderHeight(0) + 1;
var fixedColumns = coords.col < priv.fixedColumns;
var scrollableElement = this.hot.view.wt.wtOverlays.scrollableElement;
var wrapperIsWindow = scrollableElement.scrollX ? scrollableElement.scrollX - priv.rootElementOffset : 0;
var mouseOffset = event.layerX - (fixedColumns ? wrapperIsWindow : 0);
var leftOffset = Math.abs(this.getColumnsWidth(start, coords.col) + mouseOffset);
this.backlight.setPosition(topPos, this.getColumnsWidth(countColumnsFrom, start) + leftOffset);
this.backlight.setSize(this.getColumnsWidth(start, end + 1), wtTable.hider.offsetHeight - topPos);
this.backlight.setOffset(null, leftOffset * -1);
(0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING);
} else {
(0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
priv.pressed = false;
priv.columnsToMove.length = 0;
}
}
/**
* 'mouseMove' event callback. Fired when pointer move on document.documentElement.
*
* @private
* @param {MouseEvent} event `mousemove` event properties.
*/
}, {
key: "onMouseMove",
value: function onMouseMove(event) {
var priv = privatePool.get(this);
if (!priv.pressed) {
return;
} // callback for browser which doesn't supports CSS pointer-event: none
if (event.realTarget === this.backlight.element) {
var width = this.backlight.getSize().width;
this.backlight.setSize(0);
setTimeout(function () {
this.backlight.setPosition(width);
});
}
priv.target.eventPageX = event.pageX;
this.refreshPositions();
}
/**
* 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell.
*
* @private
* @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} blockCalculations Object which contains information about blockCalculation for row, column or cells.
*/
}, {
key: "onBeforeOnCellMouseOver",
value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) {
var selectedRange = this.hot.getSelectedRangeLast();
var priv = privatePool.get(this);
if (!selectedRange || !priv.pressed) {
return;
}
if (priv.columnsToMove.indexOf(coords.col) > -1) {
(0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI);
} else {
(0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI);
}
blockCalculations.row = true;
blockCalculations.column = true;
blockCalculations.cell = true;
priv.coordsColumn = coords.col;
priv.target.TD = TD;
}
/**
* `onMouseUp` hook callback.
*
* @private
*/
}, {
key: "onMouseUp",
value: function onMouseUp() {
var priv = privatePool.get(this);
priv.coordsColumn = void 0;
priv.pressed = false;
priv.backlightWidth = 0;
(0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]);
if (this.hot.selection.isSelectedByColumnHeader()) {
(0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
}
if (priv.columnsToMove.length < 1 || priv.target.col === void 0 || priv.columnsToMove.indexOf(priv.target.col) > -1) {
return;
}
this.moveColumns(priv.columnsToMove, priv.target.col);
this.persistentStateSave();
this.hot.render();
this.hot.view.wt.wtOverlays.adjustElementsSize(true);
if (!priv.disallowMoving) {
var selectionStart = this.columnsMapper.getIndexByValue(priv.columnsToMove[0]);
var selectionEnd = this.columnsMapper.getIndexByValue(priv.columnsToMove[priv.columnsToMove.length - 1]);
this.changeSelection(selectionStart, selectionEnd);
}
priv.columnsToMove.length = 0;
}
/**
* `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally.
*
* @private
*/
}, {
key: "onAfterScrollVertically",
value: function onAfterScrollVertically() {
var wtTable = this.hot.view.wt.wtTable;
var headerHeight = wtTable.getColumnHeaderHeight(0) + 1;
var scrollTop = wtTable.holder.scrollTop;
var posTop = headerHeight + scrollTop;
this.backlight.setPosition(posTop);
this.backlight.setSize(null, wtTable.hider.offsetHeight - posTop);
}
/**
* `afterCreateCol` hook callback.
*
* @private
* @param {Number} index Visual index of the created column.
* @param {Number} amount Amount of created columns.
*/
}, {
key: "onAfterCreateCol",
value: function onAfterCreateCol(index, amount) {
this.columnsMapper.shiftItems(index, amount);
}
/**
* On before remove column listener.
*
* @private
* @param {Number} index Visual column index.
* @param {Number} amount Defines how many columns removed.
*/
}, {
key: "onBeforeRemoveCol",
value: function onBeforeRemoveCol(index, amount) {
var _this5 = this;
this.removedColumns.length = 0;
if (index !== false) {
// Collect physical row index.
(0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
_this5.removedColumns.push(_this5.hot.runHooks('modifyCol', removedIndex, _this5.pluginName));
});
}
}
/**
* `afterRemoveCol` hook callback.
*
* @private
*/
}, {
key: "onAfterRemoveCol",
value: function onAfterRemoveCol() {
this.columnsMapper.unshiftItems(this.removedColumns);
}
/**
* `afterLoadData` hook callback.
*
* @private
*/
}, {
key: "onAfterLoadData",
value: function onAfterLoadData() {
this.updateColumnsMapper();
}
/**
* 'modifyRow' hook callback.
*
* @private
* @param {Number} column Visual column index.
* @returns {Number} Physical column index.
*/
}, {
key: "onModifyCol",
value: function onModifyCol(column, source) {
var physicalColumn = column;
if (source !== this.pluginName) {
// ugly fix for try to insert new, needed columns after pasting data
var columnInMapper = this.columnsMapper.getValueByIndex(physicalColumn);
physicalColumn = columnInMapper === null ? physicalColumn : columnInMapper;
}
return physicalColumn;
}
/**
* 'unmodifyCol' hook callback.
*
* @private
* @param {Number} column Physical column index.
* @returns {Number} Visual column index.
*/
}, {
key: "onUnmodifyCol",
value: function onUnmodifyCol(column) {
var indexInMapper = this.columnsMapper.getIndexByValue(column);
return indexInMapper === null ? column : indexInMapper;
}
/**
* `afterPluginsInitialized` hook callback.
*
* @private
*/
}, {
key: "onAfterPluginsInitialized",
value: function onAfterPluginsInitialized() {
this.updateColumnsMapper();
this.initialSettings();
this.backlight.build();
this.guideline.build();
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.backlight.destroy();
this.guideline.destroy();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnMove.prototype), "destroy", this).call(this);
}
}]);
return ManualColumnMove;
}(_base.default);
(0, _plugins.registerPlugin)('ManualColumnMove', ManualColumnMove);
var _default = ManualColumnMove;
exports.default = _default;
/***/ }),
/* 407 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(33);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _arrayMapper = _interopRequireDefault(__webpack_require__(91));
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var _number = __webpack_require__(15);
/**
* @class ColumnsMapper
* @plugin ManualColumnMove
*/
var ColumnsMapper =
/*#__PURE__*/
function () {
function ColumnsMapper(manualColumnMove) {
(0, _classCallCheck2.default)(this, ColumnsMapper);
/**
* Instance of ManualColumnMove plugin.
*
* @type {ManualColumnMove}
*/
this.manualColumnMove = manualColumnMove;
}
/**
* Reset current map array and create new one.
*
* @param {Number} [length] Custom generated map length.
*/
(0, _createClass2.default)(ColumnsMapper, [{
key: "createMap",
value: function createMap(length) {
var _this = this;
var originLength = length === void 0 ? this._arrayMap.length : length;
this._arrayMap.length = 0;
(0, _number.rangeEach)(originLength - 1, function (itemIndex) {
_this._arrayMap[itemIndex] = itemIndex;
});
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
this._arrayMap = null;
}
/**
* Moving elements in columnsMapper.
*
* @param {Number} from Column index to move.
* @param {Number} to Target index.
*/
}, {
key: "moveColumn",
value: function moveColumn(from, to) {
var indexToMove = this._arrayMap[from];
this._arrayMap[from] = null;
this._arrayMap.splice(to, 0, indexToMove);
}
/**
* Clearing arrayMap from `null` entries.
*/
}, {
key: "clearNull",
value: function clearNull() {
this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) {
return i !== null;
});
}
}]);
return ColumnsMapper;
}();
(0, _object.mixin)(ColumnsMapper, _arrayMapper.default);
var _default = ColumnsMapper;
exports.default = _default;
/***/ }),
/* 408 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(242));
var _element = __webpack_require__(5);
var CSS_CLASSNAME = 'ht__manualColumnMove--backlight';
/**
* @class BacklightUI
* @util
*/
var BacklightUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(BacklightUI, _BaseUI);
function BacklightUI() {
(0, _classCallCheck2.default)(this, BacklightUI);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BacklightUI).apply(this, arguments));
}
(0, _createClass2.default)(BacklightUI, [{
key: "build",
/**
* Custom className on build process.
*/
value: function build() {
(0, _get2.default)((0, _getPrototypeOf2.default)(BacklightUI.prototype), "build", this).call(this);
(0, _element.addClass)(this._element, CSS_CLASSNAME);
}
}]);
return BacklightUI;
}(_base.default);
var _default = BacklightUI;
exports.default = _default;
/***/ }),
/* 409 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(242));
var _element = __webpack_require__(5);
var CSS_CLASSNAME = 'ht__manualColumnMove--guideline';
/**
* @class GuidelineUI
* @util
*/
var GuidelineUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(GuidelineUI, _BaseUI);
function GuidelineUI() {
(0, _classCallCheck2.default)(this, GuidelineUI);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(GuidelineUI).apply(this, arguments));
}
(0, _createClass2.default)(GuidelineUI, [{
key: "build",
/**
* Custom className on build process.
*/
value: function build() {
(0, _get2.default)((0, _getPrototypeOf2.default)(GuidelineUI.prototype), "build", this).call(this);
(0, _element.addClass)(this._element, CSS_CLASSNAME);
}
}]);
return GuidelineUI;
}(_base.default);
var _default = GuidelineUI;
exports.default = _default;
/***/ }),
/* 410 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 411 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _element = __webpack_require__(5);
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _event = __webpack_require__(31);
var _array = __webpack_require__(3);
var _number = __webpack_require__(15);
var _plugins = __webpack_require__(20);
// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js
/**
* @description
* This plugin allows to change columns width. To make columns width persistent the {@link Options#persistentState}
* plugin should be enabled.
*
* The plugin creates additional components to make resizing possibly using user interface:
* - handle - the draggable element that sets the desired width of the column.
* - guide - the helper guide that shows the desired width as a vertical guide.
*
* @plugin ManualColumnResize
*/
var ManualColumnResize =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ManualColumnResize, _BasePlugin);
function ManualColumnResize(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ManualColumnResize);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualColumnResize).call(this, hotInstance));
var rootDocument = _this.hot.rootDocument;
_this.currentTH = null;
_this.currentCol = null;
_this.selectedCols = [];
_this.currentWidth = null;
_this.newSize = null;
_this.startY = null;
_this.startWidth = null;
_this.startOffset = null;
_this.handle = rootDocument.createElement('DIV');
_this.guide = rootDocument.createElement('DIV');
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
_this.pressed = null;
_this.dblclick = 0;
_this.autoresizeTimeout = null;
_this.manualColumnWidths = [];
(0, _element.addClass)(_this.handle, 'manualColumnResizer');
(0, _element.addClass)(_this.guide, 'manualColumnResizerGuide');
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ManualColumnResize#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(ManualColumnResize, [{
key: "isEnabled",
value: function isEnabled() {
return this.hot.getSettings().manualColumnResize;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.manualColumnWidths = [];
var initialColumnWidth = this.hot.getSettings().manualColumnResize;
var loadedManualColumnWidths = this.loadManualColumnWidths();
this.addHook('modifyColWidth', function (width, col) {
return _this2.onModifyColWidth(width, col);
});
this.addHook('beforeStretchingColumnWidth', function (stretchedWidth, column) {
return _this2.onBeforeStretchingColumnWidth(stretchedWidth, column);
});
this.addHook('beforeColumnResize', function (currentColumn, newSize, isDoubleClick) {
return _this2.onBeforeColumnResize(currentColumn, newSize, isDoubleClick);
});
if (typeof loadedManualColumnWidths !== 'undefined') {
this.manualColumnWidths = loadedManualColumnWidths;
} else if (Array.isArray(initialColumnWidth)) {
this.manualColumnWidths = initialColumnWidth;
} else {
this.manualColumnWidths = [];
} // Handsontable.hooks.register('beforeColumnResize');
// Handsontable.hooks.register('afterColumnResize');
this.bindEvents();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnResize.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
var initialColumnWidth = this.hot.getSettings().manualColumnResize;
if (Array.isArray(initialColumnWidth)) {
this.manualColumnWidths = initialColumnWidth;
} else if (!initialColumnWidth) {
this.manualColumnWidths = [];
}
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualColumnResize.prototype), "disablePlugin", this).call(this);
}
/**
* Saves the current sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
*/
}, {
key: "saveManualColumnWidths",
value: function saveManualColumnWidths() {
this.hot.runHooks('persistentStateSave', 'manualColumnWidths', this.manualColumnWidths);
}
/**
* Loads the previously saved sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
*
* @returns {Array}
*
* @fires Hooks#persistentStateLoad
* @fires Hooks#manualColumnWidths
*/
}, {
key: "loadManualColumnWidths",
value: function loadManualColumnWidths() {
var storedState = {};
this.hot.runHooks('persistentStateLoad', 'manualColumnWidths', storedState);
return storedState.value;
}
/**
* Set the resize handle position.
*
* @private
* @param {HTMLCellElement} TH TH HTML element.
*/
}, {
key: "setupHandlePosition",
value: function setupHandlePosition(TH) {
var _this3 = this;
if (!TH.parentNode) {
return false;
}
this.currentTH = TH;
var cellCoords = this.hot.view.wt.wtTable.getCoords(this.currentTH);
var col = cellCoords.col;
var headerHeight = (0, _element.outerHeight)(this.currentTH);
if (col >= 0) {
// if col header
var box = this.currentTH.getBoundingClientRect();
var fixedColumn = col < this.hot.getSettings().fixedColumnsLeft;
var parentOverlay = fixedColumn ? this.hot.view.wt.wtOverlays.topLeftCornerOverlay : this.hot.view.wt.wtOverlays.topOverlay;
var relativeHeaderPosition = parentOverlay.getRelativeCellPosition(this.currentTH, cellCoords.row, cellCoords.col); // If the TH is not a child of the top/top-left overlay, recalculate using the top-most header
if (!relativeHeaderPosition) {
var topMostHeader = parentOverlay.clone.wtTable.THEAD.lastChild.children[+!!this.hot.getSettings().rowHeaders + col];
relativeHeaderPosition = parentOverlay.getRelativeCellPosition(topMostHeader, cellCoords.row, cellCoords.col);
}
this.currentCol = col;
this.selectedCols = [];
if (this.hot.selection.isSelected() && this.hot.selection.isSelectedByColumnHeader()) {
var _this$hot$getSelected = this.hot.getSelectedRangeLast(),
from = _this$hot$getSelected.from,
to = _this$hot$getSelected.to;
var start = from.col;
var end = to.col;
if (start >= end) {
start = to.col;
end = from.col;
}
if (this.currentCol >= start && this.currentCol <= end) {
(0, _number.rangeEach)(start, end, function (i) {
return _this3.selectedCols.push(i);
});
} else {
this.selectedCols.push(this.currentCol);
}
} else {
this.selectedCols.push(this.currentCol);
}
this.startOffset = relativeHeaderPosition.left - 6;
this.startWidth = parseInt(box.width, 10);
this.handle.style.top = "".concat(relativeHeaderPosition.top, "px");
this.handle.style.left = "".concat(this.startOffset + this.startWidth, "px");
this.handle.style.height = "".concat(headerHeight, "px");
this.hot.rootElement.appendChild(this.handle);
}
}
/**
* Refresh the resize handle position.
*
* @private
*/
}, {
key: "refreshHandlePosition",
value: function refreshHandlePosition() {
this.handle.style.left = "".concat(this.startOffset + this.currentWidth, "px");
}
/**
* Sets the resize guide position.
*
* @private
*/
}, {
key: "setupGuidePosition",
value: function setupGuidePosition() {
var handleHeight = parseInt((0, _element.outerHeight)(this.handle), 10);
var handleBottomPosition = parseInt(this.handle.style.top, 10) + handleHeight;
var maximumVisibleElementHeight = parseInt(this.hot.view.maximumVisibleElementHeight(0), 10);
(0, _element.addClass)(this.handle, 'active');
(0, _element.addClass)(this.guide, 'active');
this.guide.style.top = "".concat(handleBottomPosition, "px");
this.guide.style.left = this.handle.style.left;
this.guide.style.height = "".concat(maximumVisibleElementHeight - handleHeight, "px");
this.hot.rootElement.appendChild(this.guide);
}
/**
* Refresh the resize guide position.
*
* @private
*/
}, {
key: "refreshGuidePosition",
value: function refreshGuidePosition() {
this.guide.style.left = this.handle.style.left;
}
/**
* Hides both the resize handle and resize guide.
*
* @private
*/
}, {
key: "hideHandleAndGuide",
value: function hideHandleAndGuide() {
(0, _element.removeClass)(this.handle, 'active');
(0, _element.removeClass)(this.guide, 'active');
}
/**
* Checks if provided element is considered a column header.
*
* @private
* @param {HTMLElement} element HTML element.
* @returns {Boolean}
*/
}, {
key: "checkIfColumnHeader",
value: function checkIfColumnHeader(element) {
if (element !== this.hot.rootElement) {
var parent = element.parentNode;
if (parent.tagName === 'THEAD') {
return true;
}
return this.checkIfColumnHeader(parent);
}
return false;
}
/**
* Gets the TH element from the provided element.
*
* @private
* @param {HTMLElement} element HTML element.
* @returns {HTMLElement}
*/
}, {
key: "getTHFromTargetElement",
value: function getTHFromTargetElement(element) {
if (element.tagName !== 'TABLE') {
if (element.tagName === 'TH') {
return element;
}
return this.getTHFromTargetElement(element.parentNode);
}
return null;
}
/**
* 'mouseover' event callback - set the handle position.
*
* @private
* @param {MouseEvent} event
*/
}, {
key: "onMouseOver",
value: function onMouseOver(event) {
if (this.checkIfColumnHeader(event.target)) {
var th = this.getTHFromTargetElement(event.target);
if (!th) {
return;
}
var colspan = th.getAttribute('colspan');
if (th && (colspan === null || colspan === 1)) {
if (!this.pressed) {
this.setupHandlePosition(th);
}
}
}
}
/**
* Auto-size row after doubleclick - callback.
*
* @private
*
* @fires Hooks#beforeColumnResize
* @fires Hooks#afterColumnResize
*/
}, {
key: "afterMouseDownTimeout",
value: function afterMouseDownTimeout() {
var _this4 = this;
var render = function render() {
_this4.hot.forceFullRender = true;
_this4.hot.view.render(); // updates all
_this4.hot.view.wt.wtOverlays.adjustElementsSize(true);
};
var resize = function resize(selectedCol, forceRender) {
var hookNewSize = _this4.hot.runHooks('beforeColumnResize', selectedCol, _this4.newSize, true);
if (hookNewSize !== void 0) {
_this4.newSize = hookNewSize;
}
if (_this4.hot.getSettings().stretchH === 'all') {
_this4.clearManualSize(selectedCol);
} else {
_this4.setManualSize(selectedCol, _this4.newSize); // double click sets by auto row size plugin
}
if (forceRender) {
render();
}
_this4.saveManualColumnWidths();
_this4.hot.runHooks('afterColumnResize', selectedCol, _this4.newSize, true);
};
if (this.dblclick >= 2) {
var selectedColsLength = this.selectedCols.length;
if (selectedColsLength > 1) {
(0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
resize(selectedCol);
});
render();
} else {
(0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
resize(selectedCol, true);
});
}
}
this.dblclick = 0;
this.autoresizeTimeout = null;
}
/**
* 'mousedown' event callback.
*
* @private
* @param {MouseEvent} event
*/
}, {
key: "onMouseDown",
value: function onMouseDown(event) {
var _this5 = this;
if ((0, _element.hasClass)(event.target, 'manualColumnResizer')) {
this.setupGuidePosition();
this.pressed = this.hot;
if (this.autoresizeTimeout === null) {
this.autoresizeTimeout = setTimeout(function () {
return _this5.afterMouseDownTimeout();
}, 500);
this.hot._registerTimeout(this.autoresizeTimeout);
}
this.dblclick += 1;
this.startX = (0, _event.pageX)(event);
this.newSize = this.startWidth;
}
}
/**
* 'mousemove' event callback - refresh the handle and guide positions, cache the new column width.
*
* @private
* @param {MouseEvent} event
*/
}, {
key: "onMouseMove",
value: function onMouseMove(event) {
var _this6 = this;
if (this.pressed) {
this.currentWidth = this.startWidth + ((0, _event.pageX)(event) - this.startX);
(0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
_this6.newSize = _this6.setManualSize(selectedCol, _this6.currentWidth);
});
this.refreshHandlePosition();
this.refreshGuidePosition();
}
}
/**
* 'mouseup' event callback - apply the column resizing.
*
* @private
*
* @fires Hooks#beforeColumnResize
* @fires Hooks#afterColumnResize
*/
}, {
key: "onMouseUp",
value: function onMouseUp() {
var _this7 = this;
var render = function render() {
_this7.hot.forceFullRender = true;
_this7.hot.view.render(); // updates all
_this7.hot.view.wt.wtOverlays.adjustElementsSize(true);
};
var resize = function resize(selectedCol, forceRender) {
_this7.hot.runHooks('beforeColumnResize', selectedCol, _this7.newSize, false);
if (forceRender) {
render();
}
_this7.saveManualColumnWidths();
_this7.hot.runHooks('afterColumnResize', selectedCol, _this7.newSize);
};
if (this.pressed) {
this.hideHandleAndGuide();
this.pressed = false;
if (this.newSize !== this.startWidth) {
var selectedColsLength = this.selectedCols.length;
if (selectedColsLength > 1) {
(0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
resize(selectedCol);
});
render();
} else {
(0, _array.arrayEach)(this.selectedCols, function (selectedCol) {
resize(selectedCol, true);
});
}
}
this.setupHandlePosition(this.currentTH);
}
}
/**
* Binds the mouse events.
*
* @private
*/
}, {
key: "bindEvents",
value: function bindEvents() {
var _this8 = this;
var _this$hot = this.hot,
rootWindow = _this$hot.rootWindow,
rootElement = _this$hot.rootElement;
this.eventManager.addEventListener(rootElement, 'mouseover', function (e) {
return _this8.onMouseOver(e);
});
this.eventManager.addEventListener(rootElement, 'mousedown', function (e) {
return _this8.onMouseDown(e);
});
this.eventManager.addEventListener(rootWindow, 'mousemove', function (e) {
return _this8.onMouseMove(e);
});
this.eventManager.addEventListener(rootWindow, 'mouseup', function () {
return _this8.onMouseUp();
});
}
/**
* Sets the new width for specified column index.
*
* @param {Number} column Visual column index.
* @param {Number} width Column width (no less than 20px).
* @returns {Number} Returns new width.
*/
}, {
key: "setManualSize",
value: function setManualSize(column, width) {
var newWidth = Math.max(width, 20);
/**
* We need to run col through modifyCol hook, in case the order of displayed columns is different than the order
* in data source. For instance, this order can be modified by manualColumnMove plugin.
*/
var physicalColumn = this.hot.runHooks('modifyCol', column);
this.manualColumnWidths[physicalColumn] = newWidth;
return newWidth;
}
/**
* Clears the cache for the specified column index.
*
* @param {Number} column Visual column index.
*/
}, {
key: "clearManualSize",
value: function clearManualSize(column) {
var physicalColumn = this.hot.runHooks('modifyCol', column);
this.manualColumnWidths[physicalColumn] = void 0;
}
/**
* Modifies the provided column width, based on the plugin settings
*
* @private
* @param {Number} width Column width.
* @param {Number} column Visual column index.
* @returns {Number}
*/
}, {
key: "onModifyColWidth",
value: function onModifyColWidth(width, column) {
var newWidth = width;
if (this.enabled) {
var physicalColumn = this.hot.runHooks('modifyCol', column);
var columnWidth = this.manualColumnWidths[physicalColumn];
if (this.hot.getSettings().manualColumnResize && columnWidth) {
newWidth = columnWidth;
}
}
return newWidth;
}
/**
* Modifies the provided column stretched width. This hook decides if specified column should be stretched or not.
*
* @private
* @param {Number} stretchedWidth Stretched width.
* @param {Number} column Physical column index.
* @returns {Number}
*/
}, {
key: "onBeforeStretchingColumnWidth",
value: function onBeforeStretchingColumnWidth(stretchedWidth, column) {
var width = this.manualColumnWidths[column];
if (width === void 0) {
width = stretchedWidth;
}
return width;
}
/**
* `beforeColumnResize` hook callback.
*
* @private
*/
}, {
key: "onBeforeColumnResize",
value: function onBeforeColumnResize() {
// clear the header height cache information
this.hot.view.wt.wtViewport.hasOversizedColumnHeadersMarked = {};
}
}]);
return ManualColumnResize;
}(_base.default);
(0, _plugins.registerPlugin)('manualColumnResize', ManualColumnResize);
var _default = ManualColumnResize;
exports.default = _default;
/***/ }),
/* 412 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _array = __webpack_require__(3);
var _element = __webpack_require__(5);
var _number = __webpack_require__(15);
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _plugins = __webpack_require__(20);
var _rowsMapper = _interopRequireDefault(__webpack_require__(413));
var _backlight = _interopRequireDefault(__webpack_require__(414));
var _guideline = _interopRequireDefault(__webpack_require__(415));
__webpack_require__(416);
_pluginHooks.default.getSingleton().register('beforeRowMove');
_pluginHooks.default.getSingleton().register('afterRowMove');
_pluginHooks.default.getSingleton().register('unmodifyRow');
var privatePool = new WeakMap();
var CSS_PLUGIN = 'ht__manualRowMove';
var CSS_SHOW_UI = 'show-ui';
var CSS_ON_MOVING = 'on-moving--rows';
var CSS_AFTER_SELECTION = 'after-selection--rows';
/**
* @plugin ManualRowMove
*
* @description
* This plugin allows to change rows order. To make rows order persistent the {@link Options#persistentState}
* plugin should be enabled.
*
* API:
* - moveRow - move single row to the new position.
* - moveRows - move many rows (as an array of indexes) to the new position.
*
* 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 rows.
* - guideline - line which shows where rows has been moved.
*
* @class ManualRowMove
* @plugin ManualRowMove
*/
var ManualRowMove =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ManualRowMove, _BasePlugin);
function ManualRowMove(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ManualRowMove);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualRowMove).call(this, hotInstance));
/**
* Set up WeakMap of plugin to sharing private parameters;
*/
privatePool.set((0, _assertThisInitialized2.default)(_this), {
rowsToMove: [],
pressed: void 0,
disallowMoving: void 0,
target: {
eventPageY: void 0,
coords: void 0,
TD: void 0,
row: void 0
}
});
/**
* List of last removed row indexes.
*
* @private
* @type {Array}
*/
_this.removedRows = [];
/**
* Object containing visual row indexes mapped to data source indexes.
*
* @private
* @type {RowsMapper}
*/
_this.rowsMapper = new _rowsMapper.default((0, _assertThisInitialized2.default)(_this));
/**
* Event Manager object.
*
* @private
* @type {Object}
*/
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
/**
* Backlight UI object.
*
* @private
* @type {Object}
*/
_this.backlight = new _backlight.default(hotInstance);
/**
* Guideline UI object.
*
* @private
* @type {Object}
*/
_this.guideline = new _guideline.default(hotInstance);
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ManualRowMove#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(ManualRowMove, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().manualRowMove;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.addHook('beforeOnCellMouseDown', function (event, coords, TD, blockCalculations) {
return _this2.onBeforeOnCellMouseDown(event, coords, TD, blockCalculations);
});
this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) {
return _this2.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations);
});
this.addHook('afterScrollHorizontally', function () {
return _this2.onAfterScrollHorizontally();
});
this.addHook('modifyRow', function (row, source) {
return _this2.onModifyRow(row, source);
});
this.addHook('beforeRemoveRow', function (index, amount) {
return _this2.onBeforeRemoveRow(index, amount);
});
this.addHook('afterRemoveRow', function () {
return _this2.onAfterRemoveRow();
});
this.addHook('afterCreateRow', function (index, amount) {
return _this2.onAfterCreateRow(index, amount);
});
this.addHook('afterLoadData', function () {
return _this2.onAfterLoadData();
});
this.addHook('beforeColumnSort', function (column, order) {
return _this2.onBeforeColumnSort(column, order);
});
this.addHook('unmodifyRow', function (row) {
return _this2.onUnmodifyRow(row);
});
this.registerEvents(); // TODO: move adding plugin classname to BasePlugin.
(0, _element.addClass)(this.hot.rootElement, CSS_PLUGIN);
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
this.onAfterPluginsInitialized();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
var pluginSettings = this.hot.getSettings().manualRowMove;
if (Array.isArray(pluginSettings)) {
this.rowsMapper.clearMap();
}
(0, _element.removeClass)(this.hot.rootElement, CSS_PLUGIN);
this.unregisterEvents();
this.backlight.destroy();
this.guideline.destroy();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "disablePlugin", this).call(this);
}
/**
* Moves a single row.
*
* @param {Number} row Visual row index to be moved.
* @param {Number} target Visual row index being a target for the moved row.
* @fires Hooks#beforeRowMove
* @fires Hooks#afterRowMove
*/
}, {
key: "moveRow",
value: function moveRow(row, target) {
this.moveRows([row], target);
}
/**
* Moves a multiple rows.
*
* @param {Array} rows Array of visual row indexes to be moved.
* @param {Number} target Visual row index being a target for the moved rows.
* @fires Hooks#beforeRowMove
* @fires Hooks#afterRowMove
*/
}, {
key: "moveRows",
value: function moveRows(rows, target) {
var _this3 = this;
var visualRows = (0, _toConsumableArray2.default)(rows);
var priv = privatePool.get(this);
var beforeMoveHook = this.hot.runHooks('beforeRowMove', visualRows, target);
priv.disallowMoving = beforeMoveHook === false;
if (!priv.disallowMoving) {
// first we need to rewrite an visual indexes to physical for save reference after move
(0, _array.arrayEach)(rows, function (row, index, array) {
array[index] = _this3.rowsMapper.getValueByIndex(row);
}); // next, when we have got an physical indexes, we can move rows
(0, _array.arrayEach)(rows, function (row, index) {
var actualPosition = _this3.rowsMapper.getIndexByValue(row);
if (actualPosition !== target) {
_this3.rowsMapper.moveRow(actualPosition, target + index);
}
}); // after moving we have to clear rowsMapper from null entries
this.rowsMapper.clearNull();
}
this.hot.runHooks('afterRowMove', visualRows, target);
}
/**
* Correct the cell selection after the move action. Fired only when action was made with a mouse.
* That means that changing the row order using the API won't correct the selection.
*
* @private
* @param {Number} startRow Visual row index for the start of the selection.
* @param {Number} endRow Visual row index for the end of the selection.
*/
}, {
key: "changeSelection",
value: function changeSelection(startRow, endRow) {
this.hot.selectRows(startRow, endRow);
}
/**
* Gets the sum of the heights of rows in the provided range.
*
* @private
* @param {Number} from Visual row index.
* @param {Number} to Visual row index.
* @returns {Number}
*/
}, {
key: "getRowsHeight",
value: function getRowsHeight(from, to) {
var height = 0;
for (var i = from; i < to; i++) {
var rowHeight = this.hot.view.wt.wtTable.getRowHeight(i) || 23;
height += rowHeight;
}
return height;
}
/**
* Loads initial settings when persistent state is saved or when plugin was initialized as an array.
*
* @private
*/
}, {
key: "initialSettings",
value: function initialSettings() {
var pluginSettings = this.hot.getSettings().manualRowMove;
if (Array.isArray(pluginSettings)) {
this.moveRows(pluginSettings, 0);
} else if (pluginSettings !== void 0) {
var persistentState = this.persistentStateLoad();
if (persistentState.length) {
this.moveRows(persistentState, 0);
}
}
}
/**
* Checks if the provided row is in the fixedRowsTop section.
*
* @private
* @param {Number} row Visual row index to check.
* @returns {Boolean}
*/
}, {
key: "isFixedRowTop",
value: function isFixedRowTop(row) {
return row < this.hot.getSettings().fixedRowsTop;
}
/**
* Checks if the provided row is in the fixedRowsBottom section.
*
* @private
* @param {Number} row Visual row index to check.
* @returns {Boolean}
*/
}, {
key: "isFixedRowBottom",
value: function isFixedRowBottom(row) {
return row > this.hot.getSettings().fixedRowsBottom;
}
/**
* Saves the manual row positions to the persistent state (the {@link Options#persistentState} option has to be enabled).
*
* @fires Hooks#persistentStateSave
* @fires Hooks#manualRowMove
*/
}, {
key: "persistentStateSave",
value: function persistentStateSave() {
this.hot.runHooks('persistentStateSave', 'manualRowMove', this.rowsMapper._arrayMap);
}
/**
* Loads the manual row positions from the persistent state (the {@link Options#persistentState} option has to be enabled).
*
* @returns {Array} Stored state.
*
* @fires Hooks#persistentStateLoad
* @fires Hooks#manualRowMove
*/
}, {
key: "persistentStateLoad",
value: function persistentStateLoad() {
var storedState = {};
this.hot.runHooks('persistentStateLoad', 'manualRowMove', storedState);
return storedState.value ? storedState.value : [];
}
/**
* Prepare array of indexes based on actual selection.
*
* @private
* @returns {Array}
*/
}, {
key: "prepareRowsToMoving",
value: function prepareRowsToMoving() {
var selection = this.hot.getSelectedRangeLast();
var selectedRows = [];
if (!selection) {
return selectedRows;
}
var from = selection.from,
to = selection.to;
var start = Math.min(from.row, to.row);
var end = Math.max(from.row, to.row);
(0, _number.rangeEach)(start, end, function (i) {
selectedRows.push(i);
});
return selectedRows;
}
/**
* Update the UI visual position.
*
* @private
*/
}, {
key: "refreshPositions",
value: function refreshPositions() {
var priv = privatePool.get(this);
var coords = priv.target.coords;
var firstVisible = this.hot.view.wt.wtTable.getFirstVisibleRow();
var lastVisible = this.hot.view.wt.wtTable.getLastVisibleRow();
var fixedRows = this.hot.getSettings().fixedRowsTop;
var countRows = this.hot.countRows();
if (coords.row < fixedRows && firstVisible > 0) {
this.hot.scrollViewportTo(firstVisible - 1);
}
if (coords.row >= lastVisible && lastVisible < countRows) {
this.hot.scrollViewportTo(lastVisible + 1, undefined, true);
}
var wtTable = this.hot.view.wt.wtTable;
var TD = priv.target.TD;
var rootElementOffset = (0, _element.offset)(this.hot.rootElement);
var tdOffsetTop = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row);
var mouseOffsetTop = priv.target.eventPageY - rootElementOffset.top + wtTable.holder.scrollTop;
var hiderHeight = wtTable.hider.offsetHeight;
var tbodyOffsetTop = wtTable.TBODY.offsetTop;
var backlightElemMarginTop = this.backlight.getOffset().top;
var backlightElemHeight = this.backlight.getSize().height;
if (this.isFixedRowTop(coords.row)) {
tdOffsetTop += wtTable.holder.scrollTop;
} // todo: fixedRowsBottom
// if (this.isFixedRowBottom(coords.row)) {
//
// }
if (coords.row < 0) {
// if hover on colHeader
priv.target.row = firstVisible > 0 ? firstVisible - 1 : firstVisible;
} else if (TD.offsetHeight / 2 + tdOffsetTop <= mouseOffsetTop) {
// if hover on lower part of TD
priv.target.row = coords.row + 1; // unfortunately first row is bigger than rest
tdOffsetTop += coords.row === 0 ? TD.offsetHeight - 1 : TD.offsetHeight;
} else {
// elsewhere on table
priv.target.row = coords.row;
}
var backlightTop = mouseOffsetTop;
var guidelineTop = tdOffsetTop;
if (mouseOffsetTop + backlightElemHeight + backlightElemMarginTop >= hiderHeight) {
// prevent display backlight below table
backlightTop = hiderHeight - backlightElemHeight - backlightElemMarginTop;
} else if (mouseOffsetTop + backlightElemMarginTop < tbodyOffsetTop) {
// prevent display above below table
backlightTop = tbodyOffsetTop + Math.abs(backlightElemMarginTop);
}
if (tdOffsetTop >= hiderHeight - 1) {
// prevent display guideline below table
guidelineTop = hiderHeight - 1;
}
var topOverlayHeight = 0;
if (this.hot.view.wt.wtOverlays.topOverlay) {
topOverlayHeight = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.TABLE.offsetHeight;
}
if (coords.row >= fixedRows && guidelineTop - wtTable.holder.scrollTop < topOverlayHeight) {
this.hot.scrollViewportTo(coords.row);
}
this.backlight.setPosition(backlightTop);
this.guideline.setPosition(guidelineTop);
}
/**
* This method checks arrayMap from rowsMapper and updates the rowsMapper if it's necessary.
*
* @private
*/
}, {
key: "updateRowsMapper",
value: function updateRowsMapper() {
var countRows = this.hot.countSourceRows();
var rowsMapperLen = this.rowsMapper._arrayMap.length;
if (rowsMapperLen === 0) {
this.rowsMapper.createMap(countRows || this.hot.getSettings().startRows);
} else if (rowsMapperLen < countRows) {
var diff = countRows - rowsMapperLen;
this.rowsMapper.insertItems(rowsMapperLen, diff);
} else if (rowsMapperLen > countRows) {
var maxIndex = countRows - 1;
var rowsToRemove = [];
(0, _array.arrayEach)(this.rowsMapper._arrayMap, function (value, index) {
if (value > maxIndex) {
rowsToRemove.push(index);
}
});
this.rowsMapper.removeItems(rowsToRemove);
}
}
/**
* Binds the events used by the plugin.
*
* @private
*/
}, {
key: "registerEvents",
value: function registerEvents() {
var _this4 = this;
var documentElement = this.hot.rootDocument.documentElement;
this.eventManager.addEventListener(documentElement, 'mousemove', function (event) {
return _this4.onMouseMove(event);
});
this.eventManager.addEventListener(documentElement, 'mouseup', function () {
return _this4.onMouseUp();
});
}
/**
* Unbinds the events used by the plugin.
*
* @private
*/
}, {
key: "unregisterEvents",
value: function unregisterEvents() {
this.eventManager.clear();
}
/**
* `beforeColumnSort` hook callback. If user uses the sorting, manual row moving is disabled.
*
* @private
* @param {Number} column Column index where soring is present
* @param {*} order State of sorting. ASC/DESC/None
*/
}, {
key: "onBeforeColumnSort",
value: function onBeforeColumnSort(column, order) {
var priv = privatePool.get(this);
priv.disallowMoving = order !== void 0;
}
/**
* Changes the behavior of selection / dragging.
*
* @private
* @param {MouseEvent} event
* @param {CellCoords} coords Visual coordinates.
* @param {HTMLElement} TD
* @param {Object} blockCalculations
*/
}, {
key: "onBeforeOnCellMouseDown",
value: function onBeforeOnCellMouseDown(event, coords, TD, blockCalculations) {
var _this$hot$view$wt = this.hot.view.wt,
wtTable = _this$hot$view$wt.wtTable,
wtViewport = _this$hot$view$wt.wtViewport;
var isHeaderSelection = this.hot.selection.isSelectedByRowHeader();
var selection = this.hot.getSelectedRangeLast();
var priv = privatePool.get(this);
if (!selection || !isHeaderSelection || priv.pressed || event.button !== 0) {
priv.pressed = false;
priv.rowsToMove.length = 0;
(0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI]);
return;
}
var guidelineIsNotReady = this.guideline.isBuilt() && !this.guideline.isAppended();
var backlightIsNotReady = this.backlight.isBuilt() && !this.backlight.isAppended();
if (guidelineIsNotReady && backlightIsNotReady) {
this.guideline.appendTo(wtTable.hider);
this.backlight.appendTo(wtTable.hider);
}
var from = selection.from,
to = selection.to;
var start = Math.min(from.row, to.row);
var end = Math.max(from.row, to.row);
if (coords.col < 0 && coords.row >= start && coords.row <= end) {
blockCalculations.row = true;
priv.pressed = true;
priv.target.eventPageY = event.pageY;
priv.target.coords = coords;
priv.target.TD = TD;
priv.rowsToMove = this.prepareRowsToMoving();
var leftPos = wtTable.holder.scrollLeft + wtViewport.getRowHeaderWidth();
this.backlight.setPosition(null, leftPos);
this.backlight.setSize(wtTable.hider.offsetWidth - leftPos, this.getRowsHeight(start, end + 1));
this.backlight.setOffset((this.getRowsHeight(start, coords.row) + event.layerY) * -1, null);
(0, _element.addClass)(this.hot.rootElement, CSS_ON_MOVING);
this.refreshPositions();
} else {
(0, _element.removeClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
priv.pressed = false;
priv.rowsToMove.length = 0;
}
}
/**
* 'mouseMove' event callback. Fired when pointer move on document.documentElement.
*
* @private
* @param {MouseEvent} event `mousemove` event properties.
*/
}, {
key: "onMouseMove",
value: function onMouseMove(event) {
var priv = privatePool.get(this);
if (!priv.pressed) {
return;
} // callback for browser which doesn't supports CSS pointer-event: none
if (event.realTarget === this.backlight.element) {
var height = this.backlight.getSize().height;
this.backlight.setSize(null, 0);
setTimeout(function () {
this.backlight.setPosition(null, height);
});
}
priv.target.eventPageY = event.pageY;
this.refreshPositions();
}
/**
* 'beforeOnCellMouseOver' hook callback. Fired when pointer was over cell.
*
* @private
* @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} blockCalculations Object which contains information about blockCalculation for row, column or cells.
*/
}, {
key: "onBeforeOnCellMouseOver",
value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) {
var selectedRange = this.hot.getSelectedRangeLast();
var priv = privatePool.get(this);
if (!selectedRange || !priv.pressed) {
return;
}
if (priv.rowsToMove.indexOf(coords.row) > -1) {
(0, _element.removeClass)(this.hot.rootElement, CSS_SHOW_UI);
} else {
(0, _element.addClass)(this.hot.rootElement, CSS_SHOW_UI);
}
blockCalculations.row = true;
blockCalculations.column = true;
blockCalculations.cell = true;
priv.target.coords = coords;
priv.target.TD = TD;
}
/**
* `onMouseUp` hook callback.
*
* @private
*/
}, {
key: "onMouseUp",
value: function onMouseUp() {
var priv = privatePool.get(this);
var target = priv.target.row;
var rowsLen = priv.rowsToMove.length;
priv.pressed = false;
priv.backlightHeight = 0;
(0, _element.removeClass)(this.hot.rootElement, [CSS_ON_MOVING, CSS_SHOW_UI, CSS_AFTER_SELECTION]);
if (this.hot.selection.isSelectedByRowHeader()) {
(0, _element.addClass)(this.hot.rootElement, CSS_AFTER_SELECTION);
}
if (rowsLen < 1 || target === void 0 || priv.rowsToMove.indexOf(target) > -1 || priv.rowsToMove[rowsLen - 1] === target - 1) {
return;
}
this.moveRows(priv.rowsToMove, target);
this.persistentStateSave();
this.hot.render();
if (!priv.disallowMoving) {
var selectionStart = this.rowsMapper.getIndexByValue(priv.rowsToMove[0]);
var selectionEnd = this.rowsMapper.getIndexByValue(priv.rowsToMove[rowsLen - 1]);
this.changeSelection(selectionStart, selectionEnd);
}
priv.rowsToMove.length = 0;
}
/**
* `afterScrollHorizontally` hook callback. Fired the table was scrolled horizontally.
*
* @private
*/
}, {
key: "onAfterScrollHorizontally",
value: function onAfterScrollHorizontally() {
var wtTable = this.hot.view.wt.wtTable;
var headerWidth = this.hot.view.wt.wtViewport.getRowHeaderWidth();
var scrollLeft = wtTable.holder.scrollLeft;
var posLeft = headerWidth + scrollLeft;
this.backlight.setPosition(null, posLeft);
this.backlight.setSize(wtTable.hider.offsetWidth - posLeft);
}
/**
* `afterCreateRow` hook callback.
*
* @private
* @param {Number} index Visual index of the created row.
* @param {Number} amount Amount of created rows.
*/
}, {
key: "onAfterCreateRow",
value: function onAfterCreateRow(index, amount) {
this.rowsMapper.shiftItems(index, amount);
}
/**
* On before remove row listener.
*
* @private
* @param {Number} index Visual row index.
* @param {Number} amount Defines how many rows removed.
*/
}, {
key: "onBeforeRemoveRow",
value: function onBeforeRemoveRow(index, amount) {
var _this5 = this;
this.removedRows.length = 0;
if (index !== false) {
// Collect physical row index.
(0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
_this5.removedRows.push(_this5.hot.runHooks('modifyRow', removedIndex, _this5.pluginName));
});
}
}
/**
* `afterRemoveRow` hook callback.
*
* @private
*/
}, {
key: "onAfterRemoveRow",
value: function onAfterRemoveRow() {
this.rowsMapper.unshiftItems(this.removedRows);
}
/**
* `afterLoadData` hook callback.
*
* @private
*/
}, {
key: "onAfterLoadData",
value: function onAfterLoadData() {
this.updateRowsMapper();
}
/**
* 'modifyRow' hook callback.
*
* @private
* @param {Number} row Visual Row index.
* @returns {Number} Physical row index.
*/
}, {
key: "onModifyRow",
value: function onModifyRow(row, source) {
var physicalRow = row;
if (source !== this.pluginName) {
var rowInMapper = this.rowsMapper.getValueByIndex(physicalRow);
physicalRow = rowInMapper === null ? physicalRow : rowInMapper;
}
return physicalRow;
}
/**
* 'unmodifyRow' hook callback.
*
* @private
* @param {Number} row Physical row index.
* @returns {Number} Visual row index.
*/
}, {
key: "onUnmodifyRow",
value: function onUnmodifyRow(row) {
var indexInMapper = this.rowsMapper.getIndexByValue(row);
return indexInMapper === null ? row : indexInMapper;
}
/**
* `afterPluginsInitialized` hook callback.
*
* @private
*/
}, {
key: "onAfterPluginsInitialized",
value: function onAfterPluginsInitialized() {
this.updateRowsMapper();
this.initialSettings();
this.backlight.build();
this.guideline.build();
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.backlight.destroy();
this.guideline.destroy();
this.rowsMapper.destroy();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowMove.prototype), "destroy", this).call(this);
}
}]);
return ManualRowMove;
}(_base.default);
(0, _plugins.registerPlugin)('ManualRowMove', ManualRowMove);
var _default = ManualRowMove;
exports.default = _default;
/***/ }),
/* 413 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(33);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _arrayMapper = _interopRequireDefault(__webpack_require__(91));
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var _number = __webpack_require__(15);
/**
* @class RowsMapper
* @plugin ManualRowMove
*/
var RowsMapper =
/*#__PURE__*/
function () {
function RowsMapper(manualRowMove) {
(0, _classCallCheck2.default)(this, RowsMapper);
/**
* Instance of ManualRowMove plugin.
*
* @type {ManualRowMove}
*/
this.manualRowMove = manualRowMove;
}
/**
* Reset current map array and create new one.
*
* @param {Number} [length] Custom generated map length.
*/
(0, _createClass2.default)(RowsMapper, [{
key: "createMap",
value: function createMap(length) {
var _this = this;
var originLength = length === void 0 ? this._arrayMap.length : length;
this._arrayMap.length = 0;
(0, _number.rangeEach)(originLength - 1, function (itemIndex) {
_this._arrayMap[itemIndex] = itemIndex;
});
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
this._arrayMap = null;
}
/**
*
* Moving elements in rowsMapper.
* @param {Number} from Row index to move.
* @param {Number} to Target index.
*/
}, {
key: "moveRow",
value: function moveRow(from, to) {
var indexToMove = this._arrayMap[from];
this._arrayMap[from] = null;
this._arrayMap.splice(to, 0, indexToMove);
}
/**
* Clearing arrayMap from `null` entries.
*/
}, {
key: "clearNull",
value: function clearNull() {
this._arrayMap = (0, _array.arrayFilter)(this._arrayMap, function (i) {
return i !== null;
});
}
}]);
return RowsMapper;
}();
(0, _object.mixin)(RowsMapper, _arrayMapper.default);
var _default = RowsMapper;
exports.default = _default;
/***/ }),
/* 414 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(243));
var _element = __webpack_require__(5);
var CSS_CLASSNAME = 'ht__manualRowMove--backlight';
/**
* @class BacklightUI
* @util
*/
var BacklightUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(BacklightUI, _BaseUI);
function BacklightUI() {
(0, _classCallCheck2.default)(this, BacklightUI);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BacklightUI).apply(this, arguments));
}
(0, _createClass2.default)(BacklightUI, [{
key: "build",
/**
* Custom className on build process.
*/
value: function build() {
(0, _get2.default)((0, _getPrototypeOf2.default)(BacklightUI.prototype), "build", this).call(this);
(0, _element.addClass)(this._element, CSS_CLASSNAME);
}
}]);
return BacklightUI;
}(_base.default);
var _default = BacklightUI;
exports.default = _default;
/***/ }),
/* 415 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(243));
var _element = __webpack_require__(5);
var CSS_CLASSNAME = 'ht__manualRowMove--guideline';
/**
* @class GuidelineUI
* @util
*/
var GuidelineUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(GuidelineUI, _BaseUI);
function GuidelineUI() {
(0, _classCallCheck2.default)(this, GuidelineUI);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(GuidelineUI).apply(this, arguments));
}
(0, _createClass2.default)(GuidelineUI, [{
key: "build",
/**
* Custom className on build process.
*/
value: function build() {
(0, _get2.default)((0, _getPrototypeOf2.default)(GuidelineUI.prototype), "build", this).call(this);
(0, _element.addClass)(this._element, CSS_CLASSNAME);
}
}]);
return GuidelineUI;
}(_base.default);
var _default = GuidelineUI;
exports.default = _default;
/***/ }),
/* 416 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 417 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _element = __webpack_require__(5);
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _event = __webpack_require__(31);
var _array = __webpack_require__(3);
var _number = __webpack_require__(15);
var _plugins = __webpack_require__(20);
// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js
/**
* @description
* This plugin allows to change rows height. To make rows height persistent the {@link Options#persistentState}
* plugin should be enabled.
*
* The plugin creates additional components to make resizing possibly using user interface:
* - handle - the draggable element that sets the desired height of the row.
* - guide - the helper guide that shows the desired height as a horizontal guide.
*
* @plugin ManualRowResize
*/
var ManualRowResize =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ManualRowResize, _BasePlugin);
function ManualRowResize(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ManualRowResize);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ManualRowResize).call(this, hotInstance));
var rootDocument = _this.hot.rootDocument;
_this.currentTH = null;
_this.currentRow = null;
_this.selectedRows = [];
_this.currentHeight = null;
_this.newSize = null;
_this.startY = null;
_this.startHeight = null;
_this.startOffset = null;
_this.handle = rootDocument.createElement('DIV');
_this.guide = rootDocument.createElement('DIV');
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
_this.pressed = null;
_this.dblclick = 0;
_this.autoresizeTimeout = null;
_this.manualRowHeights = [];
(0, _element.addClass)(_this.handle, 'manualRowResizer');
(0, _element.addClass)(_this.guide, 'manualRowResizerGuide');
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ManualRowResize#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(ManualRowResize, [{
key: "isEnabled",
value: function isEnabled() {
return this.hot.getSettings().manualRowResize;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.manualRowHeights = [];
var initialRowHeights = this.hot.getSettings().manualRowResize;
var loadedManualRowHeights = this.loadManualRowHeights();
if (typeof loadedManualRowHeights !== 'undefined') {
this.manualRowHeights = loadedManualRowHeights;
} else if (Array.isArray(initialRowHeights)) {
this.manualRowHeights = initialRowHeights;
} else {
this.manualRowHeights = [];
}
this.addHook('modifyRowHeight', function (height, row) {
return _this2.onModifyRowHeight(height, row);
}); // Handsontable.hooks.register('beforeRowResize');
// Handsontable.hooks.register('afterRowResize');
this.bindEvents();
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowResize.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
var initialRowHeights = this.hot.getSettings().manualRowResize;
if (Array.isArray(initialRowHeights)) {
this.manualRowHeights = initialRowHeights;
} else if (!initialRowHeights) {
this.manualRowHeights = [];
}
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
(0, _get2.default)((0, _getPrototypeOf2.default)(ManualRowResize.prototype), "disablePlugin", this).call(this);
}
/**
* Saves the current sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
* @fires Hooks#persistentStateSave
* @fires Hooks#manualRowHeights
*/
}, {
key: "saveManualRowHeights",
value: function saveManualRowHeights() {
this.hot.runHooks('persistentStateSave', 'manualRowHeights', this.manualRowHeights);
}
/**
* Loads the previously saved sizes using the persistentState plugin (the {@link Options#persistentState} option has to be enabled).
*
* @returns {Array}
* @fires Hooks#persistentStateLoad
* @fires Hooks#manualRowHeights
*/
}, {
key: "loadManualRowHeights",
value: function loadManualRowHeights() {
var storedState = {};
this.hot.runHooks('persistentStateLoad', 'manualRowHeights', storedState);
return storedState.value;
}
/**
* Sets the resize handle position.
*
* @private
* @param {HTMLCellElement} TH TH HTML element.
*/
}, {
key: "setupHandlePosition",
value: function setupHandlePosition(TH) {
var _this3 = this;
this.currentTH = TH;
var cellCoords = this.hot.getCoords(this.currentTH);
var row = cellCoords.row;
var headerWidth = (0, _element.outerWidth)(this.currentTH);
if (row >= 0) {
// if not col header
var box = this.currentTH.getBoundingClientRect();
var fixedRowTop = row < this.hot.getSettings().fixedRowsTop;
var fixedRowBottom = row >= this.hot.countRows() - this.hot.getSettings().fixedRowsBottom;
var parentOverlay = this.hot.view.wt.wtOverlays.leftOverlay;
if (fixedRowTop) {
parentOverlay = this.hot.view.wt.wtOverlays.topLeftCornerOverlay;
} else if (fixedRowBottom) {
parentOverlay = this.hot.view.wt.wtOverlays.bottomLeftCornerOverlay;
}
var relativeHeaderPosition = parentOverlay.getRelativeCellPosition(this.currentTH, cellCoords.row, cellCoords.col); // If the TH is not a child of the left/top-left/bottom-left overlay, recalculate using the top-most header
if (!relativeHeaderPosition) {
var topMostHeader = parentOverlay.clone.wtTable.TBODY.children[+!!this.hot.getSettings().colHeaders + row].firstChild;
relativeHeaderPosition = parentOverlay.getRelativeCellPosition(topMostHeader, cellCoords.row, cellCoords.col);
}
this.currentRow = row;
this.selectedRows = [];
if (this.hot.selection.isSelected() && this.hot.selection.isSelectedByRowHeader()) {
var _this$hot$getSelected = this.hot.getSelectedRangeLast(),
from = _this$hot$getSelected.from,
to = _this$hot$getSelected.to;
var start = from.row;
var end = to.row;
if (start >= end) {
start = to.row;
end = from.row;
}
if (this.currentRow >= start && this.currentRow <= end) {
(0, _number.rangeEach)(start, end, function (i) {
return _this3.selectedRows.push(i);
});
} else {
this.selectedRows.push(this.currentRow);
}
} else {
this.selectedRows.push(this.currentRow);
}
this.startOffset = relativeHeaderPosition.top - 6;
this.startHeight = parseInt(box.height, 10);
this.handle.style.top = "".concat(this.startOffset + this.startHeight, "px");
this.handle.style.left = "".concat(relativeHeaderPosition.left, "px");
this.handle.style.width = "".concat(headerWidth, "px");
this.hot.rootElement.appendChild(this.handle);
}
}
/**
* Refresh the resize handle position.
*
* @private
*/
}, {
key: "refreshHandlePosition",
value: function refreshHandlePosition() {
this.handle.style.top = "".concat(this.startOffset + this.currentHeight, "px");
}
/**
* Sets the resize guide position.
*
* @private
*/
}, {
key: "setupGuidePosition",
value: function setupGuidePosition() {
var handleWidth = parseInt((0, _element.outerWidth)(this.handle), 10);
var handleRightPosition = parseInt(this.handle.style.left, 10) + handleWidth;
var maximumVisibleElementWidth = parseInt(this.hot.view.maximumVisibleElementWidth(0), 10);
(0, _element.addClass)(this.handle, 'active');
(0, _element.addClass)(this.guide, 'active');
this.guide.style.top = this.handle.style.top;
this.guide.style.left = "".concat(handleRightPosition, "px");
this.guide.style.width = "".concat(maximumVisibleElementWidth - handleWidth, "px");
this.hot.rootElement.appendChild(this.guide);
}
/**
* Refresh the resize guide position.
*
* @private
*/
}, {
key: "refreshGuidePosition",
value: function refreshGuidePosition() {
this.guide.style.top = this.handle.style.top;
}
/**
* Hides both the resize handle and resize guide.
*
* @private
*/
}, {
key: "hideHandleAndGuide",
value: function hideHandleAndGuide() {
(0, _element.removeClass)(this.handle, 'active');
(0, _element.removeClass)(this.guide, 'active');
}
/**
* Checks if provided element is considered as a row header.
*
* @private
* @param {HTMLElement} element HTML element.
* @returns {Boolean}
*/
}, {
key: "checkIfRowHeader",
value: function checkIfRowHeader(element) {
if (element !== this.hot.rootElement) {
var parent = element.parentNode;
if (parent.tagName === 'TBODY') {
return true;
}
return this.checkIfRowHeader(parent);
}
return false;
}
/**
* Gets the TH element from the provided element.
*
* @private
* @param {HTMLElement} element HTML element.
* @returns {HTMLElement}
*/
}, {
key: "getTHFromTargetElement",
value: function getTHFromTargetElement(element) {
if (element.tagName !== 'TABLE') {
if (element.tagName === 'TH') {
return element;
}
return this.getTHFromTargetElement(element.parentNode);
}
return null;
}
/**
* 'mouseover' event callback - set the handle position.
*
* @private
* @param {MouseEvent} event
*/
}, {
key: "onMouseOver",
value: function onMouseOver(event) {
if (this.checkIfRowHeader(event.target)) {
var th = this.getTHFromTargetElement(event.target);
if (th) {
if (!this.pressed) {
this.setupHandlePosition(th);
}
}
}
}
/**
* Auto-size row after doubleclick - callback.
*
* @private
* @fires Hooks#beforeRowResize
* @fires Hooks#afterRowResize
*/
}, {
key: "afterMouseDownTimeout",
value: function afterMouseDownTimeout() {
var _this4 = this;
var render = function render() {
_this4.hot.forceFullRender = true;
_this4.hot.view.render(); // updates all
_this4.hot.view.wt.wtOverlays.adjustElementsSize(true);
};
var resize = function resize(selectedRow, forceRender) {
var hookNewSize = _this4.hot.runHooks('beforeRowResize', selectedRow, _this4.newSize, true);
if (hookNewSize !== void 0) {
_this4.newSize = hookNewSize;
}
_this4.setManualSize(selectedRow, _this4.newSize); // double click sets auto row size
if (forceRender) {
render();
}
_this4.hot.runHooks('afterRowResize', selectedRow, _this4.newSize, true);
};
if (this.dblclick >= 2) {
var selectedRowsLength = this.selectedRows.length;
if (selectedRowsLength > 1) {
(0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
resize(selectedRow);
});
render();
} else {
(0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
resize(selectedRow, true);
});
}
}
this.dblclick = 0;
this.autoresizeTimeout = null;
}
/**
* 'mousedown' event callback.
*
* @private
* @param {MouseEvent} event
*/
}, {
key: "onMouseDown",
value: function onMouseDown(event) {
var _this5 = this;
if ((0, _element.hasClass)(event.target, 'manualRowResizer')) {
this.setupGuidePosition();
this.pressed = this.hot;
if (this.autoresizeTimeout === null) {
this.autoresizeTimeout = setTimeout(function () {
return _this5.afterMouseDownTimeout();
}, 500);
this.hot._registerTimeout(this.autoresizeTimeout);
}
this.dblclick += 1;
this.startY = (0, _event.pageY)(event);
this.newSize = this.startHeight;
}
}
/**
* 'mousemove' event callback - refresh the handle and guide positions, cache the new row height.
*
* @private
* @param {MouseEvent} event
*/
}, {
key: "onMouseMove",
value: function onMouseMove(event) {
var _this6 = this;
if (this.pressed) {
this.currentHeight = this.startHeight + ((0, _event.pageY)(event) - this.startY);
(0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
_this6.newSize = _this6.setManualSize(selectedRow, _this6.currentHeight);
});
this.refreshHandlePosition();
this.refreshGuidePosition();
}
}
/**
* 'mouseup' event callback - apply the row resizing.
*
* @private
*
* @fires Hooks#beforeRowResize
* @fires Hooks#afterRowResize
*/
}, {
key: "onMouseUp",
value: function onMouseUp() {
var _this7 = this;
var render = function render() {
_this7.hot.forceFullRender = true;
_this7.hot.view.render(); // updates all
_this7.hot.view.wt.wtOverlays.adjustElementsSize(true);
};
var runHooks = function runHooks(selectedRow, forceRender) {
_this7.hot.runHooks('beforeRowResize', selectedRow, _this7.newSize);
if (forceRender) {
render();
}
_this7.saveManualRowHeights();
_this7.hot.runHooks('afterRowResize', selectedRow, _this7.newSize, false);
};
if (this.pressed) {
this.hideHandleAndGuide();
this.pressed = false;
if (this.newSize !== this.startHeight) {
var selectedRowsLength = this.selectedRows.length;
if (selectedRowsLength > 1) {
(0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
runHooks(selectedRow);
});
render();
} else {
(0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
runHooks(selectedRow, true);
});
}
}
this.setupHandlePosition(this.currentTH);
}
}
/**
* Binds the mouse events.
*
* @private
*/
}, {
key: "bindEvents",
value: function bindEvents() {
var _this8 = this;
var _this$hot = this.hot,
rootElement = _this$hot.rootElement,
rootWindow = _this$hot.rootWindow;
this.eventManager.addEventListener(rootElement, 'mouseover', function (e) {
return _this8.onMouseOver(e);
});
this.eventManager.addEventListener(rootElement, 'mousedown', function (e) {
return _this8.onMouseDown(e);
});
this.eventManager.addEventListener(rootWindow, 'mousemove', function (e) {
return _this8.onMouseMove(e);
});
this.eventManager.addEventListener(rootWindow, 'mouseup', function () {
return _this8.onMouseUp();
});
}
/**
* Sets the new height for specified row index.
*
* @param {Number} row Visual row index.
* @param {Number} height Row height.
* @returns {Number} Returns new height.
*
* @fires Hooks#modifyRow
*/
}, {
key: "setManualSize",
value: function setManualSize(row, height) {
var physicalRow = this.hot.runHooks('modifyRow', row);
this.manualRowHeights[physicalRow] = height;
return height;
}
/**
* Modifies the provided row height, based on the plugin settings.
*
* @private
* @param {Number} height Row height.
* @param {Number} row Visual row index.
* @returns {Number}
*
* @fires Hooks#modifyRow
*/
}, {
key: "onModifyRowHeight",
value: function onModifyRowHeight(height, row) {
if (this.enabled) {
var autoRowSizePlugin = this.hot.getPlugin('autoRowSize');
var autoRowHeightResult = autoRowSizePlugin ? autoRowSizePlugin.heights[row] : null;
var physicalRow = this.hot.runHooks('modifyRow', row);
var manualRowHeight = this.manualRowHeights[physicalRow];
if (manualRowHeight !== void 0 && (manualRowHeight === autoRowHeightResult || manualRowHeight > (height || 0))) {
return manualRowHeight;
}
}
return height;
}
}]);
return ManualRowResize;
}(_base.default);
(0, _plugins.registerPlugin)('manualRowResize', ManualRowResize);
var _default = ManualRowResize;
exports.default = _default;
/***/ }),
/* 418 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(56);
__webpack_require__(34);
__webpack_require__(16);
__webpack_require__(33);
__webpack_require__(10);
__webpack_require__(39);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _plugins = __webpack_require__(20);
var _event = __webpack_require__(31);
var _src = __webpack_require__(25);
var _cellsCollection = _interopRequireDefault(__webpack_require__(419));
var _cellCoords = _interopRequireDefault(__webpack_require__(168));
var _autofill = _interopRequireDefault(__webpack_require__(420));
var _selection = _interopRequireDefault(__webpack_require__(421));
var _toggleMerge = _interopRequireDefault(__webpack_require__(422));
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var _console = __webpack_require__(55);
var _number = __webpack_require__(15);
var _utils = __webpack_require__(244);
__webpack_require__(423);
_pluginHooks.default.getSingleton().register('beforeMergeCells');
_pluginHooks.default.getSingleton().register('afterMergeCells');
_pluginHooks.default.getSingleton().register('beforeUnmergeCells');
_pluginHooks.default.getSingleton().register('afterUnmergeCells');
var privatePool = new WeakMap();
/**
* @plugin MergeCells
*
* @description
* Plugin, which allows merging cells in the table (using the initial configuration, API or context menu).
*
* @example
*
* ```js
* const hot = new Handsontable(document.getElementById('example'), {
* data: getData(),
* mergeCells: [
* {row: 0, col: 3, rowspan: 3, colspan: 3},
* {row: 2, col: 6, rowspan: 2, colspan: 2},
* {row: 4, col: 8, rowspan: 3, colspan: 3}
* ],
* ```
*/
var MergeCells =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(MergeCells, _BasePlugin);
function MergeCells(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, MergeCells);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MergeCells).call(this, hotInstance));
privatePool.set((0, _assertThisInitialized2.default)(_this), {
lastDesiredCoords: null
});
/**
* A container for all the merged cells.
*
* @private
* @type {MergedCellsCollection}
*/
_this.mergedCellsCollection = null;
/**
* Instance of the class responsible for all the autofill-related calculations.
*
* @private
* @type {AutofillCalculations}
*/
_this.autofillCalculations = null;
/**
* Instance of the class responsible for the selection-related calculations.
*
* @private
* @type {SelectionCalculations}
*/
_this.selectionCalculations = null;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link MergeCells#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(MergeCells, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().mergeCells;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.mergedCellsCollection = new _cellsCollection.default(this);
this.autofillCalculations = new _autofill.default(this);
this.selectionCalculations = new _selection.default(this);
this.addHook('afterInit', function () {
return _this2.onAfterInit.apply(_this2, arguments);
});
this.addHook('beforeKeyDown', function () {
return _this2.onBeforeKeyDown.apply(_this2, arguments);
});
this.addHook('modifyTransformStart', function () {
return _this2.onModifyTransformStart.apply(_this2, arguments);
});
this.addHook('afterModifyTransformStart', function () {
return _this2.onAfterModifyTransformStart.apply(_this2, arguments);
});
this.addHook('modifyTransformEnd', function () {
return _this2.onModifyTransformEnd.apply(_this2, arguments);
});
this.addHook('modifyGetCellCoords', function () {
return _this2.onModifyGetCellCoords.apply(_this2, arguments);
});
this.addHook('beforeSetRangeEnd', function () {
return _this2.onBeforeSetRangeEnd.apply(_this2, arguments);
});
this.addHook('afterIsMultipleSelection', function () {
return _this2.onAfterIsMultipleSelection.apply(_this2, arguments);
});
this.addHook('afterRenderer', function () {
return _this2.onAfterRenderer.apply(_this2, arguments);
});
this.addHook('afterContextMenuDefaultOptions', function () {
return _this2.addMergeActionsToContextMenu.apply(_this2, arguments);
});
this.addHook('afterGetCellMeta', function () {
return _this2.onAfterGetCellMeta.apply(_this2, arguments);
});
this.addHook('afterViewportRowCalculatorOverride', function () {
return _this2.onAfterViewportRowCalculatorOverride.apply(_this2, arguments);
});
this.addHook('afterViewportColumnCalculatorOverride', function () {
return _this2.onAfterViewportColumnCalculatorOverride.apply(_this2, arguments);
});
this.addHook('modifyAutofillRange', function () {
return _this2.onModifyAutofillRange.apply(_this2, arguments);
});
this.addHook('afterCreateCol', function () {
return _this2.onAfterCreateCol.apply(_this2, arguments);
});
this.addHook('afterRemoveCol', function () {
return _this2.onAfterRemoveCol.apply(_this2, arguments);
});
this.addHook('afterCreateRow', function () {
return _this2.onAfterCreateRow.apply(_this2, arguments);
});
this.addHook('afterRemoveRow', function () {
return _this2.onAfterRemoveRow.apply(_this2, arguments);
});
this.addHook('afterChange', function () {
return _this2.onAfterChange.apply(_this2, arguments);
});
this.addHook('beforeDrawBorders', function () {
return _this2.onBeforeDrawAreaBorders.apply(_this2, arguments);
});
this.addHook('afterDrawSelection', function () {
return _this2.onAfterDrawSelection.apply(_this2, arguments);
});
this.addHook('beforeRemoveCellClassNames', function () {
return _this2.onBeforeRemoveCellClassNames.apply(_this2, arguments);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(MergeCells.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.clearCollections();
this.hot.render();
(0, _get2.default)((0, _getPrototypeOf2.default)(MergeCells.prototype), "disablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
var settings = this.hot.getSettings().mergeCells;
this.disablePlugin();
this.enablePlugin();
this.generateFromSettings(settings);
(0, _get2.default)((0, _getPrototypeOf2.default)(MergeCells.prototype), "updatePlugin", this).call(this);
}
/**
* Validates a single setting object, represented by a single merged cell information object.
*
* @private
* @param {Object} setting An object with `row`, `col`, `rowspan` and `colspan` properties.
* @return {Boolean}
*/
}, {
key: "validateSetting",
value: function validateSetting(setting) {
var valid = true;
if (!setting) {
return false;
}
if (_cellCoords.default.containsNegativeValues(setting)) {
(0, _console.warn)(_cellCoords.default.NEGATIVE_VALUES_WARNING(setting));
valid = false;
} else if (_cellCoords.default.isOutOfBounds(setting, this.hot.countRows(), this.hot.countCols())) {
(0, _console.warn)(_cellCoords.default.IS_OUT_OF_BOUNDS_WARNING(setting));
valid = false;
} else if (_cellCoords.default.isSingleCell(setting)) {
(0, _console.warn)(_cellCoords.default.IS_SINGLE_CELL(setting));
valid = false;
} else if (_cellCoords.default.containsZeroSpan(setting)) {
(0, _console.warn)(_cellCoords.default.ZERO_SPAN_WARNING(setting));
valid = false;
}
return valid;
}
/**
* Generates the merged cells from the settings provided to the plugin.
*
* @private
* @param {Array|Boolean} settings The settings provided to the plugin.
*/
}, {
key: "generateFromSettings",
value: function generateFromSettings(settings) {
var _this3 = this;
if (Array.isArray(settings)) {
var _this$hot;
var populationArgumentsList = [];
(0, _array.arrayEach)(settings, function (setting) {
if (!_this3.validateSetting(setting)) {
return;
}
var highlight = new _src.CellCoords(setting.row, setting.col);
var rangeEnd = new _src.CellCoords(setting.row + setting.rowspan - 1, setting.col + setting.colspan - 1);
var mergeRange = new _src.CellRange(highlight, highlight, rangeEnd);
populationArgumentsList.push(_this3.mergeRange(mergeRange, true, true));
}); // remove 'empty' setting objects, caused by improper merge range declarations
populationArgumentsList = populationArgumentsList.filter(function (value) {
return value !== true;
});
var bulkPopulationData = this.getBulkCollectionData(populationArgumentsList);
(_this$hot = this.hot).populateFromArray.apply(_this$hot, (0, _toConsumableArray2.default)(bulkPopulationData));
}
}
/**
* Generates a bulk set of all the data to be populated to fill the data "under" the added merged cells.
*
* @private
* @param {Array} populationArgumentsList Array in a form of `[row, column, dataUnderCollection]`.
* @return {Array} Array in a form of `[row, column, dataOfAllCollections]`.
*/
}, {
key: "getBulkCollectionData",
value: function getBulkCollectionData(populationArgumentsList) {
var _this$hot2;
var populationDataRange = this.getBulkCollectionDataRange(populationArgumentsList);
var dataAtRange = (_this$hot2 = this.hot).getData.apply(_this$hot2, (0, _toConsumableArray2.default)(populationDataRange));
var newDataAtRange = dataAtRange.splice(0);
(0, _array.arrayEach)(populationArgumentsList, function (mergedCellArguments) {
var _mergedCellArguments = (0, _slicedToArray2.default)(mergedCellArguments, 3),
mergedCellRowIndex = _mergedCellArguments[0],
mergedCellColumnIndex = _mergedCellArguments[1],
mergedCellData = _mergedCellArguments[2];
(0, _array.arrayEach)(mergedCellData, function (mergedCellRow, rowIndex) {
(0, _array.arrayEach)(mergedCellRow, function (mergedCellElement, columnIndex) {
newDataAtRange[mergedCellRowIndex - populationDataRange[0] + rowIndex][mergedCellColumnIndex - populationDataRange[1] + columnIndex] = mergedCellElement;
});
});
});
return [populationDataRange[0], populationDataRange[1], newDataAtRange];
}
/**
* Gets the range of combined data ranges provided in a form of an array of arrays ([row, column, dataUnderCollection])
*
* @private
* @param {Array} populationArgumentsList Array containing argument lists for the `populateFromArray` method - row, column and data for population.
* @return {Array[]} Start and end coordinates of the merged cell range. (in a form of [rowIndex, columnIndex])
*/
}, {
key: "getBulkCollectionDataRange",
value: function getBulkCollectionDataRange(populationArgumentsList) {
var start = [0, 0];
var end = [0, 0];
var mergedCellRow = null;
var mergedCellColumn = null;
var mergedCellData = null;
(0, _array.arrayEach)(populationArgumentsList, function (mergedCellArguments) {
mergedCellRow = mergedCellArguments[0];
mergedCellColumn = mergedCellArguments[1];
mergedCellData = mergedCellArguments[2];
start[0] = Math.min(mergedCellRow, start[0]);
start[1] = Math.min(mergedCellColumn, start[1]);
end[0] = Math.max(mergedCellRow + mergedCellData.length - 1, end[0]);
end[1] = Math.max(mergedCellColumn + mergedCellData[0].length - 1, end[1]);
});
return [].concat(start, end);
}
/**
* Clears the merged cells from the merged cell container.
*/
}, {
key: "clearCollections",
value: function clearCollections() {
this.mergedCellsCollection.clear();
}
/**
* Returns `true` if a range is mergeable.
*
* @private
* @param {Object} newMergedCellInfo Merged cell information object to test.
* @param {Boolean} [auto=false] `true` if triggered at initialization.
* @returns {Boolean}
*/
}, {
key: "canMergeRange",
value: function canMergeRange(newMergedCellInfo) {
var auto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
return auto ? true : this.validateSetting(newMergedCellInfo);
}
/**
* Merge or unmerge, based on last selected range.
*
* @private
*/
}, {
key: "toggleMergeOnSelection",
value: function toggleMergeOnSelection() {
var currentRange = this.hot.getSelectedRangeLast();
if (!currentRange) {
return;
}
currentRange.setDirection('NW-SE');
var from = currentRange.from,
to = currentRange.to;
this.toggleMerge(currentRange);
this.hot.selectCell(from.row, from.col, to.row, to.col, false);
}
/**
* Merges the selection provided as a cell range.
*
* @param {CellRange} [cellRange] Selection cell range.
*/
}, {
key: "mergeSelection",
value: function mergeSelection() {
var cellRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.hot.getSelectedRangeLast();
if (!cellRange) {
return;
}
cellRange.setDirection('NW-SE');
var from = cellRange.from,
to = cellRange.to;
this.unmergeRange(cellRange, true);
this.mergeRange(cellRange);
this.hot.selectCell(from.row, from.col, to.row, to.col, false);
}
/**
* Unmerges the selection provided as a cell range.
*
* @param {CellRange} [cellRange] Selection cell range.
*/
}, {
key: "unmergeSelection",
value: function unmergeSelection() {
var cellRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.hot.getSelectedRangeLast();
if (!cellRange) {
return;
}
var from = cellRange.from,
to = cellRange.to;
this.unmergeRange(cellRange, true);
this.hot.selectCell(from.row, from.col, to.row, to.col, false);
}
/**
* Merges cells in the provided cell range.
*
* @private
* @param {CellRange} cellRange Cell range to merge.
* @param {Boolean} [auto=false] `true` if is called automatically, e.g. at initialization.
* @param {Boolean} [preventPopulation=false] `true`, if the method should not run `populateFromArray` at the end, but rather return its arguments.
* @returns {Array|Boolean} Returns an array of [row, column, dataUnderCollection] if preventPopulation is set to true. If the the merging process went successful, it returns `true`, otherwise - `false`.
* @fires Hooks#beforeMergeCells
* @fires Hooks#afterMergeCells
*/
}, {
key: "mergeRange",
value: function mergeRange(cellRange) {
var _this4 = this;
var auto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var preventPopulation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var topLeft = cellRange.getTopLeftCorner();
var bottomRight = cellRange.getBottomRightCorner();
var mergeParent = {
row: topLeft.row,
col: topLeft.col,
rowspan: bottomRight.row - topLeft.row + 1,
colspan: bottomRight.col - topLeft.col + 1
};
var clearedData = [];
var populationInfo = null;
if (!this.canMergeRange(mergeParent, auto)) {
return false;
}
this.hot.runHooks('beforeMergeCells', cellRange, auto);
(0, _number.rangeEach)(0, mergeParent.rowspan - 1, function (i) {
(0, _number.rangeEach)(0, mergeParent.colspan - 1, function (j) {
var clearedValue = null;
if (!clearedData[i]) {
clearedData[i] = [];
}
if (i === 0 && j === 0) {
clearedValue = _this4.hot.getDataAtCell(mergeParent.row, mergeParent.col);
} else {
_this4.hot.setCellMeta(mergeParent.row + i, mergeParent.col + j, 'hidden', true);
}
clearedData[i][j] = clearedValue;
});
});
this.hot.setCellMeta(mergeParent.row, mergeParent.col, 'spanned', true);
var mergedCellAdded = this.mergedCellsCollection.add(mergeParent);
if (mergedCellAdded) {
if (preventPopulation) {
populationInfo = [mergeParent.row, mergeParent.col, clearedData];
} else {
this.hot.populateFromArray(mergeParent.row, mergeParent.col, clearedData, void 0, void 0, this.pluginName);
}
this.hot.runHooks('afterMergeCells', cellRange, mergeParent, auto);
return populationInfo;
}
return true;
}
/**
* Unmerges the selection provided as a cell range. If no cell range is provided, it uses the current selection.
*
* @private
* @param {CellRange} cellRange Selection cell range.
* @param {Boolean} [auto=false] `true` if called automatically by the plugin.
*
* @fires Hooks#beforeUnmergeCells
* @fires Hooks#afterUnmergeCells
*/
}, {
key: "unmergeRange",
value: function unmergeRange(cellRange) {
var _this5 = this;
var auto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var mergedCells = this.mergedCellsCollection.getWithinRange(cellRange);
if (!mergedCells) {
return;
}
this.hot.runHooks('beforeUnmergeCells', cellRange, auto);
(0, _array.arrayEach)(mergedCells, function (currentCollection) {
_this5.mergedCellsCollection.remove(currentCollection.row, currentCollection.col);
(0, _number.rangeEach)(0, currentCollection.rowspan - 1, function (i) {
(0, _number.rangeEach)(0, currentCollection.colspan - 1, function (j) {
_this5.hot.removeCellMeta(currentCollection.row + i, currentCollection.col + j, 'hidden');
});
});
_this5.hot.removeCellMeta(currentCollection.row, currentCollection.col, 'spanned');
});
this.hot.render();
this.hot.runHooks('afterUnmergeCells', cellRange, auto);
}
/**
* Merges or unmerges, based on the cell range provided as `cellRange`.
*
* @private
* @param {CellRange} cellRange The cell range to merge or unmerged.
*/
}, {
key: "toggleMerge",
value: function toggleMerge(cellRange) {
var mergedCell = this.mergedCellsCollection.get(cellRange.from.row, cellRange.from.col);
var mergedCellCoversWholeRange = mergedCell.row === cellRange.from.row && mergedCell.col === cellRange.from.col && mergedCell.row + mergedCell.rowspan - 1 === cellRange.to.row && mergedCell.col + mergedCell.colspan - 1 === cellRange.to.col;
if (mergedCellCoversWholeRange) {
this.unmergeRange(cellRange);
} else {
this.mergeSelection(cellRange);
}
}
/**
* Merges the specified range.
*
* @param {Number} startRow Start row of the merged cell.
* @param {Number} startColumn Start column of the merged cell.
* @param {Number} endRow End row of the merged cell.
* @param {Number} endColumn End column of the merged cell.
* @fires Hooks#beforeMergeCells
* @fires Hooks#afterMergeCells
*/
}, {
key: "merge",
value: function merge(startRow, startColumn, endRow, endColumn) {
var start = new _src.CellCoords(startRow, startColumn);
var end = new _src.CellCoords(endRow, endColumn);
this.mergeRange(new _src.CellRange(start, start, end));
}
/**
* Unmerges the merged cell in the provided range.
*
* @param {Number} startRow Start row of the merged cell.
* @param {Number} startColumn Start column of the merged cell.
* @param {Number} endRow End row of the merged cell.
* @param {Number} endColumn End column of the merged cell.
* @fires Hooks#beforeUnmergeCells
* @fires Hooks#afterUnmergeCells
*/
}, {
key: "unmerge",
value: function unmerge(startRow, startColumn, endRow, endColumn) {
var start = new _src.CellCoords(startRow, startColumn);
var end = new _src.CellCoords(endRow, endColumn);
this.unmergeRange(new _src.CellRange(start, start, end));
}
/**
* `afterInit` hook callback.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
this.generateFromSettings(this.hot.getSettings().mergeCells);
this.hot.render();
}
/**
* `beforeKeyDown` hook callback.
*
* @private
* @param {KeyboardEvent} event The `keydown` event object.
*/
}, {
key: "onBeforeKeyDown",
value: function onBeforeKeyDown(event) {
var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
if (ctrlDown && event.keyCode === 77) {
// CTRL + M
this.toggleMerge(this.hot.getSelectedRangeLast());
this.hot.render();
(0, _event.stopImmediatePropagation)(event);
}
}
/**
* Modifies the information on whether the current selection contains multiple cells. The `afterIsMultipleSelection` hook callback.
*
* @private
* @param {Boolean} isMultiple
* @returns {Boolean}
*/
}, {
key: "onAfterIsMultipleSelection",
value: function onAfterIsMultipleSelection(isMultiple) {
if (isMultiple) {
var mergedCells = this.mergedCellsCollection.mergedCells;
var selectionRange = this.hot.getSelectedRangeLast();
for (var group = 0; group < mergedCells.length; group += 1) {
if (selectionRange.highlight.row === mergedCells[group].row && selectionRange.highlight.col === mergedCells[group].col && selectionRange.to.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && selectionRange.to.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
return false;
}
}
}
return isMultiple;
}
/**
* `modifyTransformStart` hook callback.
*
* @private
* @param {Object} delta The transformation delta.
*/
}, {
key: "onModifyTransformStart",
value: function onModifyTransformStart(delta) {
var priv = privatePool.get(this);
var currentlySelectedRange = this.hot.getSelectedRangeLast();
var newDelta = {
row: delta.row,
col: delta.col
};
var nextPosition = null;
var currentPosition = new _src.CellCoords(currentlySelectedRange.highlight.row, currentlySelectedRange.highlight.col);
var mergedParent = this.mergedCellsCollection.get(currentPosition.row, currentPosition.col);
if (!priv.lastDesiredCoords) {
priv.lastDesiredCoords = new _src.CellCoords(null, null);
}
if (mergedParent) {
// only merge selected
var mergeTopLeft = new _src.CellCoords(mergedParent.row, mergedParent.col);
var mergeBottomRight = new _src.CellCoords(mergedParent.row + mergedParent.rowspan - 1, mergedParent.col + mergedParent.colspan - 1);
var mergeRange = new _src.CellRange(mergeTopLeft, mergeTopLeft, mergeBottomRight);
if (!mergeRange.includes(priv.lastDesiredCoords)) {
priv.lastDesiredCoords = new _src.CellCoords(null, null); // reset outdated version of lastDesiredCoords
}
newDelta.row = priv.lastDesiredCoords.row ? priv.lastDesiredCoords.row - currentPosition.row : newDelta.row;
newDelta.col = priv.lastDesiredCoords.col ? priv.lastDesiredCoords.col - currentPosition.col : newDelta.col;
if (delta.row > 0) {
// moving down
newDelta.row = mergedParent.row + mergedParent.rowspan - 1 - currentPosition.row + delta.row;
} else if (delta.row < 0) {
// moving up
newDelta.row = currentPosition.row - mergedParent.row + delta.row;
}
if (delta.col > 0) {
// moving right
newDelta.col = mergedParent.col + mergedParent.colspan - 1 - currentPosition.col + delta.col;
} else if (delta.col < 0) {
// moving left
newDelta.col = currentPosition.col - mergedParent.col + delta.col;
}
}
nextPosition = new _src.CellCoords(currentlySelectedRange.highlight.row + newDelta.row, currentlySelectedRange.highlight.col + newDelta.col);
var nextParentIsMerged = this.mergedCellsCollection.get(nextPosition.row, nextPosition.col);
if (nextParentIsMerged) {
// skipping the invisible cells in the merge range
priv.lastDesiredCoords = nextPosition;
newDelta = {
row: nextParentIsMerged.row - currentPosition.row,
col: nextParentIsMerged.col - currentPosition.col
};
}
if (newDelta.row !== 0) {
delta.row = newDelta.row;
}
if (newDelta.col !== 0) {
delta.col = newDelta.col;
}
}
/**
* `modifyTransformEnd` hook callback. Needed to handle "jumping over" merged merged cells, while selecting.
*
* @private
* @param {Object} delta The transformation delta.
*/
}, {
key: "onModifyTransformEnd",
value: function onModifyTransformEnd(delta) {
var _this6 = this;
var currentSelectionRange = this.hot.getSelectedRangeLast();
var newDelta = (0, _object.clone)(delta);
var newSelectionRange = this.selectionCalculations.getUpdatedSelectionRange(currentSelectionRange, delta);
var tempDelta = (0, _object.clone)(newDelta);
var mergedCellsWithinRange = this.mergedCellsCollection.getWithinRange(newSelectionRange, true);
do {
tempDelta = (0, _object.clone)(newDelta);
this.selectionCalculations.getUpdatedSelectionRange(currentSelectionRange, newDelta);
(0, _array.arrayEach)(mergedCellsWithinRange, function (mergedCell) {
_this6.selectionCalculations.snapDelta(newDelta, currentSelectionRange, mergedCell);
});
} while (newDelta.row !== tempDelta.row || newDelta.col !== tempDelta.col);
delta.row = newDelta.row;
delta.col = newDelta.col;
}
/**
* `modifyGetCellCoords` hook callback. Swaps the `getCell` coords with the merged parent coords.
*
* @private
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {Array}
*/
}, {
key: "onModifyGetCellCoords",
value: function onModifyGetCellCoords(row, column) {
var mergeParent = this.mergedCellsCollection.get(row, column);
return mergeParent ? [mergeParent.row, mergeParent.col, mergeParent.row + mergeParent.rowspan - 1, mergeParent.col + mergeParent.colspan - 1] : void 0;
}
/**
* `afterContextMenuDefaultOptions` hook callback.
*
* @private
* @param {Object} defaultOptions The default context menu options.
*/
}, {
key: "addMergeActionsToContextMenu",
value: function addMergeActionsToContextMenu(defaultOptions) {
defaultOptions.items.push({
name: '---------'
}, (0, _toggleMerge.default)(this));
}
/**
* `afterRenderer` hook callback.
*
* @private
* @param {HTMLElement} TD The cell to be modified.
* @param {Number} row Row index.
* @param {Number} col Column index.
*/
}, {
key: "onAfterRenderer",
value: function onAfterRenderer(TD, row, col) {
var mergedCell = this.mergedCellsCollection.get(row, col);
(0, _utils.applySpanProperties)(TD, mergedCell, row, col);
}
/**
* `beforeSetRangeEnd` hook callback.
* While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell
*
* @private
* @param {Object} coords Cell coords.
*/
}, {
key: "onBeforeSetRangeEnd",
value: function onBeforeSetRangeEnd(coords) {
var selRange = this.hot.getSelectedRangeLast();
selRange.highlight = new _src.CellCoords(selRange.highlight.row, selRange.highlight.col); // clone in case we will modify its reference
selRange.to = coords;
var rangeExpanded = false;
if (this.hot.selection.isSelectedByColumnHeader() || this.hot.selection.isSelectedByRowHeader()) {
return;
}
do {
rangeExpanded = false;
for (var i = 0; i < this.mergedCellsCollection.mergedCells.length; i += 1) {
var cellInfo = this.mergedCellsCollection.mergedCells[i];
var mergedCellRange = cellInfo.getRange();
if (selRange.expandByRange(mergedCellRange)) {
coords.row = selRange.to.row;
coords.col = selRange.to.col;
rangeExpanded = true;
}
}
} while (rangeExpanded);
}
/**
* The `afterGetCellMeta` hook callback.
*
* @private
* @param {Number} row Row index.
* @param {Number} col Column index.
* @param {Object} cellProperties The cell properties object.
*/
}, {
key: "onAfterGetCellMeta",
value: function onAfterGetCellMeta(row, col, cellProperties) {
var mergeParent = this.mergedCellsCollection.get(row, col);
if (mergeParent && (mergeParent.row !== row || mergeParent.col !== col)) {
cellProperties.copyable = false;
}
}
/**
* `afterViewportRowCalculatorOverride` hook callback.
*
* @private
* @param {Object} calc The row calculator object.
*/
}, {
key: "onAfterViewportRowCalculatorOverride",
value: function onAfterViewportRowCalculatorOverride(calc) {
var _this7 = this;
var colCount = this.hot.countCols();
var mergeParent;
(0, _number.rangeEach)(0, colCount - 1, function (c) {
mergeParent = _this7.mergedCellsCollection.get(calc.startRow, c);
if (mergeParent) {
if (mergeParent.row < calc.startRow) {
calc.startRow = mergeParent.row;
return _this7.onAfterViewportRowCalculatorOverride.call(_this7, calc); // recursively search upwards
}
}
mergeParent = _this7.mergedCellsCollection.get(calc.endRow, c);
if (mergeParent) {
var mergeEnd = mergeParent.row + mergeParent.rowspan - 1;
if (mergeEnd > calc.endRow) {
calc.endRow = mergeEnd;
return _this7.onAfterViewportRowCalculatorOverride.call(_this7, calc); // recursively search upwards
}
}
return true;
});
}
/**
* `afterViewportColumnCalculatorOverride` hook callback.
*
* @private
* @param {Object} calc The column calculator object.
*/
}, {
key: "onAfterViewportColumnCalculatorOverride",
value: function onAfterViewportColumnCalculatorOverride(calc) {
var _this8 = this;
var rowCount = this.hot.countRows();
var mergeParent;
(0, _number.rangeEach)(0, rowCount - 1, function (r) {
mergeParent = _this8.mergedCellsCollection.get(r, calc.startColumn);
if (mergeParent && mergeParent.col < calc.startColumn) {
calc.startColumn = mergeParent.col;
return _this8.onAfterViewportColumnCalculatorOverride.call(_this8, calc); // recursively search upwards
}
mergeParent = _this8.mergedCellsCollection.get(r, calc.endColumn);
if (mergeParent) {
var mergeEnd = mergeParent.col + mergeParent.colspan - 1;
if (mergeEnd > calc.endColumn) {
calc.endColumn = mergeEnd;
return _this8.onAfterViewportColumnCalculatorOverride.call(_this8, calc); // recursively search upwards
}
}
return true;
});
}
/**
* The `modifyAutofillRange` hook callback.
*
* @private
* @param {Array} drag The drag area coordinates.
* @param {Array} select The selection information.
* @return {Array} The new drag area.
*/
}, {
key: "onModifyAutofillRange",
value: function onModifyAutofillRange(drag, select) {
this.autofillCalculations.correctSelectionAreaSize(select);
var dragDirection = this.autofillCalculations.getDirection(select, drag);
var dragArea = drag;
if (this.autofillCalculations.dragAreaOverlapsCollections(select, dragArea, dragDirection)) {
dragArea = select;
return dragArea;
}
var mergedCellsWithinSelectionArea = this.mergedCellsCollection.getWithinRange({
from: {
row: select[0],
col: select[1]
},
to: {
row: select[2],
col: select[3]
}
});
if (!mergedCellsWithinSelectionArea) {
return dragArea;
}
dragArea = this.autofillCalculations.snapDragArea(select, dragArea, dragDirection, mergedCellsWithinSelectionArea);
return dragArea;
}
/**
* `afterCreateCol` hook callback.
*
* @private
* @param {Number} column Column index.
* @param {Number} count Number of created columns.
*/
}, {
key: "onAfterCreateCol",
value: function onAfterCreateCol(column, count) {
this.mergedCellsCollection.shiftCollections('right', column, count);
}
/**
* `afterRemoveCol` hook callback.
*
* @private
* @param {Number} column Column index.
* @param {Number} count Number of removed columns.
*/
}, {
key: "onAfterRemoveCol",
value: function onAfterRemoveCol(column, count) {
this.mergedCellsCollection.shiftCollections('left', column, count);
}
/**
* `afterCreateRow` hook callback.
*
* @private
* @param {Number} row Row index.
* @param {Number} count Number of created rows.
* @param {String} source Source of change.
*/
}, {
key: "onAfterCreateRow",
value: function onAfterCreateRow(row, count, source) {
if (source === 'auto') {
return;
}
this.mergedCellsCollection.shiftCollections('down', row, count);
}
/**
* `afterRemoveRow` hook callback.
*
* @private
* @param {Number} row Row index.
* @param {Number} count Number of removed rows.
*/
}, {
key: "onAfterRemoveRow",
value: function onAfterRemoveRow(row, count) {
this.mergedCellsCollection.shiftCollections('up', row, count);
}
/**
* `afterChange` hook callback. Used to propagate merged cells after using Autofill.
*
* @private
* @param {Array} changes The changes array.
* @param {String} source Determines the source of the change.
*/
}, {
key: "onAfterChange",
value: function onAfterChange(changes, source) {
if (source !== 'Autofill.fill') {
return;
}
this.autofillCalculations.recreateAfterDataPopulation(changes);
}
/**
* `beforeDrawAreaBorders` hook callback.
*
* @private
* @param {Array} corners Coordinates of the area corners.
* @param {String} className Class name for the area.
*/
}, {
key: "onBeforeDrawAreaBorders",
value: function onBeforeDrawAreaBorders(corners, className) {
if (className && className === 'area') {
var selectedRange = this.hot.getSelectedRangeLast();
var mergedCellsWithinRange = this.mergedCellsCollection.getWithinRange(selectedRange);
(0, _array.arrayEach)(mergedCellsWithinRange, function (mergedCell) {
if (selectedRange.getBottomRightCorner().row === mergedCell.getLastRow() && selectedRange.getBottomRightCorner().col === mergedCell.getLastColumn()) {
corners[2] = mergedCell.row;
corners[3] = mergedCell.col;
}
});
}
}
/**
* `afterModifyTransformStart` hook callback. Fixes a problem with navigating through merged cells at the edges of the table
* with the ENTER/SHIFT+ENTER/TAB/SHIFT+TAB keys.
*
* @private
* @param {CellCoords} coords Coordinates of the to-be-selected cell.
* @param {Number} rowTransformDir Row transformation direction (negative value = up, 0 = none, positive value = down)
* @param {Number} colTransformDir Column transformation direction (negative value = up, 0 = none, positive value = down)
*/
}, {
key: "onAfterModifyTransformStart",
value: function onAfterModifyTransformStart(coords, rowTransformDir, colTransformDir) {
if (!this.enabled) {
return;
}
var mergedCellAtCoords = this.mergedCellsCollection.get(coords.row, coords.col);
if (!mergedCellAtCoords) {
return;
}
var goingDown = rowTransformDir > 0;
var goingUp = rowTransformDir < 0;
var goingLeft = colTransformDir < 0;
var goingRight = colTransformDir > 0;
var mergedCellOnBottomEdge = mergedCellAtCoords.row + mergedCellAtCoords.rowspan - 1 === this.hot.countRows() - 1;
var mergedCellOnTopEdge = mergedCellAtCoords.row === 0;
var mergedCellOnRightEdge = mergedCellAtCoords.col + mergedCellAtCoords.colspan - 1 === this.hot.countCols() - 1;
var mergedCellOnLeftEdge = mergedCellAtCoords.col === 0;
if (goingDown && mergedCellOnBottomEdge || goingUp && mergedCellOnTopEdge || goingRight && mergedCellOnRightEdge || goingLeft && mergedCellOnLeftEdge) {
coords.row = mergedCellAtCoords.row;
coords.col = mergedCellAtCoords.col;
}
}
/**
* `afterDrawSelection` hook callback. Used to add the additional class name for the entirely-selected merged cells.
*
* @private
* @param {Number} currentRow Row index of the currently processed cell.
* @param {Number} currentColumn Column index of the currently cell.
* @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
* @param {Number|undefined} layerLevel Number indicating which layer of selection is currently processed.
* @returns {String|undefined} A `String`, which will act as an additional `className` to be added to the currently processed cell.
*/
}, {
key: "onAfterDrawSelection",
value: function onAfterDrawSelection(currentRow, currentColumn, cornersOfSelection, layerLevel) {
return this.selectionCalculations.getSelectedMergedCellClassName(currentRow, currentColumn, cornersOfSelection, layerLevel);
}
/**
* `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
*
* @private
* @returns {String[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
*/
}, {
key: "onBeforeRemoveCellClassNames",
value: function onBeforeRemoveCellClassNames() {
return this.selectionCalculations.getSelectedMergedCellClassNameToRemove();
}
}]);
return MergeCells;
}(_base.default);
(0, _plugins.registerPlugin)('mergeCells', MergeCells);
var _default = MergeCells;
exports.default = _default;
/***/ }),
/* 419 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(33);
exports.__esModule = true;
exports.default = void 0;
var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(65));
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _cellCoords = _interopRequireDefault(__webpack_require__(168));
var _index = __webpack_require__(25);
var _number = __webpack_require__(15);
var _console = __webpack_require__(55);
var _array = __webpack_require__(3);
var _utils = __webpack_require__(244);
var _templateLiteralTag = __webpack_require__(67);
function _templateObject() {
var data = (0, _taggedTemplateLiteral2.default)(["The merged cell declared at [", ", ", "], overlaps with the other declared merged \n cell. The overlapping merged cell was not added to the table, please fix your setup."]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
/**
* Defines a container object for the merged cells.
*
* @class MergedCellsCollection
* @plugin MergeCells
*/
var MergedCellsCollection =
/*#__PURE__*/
function () {
function MergedCellsCollection(plugin) {
(0, _classCallCheck2.default)(this, MergedCellsCollection);
/**
* Reference to the Merge Cells plugin.
*
* @type {MergeCells}
*/
this.plugin = plugin;
/**
* Array of merged cells.
*
* @type {Array}
*/
this.mergedCells = [];
/**
* The Handsontable instance.
*
* @type {Handsontable}
*/
this.hot = plugin.hot;
}
/**
* Get a warning message for when the declared merged cell data overlaps already existing merged cells.
*
* @param {Object} newMergedCell Object containg information about the merged cells that was about to be added.
* @return {String}
*/
(0, _createClass2.default)(MergedCellsCollection, [{
key: "get",
/**
* Get a merged cell from the container, based on the provided arguments. You can provide either the "starting coordinates"
* of a merged cell, or any coordinates from the body of the merged cell.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {MergedCellCoords|Boolean} Returns a wanted merged cell on success and `false` on failure.
*/
value: function get(row, column) {
var mergedCells = this.mergedCells;
var result = false;
(0, _array.arrayEach)(mergedCells, function (mergedCell) {
if (mergedCell.row <= row && mergedCell.row + mergedCell.rowspan - 1 >= row && mergedCell.col <= column && mergedCell.col + mergedCell.colspan - 1 >= column) {
result = mergedCell;
return false;
}
return true;
});
return result;
}
/**
* Get a merged cell containing the provided range.
*
* @param {CellRange|Object} range The range to search merged cells for.
* @return {MergedCellCoords|Boolean}
*/
}, {
key: "getByRange",
value: function getByRange(range) {
var mergedCells = this.mergedCells;
var result = false;
(0, _array.arrayEach)(mergedCells, function (mergedCell) {
if (mergedCell.row <= range.from.row && mergedCell.row + mergedCell.rowspan - 1 >= range.to.row && mergedCell.col <= range.from.col && mergedCell.col + mergedCell.colspan - 1 >= range.to.col) {
result = mergedCell;
return result;
}
return true;
});
return result;
}
/**
* Get a merged cell contained in the provided range.
*
* @param {CellRange|Object} range The range to search merged cells in.
* @param [countPartials=false] If set to `true`, all the merged cells overlapping the range will be taken into calculation.
* @return {Array|Boolean} Array of found merged cells of `false` if none were found.
*/
}, {
key: "getWithinRange",
value: function getWithinRange(range) {
var countPartials = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var mergedCells = this.mergedCells;
var foundMergedCells = [];
var testedRange = range;
if (!testedRange.includesRange) {
var from = new _index.CellCoords(testedRange.from.row, testedRange.from.col);
var to = new _index.CellCoords(testedRange.to.row, testedRange.to.col);
testedRange = new _index.CellRange(from, from, to);
}
(0, _array.arrayEach)(mergedCells, function (mergedCell) {
var mergedCellTopLeft = new _index.CellCoords(mergedCell.row, mergedCell.col);
var mergedCellBottomRight = new _index.CellCoords(mergedCell.row + mergedCell.rowspan - 1, mergedCell.col + mergedCell.colspan - 1);
var mergedCellRange = new _index.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight);
if (countPartials) {
if (testedRange.overlaps(mergedCellRange)) {
foundMergedCells.push(mergedCell);
}
} else if (testedRange.includesRange(mergedCellRange)) {
foundMergedCells.push(mergedCell);
}
});
return foundMergedCells.length ? foundMergedCells : false;
}
/**
* Add a merged cell to the container.
*
* @param {Object} mergedCellInfo The merged cell information object. Has to contain `row`, `col`, `colspan` and `rowspan` properties.
* @return {MergedCellCoords|Boolean} Returns the new merged cell on success and `false` on failure.
*/
}, {
key: "add",
value: function add(mergedCellInfo) {
var mergedCells = this.mergedCells;
var row = mergedCellInfo.row;
var column = mergedCellInfo.col;
var rowspan = mergedCellInfo.rowspan;
var colspan = mergedCellInfo.colspan;
var newMergedCell = new _cellCoords.default(row, column, rowspan, colspan);
var alreadyExists = this.get(row, column);
var isOverlapping = this.isOverlapping(newMergedCell);
if (!alreadyExists && !isOverlapping) {
if (this.hot) {
newMergedCell.normalize(this.hot);
}
mergedCells.push(newMergedCell);
return newMergedCell;
}
(0, _console.warn)(MergedCellsCollection.IS_OVERLAPPING_WARNING(newMergedCell));
return false;
}
/**
* Remove a merged cell from the container. You can provide either the "starting coordinates"
* of a merged cell, or any coordinates from the body of the merged cell.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @return {MergedCellCoords|Boolean} Returns the removed merged cell on success and `false` on failure.
*/
}, {
key: "remove",
value: function remove(row, column) {
var mergedCells = this.mergedCells;
var wantedCollection = this.get(row, column);
var wantedCollectionIndex = wantedCollection ? this.mergedCells.indexOf(wantedCollection) : null;
if (wantedCollection && wantedCollectionIndex !== false) {
mergedCells.splice(wantedCollectionIndex, 1);
return wantedCollection;
}
return false;
}
/**
* Clear all the merged cells.
*/
}, {
key: "clear",
value: function clear() {
var _this = this;
var mergedCells = this.mergedCells;
var mergedCellParentsToClear = [];
var hiddenCollectionElements = [];
(0, _array.arrayEach)(mergedCells, function (mergedCell) {
var TD = _this.hot.getCell(mergedCell.row, mergedCell.col);
if (TD) {
mergedCellParentsToClear.push([TD, _this.get(mergedCell.row, mergedCell.col), mergedCell.row, mergedCell.col]);
}
});
this.mergedCells.length = 0;
(0, _array.arrayEach)(mergedCellParentsToClear, function (mergedCell, i) {
(0, _number.rangeEach)(0, mergedCell.rowspan - 1, function (j) {
(0, _number.rangeEach)(0, mergedCell.colspan - 1, function (k) {
if (k !== 0 || j !== 0) {
var TD = _this.hot.getCell(mergedCell.row + j, mergedCell.col + k);
if (TD) {
hiddenCollectionElements.push([TD, null, null, null]);
}
}
});
});
mergedCellParentsToClear[i][1] = null;
});
(0, _array.arrayEach)(mergedCellParentsToClear, function (mergedCellParents) {
_utils.applySpanProperties.apply(void 0, (0, _toConsumableArray2.default)(mergedCellParents));
});
(0, _array.arrayEach)(hiddenCollectionElements, function (hiddenCollectionElement) {
_utils.applySpanProperties.apply(void 0, (0, _toConsumableArray2.default)(hiddenCollectionElement));
});
}
/**
* Check if the provided merged cell overlaps with the others in the container.
*
* @param {MergedCellCoords} mergedCell The merged cell to check against all others in the container.
* @return {Boolean} `true` if the provided merged cell overlaps with the others, `false` otherwise.
*/
}, {
key: "isOverlapping",
value: function isOverlapping(mergedCell) {
var mergedCellRange = new _index.CellRange(null, new _index.CellCoords(mergedCell.row, mergedCell.col), new _index.CellCoords(mergedCell.row + mergedCell.rowspan - 1, mergedCell.col + mergedCell.colspan - 1));
var result = false;
(0, _array.arrayEach)(this.mergedCells, function (col) {
var currentRange = new _index.CellRange(null, new _index.CellCoords(col.row, col.col), new _index.CellCoords(col.row + col.rowspan - 1, col.col + col.colspan - 1));
if (currentRange.overlaps(mergedCellRange)) {
result = true;
return false;
}
return true;
});
return result;
}
/**
* Check whether the provided row/col coordinates direct to a merged parent.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @return {Boolean}
*/
}, {
key: "isMergedParent",
value: function isMergedParent(row, column) {
var mergedCells = this.mergedCells;
var result = false;
(0, _array.arrayEach)(mergedCells, function (mergedCell) {
if (mergedCell.row === row && mergedCell.col === column) {
result = true;
return false;
}
return true;
});
return result;
}
/**
* Shift the merged cell in the direction and by an offset defined in the arguments.
*
* @param {String} direction `right`, `left`, `up` or `down`.
* @param {Number} index Index where the change, which caused the shifting took place.
* @param {Number} count Number of rows/columns added/removed in the preceding action.
*/
}, {
key: "shiftCollections",
value: function shiftCollections(direction, index, count) {
var _this2 = this;
var shiftVector = [0, 0];
switch (direction) {
case 'right':
shiftVector[0] += count;
break;
case 'left':
shiftVector[0] -= count;
break;
case 'down':
shiftVector[1] += count;
break;
case 'up':
shiftVector[1] -= count;
break;
default:
}
(0, _array.arrayEach)(this.mergedCells, function (currentMerge) {
currentMerge.shift(shiftVector, index);
});
(0, _number.rangeEachReverse)(this.mergedCells.length - 1, 0, function (i) {
var currentMerge = _this2.mergedCells[i];
if (currentMerge && currentMerge.removed) {
_this2.mergedCells.splice(_this2.mergedCells.indexOf(currentMerge), 1);
}
});
}
}], [{
key: "IS_OVERLAPPING_WARNING",
value: function IS_OVERLAPPING_WARNING(newMergedCell) {
return (0, _templateLiteralTag.toSingleLine)(_templateObject(), newMergedCell.row, newMergedCell.col);
}
}]);
return MergedCellsCollection;
}();
var _default = MergedCellsCollection;
exports.default = _default;
/***/ }),
/* 420 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(40);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _object = __webpack_require__(4);
var _src = __webpack_require__(25);
var _array = __webpack_require__(3);
/**
* Class responsible for all of the Autofill-related operations on merged cells.
*
* @class AutofillCalculations
* @plugin MergeCells
* @util
*/
var AutofillCalculations =
/*#__PURE__*/
function () {
function AutofillCalculations(plugin) {
(0, _classCallCheck2.default)(this, AutofillCalculations);
/**
* Reference to the Merge Cells plugin.
*
* @type {MergeCells}
*/
this.plugin = plugin;
/**
* Reference to the MergedCellsCollection class instance.
*
* @type {MergedCellsCollection}
*/
this.mergedCellsCollection = this.plugin.mergedCellsCollection;
/**
* Cache of the currently processed autofill data.
*
* @private
* @type {Object}
*/
this.currentFillData = null;
}
/**
* Correct the provided selection area, so it's not selecting only a part of a merged cell.
*
* @param {Array} selectionArea
*/
(0, _createClass2.default)(AutofillCalculations, [{
key: "correctSelectionAreaSize",
value: function correctSelectionAreaSize(selectionArea) {
if (selectionArea[0] === selectionArea[2] && selectionArea[1] === selectionArea[3]) {
var mergedCell = this.mergedCellsCollection.get(selectionArea[0], selectionArea[1]);
if (mergedCell) {
selectionArea[2] = selectionArea[0] + mergedCell.rowspan - 1;
selectionArea[3] = selectionArea[1] + mergedCell.colspan - 1;
}
}
}
/**
* Get the direction of the autofill process.
*
* @param {Array} selectionArea The selection area.
* @param {Array} finalArea The final area (base + drag).
* @return {String} `up`, `down`, `left` or `right`.
*/
}, {
key: "getDirection",
value: function getDirection(selectionArea, finalArea) {
var direction = null;
if (finalArea[0] === selectionArea[0] && finalArea[1] === selectionArea[1] && finalArea[3] === selectionArea[3]) {
direction = 'down';
} else if (finalArea[2] === selectionArea[2] && finalArea[1] === selectionArea[1] && finalArea[3] === selectionArea[3]) {
direction = 'up';
} else if (finalArea[1] === selectionArea[1] && finalArea[2] === selectionArea[2]) {
direction = 'right';
} else {
direction = 'left';
}
return direction;
}
/**
* Snap the drag area to the farthest merged cell, so it won't clip any of the merged cells.
*
* @param {Array} baseArea The base selected area.
* @param {Array} dragArea The drag area.
* @param {String} dragDirection The autofill drag direction.
* @param {Array} foundMergedCells MergeCellCoords found in the base selection area.
* @return {Array} The new drag area
*/
}, {
key: "snapDragArea",
value: function snapDragArea(baseArea, dragArea, dragDirection, foundMergedCells) {
var newDragArea = dragArea.slice(0);
var fillSize = this.getAutofillSize(baseArea, dragArea, dragDirection);
var _baseArea = (0, _slicedToArray2.default)(baseArea, 4),
baseAreaStartRow = _baseArea[0],
baseAreaStartColumn = _baseArea[1],
baseAreaEndRow = _baseArea[2],
baseAreaEndColumn = _baseArea[3];
var verticalDirection = ['up', 'down'].indexOf(dragDirection) > -1;
var fullCycle = verticalDirection ? baseAreaEndRow - baseAreaStartRow + 1 : baseAreaEndColumn - baseAreaStartColumn + 1;
var fulls = Math.floor(fillSize / fullCycle) * fullCycle;
var partials = fillSize - fulls;
var farthestCollection = this.getFarthestCollection(baseArea, dragArea, dragDirection, foundMergedCells);
if (farthestCollection) {
if (dragDirection === 'down') {
var fill = farthestCollection.row + farthestCollection.rowspan - baseAreaStartRow - partials;
var newLimit = newDragArea[2] + fill;
if (newLimit >= this.plugin.hot.countRows()) {
newDragArea[2] -= partials;
} else {
newDragArea[2] += partials ? fill : 0;
}
} else if (dragDirection === 'right') {
var _fill = farthestCollection.col + farthestCollection.colspan - baseAreaStartColumn - partials;
var _newLimit = newDragArea[3] + _fill;
if (_newLimit >= this.plugin.hot.countCols()) {
newDragArea[3] -= partials;
} else {
newDragArea[3] += partials ? _fill : 0;
}
} else if (dragDirection === 'up') {
var _fill2 = baseAreaEndRow - partials - farthestCollection.row + 1;
var _newLimit2 = newDragArea[0] + _fill2;
if (_newLimit2 < 0) {
newDragArea[0] += partials;
} else {
newDragArea[0] -= partials ? _fill2 : 0;
}
} else if (dragDirection === 'left') {
var _fill3 = baseAreaEndColumn - partials - farthestCollection.col + 1;
var _newLimit3 = newDragArea[1] + _fill3;
if (_newLimit3 < 0) {
newDragArea[1] += partials;
} else {
newDragArea[1] -= partials ? _fill3 : 0;
}
}
}
this.updateCurrentFillCache({
baseArea: baseArea,
dragDirection: dragDirection,
foundMergedCells: foundMergedCells,
fillSize: fillSize,
dragArea: newDragArea,
cycleLength: fullCycle
});
return newDragArea;
}
/**
* Update the current fill cache with the provided object.
*
* @private
* @param {Object} updateObject
*/
}, {
key: "updateCurrentFillCache",
value: function updateCurrentFillCache(updateObject) {
if (!this.currentFillData) {
this.currentFillData = {};
}
(0, _object.extend)(this.currentFillData, updateObject);
}
/**
* Get the "length" of the drag area.
*
* @private
* @param {Array} baseArea The base selection area.
* @param {Array} dragArea The drag area (containing the base area).
* @param {String} direction The drag direction.
* @return {Number|null} The "length" (height or width, depending on the direction) of the drag.
*/
}, {
key: "getAutofillSize",
value: function getAutofillSize(baseArea, dragArea, direction) {
var _baseArea2 = (0, _slicedToArray2.default)(baseArea, 4),
baseAreaStartRow = _baseArea2[0],
baseAreaStartColumn = _baseArea2[1],
baseAreaEndRow = _baseArea2[2],
baseAreaEndColumn = _baseArea2[3];
var _dragArea = (0, _slicedToArray2.default)(dragArea, 4),
dragAreaStartRow = _dragArea[0],
dragAreaStartColumn = _dragArea[1],
dragAreaEndRow = _dragArea[2],
dragAreaEndColumn = _dragArea[3];
switch (direction) {
case 'up':
return baseAreaStartRow - dragAreaStartRow;
case 'down':
return dragAreaEndRow - baseAreaEndRow;
case 'left':
return baseAreaStartColumn - dragAreaStartColumn;
case 'right':
return dragAreaEndColumn - baseAreaEndColumn;
default:
return null;
}
}
/**
* Trim the default drag area (containing the selection area) to the drag-only area.
*
* @private
* @param {Array} baseArea The base selection area.
* @param {Array} dragArea The base selection area extended by the drag area.
* @param {String} direction Drag direction.
* @return {Array|null} Array representing the drag area coordinates.
*/
}, {
key: "getDragArea",
value: function getDragArea(baseArea, dragArea, direction) {
var _baseArea3 = (0, _slicedToArray2.default)(baseArea, 4),
baseAreaStartRow = _baseArea3[0],
baseAreaStartColumn = _baseArea3[1],
baseAreaEndRow = _baseArea3[2],
baseAreaEndColumn = _baseArea3[3];
var _dragArea2 = (0, _slicedToArray2.default)(dragArea, 4),
dragAreaStartRow = _dragArea2[0],
dragAreaStartColumn = _dragArea2[1],
dragAreaEndRow = _dragArea2[2],
dragAreaEndColumn = _dragArea2[3];
switch (direction) {
case 'up':
return [dragAreaStartRow, dragAreaStartColumn, baseAreaStartRow - 1, baseAreaEndColumn];
case 'down':
return [baseAreaEndRow + 1, baseAreaStartColumn, dragAreaEndRow, baseAreaEndColumn];
case 'left':
return [dragAreaStartRow, dragAreaStartColumn, baseAreaEndRow, baseAreaStartColumn - 1];
case 'right':
return [baseAreaStartRow, baseAreaEndColumn + 1, dragAreaEndRow, dragAreaEndColumn];
default:
return null;
}
}
/**
* Get the to-be-farthest merged cell in the newly filled area.
*
* @private
* @param {Array} baseArea The base selection area.
* @param {Array} dragArea The drag area (containing the base area).
* @param {String} direction The drag direction.
* @param {Array} mergedCellArray Array of the merged cells found in the base area.
* @return {MergedCellCoords|null}
*/
}, {
key: "getFarthestCollection",
value: function getFarthestCollection(baseArea, dragArea, direction, mergedCellArray) {
var _baseArea4 = (0, _slicedToArray2.default)(baseArea, 4),
baseAreaStartRow = _baseArea4[0],
baseAreaStartColumn = _baseArea4[1],
baseAreaEndRow = _baseArea4[2],
baseAreaEndColumn = _baseArea4[3];
var verticalDirection = ['up', 'down'].indexOf(direction) > -1;
var baseEnd = verticalDirection ? baseAreaEndRow : baseAreaEndColumn;
var baseStart = verticalDirection ? baseAreaStartRow : baseAreaStartColumn;
var fillSize = this.getAutofillSize(baseArea, dragArea, direction);
var fullCycle = verticalDirection ? baseAreaEndRow - baseAreaStartRow + 1 : baseAreaEndColumn - baseAreaStartColumn + 1;
var fulls = Math.floor(fillSize / fullCycle) * fullCycle;
var partials = fillSize - fulls;
var inclusionFunctionName = null;
var farthestCollection = null;
var endOfDragRecreationIndex = null;
switch (direction) {
case 'up':
inclusionFunctionName = 'includesVertically';
endOfDragRecreationIndex = baseEnd - partials + 1;
break;
case 'left':
inclusionFunctionName = 'includesHorizontally';
endOfDragRecreationIndex = baseEnd - partials + 1;
break;
case 'down':
inclusionFunctionName = 'includesVertically';
endOfDragRecreationIndex = baseStart + partials - 1;
break;
case 'right':
inclusionFunctionName = 'includesHorizontally';
endOfDragRecreationIndex = baseStart + partials - 1;
break;
default:
}
(0, _array.arrayEach)(mergedCellArray, function (currentCollection) {
if (currentCollection[inclusionFunctionName](endOfDragRecreationIndex) && currentCollection.isFarther(farthestCollection, direction)) {
farthestCollection = currentCollection;
}
});
return farthestCollection;
}
/**
* Recreate the merged cells after the autofill process.
*
* @param {Array} changes Changes made.
*/
}, {
key: "recreateAfterDataPopulation",
value: function recreateAfterDataPopulation(changes) {
if (!this.currentFillData) {
return;
}
var fillRange = this.getRangeFromChanges(changes);
var foundMergedCells = this.currentFillData.foundMergedCells;
var dragDirection = this.currentFillData.dragDirection;
var inBounds = function inBounds(current, offset) {
switch (dragDirection) {
case 'up':
return current.row - offset >= fillRange.from.row;
case 'down':
return current.row + current.rowspan - 1 + offset <= fillRange.to.row;
case 'left':
return current.col - offset >= fillRange.from.column;
case 'right':
return current.col + current.colspan - 1 + offset <= fillRange.to.column;
default:
return null;
}
};
var fillOffset = 0;
var current = null;
var multiplier = 1;
do {
for (var j = 0; j < foundMergedCells.length; j += 1) {
current = foundMergedCells[j];
fillOffset = multiplier * this.currentFillData.cycleLength;
if (inBounds(current, fillOffset)) {
switch (dragDirection) {
case 'up':
this.plugin.mergedCellsCollection.add({
row: current.row - fillOffset,
rowspan: current.rowspan,
col: current.col,
colspan: current.colspan
});
break;
case 'down':
this.plugin.mergedCellsCollection.add({
row: current.row + fillOffset,
rowspan: current.rowspan,
col: current.col,
colspan: current.colspan
});
break;
case 'left':
this.plugin.mergedCellsCollection.add({
row: current.row,
rowspan: current.rowspan,
col: current.col - fillOffset,
colspan: current.colspan
});
break;
case 'right':
this.plugin.mergedCellsCollection.add({
row: current.row,
rowspan: current.rowspan,
col: current.col + fillOffset,
colspan: current.colspan
});
break;
default:
}
}
if (j === foundMergedCells.length - 1) {
multiplier += 1;
}
}
} while (inBounds(current, fillOffset));
this.currentFillData = null;
this.plugin.hot.render();
}
/**
* Get the drag range from the changes made.
*
* @private
* @param {Array} changes The changes made.
* @returns {Object} Object with `from` and `to` properties, both containing `row` and `column` keys.
*/
}, {
key: "getRangeFromChanges",
value: function getRangeFromChanges(changes) {
var _this = this;
var rows = {
min: null,
max: null
};
var columns = {
min: null,
max: null
};
(0, _array.arrayEach)(changes, function (change) {
var rowIndex = change[0];
var columnIndex = _this.plugin.hot.propToCol(change[1]);
if (rows.min === null || rowIndex < rows.min) {
rows.min = rowIndex;
}
if (rows.max === null || rowIndex > rows.max) {
rows.max = rowIndex;
}
if (columns.min === null || columnIndex < columns.min) {
columns.min = columnIndex;
}
if (columns.max === null || columnIndex > columns.max) {
columns.max = columnIndex;
}
});
return {
from: {
row: rows.min,
column: columns.min
},
to: {
row: rows.max,
column: columns.max
}
};
}
/**
* Check if the drag area contains any merged cells.
*
* @param {Array} baseArea The base selection area.
* @param {Array} fullArea The base area extended by the drag area.
* @param {String} direction Drag direction.
* @returns {Boolean}
*/
}, {
key: "dragAreaOverlapsCollections",
value: function dragAreaOverlapsCollections(baseArea, fullArea, direction) {
var dragArea = this.getDragArea(baseArea, fullArea, direction);
var _dragArea3 = (0, _slicedToArray2.default)(dragArea, 4),
dragAreaStartRow = _dragArea3[0],
dragAreaStartColumn = _dragArea3[1],
dragAreaEndRow = _dragArea3[2],
dragAreaEndColumn = _dragArea3[3];
var topLeft = new _src.CellCoords(dragAreaStartRow, dragAreaStartColumn);
var bottomRight = new _src.CellCoords(dragAreaEndRow, dragAreaEndColumn);
var dragRange = new _src.CellRange(topLeft, topLeft, bottomRight);
return !!this.mergedCellsCollection.getWithinRange(dragRange, true);
}
}]);
return AutofillCalculations;
}();
var _default = AutofillCalculations;
exports.default = _default;
/***/ }),
/* 421 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(34);
__webpack_require__(39);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _src = __webpack_require__(25);
/**
* Class responsible for all of the Selection-related operations on merged cells.
*
* @class SelectionCalculations
* @plugin MergeCells
* @util
*/
var SelectionCalculations =
/*#__PURE__*/
function () {
function SelectionCalculations(plugin) {
(0, _classCallCheck2.default)(this, SelectionCalculations);
/**
* Reference to the Merge Cells plugin.
*
* @type {MergeCells}
*/
this.plugin = plugin;
/**
* Class name used for fully selected merged cells.
*
* @type {String}
*/
this.fullySelectedMergedCellClassName = 'fullySelectedMergedCell';
}
/**
* "Snap" the delta value according to defined merged cells. (In other words, compensate the rowspan -
* e.g. going up with `delta.row = -1` over a merged cell with `rowspan = 3`, `delta.row` should change to `-3`.)
*
* @param {Object} delta The delta object containing `row` and `col` properties.
* @param {CellRange} selectionRange The selection range.
* @param {Object} mergedCell A merged cell object.
*/
(0, _createClass2.default)(SelectionCalculations, [{
key: "snapDelta",
value: function snapDelta(delta, selectionRange, mergedCell) {
var cellCoords = selectionRange.to;
var newRow = cellCoords.row + delta.row;
var newColumn = cellCoords.col + delta.col;
if (delta.row) {
this.jumpOverMergedCell(delta, mergedCell, newRow);
} else if (delta.col) {
this.jumpOverMergedCell(delta, mergedCell, newColumn);
}
}
/**
* "Jump" over the merged cell (compensate for the indexes within the merged cell to get past it)
*
* @private
* @param {Object} delta The delta object.
* @param {MergedCellCoords} mergedCell The merge cell object.
* @param {Number} newIndex New row/column index, created with the delta.
*/
}, {
key: "jumpOverMergedCell",
value: function jumpOverMergedCell(delta, mergedCell, newIndex) {
var flatDelta = delta.row || delta.col;
var includesIndex = null;
var firstIndex = null;
var lastIndex = null;
if (delta.row) {
includesIndex = mergedCell.includesVertically(newIndex);
firstIndex = mergedCell.row;
lastIndex = mergedCell.getLastRow();
} else if (delta.col) {
includesIndex = mergedCell.includesHorizontally(newIndex);
firstIndex = mergedCell.col;
lastIndex = mergedCell.getLastColumn();
}
if (flatDelta === 0) {
return;
} else if (flatDelta > 0) {
if (includesIndex && newIndex !== firstIndex) {
flatDelta += lastIndex - newIndex + 1;
}
} else if (includesIndex && newIndex !== lastIndex) {
flatDelta -= newIndex - firstIndex + 1;
}
if (delta.row) {
delta.row = flatDelta;
} else if (delta.col) {
delta.col = flatDelta;
}
}
/**
* Get a selection range with `to` property incremented by the provided delta.
*
* @param {CellRange} oldSelectionRange The base selection range.
* @param {Object} delta The delta object with `row` and `col` properties.
* @returns {CellRange} A new `CellRange` object.
*/
}, {
key: "getUpdatedSelectionRange",
value: function getUpdatedSelectionRange(oldSelectionRange, delta) {
return new _src.CellRange(oldSelectionRange.highlight, oldSelectionRange.from, new _src.CellCoords(oldSelectionRange.to.row + delta.row, oldSelectionRange.to.col + delta.col));
}
/**
* Generate an additional class name for the entirely-selected merged cells.
*
* @param {Number} currentRow Row index of the currently processed cell.
* @param {Number} currentColumn Column index of the currently cell.
* @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
* @param {Number|undefined} layerLevel Number indicating which layer of selection is currently processed.
* @returns {String|undefined} A `String`, which will act as an additional `className` to be added to the currently processed cell.
*/
}, {
key: "getSelectedMergedCellClassName",
value: function getSelectedMergedCellClassName(currentRow, currentColumn, cornersOfSelection, layerLevel) {
var _cornersOfSelection = (0, _slicedToArray2.default)(cornersOfSelection, 4),
startRow = _cornersOfSelection[0],
startColumn = _cornersOfSelection[1],
endRow = _cornersOfSelection[2],
endColumn = _cornersOfSelection[3];
if (layerLevel === void 0) {
return;
}
if (currentRow >= startRow && currentRow <= endRow && currentColumn >= startColumn && currentColumn <= endColumn) {
var isMergedCellParent = this.plugin.mergedCellsCollection.isMergedParent(currentRow, currentColumn);
if (!isMergedCellParent) {
return;
}
var mergedCell = this.plugin.mergedCellsCollection.get(currentRow, currentColumn);
if (!mergedCell) {
return;
}
if (mergedCell.row + mergedCell.rowspan - 1 <= endRow && mergedCell.col + mergedCell.colspan - 1 <= endColumn) {
return "".concat(this.fullySelectedMergedCellClassName, "-").concat(layerLevel);
} else if (this.plugin.selectionCalculations.isMergeCellFullySelected(mergedCell, this.plugin.hot.getSelectedRange())) {
return "".concat(this.fullySelectedMergedCellClassName, "-multiple");
}
}
}
/**
* Check if the provided merged cell is fully selected (by one or many layers of selection)
*
* @param {MergedCellCoords} mergedCell The merged cell to be processed.
* @param {CellRange[]} selectionRangesArray Array of selection ranges.
* @returns {Boolean}
*/
}, {
key: "isMergeCellFullySelected",
value: function isMergeCellFullySelected(mergedCell, selectionRangesArray) {
var mergedCellIndividualCoords = [];
if (!selectionRangesArray || !mergedCell) {
return false;
}
for (var r = 0; r < mergedCell.rowspan; r += 1) {
for (var c = 0; c < mergedCell.colspan; c += 1) {
mergedCellIndividualCoords.push(new _src.CellCoords(mergedCell.row + r, mergedCell.col + c));
}
}
for (var i = 0; i < mergedCellIndividualCoords.length; i += 1) {
var insideSelections = [];
for (var s = 0; s < selectionRangesArray.length; s += 1) {
insideSelections[s] = selectionRangesArray[s].includes(mergedCellIndividualCoords[i]);
}
if (!insideSelections.includes(true)) {
return false;
}
}
return true;
}
/**
* Generate an array of the entirely-selected merged cells' class names.
*
* @returns {String[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
*/
}, {
key: "getSelectedMergedCellClassNameToRemove",
value: function getSelectedMergedCellClassNameToRemove() {
var classNames = [];
for (var i = 0; i <= 7; i += 1) {
classNames.push("".concat(this.fullySelectedMergedCellClassName, "-").concat(i));
}
classNames.push("".concat(this.fullySelectedMergedCellClassName, "-multiple"));
return classNames;
}
}]);
return SelectionCalculations;
}();
var _default = SelectionCalculations;
exports.default = _default;
/***/ }),
/* 422 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.default = toggleMergeItem;
var C = _interopRequireWildcard(__webpack_require__(11));
var _cellCoords = _interopRequireDefault(__webpack_require__(168));
function toggleMergeItem(plugin) {
return {
key: 'mergeCells',
name: function name() {
var sel = this.getSelectedLast();
if (sel) {
var info = plugin.mergedCellsCollection.get(sel[0], sel[1]);
if (info.row === sel[0] && info.col === sel[1] && info.row + info.rowspan - 1 === sel[2] && info.col + info.colspan - 1 === sel[3]) {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_UNMERGE_CELLS);
}
}
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_MERGE_CELLS);
},
callback: function callback() {
plugin.toggleMergeOnSelection();
},
disabled: function disabled() {
var sel = this.getSelectedLast();
if (!sel) {
return true;
}
var isSingleCell = _cellCoords.default.isSingleCell({
row: sel[0],
col: sel[1],
rowspan: sel[2] - sel[0] + 1,
colspan: sel[3] - sel[1] + 1
});
return isSingleCell || this.selection.isSelectedByCorner();
},
hidden: false
};
}
/***/ }),
/* 423 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 424 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(40);
__webpack_require__(33);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _browser = __webpack_require__(72);
var _base = _interopRequireDefault(__webpack_require__(21));
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _plugins = __webpack_require__(20);
var _src = __webpack_require__(25);
/**
* @private
* @plugin MultipleSelectionHandles
*/
var MultipleSelectionHandles =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(MultipleSelectionHandles, _BasePlugin);
/**
* @param {Object} hotInstance
*/
function MultipleSelectionHandles(hotInstance) {
var _this2;
(0, _classCallCheck2.default)(this, MultipleSelectionHandles);
_this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MultipleSelectionHandles).call(this, hotInstance));
/**
* @type {Array}
*/
_this2.dragged = [];
/**
* Instance of EventManager.
*
* @type {EventManager}
*/
_this2.eventManager = null;
/**
* @type {null}
*/
_this2.lastSetCell = null;
return _this2;
}
/**
* Check if the plugin is enabled in the handsontable settings.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(MultipleSelectionHandles, [{
key: "isEnabled",
value: function isEnabled() {
return (0, _browser.isMobileBrowser)();
}
/**
* Enable plugin for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
if (this.enabled) {
return;
}
if (!this.eventManager) {
this.eventManager = new _eventManager.default(this);
}
this.registerListeners();
(0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectionHandles.prototype), "enablePlugin", this).call(this);
}
/**
* Bind the touch events
* @private
*/
}, {
key: "registerListeners",
value: function registerListeners() {
var _this3 = this;
var _this = this;
var rootElement = this.hot.rootElement;
function removeFromDragged(query) {
if (_this.dragged.length === 1) {
// clear array
_this.dragged.splice(0, _this.dragged.length);
return true;
}
var entryPosition = _this.dragged.indexOf(query);
if (entryPosition === -1) {
return false;
} else if (entryPosition === 0) {
_this.dragged = _this.dragged.slice(0, 1);
} else if (entryPosition === 1) {
_this.dragged = _this.dragged.slice(-1);
}
}
this.eventManager.addEventListener(rootElement, 'touchstart', function (event) {
var selectedRange;
if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) {
selectedRange = _this.hot.getSelectedRangeLast();
_this.dragged.push('topLeft');
_this.touchStartRange = {
width: selectedRange.getWidth(),
height: selectedRange.getHeight(),
direction: selectedRange.getDirection()
};
event.preventDefault();
return false;
} else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) {
selectedRange = _this.hot.getSelectedRangeLast();
_this.dragged.push('bottomRight');
_this.touchStartRange = {
width: selectedRange.getWidth(),
height: selectedRange.getHeight(),
direction: selectedRange.getDirection()
};
event.preventDefault();
return false;
}
});
this.eventManager.addEventListener(rootElement, 'touchend', function (event) {
if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) {
removeFromDragged.call(_this, 'topLeft');
_this.touchStartRange = void 0;
event.preventDefault();
return false;
} else if ((0, _element.hasClass)(event.target, 'bottomRightSelectionHandle-HitArea')) {
removeFromDragged.call(_this, 'bottomRight');
_this.touchStartRange = void 0;
event.preventDefault();
return false;
}
});
this.eventManager.addEventListener(rootElement, 'touchmove', function (event) {
var _this3$hot = _this3.hot,
rootWindow = _this3$hot.rootWindow,
rootDocument = _this3$hot.rootDocument;
var scrollTop = (0, _element.getWindowScrollTop)(rootWindow);
var scrollLeft = (0, _element.getWindowScrollLeft)(rootWindow);
var targetCoords;
var selectedRange;
var rangeWidth;
var rangeHeight;
var rangeDirection;
var newRangeCoords;
if (_this.dragged.length === 0) {
return;
}
var endTarget = rootDocument.elementFromPoint(event.touches[0].screenX - scrollLeft, event.touches[0].screenY - scrollTop);
if (!endTarget || endTarget === _this.lastSetCell) {
return;
}
if (endTarget.nodeName === 'TD' || endTarget.nodeName === 'TH') {
targetCoords = _this.hot.getCoords(endTarget);
if (targetCoords.col === -1) {
targetCoords.col = 0;
}
selectedRange = _this.hot.getSelectedRangeLast();
rangeWidth = selectedRange.getWidth();
rangeHeight = selectedRange.getHeight();
rangeDirection = selectedRange.getDirection();
if (rangeWidth === 1 && rangeHeight === 1) {
_this.hot.selection.setRangeEnd(targetCoords);
}
newRangeCoords = _this.getCurrentRangeCoords(selectedRange, targetCoords, _this.touchStartRange.direction, rangeDirection, _this.dragged[0]);
if (newRangeCoords.start !== null) {
_this.hot.selection.setRangeStart(newRangeCoords.start);
}
_this.hot.selection.setRangeEnd(newRangeCoords.end);
_this.lastSetCell = endTarget;
}
event.preventDefault();
});
}
}, {
key: "getCurrentRangeCoords",
value: function getCurrentRangeCoords(selectedRange, currentTouch, touchStartDirection, currentDirection, draggedHandle) {
var topLeftCorner = selectedRange.getTopLeftCorner();
var bottomRightCorner = selectedRange.getBottomRightCorner();
var bottomLeftCorner = selectedRange.getBottomLeftCorner();
var topRightCorner = selectedRange.getTopRightCorner();
var newCoords = {
start: null,
end: null
};
switch (touchStartDirection) {
case 'NE-SW':
switch (currentDirection) {
case 'NE-SW':
case 'NW-SE':
if (draggedHandle === 'topLeft') {
newCoords = {
start: new _src.CellCoords(currentTouch.row, selectedRange.highlight.col),
end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col)
};
} else {
newCoords = {
start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col),
end: new _src.CellCoords(currentTouch.row, topLeftCorner.col)
};
}
break;
case 'SE-NW':
if (draggedHandle === 'bottomRight') {
newCoords = {
start: new _src.CellCoords(bottomRightCorner.row, currentTouch.col),
end: new _src.CellCoords(currentTouch.row, topLeftCorner.col)
};
}
break;
default:
break;
}
break;
case 'NW-SE':
switch (currentDirection) {
case 'NE-SW':
if (draggedHandle === 'topLeft') {
newCoords = {
start: currentTouch,
end: bottomLeftCorner
};
} else {
newCoords.end = currentTouch;
}
break;
case 'NW-SE':
if (draggedHandle === 'topLeft') {
newCoords = {
start: currentTouch,
end: bottomRightCorner
};
} else {
newCoords.end = currentTouch;
}
break;
case 'SE-NW':
if (draggedHandle === 'topLeft') {
newCoords = {
start: currentTouch,
end: topLeftCorner
};
} else {
newCoords.end = currentTouch;
}
break;
case 'SW-NE':
if (draggedHandle === 'topLeft') {
newCoords = {
start: currentTouch,
end: topRightCorner
};
} else {
newCoords.end = currentTouch;
}
break;
default:
break;
}
break;
case 'SW-NE':
switch (currentDirection) {
case 'NW-SE':
if (draggedHandle === 'bottomRight') {
newCoords = {
start: new _src.CellCoords(currentTouch.row, topLeftCorner.col),
end: new _src.CellCoords(bottomLeftCorner.row, currentTouch.col)
};
} else {
newCoords = {
start: new _src.CellCoords(topLeftCorner.row, currentTouch.col),
end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col)
};
}
break;
// case 'NE-SW':
//
// break;
case 'SW-NE':
if (draggedHandle === 'topLeft') {
newCoords = {
start: new _src.CellCoords(selectedRange.highlight.row, currentTouch.col),
end: new _src.CellCoords(currentTouch.row, bottomRightCorner.col)
};
} else {
newCoords = {
start: new _src.CellCoords(currentTouch.row, topLeftCorner.col),
end: new _src.CellCoords(topLeftCorner.row, currentTouch.col)
};
}
break;
case 'SE-NW':
if (draggedHandle === 'bottomRight') {
newCoords = {
start: new _src.CellCoords(currentTouch.row, topRightCorner.col),
end: new _src.CellCoords(topLeftCorner.row, currentTouch.col)
};
} else if (draggedHandle === 'topLeft') {
newCoords = {
start: bottomLeftCorner,
end: currentTouch
};
}
break;
default:
break;
}
break;
case 'SE-NW':
switch (currentDirection) {
case 'NW-SE':
case 'NE-SW':
case 'SW-NE':
if (draggedHandle === 'topLeft') {
newCoords.end = currentTouch;
}
break;
case 'SE-NW':
if (draggedHandle === 'topLeft') {
newCoords.end = currentTouch;
} else {
newCoords = {
start: currentTouch,
end: topLeftCorner
};
}
break;
default:
break;
}
break;
default:
break;
}
return newCoords;
}
/**
* Check if user is currently dragging the handle.
*
* @returns {boolean} Dragging state
*/
}, {
key: "isDragged",
value: function isDragged() {
return this.dragged.length > 0;
}
}]);
return MultipleSelectionHandles;
}(_base.default);
(0, _plugins.registerPlugin)('multipleSelectionHandles', MultipleSelectionHandles);
var _default = MultipleSelectionHandles;
exports.default = _default;
/***/ }),
/* 425 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _dataObserver = _interopRequireDefault(__webpack_require__(426));
var _array = __webpack_require__(3);
var _plugins = __webpack_require__(20);
// Handsontable.hooks.register('afterChangesObserved');
/**
* @plugin ObserveChanges
*
* @description
* This plugin allows to observe data source changes. By default, the plugin is declared as `undefined`, which makes it
* disabled. Enabling this plugin switches the table into one-way data binding where changes are applied into the data
* source (outside from the table) will be automatically reflected in the table.
*
* ```js
* // as a boolean
* observeChanges: true,
* ```
*
* To configure this plugin see {@link Options#observeChanges}.
*/
var ObserveChanges =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ObserveChanges, _BasePlugin);
function ObserveChanges(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ObserveChanges);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ObserveChanges).call(this, hotInstance));
/**
* Instance of {@link DataObserver}.
*
* @private
* @type {DataObserver}
*/
_this.observer = null;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ObserveChanges#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(ObserveChanges, [{
key: "isEnabled",
value: function isEnabled() {
return this.hot.getSettings().observeChanges;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
if (!this.observer) {
this.observer = new _dataObserver.default(this.hot.getSourceData());
this._exposePublicApi();
}
this.observer.addLocalHook('change', function (patches) {
return _this2.onDataChange(patches);
});
this.addHook('afterCreateRow', function () {
return _this2.onAfterTableAlter();
});
this.addHook('afterRemoveRow', function () {
return _this2.onAfterTableAlter();
});
this.addHook('afterCreateCol', function () {
return _this2.onAfterTableAlter();
});
this.addHook('afterRemoveCol', function () {
return _this2.onAfterTableAlter();
});
this.addHook('afterChange', function (changes, source) {
return _this2.onAfterTableAlter(source);
});
this.addHook('afterLoadData', function (firstRun) {
return _this2.onAfterLoadData(firstRun);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(ObserveChanges.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
if (this.observer) {
this.observer.destroy();
this.observer = null;
this._deletePublicApi();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(ObserveChanges.prototype), "disablePlugin", this).call(this);
}
/**
* Data change observer.
*
* @private
* @param {Array} patches An array of objects which every item defines coordinates where data was changed.
*/
}, {
key: "onDataChange",
value: function onDataChange(patches) {
var _this3 = this;
if (!this.observer.isPaused()) {
var sourceName = "".concat(this.pluginName, ".change");
var actions = {
add: function add(patch) {
if (isNaN(patch.col)) {
_this3.hot.runHooks('afterCreateRow', patch.row, 1, sourceName);
} else {
_this3.hot.runHooks('afterCreateCol', patch.col, 1, sourceName);
}
},
remove: function remove(patch) {
if (isNaN(patch.col)) {
_this3.hot.runHooks('afterRemoveRow', patch.row, 1, sourceName);
} else {
_this3.hot.runHooks('afterRemoveCol', patch.col, 1, sourceName);
}
},
replace: function replace(patch) {
_this3.hot.runHooks('afterChange', [[patch.row, patch.col, null, patch.value]], sourceName);
}
};
(0, _array.arrayEach)(patches, function (patch) {
if (actions[patch.op]) {
actions[patch.op](patch);
}
});
this.hot.render();
}
this.hot.runHooks('afterChangesObserved');
}
/**
* On after table alter listener. Prevents infinity loop between internal and external data changing.
*
* @private
* @param source
*/
}, {
key: "onAfterTableAlter",
value: function onAfterTableAlter(source) {
var _this4 = this;
if (source !== 'loadData') {
this.observer.pause();
this.hot.addHookOnce('afterChangesObserved', function () {
return _this4.observer.resume();
});
}
}
/**
* On after load data listener.
*
* @private
* @param {Boolean} firstRun `true` if event was fired first time.
*/
}, {
key: "onAfterLoadData",
value: function onAfterLoadData(firstRun) {
if (!firstRun) {
this.observer.setObservedData(this.hot.getSourceData());
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
if (this.observer) {
this.observer.destroy();
this._deletePublicApi();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(ObserveChanges.prototype), "destroy", this).call(this);
}
/**
* Expose plugins methods to the core.
*
* @private
*/
}, {
key: "_exposePublicApi",
value: function _exposePublicApi() {
var _this5 = this;
var hot = this.hot;
hot.pauseObservingChanges = function () {
return _this5.observer.pause();
};
hot.resumeObservingChanges = function () {
return _this5.observer.resume();
};
hot.isPausedObservingChanges = function () {
return _this5.observer.isPaused();
};
}
/**
* Deletes all previously exposed methods.
*
* @private
*/
}, {
key: "_deletePublicApi",
value: function _deletePublicApi() {
var hot = this.hot;
delete hot.pauseObservingChanges;
delete hot.resumeObservingChanges;
delete hot.isPausedObservingChanges;
}
}]);
return ObserveChanges;
}(_base.default);
var _default = ObserveChanges;
exports.default = _default;
(0, _plugins.registerPlugin)('observeChanges', ObserveChanges);
/***/ }),
/* 426 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _jsonPatchDuplex = _interopRequireDefault(__webpack_require__(427));
var _localHooks = _interopRequireDefault(__webpack_require__(57));
var _object = __webpack_require__(4);
var _utils = __webpack_require__(428);
/**
* @class DataObserver
* @plugin ObserveChanges
*/
var DataObserver =
/*#__PURE__*/
function () {
function DataObserver(observedData) {
(0, _classCallCheck2.default)(this, DataObserver);
/**
* Observed source data.
*
* @type {Array}
*/
this.observedData = null;
/**
* JsonPatch observer.
*
* @type {Object}
*/
this.observer = null;
/**
* Flag which determines if observer is paused or not. Paused observer doesn't emit `change` hooks.
*
* @type {Boolean}
* @default false
*/
this.paused = false;
this.setObservedData(observedData);
}
/**
* Set data to observe.
*
* @param {*} observedData
*/
(0, _createClass2.default)(DataObserver, [{
key: "setObservedData",
value: function setObservedData(observedData) {
var _this = this;
if (this.observer) {
_jsonPatchDuplex.default.unobserve(this.observedData, this.observer);
}
this.observedData = observedData;
this.observer = _jsonPatchDuplex.default.observe(this.observedData, function (patches) {
return _this.onChange(patches);
});
}
/**
* Check if observer was paused.
*
* @returns {Boolean}
*/
}, {
key: "isPaused",
value: function isPaused() {
return this.paused;
}
/**
* Pause observer (stop emitting all detected changes).
*/
}, {
key: "pause",
value: function pause() {
this.paused = true;
}
/**
* Resume observer (emit all detected changes).
*/
}, {
key: "resume",
value: function resume() {
this.paused = false;
}
/**
* JsonPatch on change listener.
*
* @private
* @param {Array} patches An array of object passed from jsonpatch.
*/
}, {
key: "onChange",
value: function onChange(patches) {
this.runLocalHooks('change', (0, _utils.cleanPatches)(patches));
}
/**
* Destroy observer instance.
*/
}, {
key: "destroy",
value: function destroy() {
_jsonPatchDuplex.default.unobserve(this.observedData, this.observer);
this.observedData = null;
this.observer = null;
}
}]);
return DataObserver;
}();
(0, _object.mixin)(DataObserver, _localHooks.default);
var _default = DataObserver;
exports.default = _default;
/***/ }),
/* 427 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(54);
__webpack_require__(40);
__webpack_require__(33);
__webpack_require__(51);
__webpack_require__(76);
__webpack_require__(37);
__webpack_require__(46);
__webpack_require__(30);
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
/*!
* https://github.com/Starcounter-Jack/JSON-Patch
* json-patch-duplex.js version: 0.5.7
* (c) 2013 Joachim Wester
* MIT license
*/
var __extends = void 0 && (void 0).__extends || function (d, b) {
for (var p in b) {
if (b.hasOwnProperty(p)) d[p] = b[p];
}
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var OriginalError = Error;
var jsonpatch;
(function (jsonpatch) {
var _objectKeys = function _objectKeys(obj) {
if (_isArray(obj)) {
var keys = new Array(obj.length);
for (var k = 0; k < keys.length; k++) {
keys[k] = "" + k;
}
return keys;
}
if (Object.keys) {
return Object.keys(obj);
}
var keys = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
keys.push(i);
}
}
return keys;
};
function _equals(a, b) {
switch ((0, _typeof2.default)(a)) {
case 'undefined': //backward compatibility, but really I think we should return false
case 'boolean':
case 'string':
case 'number':
return a === b;
case 'object':
if (a === null) return b === null;
if (_isArray(a)) {
if (!_isArray(b) || a.length !== b.length) return false;
for (var i = 0, l = a.length; i < l; i++) {
if (!_equals(a[i], b[i])) return false;
}
return true;
}
var bKeys = _objectKeys(b);
var bLength = bKeys.length;
if (_objectKeys(a).length !== bLength) return false;
for (var i = 0; i < bLength; i++) {
if (!_equals(a[i], b[i])) return false;
}
return true;
default:
return false;
}
}
/* We use a Javascript hash to store each
function. Each hash entry (property) uses
the operation identifiers specified in rfc6902.
In this way, we can map each patch operation
to its dedicated function in efficient way.
*/
/* The operations applicable to an object */
var objOps = {
add: function add(obj, key) {
obj[key] = this.value;
return true;
},
remove: function remove(obj, key) {
delete obj[key];
return true;
},
replace: function replace(obj, key) {
obj[key] = this.value;
return true;
},
move: function move(obj, key, tree) {
var temp = {
op: "_get",
path: this.from
};
apply(tree, [temp]);
apply(tree, [{
op: "remove",
path: this.from
}]);
apply(tree, [{
op: "add",
path: this.path,
value: temp.value
}]);
return true;
},
copy: function copy(obj, key, tree) {
var temp = {
op: "_get",
path: this.from
};
apply(tree, [temp]);
apply(tree, [{
op: "add",
path: this.path,
value: temp.value
}]);
return true;
},
test: function test(obj, key) {
return _equals(obj[key], this.value);
},
_get: function _get(obj, key) {
this.value = obj[key];
}
};
/* The operations applicable to an array. Many are the same as for the object */
var arrOps = {
add: function add(arr, i) {
arr.splice(i, 0, this.value);
return true;
},
remove: function remove(arr, i) {
arr.splice(i, 1);
return true;
},
replace: function replace(arr, i) {
arr[i] = this.value;
return true;
},
move: objOps.move,
copy: objOps.copy,
test: objOps.test,
_get: objOps._get
};
/* The operations applicable to object root. Many are the same as for the object */
var rootOps = {
add: function add(obj) {
rootOps.remove.call(this, obj);
for (var key in this.value) {
if (this.value.hasOwnProperty(key)) {
obj[key] = this.value[key];
}
}
return true;
},
remove: function remove(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
objOps.remove.call(this, obj, key);
}
}
return true;
},
replace: function replace(obj) {
apply(obj, [{
op: "remove",
path: this.path
}]);
apply(obj, [{
op: "add",
path: this.path,
value: this.value
}]);
return true;
},
move: objOps.move,
copy: objOps.copy,
test: function test(obj) {
return JSON.stringify(obj) === JSON.stringify(this.value);
},
_get: function _get(obj) {
this.value = obj;
}
};
var observeOps = {
add: function add(patches, path) {
var patch = {
op: "add",
path: path + escapePathComponent(this.name),
value: this.object[this.name]
};
patches.push(patch);
},
'delete': function _delete(patches, path) {
var patch = {
op: "remove",
path: path + escapePathComponent(this.name)
};
patches.push(patch);
},
update: function update(patches, path) {
var patch = {
op: "replace",
path: path + escapePathComponent(this.name),
value: this.object[this.name]
};
patches.push(patch);
}
};
function escapePathComponent(str) {
if (str.indexOf('/') === -1 && str.indexOf('~') === -1) return str;
return str.replace(/~/g, '~0').replace(/\//g, '~1');
}
function _getPathRecursive(root, obj) {
var found;
for (var key in root) {
if (root.hasOwnProperty(key)) {
if (root[key] === obj) {
return escapePathComponent(key) + '/';
} else if ((0, _typeof2.default)(root[key]) === 'object') {
found = _getPathRecursive(root[key], obj);
if (found != '') {
return escapePathComponent(key) + '/' + found;
}
}
}
}
return '';
}
function getPath(root, obj) {
if (root === obj) {
return '/';
}
var path = _getPathRecursive(root, obj);
if (path === '') {
throw new OriginalError("Object not found in root");
}
return '/' + path;
}
var beforeDict = [];
var Mirror = function () {
function Mirror(obj) {
this.observers = [];
this.obj = obj;
}
return Mirror;
}();
var ObserverInfo = function () {
function ObserverInfo(callback, observer) {
this.callback = callback;
this.observer = observer;
}
return ObserverInfo;
}();
function getMirror(obj) {
for (var i = 0, ilen = beforeDict.length; i < ilen; i++) {
if (beforeDict[i].obj === obj) {
return beforeDict[i];
}
}
}
function getObserverFromMirror(mirror, callback) {
for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) {
if (mirror.observers[j].callback === callback) {
return mirror.observers[j].observer;
}
}
}
function removeObserverFromMirror(mirror, observer) {
for (var j = 0, jlen = mirror.observers.length; j < jlen; j++) {
if (mirror.observers[j].observer === observer) {
mirror.observers.splice(j, 1);
return;
}
}
}
function unobserve(root, observer) {
observer.unobserve();
}
jsonpatch.unobserve = unobserve;
function deepClone(obj) {
if ((0, _typeof2.default)(obj) === "object") {
return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
} else {
return obj; //no need to clone primitives
}
}
function observe(obj, callback) {
var patches = [];
var root = obj;
var observer;
var mirror = getMirror(obj);
if (!mirror) {
mirror = new Mirror(obj);
beforeDict.push(mirror);
} else {
observer = getObserverFromMirror(mirror, callback);
}
if (observer) {
return observer;
}
observer = {};
mirror.value = deepClone(obj);
if (callback) {
observer.callback = callback;
observer.next = null;
var intervals = this.intervals || [100, 1000, 10000, 60000];
if (intervals.push === void 0) {
throw new OriginalError("jsonpatch.intervals must be an array");
}
var currentInterval = 0;
var dirtyCheck = function dirtyCheck() {
generate(observer);
};
var fastCheck = function fastCheck() {
clearTimeout(observer.next);
observer.next = setTimeout(function () {
dirtyCheck();
currentInterval = 0;
observer.next = setTimeout(slowCheck, intervals[currentInterval++]);
}, 0);
};
var slowCheck = function slowCheck() {
dirtyCheck();
if (currentInterval == intervals.length) currentInterval = intervals.length - 1;
observer.next = setTimeout(slowCheck, intervals[currentInterval++]);
};
if (typeof window !== 'undefined') {
if (window.addEventListener) {
window.addEventListener('mousedown', fastCheck);
window.addEventListener('mouseup', fastCheck);
window.addEventListener('keydown', fastCheck);
} else {
document.documentElement.attachEvent('onmousedown', fastCheck);
document.documentElement.attachEvent('onmouseup', fastCheck);
document.documentElement.attachEvent('onkeydown', fastCheck);
}
}
observer.next = setTimeout(slowCheck, intervals[currentInterval++]);
}
observer.patches = patches;
observer.object = obj;
observer.unobserve = function () {
generate(observer);
clearTimeout(observer.next);
removeObserverFromMirror(mirror, observer);
if (mirror.observers.length === 0) {
beforeDict.splice(beforeDict.indexOf(mirror), 1);
}
if (typeof window !== 'undefined') {
if (window.removeEventListener) {
window.removeEventListener('mousedown', fastCheck);
window.removeEventListener('mouseup', fastCheck);
window.removeEventListener('keydown', fastCheck);
} else {
document.documentElement.detachEvent('onmousedown', fastCheck);
document.documentElement.detachEvent('onmouseup', fastCheck);
document.documentElement.detachEvent('onkeydown', fastCheck);
}
}
};
mirror.observers.push(new ObserverInfo(callback, observer));
return observer;
}
jsonpatch.observe = observe;
function generate(observer) {
var mirror;
for (var i = 0, ilen = beforeDict.length; i < ilen; i++) {
if (beforeDict[i].obj === observer.object) {
mirror = beforeDict[i];
break;
}
}
_generate(mirror.value, observer.object, observer.patches, "");
if (observer.patches.length) {
apply(mirror.value, observer.patches);
}
var temp = observer.patches;
if (temp.length > 0) {
observer.patches = [];
if (observer.callback) {
observer.callback(temp);
}
}
return temp;
}
jsonpatch.generate = generate; // Dirty check if obj is different from mirror, generate patches and update mirror
function _generate(mirror, obj, patches, path) {
var newKeys = _objectKeys(obj);
var oldKeys = _objectKeys(mirror);
var changed = false;
var deleted = false; //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)"
for (var t = oldKeys.length - 1; t >= 0; t--) {
var key = oldKeys[t];
var oldVal = mirror[key];
if (obj.hasOwnProperty(key)) {
var newVal = obj[key];
if ((0, _typeof2.default)(oldVal) == "object" && oldVal != null && (0, _typeof2.default)(newVal) == "object" && newVal != null) {
_generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key));
} else {
if (oldVal != newVal) {
changed = true;
patches.push({
op: "replace",
path: path + "/" + escapePathComponent(key),
value: deepClone(newVal)
});
}
}
} else {
patches.push({
op: "remove",
path: path + "/" + escapePathComponent(key)
});
deleted = true; // property has been deleted
}
}
if (!deleted && newKeys.length == oldKeys.length) {
return;
}
for (var t = 0; t < newKeys.length; t++) {
var key = newKeys[t];
if (!mirror.hasOwnProperty(key)) {
patches.push({
op: "add",
path: path + "/" + escapePathComponent(key),
value: deepClone(obj[key])
});
}
}
}
var _isArray;
if (Array.isArray) {
_isArray = Array.isArray;
} else {
_isArray = function _isArray(obj) {
return obj.push && typeof obj.length === 'number';
};
} //3x faster than cached /^\d+$/.test(str)
function isInteger(str) {
var i = 0;
var len = str.length;
var charCode;
while (i < len) {
charCode = str.charCodeAt(i);
if (charCode >= 48 && charCode <= 57) {
i++;
continue;
}
return false;
}
return true;
} /// Apply a json-patch operation on an object tree
function apply(tree, patches, validate) {
var result = false,
p = 0,
plen = patches.length,
patch,
key;
while (p < plen) {
patch = patches[p];
p++; // Find the object
var path = patch.path || "";
var keys = path.split('/');
var obj = tree;
var t = 1; //skip empty element - http://jsperf.com/to-shift-or-not-to-shift
var len = keys.length;
var existingPathFragment = undefined;
while (true) {
key = keys[t];
if (validate) {
if (existingPathFragment === undefined) {
if (obj[key] === undefined) {
existingPathFragment = keys.slice(0, t).join('/');
} else if (t == len - 1) {
existingPathFragment = patch.path;
}
if (existingPathFragment !== undefined) {
this.validator(patch, p - 1, tree, existingPathFragment);
}
}
}
t++;
if (key === undefined) {
if (t >= len) {
result = rootOps[patch.op].call(patch, obj, key, tree); // Apply patch
break;
}
}
if (_isArray(obj)) {
if (key === '-') {
key = obj.length;
} else {
if (validate && !isInteger(key)) {
throw new JsonPatchError("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", p - 1, patch.path, patch);
}
key = parseInt(key, 10);
}
if (t >= len) {
if (validate && patch.op === "add" && key > obj.length) {
throw new JsonPatchError("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", p - 1, patch.path, patch);
}
result = arrOps[patch.op].call(patch, obj, key, tree); // Apply patch
break;
}
} else {
if (key && key.indexOf('~') != -1) key = key.replace(/~1/g, '/').replace(/~0/g, '~'); // escape chars
if (t >= len) {
result = objOps[patch.op].call(patch, obj, key, tree); // Apply patch
break;
}
}
obj = obj[key];
}
}
return result;
}
jsonpatch.apply = apply;
function compare(tree1, tree2) {
var patches = [];
_generate(tree1, tree2, patches, '');
return patches;
}
jsonpatch.compare = compare;
var JsonPatchError = function (_super) {
__extends(JsonPatchError, _super);
function JsonPatchError(message, name, index, operation, tree) {
_super.call(this, message);
this.message = message;
this.name = name;
this.index = index;
this.operation = operation;
this.tree = tree;
}
return JsonPatchError;
}(OriginalError);
jsonpatch.JsonPatchError = JsonPatchError;
jsonpatch.Error = JsonPatchError;
/**
* Recursively checks whether an object has any undefined values inside.
*/
function hasUndefined(obj) {
if (obj === undefined) {
return true;
}
if (typeof obj == "array" || (0, _typeof2.default)(obj) == "object") {
for (var i in obj) {
if (hasUndefined(obj[i])) {
return true;
}
}
}
return false;
}
/**
* Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error.
* @param {object} operation - operation object (patch)
* @param {number} index - index of operation in the sequence
* @param {object} [tree] - object where the operation is supposed to be applied
* @param {string} [existingPathFragment] - comes along with `tree`
*/
function validator(operation, index, tree, existingPathFragment) {
if ((0, _typeof2.default)(operation) !== 'object' || operation === null || _isArray(operation)) {
throw new JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, tree);
} else if (!objOps[operation.op]) {
throw new JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, tree);
} else if (typeof operation.path !== 'string') {
throw new JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, tree);
} else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') {
throw new JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, tree);
} else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) {
throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, tree);
} else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && hasUndefined(operation.value)) {
throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', index, operation, tree);
} else if (tree) {
if (operation.op == "add") {
var pathLen = operation.path.split("/").length;
var existingPathLen = existingPathFragment.split("/").length;
if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) {
throw new JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, tree);
}
} else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') {
if (operation.path !== existingPathFragment) {
throw new JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, tree);
}
} else if (operation.op === 'move' || operation.op === 'copy') {
var existingValue = {
op: "_get",
path: operation.from,
value: undefined
};
var error = jsonpatch.validate([existingValue], tree);
if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') {
throw new JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, tree);
}
}
}
}
jsonpatch.validator = validator;
/**
* Validates a sequence of operations. If `tree` parameter is provided, the sequence is additionally validated against the object tree.
* If error is encountered, returns a JsonPatchError object
* @param sequence
* @param tree
* @returns {JsonPatchError|undefined}
*/
function validate(sequence, tree) {
try {
if (!_isArray(sequence)) {
throw new JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');
}
if (tree) {
tree = JSON.parse(JSON.stringify(tree)); //clone tree so that we can safely try applying operations
apply.call(this, tree, sequence, true);
} else {
for (var i = 0; i < sequence.length; i++) {
this.validator(sequence[i], i);
}
}
} catch (e) {
if (e instanceof JsonPatchError) {
return e;
} else {
throw e;
}
}
}
jsonpatch.validate = validate;
})(jsonpatch || (jsonpatch = {}));
if (true) {
exports.apply = jsonpatch.apply;
exports.observe = jsonpatch.observe;
exports.unobserve = jsonpatch.unobserve;
exports.generate = jsonpatch.generate;
exports.compare = jsonpatch.compare;
exports.validate = jsonpatch.validate;
exports.validator = jsonpatch.validator;
exports.JsonPatchError = jsonpatch.JsonPatchError;
exports.Error = jsonpatch.Error;
}
/***/ }),
/* 428 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(131);
exports.__esModule = true;
exports.cleanPatches = cleanPatches;
exports.parsePath = parsePath;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _array = __webpack_require__(3);
/**
* Clean and extend patches from jsonpatch observer.
*
* @param {Array} patches
* @returns {Array}
*/
function cleanPatches(patches) {
var newOrRemovedColumns = [];
/**
* If observeChanges uses native Object.observe method, then it produces patches for length property. Filter them.
* If path can't be parsed. Filter it.
*/
var cleanedPatches = (0, _array.arrayFilter)(patches, function (patch) {
if (/[/]length/ig.test(patch.path)) {
return false;
}
if (!parsePath(patch.path)) {
return false;
}
return true;
});
/**
* Extend patches with changed cells coords
*/
cleanedPatches = (0, _array.arrayMap)(cleanedPatches, function (patch) {
var coords = parsePath(patch.path);
patch.row = coords.row;
patch.col = coords.col;
return patch;
});
/**
* Removing or adding column will produce one patch for each table row.
* Leaves only one patch for each column add/remove operation.
*/
cleanedPatches = (0, _array.arrayFilter)(cleanedPatches, function (patch) {
if (['add', 'remove'].indexOf(patch.op) !== -1 && !isNaN(patch.col)) {
if (newOrRemovedColumns.indexOf(patch.col) !== -1) {
return false;
}
newOrRemovedColumns.push(patch.col);
}
return true;
});
newOrRemovedColumns.length = 0;
return cleanedPatches;
}
/**
* Extract coordinates from path where data was changed.
*
* @param {String} path Path describing where data was changed.
* @returns {Object|null} Returns an object with `row` and `col` properties or `null` if path doesn't have necessary information.
*/
function parsePath(path) {
var match = path.match(/^\/(\d+)\/?(.*)?$/);
if (!match) {
return null;
}
var _match = (0, _slicedToArray2.default)(match, 3),
row = _match[1],
column = _match[2];
return {
row: parseInt(row, 10),
col: /^\d*$/.test(column) ? parseInt(column, 10) : column
};
}
/***/ }),
/* 429 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(34);
__webpack_require__(12);
__webpack_require__(54);
__webpack_require__(33);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(39);
__webpack_require__(219);
__webpack_require__(46);
exports.__esModule = true;
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _plugins = __webpack_require__(20);
var _object = __webpack_require__(4);
var _number = __webpack_require__(15);
var _mixed = __webpack_require__(27);
var DEFAULT_SEARCH_RESULT_CLASS = 'htSearchResult';
var DEFAULT_CALLBACK = function DEFAULT_CALLBACK(instance, row, col, data, testResult) {
instance.getCellMeta(row, col).isSearchResult = testResult;
};
var DEFAULT_QUERY_METHOD = function DEFAULT_QUERY_METHOD(query, value) {
if ((0, _mixed.isUndefined)(query) || query === null || !query.toLowerCase || query.length === 0) {
return false;
}
if ((0, _mixed.isUndefined)(value) || value === null) {
return false;
}
return value.toString().toLowerCase().indexOf(query.toLowerCase()) !== -1;
};
/**
* @plugin Search
*
* @description
* The search plugin provides an easy interface to search data across Handsontable.
*
* In order to enable search mechanism, {@link Options#search} option must be set to `true`.
*
* @example
* ```js
* // as boolean
* search: true
* // as a object with one or more options
* search: {
* callback: myNewCallbackFunction,
* queryMethod: myNewQueryMethod,
* searchResultClass: 'customClass'
* }
*
* // Access to search plugin instance:
* const searchPlugin = hot.getPlugin('search');
*
* // Set callback programmatically:
* searchPlugin.setCallback(myNewCallbackFunction);
* // Set query method programmatically:
* searchPlugin.setQueryMethod(myNewQueryMethod);
* // Set search result cells class programmatically:
* searchPlugin.setSearchResultClass(customClass);
* ```
*/
var Search =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(Search, _BasePlugin);
function Search(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, Search);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Search).call(this, hotInstance));
/**
* Function called during querying for each cell from the {@link DataMap}.
*
* @private
* @type {Function}
*/
_this.callback = DEFAULT_CALLBACK;
/**
* Query function is responsible for determining whether a query matches the value stored in a cell.
*
* @private
* @type {Function}
*/
_this.queryMethod = DEFAULT_QUERY_METHOD;
/**
* Class name added to each cell that belongs to the searched query.
*
* @private
* @type {String}
*/
_this.searchResultClass = DEFAULT_SEARCH_RESULT_CLASS;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link AutoRowSize#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(Search, [{
key: "isEnabled",
value: function isEnabled() {
return this.hot.getSettings().search;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
var searchSettings = this.hot.getSettings().search;
this.updatePluginSettings(searchSettings);
this.addHook('beforeRenderer', function () {
return _this2.onBeforeRenderer.apply(_this2, arguments);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
var _this3 = this;
var beforeRendererCallback = function beforeRendererCallback() {
return _this3.onBeforeRenderer.apply(_this3, arguments);
};
this.hot.addHook('beforeRenderer', beforeRendererCallback);
this.hot.addHookOnce('afterRender', function () {
_this3.hot.removeHook('beforeRenderer', beforeRendererCallback);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "disablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "updatePlugin", this).call(this);
}
/**
* Makes the query.
*
* @param {String} queryStr Value to be search.
* @param {Function} [callback] Callback function performed on cells with values which matches to the searched query.
* @param {Function} [queryMethod] Query function responsible for determining whether a query matches the value stored in a cell.
* @returns {Object[]} Return an array of objects with `row`, `col`, `data` properties or empty array.
*/
}, {
key: "query",
value: function query(queryStr) {
var _this4 = this;
var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getCallback();
var queryMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getQueryMethod();
var rowCount = this.hot.countRows();
var colCount = this.hot.countCols();
var queryResult = [];
var instance = this.hot;
(0, _number.rangeEach)(0, rowCount - 1, function (rowIndex) {
(0, _number.rangeEach)(0, colCount - 1, function (colIndex) {
var cellData = _this4.hot.getDataAtCell(rowIndex, colIndex);
var cellProperties = _this4.hot.getCellMeta(rowIndex, colIndex);
var cellCallback = cellProperties.search.callback || callback;
var cellQueryMethod = cellProperties.search.queryMethod || queryMethod;
var testResult = cellQueryMethod(queryStr, cellData);
if (testResult) {
var singleResult = {
row: rowIndex,
col: colIndex,
data: cellData
};
queryResult.push(singleResult);
}
if (cellCallback) {
cellCallback(instance, rowIndex, colIndex, cellData, testResult);
}
});
});
return queryResult;
}
/**
* Gets the callback function.
*
* @returns {Function} Return the callback function.
*/
}, {
key: "getCallback",
value: function getCallback() {
return this.callback;
}
/**
* Sets the callback function. This function will be called during querying for each cell.
*
* @param {Function} newCallback
*/
}, {
key: "setCallback",
value: function setCallback(newCallback) {
this.callback = newCallback;
}
/**
* Gets the query method function.
*
* @returns {Function} Return the query method.
*/
}, {
key: "getQueryMethod",
value: function getQueryMethod() {
return this.queryMethod;
}
/**
* Sets the query method function. The function is responsible for determining whether a query matches the value stored in a cell.
*
* @param {Function} newQueryMethod
*/
}, {
key: "setQueryMethod",
value: function setQueryMethod(newQueryMethod) {
this.queryMethod = newQueryMethod;
}
/**
* Gets search result cells class name.
*
* @returns {String} Return the cell class name.
*/
}, {
key: "getSearchResultClass",
value: function getSearchResultClass() {
return this.searchResultClass;
}
/**
* Sets search result cells class name. This class name will be added to each cell that belongs to the searched query.
*
* @param {String} newElementClass
*/
}, {
key: "setSearchResultClass",
value: function setSearchResultClass(newElementClass) {
this.searchResultClass = newElementClass;
}
/**
* Updates the settings of the plugin.
*
* @param {Object} searchSettings The plugin settings, taken from Handsontable configuration.
* @private
*/
}, {
key: "updatePluginSettings",
value: function updatePluginSettings(searchSettings) {
if ((0, _object.isObject)(searchSettings)) {
if (searchSettings.searchResultClass) {
this.setSearchResultClass(searchSettings.searchResultClass);
}
if (searchSettings.queryMethod) {
this.setQueryMethod(searchSettings.queryMethod);
}
if (searchSettings.callback) {
this.setCallback(searchSettings.callback);
}
}
}
/** *
* The `beforeRenderer` hook callback.
*
* @private
* @param {HTMLTableCellElement} TD The rendered `TD` element.
* @param {Number} row Visual row index.
* @param {Number} col Visual column index.
* @param {String | Number} prop Column property name or a column index, if datasource is an array of arrays.
* @param {String} value Value of the rendered cell.
* @param {Object} cellProperties Object containing the cell's properties.
*/
}, {
key: "onBeforeRenderer",
value: function onBeforeRenderer(TD, row, col, prop, value, cellProperties) {
// TODO: #4972
var className = cellProperties.className || [];
var classArray = [];
if (typeof className === 'string') {
classArray = className.split(' ');
} else {
var _classArray;
(_classArray = classArray).push.apply(_classArray, (0, _toConsumableArray2.default)(className));
}
if (this.isEnabled() && cellProperties.isSearchResult) {
if (!classArray.includes(this.searchResultClass)) {
classArray.push("".concat(this.searchResultClass));
}
} else if (classArray.includes(this.searchResultClass)) {
classArray.splice(classArray.indexOf(this.searchResultClass), 1);
}
cellProperties.className = classArray.join(' ');
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
(0, _get2.default)((0, _getPrototypeOf2.default)(Search.prototype), "destroy", this).call(this);
}
}]);
return Search;
}(_base.default);
(0, _plugins.registerPlugin)('search', Search);
var _default = Search;
exports.default = _default;
/***/ }),
/* 430 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _array = __webpack_require__(3);
var _base = _interopRequireDefault(__webpack_require__(21));
var _plugins = __webpack_require__(20);
var _feature = __webpack_require__(73);
/**
* @private
* @plugin TouchScroll
* @class TouchScroll
*/
var TouchScroll =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(TouchScroll, _BasePlugin);
function TouchScroll(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, TouchScroll);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(TouchScroll).call(this, hotInstance));
/**
* Collection of scrollbars to update.
*
* @type {Array}
*/
_this.scrollbars = [];
/**
* Collection of overlays to update.
*
* @type {Array}
*/
_this.clones = [];
/**
* Flag which determines if collection of overlays should be refilled on every table render.
*
* @type {Boolean}
* @default false
*/
_this.lockedCollection = false;
/**
* Flag which determines if walkontable should freeze overlays while scrolling.
*
* @type {Boolean}
* @default false
*/
_this.freezeOverlays = false;
return _this;
}
/**
* Check if plugin is enabled.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(TouchScroll, [{
key: "isEnabled",
value: function isEnabled() {
return (0, _feature.isTouchSupported)();
}
/**
* Enable the plugin.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.addHook('afterRender', function () {
return _this2.onAfterRender();
});
this.registerEvents();
(0, _get2.default)((0, _getPrototypeOf2.default)(TouchScroll.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin to use the latest options you have specified.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.lockedCollection = false;
(0, _get2.default)((0, _getPrototypeOf2.default)(TouchScroll.prototype), "updatePlugin", this).call(this);
}
/**
* Disable plugin for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
(0, _get2.default)((0, _getPrototypeOf2.default)(TouchScroll.prototype), "disablePlugin", this).call(this);
}
/**
* Register all necessary events.
*
* @private
*/
}, {
key: "registerEvents",
value: function registerEvents() {
var _this3 = this;
this.addHook('beforeTouchScroll', function () {
return _this3.onBeforeTouchScroll();
});
this.addHook('afterMomentumScroll', function () {
return _this3.onAfterMomentumScroll();
});
}
/**
* After render listener.
*
* @private
*/
}, {
key: "onAfterRender",
value: function onAfterRender() {
if (this.lockedCollection) {
return;
}
var _this$hot$view$wt$wtO = this.hot.view.wt.wtOverlays,
topOverlay = _this$hot$view$wt$wtO.topOverlay,
bottomOverlay = _this$hot$view$wt$wtO.bottomOverlay,
leftOverlay = _this$hot$view$wt$wtO.leftOverlay,
topLeftCornerOverlay = _this$hot$view$wt$wtO.topLeftCornerOverlay,
bottomLeftCornerOverlay = _this$hot$view$wt$wtO.bottomLeftCornerOverlay;
this.lockedCollection = true;
this.scrollbars.length = 0;
this.scrollbars.push(topOverlay);
if (bottomOverlay.clone) {
this.scrollbars.push(bottomOverlay);
}
this.scrollbars.push(leftOverlay);
if (topLeftCornerOverlay) {
this.scrollbars.push(topLeftCornerOverlay);
}
if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) {
this.scrollbars.push(bottomLeftCornerOverlay);
}
this.clones.length = 0;
if (topOverlay.needFullRender) {
this.clones.push(topOverlay.clone.wtTable.holder.parentNode);
}
if (bottomOverlay.needFullRender) {
this.clones.push(bottomOverlay.clone.wtTable.holder.parentNode);
}
if (leftOverlay.needFullRender) {
this.clones.push(leftOverlay.clone.wtTable.holder.parentNode);
}
if (topLeftCornerOverlay) {
this.clones.push(topLeftCornerOverlay.clone.wtTable.holder.parentNode);
}
if (bottomLeftCornerOverlay && bottomLeftCornerOverlay.clone) {
this.clones.push(bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
}
}
/**
* Touch scroll listener.
*
* @private
*/
}, {
key: "onBeforeTouchScroll",
value: function onBeforeTouchScroll() {
this.freezeOverlays = true;
(0, _array.arrayEach)(this.clones, function (clone) {
(0, _element.addClass)(clone, 'hide-tween');
});
}
/**
* After momentum scroll listener.
*
* @private
*/
}, {
key: "onAfterMomentumScroll",
value: function onAfterMomentumScroll() {
var _this4 = this;
this.freezeOverlays = false;
(0, _array.arrayEach)(this.clones, function (clone) {
(0, _element.removeClass)(clone, 'hide-tween');
(0, _element.addClass)(clone, 'show-tween');
});
setTimeout(function () {
(0, _array.arrayEach)(_this4.clones, function (clone) {
(0, _element.removeClass)(clone, 'show-tween');
});
}, 400);
(0, _array.arrayEach)(this.scrollbars, function (scrollbar) {
scrollbar.refresh();
scrollbar.resetFixedPosition();
});
this.hot.view.wt.wtOverlays.syncScrollWithMaster();
}
}]);
return TouchScroll;
}(_base.default);
(0, _plugins.registerPlugin)('touchScroll', TouchScroll);
var _default = TouchScroll;
exports.default = _default;
/***/ }),
/* 431 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(56);
__webpack_require__(12);
__webpack_require__(40);
__webpack_require__(63);
__webpack_require__(33);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _array = __webpack_require__(3);
var _number = __webpack_require__(15);
var _object = __webpack_require__(4);
var _event = __webpack_require__(31);
var _utils = __webpack_require__(60);
/**
* Handsontable UndoRedo class
*/
/**
* @description
* Handsontable UndoRedo plugin allows to undo and redo certain actions done in the table.
*
* __Note__, that not all actions are currently undo-able. The UndoRedo plugin is enabled by default.
*
* @example
* ```js
* undo: true
* ```
* @class UndoRedo
* @plugin UndoRedo
*/
function UndoRedo(instance) {
var plugin = this;
this.instance = instance;
this.doneActions = [];
this.undoneActions = [];
this.ignoreNewActions = false;
instance.addHook('afterChange', function (changes, source) {
if (changes && source !== 'UndoRedo.undo' && source !== 'UndoRedo.redo' && source !== 'MergeCells') {
plugin.done(new UndoRedo.ChangeAction(changes));
}
});
instance.addHook('afterCreateRow', function (index, amount, source) {
if (source === 'UndoRedo.undo' || source === 'UndoRedo.undo' || source === 'auto') {
return;
}
var action = new UndoRedo.CreateRowAction(index, amount);
plugin.done(action);
});
instance.addHook('beforeRemoveRow', function (index, amount, logicRows, source) {
if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') {
return;
}
var originalData = plugin.instance.getSourceDataArray();
var rowIndex = (originalData.length + index) % originalData.length;
var physicalRowIndex = instance.toPhysicalRow(rowIndex);
var removedData = (0, _object.deepClone)(originalData.slice(physicalRowIndex, physicalRowIndex + amount));
plugin.done(new UndoRedo.RemoveRowAction(rowIndex, removedData));
});
instance.addHook('afterCreateCol', function (index, amount, source) {
if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') {
return;
}
plugin.done(new UndoRedo.CreateColumnAction(index, amount));
});
instance.addHook('beforeRemoveCol', function (index, amount, logicColumns, source) {
if (source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto') {
return;
}
var originalData = plugin.instance.getSourceDataArray();
var columnIndex = (plugin.instance.countCols() + index) % plugin.instance.countCols();
var removedData = [];
var headers = [];
var indexes = [];
(0, _number.rangeEach)(originalData.length - 1, function (i) {
var column = [];
var origRow = originalData[i];
(0, _number.rangeEach)(columnIndex, columnIndex + (amount - 1), function (j) {
column.push(origRow[instance.runHooks('modifyCol', j)]);
});
removedData.push(column);
});
(0, _number.rangeEach)(amount - 1, function (i) {
indexes.push(instance.runHooks('modifyCol', columnIndex + i));
});
if (Array.isArray(instance.getSettings().colHeaders)) {
(0, _number.rangeEach)(amount - 1, function (i) {
headers.push(instance.getSettings().colHeaders[instance.runHooks('modifyCol', columnIndex + i)] || null);
});
}
var manualColumnMovePlugin = plugin.instance.getPlugin('manualColumnMove');
var columnsMap = manualColumnMovePlugin.isEnabled() ? manualColumnMovePlugin.columnsMapper.__arrayMap : [];
var action = new UndoRedo.RemoveColumnAction(columnIndex, indexes, removedData, headers, columnsMap);
plugin.done(action);
});
instance.addHook('beforeCellAlignment', function (stateBefore, range, type, alignment) {
var action = new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment);
plugin.done(action);
});
instance.addHook('beforeFilter', function (conditionsStack) {
plugin.done(new UndoRedo.FiltersAction(conditionsStack));
});
instance.addHook('beforeRowMove', function (movedRows, target) {
if (movedRows === false) {
return;
}
plugin.done(new UndoRedo.RowMoveAction(movedRows, target));
});
instance.addHook('beforeMergeCells', function (cellRange, auto) {
if (auto) {
return;
}
plugin.done(new UndoRedo.MergeCellsAction(instance, cellRange));
});
instance.addHook('afterUnmergeCells', function (cellRange, auto) {
if (auto) {
return;
}
plugin.done(new UndoRedo.UnmergeCellsAction(instance, cellRange));
});
}
UndoRedo.prototype.done = function (action) {
if (!this.ignoreNewActions) {
this.doneActions.push(action);
this.undoneActions.length = 0;
}
};
/**
* Undo the last action performed to the table.
*
* @function undo
* @memberof UndoRedo#
* @fires Hooks#beforeUndo
* @fires Hooks#afterUndo
*/
UndoRedo.prototype.undo = function () {
if (this.isUndoAvailable()) {
var action = this.doneActions.pop();
var actionClone = (0, _object.deepClone)(action);
var instance = this.instance;
var continueAction = instance.runHooks('beforeUndo', actionClone);
if (continueAction === false) {
return;
}
this.ignoreNewActions = true;
var that = this;
action.undo(this.instance, function () {
that.ignoreNewActions = false;
that.undoneActions.push(action);
});
instance.runHooks('afterUndo', actionClone);
}
};
/**
* Redo the previous action performed to the table (used to reverse an undo).
*
* @function redo
* @memberof UndoRedo#
* @fires Hooks#beforeRedo
* @fires Hooks#afterRedo
*/
UndoRedo.prototype.redo = function () {
if (this.isRedoAvailable()) {
var action = this.undoneActions.pop();
var actionClone = (0, _object.deepClone)(action);
var instance = this.instance;
var continueAction = instance.runHooks('beforeRedo', actionClone);
if (continueAction === false) {
return;
}
this.ignoreNewActions = true;
var that = this;
action.redo(this.instance, function () {
that.ignoreNewActions = false;
that.doneActions.push(action);
});
instance.runHooks('afterRedo', actionClone);
}
};
/**
* Checks if undo action is available.
*
* @function isUndoAvailable
* @memberof UndoRedo#
* @return {Boolean} Return `true` if undo can be performed, `false` otherwise.
*/
UndoRedo.prototype.isUndoAvailable = function () {
return this.doneActions.length > 0;
};
/**
* Checks if redo action is available.
*
* @function isRedoAvailable
* @memberof UndoRedo#
* @return {Boolean} Return `true` if redo can be performed, `false` otherwise.
*/
UndoRedo.prototype.isRedoAvailable = function () {
return this.undoneActions.length > 0;
};
/**
* Clears undo history.
*
* @function clear
* @memberof UndoRedo#
*/
UndoRedo.prototype.clear = function () {
this.doneActions.length = 0;
this.undoneActions.length = 0;
};
UndoRedo.Action = function () {};
UndoRedo.Action.prototype.undo = function () {};
UndoRedo.Action.prototype.redo = function () {};
/**
* Change action.
*
* @private
*/
UndoRedo.ChangeAction = function (changes) {
this.changes = changes;
this.actionType = 'change';
};
(0, _object.inherit)(UndoRedo.ChangeAction, UndoRedo.Action);
UndoRedo.ChangeAction.prototype.undo = function (instance, undoneCallback) {
var data = (0, _object.deepClone)(this.changes);
var emptyRowsAtTheEnd = instance.countEmptyRows(true);
var emptyColsAtTheEnd = instance.countEmptyCols(true);
for (var i = 0, len = data.length; i < len; i++) {
data[i].splice(3, 1);
}
instance.addHookOnce('afterChange', undoneCallback);
instance.setDataAtRowProp(data, null, null, 'UndoRedo.undo');
for (var _i = 0, _len = data.length; _i < _len; _i++) {
if (instance.getSettings().minSpareRows && data[_i][0] + 1 + instance.getSettings().minSpareRows === instance.countRows() && emptyRowsAtTheEnd === instance.getSettings().minSpareRows) {
instance.alter('remove_row', parseInt(data[_i][0] + 1, 10), instance.getSettings().minSpareRows);
instance.undoRedo.doneActions.pop();
}
if (instance.getSettings().minSpareCols && data[_i][1] + 1 + instance.getSettings().minSpareCols === instance.countCols() && emptyColsAtTheEnd === instance.getSettings().minSpareCols) {
instance.alter('remove_col', parseInt(data[_i][1] + 1, 10), instance.getSettings().minSpareCols);
instance.undoRedo.doneActions.pop();
}
}
};
UndoRedo.ChangeAction.prototype.redo = function (instance, onFinishCallback) {
var data = (0, _object.deepClone)(this.changes);
for (var i = 0, len = data.length; i < len; i++) {
data[i].splice(2, 1);
}
instance.addHookOnce('afterChange', onFinishCallback);
instance.setDataAtRowProp(data, null, null, 'UndoRedo.redo');
};
/**
* Create row action.
*
* @private
*/
UndoRedo.CreateRowAction = function (index, amount) {
this.index = index;
this.amount = amount;
this.actionType = 'insert_row';
};
(0, _object.inherit)(UndoRedo.CreateRowAction, UndoRedo.Action);
UndoRedo.CreateRowAction.prototype.undo = function (instance, undoneCallback) {
var rowCount = instance.countRows();
var minSpareRows = instance.getSettings().minSpareRows;
if (this.index >= rowCount && this.index - minSpareRows < rowCount) {
this.index -= minSpareRows; // work around the situation where the needed row was removed due to an 'undo' of a made change
}
instance.addHookOnce('afterRemoveRow', undoneCallback);
instance.alter('remove_row', this.index, this.amount, 'UndoRedo.undo');
};
UndoRedo.CreateRowAction.prototype.redo = function (instance, redoneCallback) {
instance.addHookOnce('afterCreateRow', redoneCallback);
instance.alter('insert_row', this.index, this.amount, 'UndoRedo.redo');
};
/**
* Remove row action.
*
* @private
*/
UndoRedo.RemoveRowAction = function (index, data) {
this.index = index;
this.data = data;
this.actionType = 'remove_row';
};
(0, _object.inherit)(UndoRedo.RemoveRowAction, UndoRedo.Action);
UndoRedo.RemoveRowAction.prototype.undo = function (instance, undoneCallback) {
instance.alter('insert_row', this.index, this.data.length, 'UndoRedo.undo');
instance.addHookOnce('afterRender', undoneCallback);
instance.populateFromArray(this.index, 0, this.data, void 0, void 0, 'UndoRedo.undo');
};
UndoRedo.RemoveRowAction.prototype.redo = function (instance, redoneCallback) {
instance.addHookOnce('afterRemoveRow', redoneCallback);
instance.alter('remove_row', this.index, this.data.length, 'UndoRedo.redo');
};
/**
* Create column action.
*
* @private
*/
UndoRedo.CreateColumnAction = function (index, amount) {
this.index = index;
this.amount = amount;
this.actionType = 'insert_col';
};
(0, _object.inherit)(UndoRedo.CreateColumnAction, UndoRedo.Action);
UndoRedo.CreateColumnAction.prototype.undo = function (instance, undoneCallback) {
instance.addHookOnce('afterRemoveCol', undoneCallback);
instance.alter('remove_col', this.index, this.amount, 'UndoRedo.undo');
};
UndoRedo.CreateColumnAction.prototype.redo = function (instance, redoneCallback) {
instance.addHookOnce('afterCreateCol', redoneCallback);
instance.alter('insert_col', this.index, this.amount, 'UndoRedo.redo');
};
/**
* Remove column action.
*
* @private
*/
UndoRedo.RemoveColumnAction = function (index, indexes, data, headers, columnPositions) {
this.index = index;
this.indexes = indexes;
this.data = data;
this.amount = this.data[0].length;
this.headers = headers;
this.columnPositions = columnPositions.slice(0);
this.actionType = 'remove_col';
};
(0, _object.inherit)(UndoRedo.RemoveColumnAction, UndoRedo.Action);
UndoRedo.RemoveColumnAction.prototype.undo = function (instance, undoneCallback) {
var _this = this;
var row;
var ascendingIndexes = this.indexes.slice(0).sort();
var sortByIndexes = function sortByIndexes(elem, j, arr) {
return arr[_this.indexes.indexOf(ascendingIndexes[j])];
};
var sortedData = [];
(0, _number.rangeEach)(this.data.length - 1, function (i) {
sortedData[i] = (0, _array.arrayMap)(_this.data[i], sortByIndexes);
});
var sortedHeaders = [];
sortedHeaders = (0, _array.arrayMap)(this.headers, sortByIndexes);
var changes = []; // TODO: Temporary hook for undo/redo mess
instance.runHooks('beforeCreateCol', this.indexes[0], this.indexes.length, 'UndoRedo.undo');
(0, _number.rangeEach)(this.data.length - 1, function (i) {
row = instance.getSourceDataAtRow(i);
(0, _number.rangeEach)(ascendingIndexes.length - 1, function (j) {
row.splice(ascendingIndexes[j], 0, sortedData[i][j]);
changes.push([i, ascendingIndexes[j], null, sortedData[i][j]]);
});
}); // TODO: Temporary hook for undo/redo mess
if (instance.getPlugin('formulas')) {
instance.getPlugin('formulas').onAfterSetDataAtCell(changes);
}
if (typeof this.headers !== 'undefined') {
(0, _number.rangeEach)(sortedHeaders.length - 1, function (j) {
instance.getSettings().colHeaders.splice(ascendingIndexes[j], 0, sortedHeaders[j]);
});
}
if (instance.getPlugin('manualColumnMove')) {
instance.getPlugin('manualColumnMove').columnsMapper.__arrayMap = this.columnPositions;
}
instance.addHookOnce('afterRender', undoneCallback); // TODO: Temporary hook for undo/redo mess
instance.runHooks('afterCreateCol', this.indexes[0], this.indexes.length, 'UndoRedo.undo');
if (instance.getPlugin('formulas')) {
instance.getPlugin('formulas').recalculateFull();
}
instance.render();
};
UndoRedo.RemoveColumnAction.prototype.redo = function (instance, redoneCallback) {
instance.addHookOnce('afterRemoveCol', redoneCallback);
instance.alter('remove_col', this.index, this.amount, 'UndoRedo.redo');
};
/**
* Cell alignment action.
*
* @private
*/
UndoRedo.CellAlignmentAction = function (stateBefore, range, type, alignment) {
this.stateBefore = stateBefore;
this.range = range;
this.type = type;
this.alignment = alignment;
};
UndoRedo.CellAlignmentAction.prototype.undo = function (instance, undoneCallback) {
var _this2 = this;
(0, _array.arrayEach)(this.range, function (_ref) {
var from = _ref.from,
to = _ref.to;
for (var row = from.row; row <= to.row; row += 1) {
for (var col = from.col; col <= to.col; col += 1) {
instance.setCellMeta(row, col, 'className', _this2.stateBefore[row][col] || ' htLeft');
}
}
});
instance.addHookOnce('afterRender', undoneCallback);
instance.render();
};
UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback) {
(0, _utils.align)(this.range, this.type, this.alignment, function (row, col) {
return instance.getCellMeta(row, col);
}, function (row, col, key, value) {
return instance.setCellMeta(row, col, key, value);
});
instance.addHookOnce('afterRender', undoneCallback);
instance.render();
};
/**
* Filters action.
*
* @private
*/
UndoRedo.FiltersAction = function (conditionsStack) {
this.conditionsStack = conditionsStack;
this.actionType = 'filter';
};
(0, _object.inherit)(UndoRedo.FiltersAction, UndoRedo.Action);
UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) {
var filters = instance.getPlugin('filters');
instance.addHookOnce('afterRender', undoneCallback);
filters.conditionCollection.importAllConditions(this.conditionsStack.slice(0, this.conditionsStack.length - 1));
filters.filter();
};
UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) {
var filters = instance.getPlugin('filters');
instance.addHookOnce('afterRender', redoneCallback);
filters.conditionCollection.importAllConditions(this.conditionsStack);
filters.filter();
};
/**
* Merge Cells action.
* @util
*/
var MergeCellsAction =
/*#__PURE__*/
function (_UndoRedo$Action) {
(0, _inherits2.default)(MergeCellsAction, _UndoRedo$Action);
function MergeCellsAction(instance, cellRange) {
var _this3;
(0, _classCallCheck2.default)(this, MergeCellsAction);
_this3 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MergeCellsAction).call(this));
_this3.cellRange = cellRange;
_this3.rangeData = instance.getData(cellRange.from.row, cellRange.from.col, cellRange.to.row, cellRange.to.col);
return _this3;
}
(0, _createClass2.default)(MergeCellsAction, [{
key: "undo",
value: function undo(instance, undoneCallback) {
var mergeCellsPlugin = instance.getPlugin('mergeCells');
instance.addHookOnce('afterRender', undoneCallback);
mergeCellsPlugin.unmergeRange(this.cellRange, true);
instance.populateFromArray(this.cellRange.from.row, this.cellRange.from.col, this.rangeData, void 0, void 0, 'MergeCells');
}
}, {
key: "redo",
value: function redo(instance, redoneCallback) {
var mergeCellsPlugin = instance.getPlugin('mergeCells');
instance.addHookOnce('afterRender', redoneCallback);
mergeCellsPlugin.mergeRange(this.cellRange);
}
}]);
return MergeCellsAction;
}(UndoRedo.Action);
UndoRedo.MergeCellsAction = MergeCellsAction;
/**
* Unmerge Cells action.
* @util
*/
var UnmergeCellsAction =
/*#__PURE__*/
function (_UndoRedo$Action2) {
(0, _inherits2.default)(UnmergeCellsAction, _UndoRedo$Action2);
function UnmergeCellsAction(instance, cellRange) {
var _this4;
(0, _classCallCheck2.default)(this, UnmergeCellsAction);
_this4 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(UnmergeCellsAction).call(this));
_this4.cellRange = cellRange;
return _this4;
}
(0, _createClass2.default)(UnmergeCellsAction, [{
key: "undo",
value: function undo(instance, undoneCallback) {
var mergeCellsPlugin = instance.getPlugin('mergeCells');
instance.addHookOnce('afterRender', undoneCallback);
mergeCellsPlugin.mergeRange(this.cellRange, true);
}
}, {
key: "redo",
value: function redo(instance, redoneCallback) {
var mergeCellsPlugin = instance.getPlugin('mergeCells');
instance.addHookOnce('afterRender', redoneCallback);
mergeCellsPlugin.unmergeRange(this.cellRange, true);
instance.render();
}
}]);
return UnmergeCellsAction;
}(UndoRedo.Action);
UndoRedo.UnmergeCellsAction = UnmergeCellsAction;
/**
* ManualRowMove action.
*
* @private
* @TODO: removeRow undo should works on logical index
*/
UndoRedo.RowMoveAction = function (movedRows, target) {
this.rows = movedRows.slice();
this.target = target;
};
(0, _object.inherit)(UndoRedo.RowMoveAction, UndoRedo.Action);
UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) {
var manualRowMove = instance.getPlugin('manualRowMove');
instance.addHookOnce('afterRender', undoneCallback);
var mod = this.rows[0] < this.target ? -1 * this.rows.length : 0;
var newTarget = this.rows[0] > this.target ? this.rows[0] + this.rows.length : this.rows[0];
var newRows = [];
var rowsLen = this.rows.length + mod;
for (var i = mod; i < rowsLen; i += 1) {
newRows.push(this.target + i);
}
manualRowMove.moveRows(newRows.slice(), newTarget);
instance.render();
instance.selectCell(this.rows[0], 0, this.rows[this.rows.length - 1], instance.countCols() - 1, false, false);
};
UndoRedo.RowMoveAction.prototype.redo = function (instance, redoneCallback) {
var manualRowMove = instance.getPlugin('manualRowMove');
instance.addHookOnce('afterRender', redoneCallback);
manualRowMove.moveRows(this.rows.slice(), this.target);
instance.render();
var startSelection = this.rows[0] < this.target ? this.target - this.rows.length : this.target;
instance.selectCell(startSelection, 0, startSelection + this.rows.length - 1, instance.countCols() - 1, false, false);
};
function init() {
var instance = this;
var pluginEnabled = typeof instance.getSettings().undo === 'undefined' || instance.getSettings().undo;
if (pluginEnabled) {
if (!instance.undoRedo) {
/**
* Instance of Handsontable.UndoRedo Plugin {@link Handsontable.UndoRedo}
*
* @alias undoRedo
* @memberof! Handsontable.Core#
* @type {UndoRedo}
*/
instance.undoRedo = new UndoRedo(instance);
exposeUndoRedoMethods(instance);
instance.addHook('beforeKeyDown', onBeforeKeyDown);
instance.addHook('afterChange', onAfterChange);
}
} else if (instance.undoRedo) {
delete instance.undoRedo;
removeExposedUndoRedoMethods(instance);
instance.removeHook('beforeKeyDown', onBeforeKeyDown);
instance.removeHook('afterChange', onAfterChange);
}
}
function onBeforeKeyDown(event) {
var instance = this;
var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
if (ctrlDown) {
if (event.keyCode === 89 || event.shiftKey && event.keyCode === 90) {
// CTRL + Y or CTRL + SHIFT + Z
instance.undoRedo.redo();
(0, _event.stopImmediatePropagation)(event);
} else if (event.keyCode === 90) {
// CTRL + Z
instance.undoRedo.undo();
(0, _event.stopImmediatePropagation)(event);
}
}
}
function onAfterChange(changes, source) {
var instance = this;
if (source === 'loadData') {
return instance.undoRedo.clear();
}
}
function exposeUndoRedoMethods(instance) {
/**
* {@link UndoRedo#undo}
* @alias undo
* @memberof! Handsontable.Core#
*/
instance.undo = function () {
return instance.undoRedo.undo();
};
/**
* {@link UndoRedo#redo}
* @alias redo
* @memberof! Handsontable.Core#
*/
instance.redo = function () {
return instance.undoRedo.redo();
};
/**
* {@link UndoRedo#isUndoAvailable}
* @alias isUndoAvailable
* @memberof! Handsontable.Core#
*/
instance.isUndoAvailable = function () {
return instance.undoRedo.isUndoAvailable();
};
/**
* {@link UndoRedo#isRedoAvailable}
* @alias isRedoAvailable
* @memberof! Handsontable.Core#
*/
instance.isRedoAvailable = function () {
return instance.undoRedo.isRedoAvailable();
};
/**
* {@link UndoRedo#clear}
* @alias clearUndo
* @memberof! Handsontable.Core#
*/
instance.clearUndo = function () {
return instance.undoRedo.clear();
};
}
function removeExposedUndoRedoMethods(instance) {
delete instance.undo;
delete instance.redo;
delete instance.isUndoAvailable;
delete instance.isRedoAvailable;
delete instance.clearUndo;
}
var hook = _pluginHooks.default.getSingleton();
hook.add('afterInit', init);
hook.add('afterUpdateSettings', init);
hook.register('beforeUndo');
hook.register('afterUndo');
hook.register('beforeRedo');
hook.register('afterRedo');
var _default = UndoRedo;
exports.default = _default;
/***/ }),
/* 432 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _number = __webpack_require__(15);
var _plugins = __webpack_require__(20);
var _bindStrategy = _interopRequireDefault(__webpack_require__(433));
/**
* @plugin BindRowsWithHeaders
*
* @description
* Plugin allows binding the table rows with their headers.
*
* If the plugin is enabled, the table row headers will "stick" to the rows, when they are hidden/moved. Basically, if
* at the initialization row 0 has a header titled "A", it will have it no matter what you do with the table.
*
* @example
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* date: getData(),
* // enable plugin
* bindRowsWithHeaders: true
* });
* ```
*/
var BindRowsWithHeaders =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(BindRowsWithHeaders, _BasePlugin);
function BindRowsWithHeaders(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, BindRowsWithHeaders);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BindRowsWithHeaders).call(this, hotInstance));
/**
* Strategy object for binding rows with headers.
*
* @private
* @type {BindStrategy}
*/
_this.bindStrategy = new _bindStrategy.default();
/**
* List of last removed row indexes.
*
* @private
* @type {Array}
*/
_this.removedRows = [];
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link BindRowsWithHeaders#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(BindRowsWithHeaders, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().bindRowsWithHeaders;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
var bindStrategy = this.hot.getSettings().bindRowsWithHeaders;
if (typeof bindStrategy !== 'string') {
bindStrategy = _bindStrategy.default.DEFAULT_STRATEGY;
}
this.bindStrategy.setStrategy(bindStrategy);
this.bindStrategy.createMap(this.hot.countSourceRows());
this.addHook('modifyRowHeader', function (row) {
return _this2.onModifyRowHeader(row);
});
this.addHook('afterCreateRow', function (index, amount) {
return _this2.onAfterCreateRow(index, amount);
});
this.addHook('beforeRemoveRow', function (index, amount) {
return _this2.onBeforeRemoveRow(index, amount);
});
this.addHook('afterRemoveRow', function () {
return _this2.onAfterRemoveRow();
});
this.addHook('afterLoadData', function (firstRun) {
return _this2.onAfterLoadData(firstRun);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
(0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.removedRows.length = 0;
this.bindStrategy.clearMap();
(0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "disablePlugin", this).call(this);
}
/**
* On modify row header listener.
*
* @private
* @param {Number} row Row index.
* @returns {Number}
*
* @fires Hooks#modifyRow
*/
}, {
key: "onModifyRowHeader",
value: function onModifyRowHeader(row) {
return this.bindStrategy.translate(this.hot.runHooks('modifyRow', row));
}
/**
* On after create row listener.
*
* @private
* @param {Number} index Row index.
* @param {Number} amount Defines how many rows removed.
*/
}, {
key: "onAfterCreateRow",
value: function onAfterCreateRow(index, amount) {
this.bindStrategy.createRow(index, amount);
}
/**
* On before remove row listener.
*
* @private
* @param {Number} index Row index.
* @param {Number} amount Defines how many rows removed.
*
* @fires Hooks#modifyRow
*/
}, {
key: "onBeforeRemoveRow",
value: function onBeforeRemoveRow(index, amount) {
var _this3 = this;
this.removedRows.length = 0;
if (index !== false) {
// Collect physical row index.
(0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
_this3.removedRows.push(_this3.hot.runHooks('modifyRow', removedIndex));
});
}
}
/**
* On after remove row listener.
*
* @private
*/
}, {
key: "onAfterRemoveRow",
value: function onAfterRemoveRow() {
this.bindStrategy.removeRow(this.removedRows);
}
/**
* On after load data listener.
*
* @private
* @param {Boolean} firstRun Indicates if hook was fired while Handsontable initialization.
*/
}, {
key: "onAfterLoadData",
value: function onAfterLoadData(firstRun) {
if (!firstRun) {
this.bindStrategy.createMap(this.hot.countSourceRows());
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.bindStrategy.destroy();
(0, _get2.default)((0, _getPrototypeOf2.default)(BindRowsWithHeaders.prototype), "destroy", this).call(this);
}
}]);
return BindRowsWithHeaders;
}(_base.default);
(0, _plugins.registerPlugin)('bindRowsWithHeaders', BindRowsWithHeaders);
var _default = BindRowsWithHeaders;
exports.default = _default;
/***/ }),
/* 433 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _number = __webpack_require__(15);
var _string = __webpack_require__(68);
var strategies = _interopRequireWildcard(__webpack_require__(434));
/**
* @class BindStrategy
* @plugin BindRowsWithHeaders
*/
var BindStrategy =
/*#__PURE__*/
function () {
(0, _createClass2.default)(BindStrategy, null, [{
key: "DEFAULT_STRATEGY",
/**
* Loose bind mode.
*
* @returns {String}
*/
get: function get() {
return 'loose';
}
}]);
function BindStrategy() {
(0, _classCallCheck2.default)(this, BindStrategy);
this.strategy = null;
}
/**
* Set strategy behaviors for binding rows with headers.
*
* @param name
*/
(0, _createClass2.default)(BindStrategy, [{
key: "setStrategy",
value: function setStrategy(name) {
var Strategy = strategies[(0, _string.toUpperCaseFirst)(name)];
if (!Strategy) {
throw new Error("Bind strategy \"".concat(name, "\" does not exist."));
}
this.strategy = new Strategy();
}
/**
* Reset current map array and create a new one.
*
* @param {Number} [length] Custom generated map length.
*/
}, {
key: "createMap",
value: function createMap(length) {
var strategy = this.strategy;
var originLength = length === void 0 ? strategy._arrayMap.length : length;
strategy._arrayMap.length = 0;
(0, _number.rangeEach)(originLength - 1, function (itemIndex) {
strategy._arrayMap.push(itemIndex);
});
}
/**
* Alias for createRow of strategy class.
*
* @param {*} params
*/
}, {
key: "createRow",
value: function createRow() {
var _this$strategy;
(_this$strategy = this.strategy).createRow.apply(_this$strategy, arguments);
}
/**
* Alias for removeRow of strategy class.
*
* @param {*} params
*/
}, {
key: "removeRow",
value: function removeRow() {
var _this$strategy2;
(_this$strategy2 = this.strategy).removeRow.apply(_this$strategy2, arguments);
}
/**
* Alias for getValueByIndex of strategy class.
*
* @param {*} params
*/
}, {
key: "translate",
value: function translate() {
var _this$strategy3;
return (_this$strategy3 = this.strategy).getValueByIndex.apply(_this$strategy3, arguments);
}
/**
* Clear array map.
*/
}, {
key: "clearMap",
value: function clearMap() {
this.strategy.clearMap();
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
if (this.strategy) {
this.strategy.destroy();
}
this.strategy = null;
}
}]);
return BindStrategy;
}();
var _default = BindStrategy;
exports.default = _default;
/***/ }),
/* 434 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
var _loose = _interopRequireDefault(__webpack_require__(435));
exports.Loose = _loose.default;
var _strict = _interopRequireDefault(__webpack_require__(436));
exports.Strict = _strict.default;
/***/ }),
/* 435 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _arrayMapper = _interopRequireDefault(__webpack_require__(91));
var _object = __webpack_require__(4);
/**
* @private
* @class LooseBindStrategy
*/
var LooseBindStrategy =
/*#__PURE__*/
function () {
function LooseBindStrategy() {
(0, _classCallCheck2.default)(this, LooseBindStrategy);
}
(0, _createClass2.default)(LooseBindStrategy, [{
key: "createRow",
/**
* Strategy for the create row action.
*
* @param {Number} index Row index.
* @param {Number} amount
*/
value: function createRow(index, amount) {
this.shiftItems(index, amount);
}
/**
* Strategy for the remove row action.
*
* @param {Number|Array} index Row index or Array of row indexes.
* @param {Number} amount
*/
}, {
key: "removeRow",
value: function removeRow(index, amount) {
this.unshiftItems(index, amount);
}
/**
* Destroy strategy class.
*/
}, {
key: "destroy",
value: function destroy() {
this._arrayMap = null;
}
}], [{
key: "STRATEGY_NAME",
/**
* Loose bind mode.
*
* @returns {String}
*/
get: function get() {
return 'loose';
}
}]);
return LooseBindStrategy;
}();
(0, _object.mixin)(LooseBindStrategy, _arrayMapper.default);
var _default = LooseBindStrategy;
exports.default = _default;
/***/ }),
/* 436 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _arrayMapper = _interopRequireDefault(__webpack_require__(91));
var _object = __webpack_require__(4);
/**
* @private
* @class StrictBindStrategy
*/
var StrictBindStrategy =
/*#__PURE__*/
function () {
function StrictBindStrategy() {
(0, _classCallCheck2.default)(this, StrictBindStrategy);
}
(0, _createClass2.default)(StrictBindStrategy, [{
key: "createRow",
/**
* Strategy for the create row action.
*
* @param {Number} index Row index.
* @param {Number} amount
*/
value: function createRow(index, amount) {
this.insertItems(index, amount);
}
/**
* Strategy for the remove row action.
*
* @param {Number|Array} index Row index or Array of row indexes.
* @param {Number} amount
*/
}, {
key: "removeRow",
value: function removeRow(index, amount) {
this.removeItems(index, amount);
}
/**
* Destroy strategy class.
*/
}, {
key: "destroy",
value: function destroy() {
this._arrayMap = null;
}
}], [{
key: "STRATEGY_NAME",
/**
* Loose bind mode.
*
* @returns {String}
*/
get: function get() {
return 'strict';
}
}]);
return StrictBindStrategy;
}();
(0, _object.mixin)(StrictBindStrategy, _arrayMapper.default);
var _default = StrictBindStrategy;
exports.default = _default;
/***/ }),
/* 437 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(33);
__webpack_require__(76);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _object = __webpack_require__(4);
var _array = __webpack_require__(3);
var _number = __webpack_require__(15);
var _console = __webpack_require__(55);
var _element = __webpack_require__(5);
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _plugins = __webpack_require__(20);
var _event = __webpack_require__(31);
var _base = _interopRequireDefault(__webpack_require__(21));
/**
* @plugin CollapsibleColumns
* @dependencies NestedHeaders HiddenColumns
*
* @description
* The {@link CollapsibleColumns} plugin allows collapsing of columns, covered by a header with the `colspan` property defined.
*
* Clicking the "collapse/expand" button collapses (or expands) all "child" headers except the first one.
*
* Setting the {@link Options#collapsibleColumns} property to `true` will display a "collapse/expand" button in every header
* with a defined `colspan` property.
*
* To limit this functionality to a smaller group of headers, define the `collapsibleColumns` property as an array
* of objects, as in the example below.
*
* @example
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* data: generateDataObj(),
* colHeaders: true,
* rowHeaders: true,
* // enable plugin
* collapsibleColumns: true,
* });
*
* // or
* const hot = new Handsontable(container, {
* data: generateDataObj(),
* colHeaders: true,
* rowHeaders: true,
* // enable and configure which columns can be collapsed
* collapsibleColumns: [
* {row: -4, col: 1, collapsible: true},
* {row: -3, col: 5, collapsible: true}
* ],
* });
* ```
*/
var CollapsibleColumns =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(CollapsibleColumns, _BasePlugin);
function CollapsibleColumns(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, CollapsibleColumns);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CollapsibleColumns).call(this, hotInstance));
/**
* Cached plugin settings.
*
* @private
* @type {Boolean|Array}
*/
_this.settings = null;
/**
* Object listing headers with buttons enabled.
*
* @private
* @type {Object}
*/
_this.buttonEnabledList = {};
/**
* Cached reference to the HiddenColumns plugin.
*
* @private
* @type {Object}
*/
_this.hiddenColumnsPlugin = null;
/**
* Cached reference to the NestedHeaders plugin.
*
* @private
* @type {Object}
*/
_this.nestedHeadersPlugin = null;
/**
* Object listing the currently collapsed sections.
*
* @private
* @type {Object}
*/
_this.collapsedSections = {};
/**
* Number of column header levels.
*
* @private
* @type {Number}
*/
_this.columnHeaderLevelCount = null;
/**
* Event manager instance reference.
*
* @private
* @type {EventManager}
*/
_this.eventManager = null;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link CollapsibleColumns#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(CollapsibleColumns, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().collapsibleColumns;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.settings = this.hot.getSettings().collapsibleColumns;
if (typeof this.settings !== 'boolean') {
this.parseSettings();
}
this.hiddenColumnsPlugin = this.hot.getPlugin('hiddenColumns');
this.nestedHeadersPlugin = this.hot.getPlugin('nestedHeaders');
this.checkDependencies();
this.addHook('afterRender', function () {
return _this2.onAfterRender();
});
this.addHook('afterInit', function () {
return _this2.onAfterInit();
});
this.addHook('afterGetColHeader', function (col, TH) {
return _this2.onAfterGetColHeader(col, TH);
});
this.addHook('beforeOnCellMouseDown', function (event, coords, TD) {
return _this2.onBeforeOnCellMouseDown(event, coords, TD);
});
this.eventManager = new _eventManager.default(this.hot);
(0, _get2.default)((0, _getPrototypeOf2.default)(CollapsibleColumns.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.settings = null;
this.buttonEnabledList = {};
this.hiddenColumnsPlugin = null;
this.collapsedSections = {};
this.clearButtons();
(0, _get2.default)((0, _getPrototypeOf2.default)(CollapsibleColumns.prototype), "disablePlugin", this).call(this);
}
/**
* Clears the expand/collapse buttons.
*
* @private
*/
}, {
key: "clearButtons",
value: function clearButtons() {
if (!this.hot.view) {
return;
}
var headerLevels = this.hot.view.wt.getSetting('columnHeaders').length;
var mainHeaders = this.hot.view.wt.wtTable.THEAD;
var topHeaders = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.THEAD;
var topLeftCornerHeaders = this.hot.view.wt.wtOverlays.topLeftCornerOverlay ? this.hot.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.THEAD : null;
var removeButton = function removeButton(button) {
if (button) {
button.parentNode.removeChild(button);
}
};
(0, _number.rangeEach)(0, headerLevels - 1, function (i) {
var masterLevel = mainHeaders.childNodes[i];
var topLevel = topHeaders.childNodes[i];
var topLeftCornerLevel = topLeftCornerHeaders ? topLeftCornerHeaders.childNodes[i] : null;
(0, _number.rangeEach)(0, masterLevel.childNodes.length - 1, function (j) {
var button = masterLevel.childNodes[j].querySelector('.collapsibleIndicator');
removeButton(button);
if (topLevel && topLevel.childNodes[j]) {
button = topLevel.childNodes[j].querySelector('.collapsibleIndicator');
removeButton(button);
}
if (topLeftCornerHeaders && topLeftCornerLevel && topLeftCornerLevel.childNodes[j]) {
button = topLeftCornerLevel.childNodes[j].querySelector('.collapsibleIndicator');
removeButton(button);
}
});
}, true);
}
/**
* Parses the plugin settings and create a button configuration array.
*
* @private
*/
}, {
key: "parseSettings",
value: function parseSettings() {
var _this3 = this;
(0, _object.objectEach)(this.settings, function (val) {
if (!_this3.buttonEnabledList[val.row]) {
_this3.buttonEnabledList[val.row] = {};
}
_this3.buttonEnabledList[val.row][val.col] = val.collapsible;
});
}
/**
* Checks if plugin dependencies are met.
*
* @private
* @returns {Boolean}
*/
}, {
key: "meetsDependencies",
value: function meetsDependencies() {
var settings = this.hot.getSettings();
return settings.nestedHeaders && settings.hiddenColumns;
}
/**
* Checks if all the required dependencies are enabled.
*
* @private
*/
}, {
key: "checkDependencies",
value: function checkDependencies() {
var settings = this.hot.getSettings();
if (this.meetsDependencies()) {
return;
}
if (!settings.nestedHeaders) {
(0, _console.warn)('You need to configure the Nested Headers plugin in order to use collapsible headers.');
}
if (!settings.hiddenColumns) {
(0, _console.warn)('You need to configure the Hidden Columns plugin in order to use collapsible headers.');
}
}
/**
* Generates the indicator element.
*
* @private
* @param {Number} column Column index.
* @param {HTMLElement} TH TH Element.
* @returns {HTMLElement}
*/
}, {
key: "generateIndicator",
value: function generateIndicator(column, TH) {
var TR = TH.parentNode;
var THEAD = TR.parentNode;
var row = -1 * THEAD.childNodes.length + Array.prototype.indexOf.call(THEAD.childNodes, TR);
if (Object.keys(this.buttonEnabledList).length > 0 && (!this.buttonEnabledList[row] || !this.buttonEnabledList[row][column])) {
return null;
}
var divEl = this.hot.rootDocument.createElement('DIV');
(0, _element.addClass)(divEl, 'collapsibleIndicator');
if (this.collapsedSections[row] && this.collapsedSections[row][column] === true) {
(0, _element.addClass)(divEl, 'collapsed');
(0, _element.fastInnerText)(divEl, '+');
} else {
(0, _element.addClass)(divEl, 'expanded');
(0, _element.fastInnerText)(divEl, '-');
}
return divEl;
}
/**
* Marks (internally) a section as 'collapsed' or 'expanded' (optionally, also mark the 'child' headers).
*
* @private
* @param {String} state State ('collapsed' or 'expanded').
* @param {Number} row Row index.
* @param {Number} column Column index.
* @param {Boolean} recursive If `true`, it will also attempt to mark the child sections.
*/
}, {
key: "markSectionAs",
value: function markSectionAs(state, row, column, recursive) {
if (!this.collapsedSections[row]) {
this.collapsedSections[row] = {};
}
switch (state) {
case 'collapsed':
this.collapsedSections[row][column] = true;
break;
case 'expanded':
this.collapsedSections[row][column] = void 0;
break;
default:
break;
}
if (recursive) {
var nestedHeadersColspans = this.nestedHeadersPlugin.colspanArray;
var level = this.nestedHeadersPlugin.rowCoordsToLevel(row);
var childHeaders = this.nestedHeadersPlugin.getChildHeaders(row, column);
var childColspanLevel = nestedHeadersColspans[level + 1];
for (var i = 1; i < childHeaders.length; i++) {
if (childColspanLevel && childColspanLevel[childHeaders[i]].colspan > 1) {
this.markSectionAs(state, row + 1, childHeaders[i], true);
}
}
}
}
/**
* Expands section at the provided coords.
*
* @param {Object} coords Contains coordinates information. (`coords.row`, `coords.col`)
*/
}, {
key: "expandSection",
value: function expandSection(coords) {
this.markSectionAs('expanded', coords.row, coords.col, true);
this.toggleCollapsibleSection(coords, 'expand');
}
/**
* Collapses section at the provided coords.
*
* @param {Object} coords Contains coordinates information. (`coords.row`, `coords.col`)
*/
}, {
key: "collapseSection",
value: function collapseSection(coords) {
this.markSectionAs('collapsed', coords.row, coords.col, true);
this.toggleCollapsibleSection(coords, 'collapse');
}
/**
* Collapses or expand all collapsible sections, depending on the action parameter.
*
* @param {String} action 'collapse' or 'expand'.
*/
}, {
key: "toggleAllCollapsibleSections",
value: function toggleAllCollapsibleSections(action) {
var _this4 = this;
var nestedHeadersColspanArray = this.nestedHeadersPlugin.colspanArray;
if (this.settings === true) {
(0, _array.arrayEach)(nestedHeadersColspanArray, function (headerLevel, i) {
(0, _array.arrayEach)(headerLevel, function (header, j) {
if (header.colspan > 1) {
var row = _this4.nestedHeadersPlugin.levelToRowCoords(parseInt(i, 10));
var col = parseInt(j, 10);
_this4.markSectionAs(action === 'collapse' ? 'collapsed' : 'expanded', row, col, true);
_this4.toggleCollapsibleSection({
row: row,
col: col
}, action);
}
});
});
} else {
(0, _object.objectEach)(this.buttonEnabledList, function (headerRow, i) {
(0, _object.objectEach)(headerRow, function (header, j) {
var rowIndex = parseInt(i, 10);
var columnIndex = parseInt(j, 10);
_this4.markSectionAs(action === 'collapse' ? 'collapsed' : 'expanded', rowIndex, columnIndex, true);
_this4.toggleCollapsibleSection({
row: rowIndex,
col: columnIndex
}, action);
});
});
}
}
/**
* Collapses all collapsible sections.
*/
}, {
key: "collapseAll",
value: function collapseAll() {
this.toggleAllCollapsibleSections('collapse');
}
/**
* Expands all collapsible sections.
*/
}, {
key: "expandAll",
value: function expandAll() {
this.toggleAllCollapsibleSections('expand');
}
/**
* Collapses/Expands a section.
*
* @param {Object} coords Section coordinates.
* @param {String} action Action definition ('collapse' or 'expand').
*/
}, {
key: "toggleCollapsibleSection",
value: function toggleCollapsibleSection(coords, action) {
var _this5 = this;
if (coords.row) {
coords.row = parseInt(coords.row, 10);
}
if (coords.col) {
coords.col = parseInt(coords.col, 10);
}
var hiddenColumns = this.hiddenColumnsPlugin.hiddenColumns;
var colspanArray = this.nestedHeadersPlugin.colspanArray;
var level = this.nestedHeadersPlugin.rowCoordsToLevel(coords.row);
var currentHeaderColspan = colspanArray[level][coords.col].colspan;
var childHeaders = this.nestedHeadersPlugin.getChildHeaders(coords.row, coords.col);
var nextLevel = level + 1;
var childColspanLevel = colspanArray[nextLevel];
var firstChildColspan = childColspanLevel ? childColspanLevel[childHeaders[0]].colspan || 1 : 1;
while (firstChildColspan === currentHeaderColspan && nextLevel < this.columnHeaderLevelCount) {
nextLevel += 1;
childColspanLevel = colspanArray[nextLevel];
firstChildColspan = childColspanLevel ? childColspanLevel[childHeaders[0]].colspan || 1 : 1;
}
(0, _number.rangeEach)(firstChildColspan, currentHeaderColspan - 1, function (i) {
var colToHide = coords.col + i;
switch (action) {
case 'collapse':
if (!_this5.hiddenColumnsPlugin.isHidden(colToHide)) {
hiddenColumns.push(colToHide);
}
break;
case 'expand':
if (_this5.hiddenColumnsPlugin.isHidden(colToHide)) {
hiddenColumns.splice(hiddenColumns.indexOf(colToHide), 1);
}
break;
default:
break;
}
});
this.hot.render();
this.hot.view.wt.wtOverlays.adjustElementsSize(true);
}
/**
* Adds the indicator to the headers.
*
* @private
* @param {Number} column Column index.
* @param {HTMLElement} TH TH element.
*/
}, {
key: "onAfterGetColHeader",
value: function onAfterGetColHeader(column, TH) {
if (TH.hasAttribute('colspan') && TH.getAttribute('colspan') > 1 && column >= this.hot.getSettings().fixedColumnsLeft) {
var button = this.generateIndicator(column, TH);
if (button !== null) {
TH.querySelector('div:first-child').appendChild(button);
}
}
}
/**
* Indicator mouse event callback.
*
* @private
* @param {Object} event Mouse event.
* @param {Object} coords Event coordinates.
*/
}, {
key: "onBeforeOnCellMouseDown",
value: function onBeforeOnCellMouseDown(event, coords) {
if ((0, _element.hasClass)(event.target, 'collapsibleIndicator')) {
if ((0, _element.hasClass)(event.target, 'expanded')) {
// mark section as collapsed
if (!this.collapsedSections[coords.row]) {
this.collapsedSections[coords.row] = [];
}
this.markSectionAs('collapsed', coords.row, coords.col, true);
this.eventManager.fireEvent(event.target, 'mouseup');
this.toggleCollapsibleSection(coords, 'collapse');
} else if ((0, _element.hasClass)(event.target, 'collapsed')) {
this.markSectionAs('expanded', coords.row, coords.col, true);
this.eventManager.fireEvent(event.target, 'mouseup');
this.toggleCollapsibleSection(coords, 'expand');
}
(0, _event.stopImmediatePropagation)(event);
return false;
}
}
/**
* AfterInit hook callback.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
this.columnHeaderLevelCount = this.hot.view.wt.getSetting('columnHeaders').length;
}
/**
* AfterRender hook callback.
*
* @private
*/
}, {
key: "onAfterRender",
value: function onAfterRender() {
if (!this.nestedHeadersPlugin.enabled || !this.hiddenColumnsPlugin.enabled) {
this.disablePlugin();
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.settings = null;
this.buttonEnabledList = null;
this.hiddenColumnsPlugin = null;
this.nestedHeadersPlugin = null;
this.collapsedSections = null;
this.columnHeaderLevelCount = null;
(0, _get2.default)((0, _getPrototypeOf2.default)(CollapsibleColumns.prototype), "destroy", this).call(this);
}
}]);
return CollapsibleColumns;
}(_base.default);
(0, _plugins.registerPlugin)('collapsibleColumns', CollapsibleColumns);
var _default = CollapsibleColumns;
exports.default = _default;
/***/ }),
/* 438 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(12);
__webpack_require__(37);
__webpack_require__(46);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _object = __webpack_require__(4);
var _plugins = __webpack_require__(20);
var _endpoints = _interopRequireDefault(__webpack_require__(439));
/**
* @plugin ColumnSummary
*
* @description
* Allows making pre-defined calculations on the cell values and display the results within Handsontable.
* [See the demo for more information](https://docs.handsontable.com/pro/demo-summary-calculations.html).
*s
* @example
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* data: getData(),
* colHeaders: true,
* rowHeaders: true,
* columnSummary: [
* {
* destinationRow: 4,
* destinationColumn: 1,
* type: 'min'
* },
* {
* destinationRow: 0,
* destinationColumn: 3,
* reversedRowCoords: true,
* type: 'max'
* },
* {
* destinationRow: 4,
* destinationColumn: 5,
* type: 'sum',
* forceNumeric: true
* }
* ]
* });
*/
var ColumnSummary =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ColumnSummary, _BasePlugin);
function ColumnSummary(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ColumnSummary);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ColumnSummary).call(this, hotInstance));
/**
* The Endpoints class instance. Used to make all endpoint-related operations.
*
* @private
* @type {null|Endpoints}
*/
_this.endpoints = null;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ColumnSummary#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(ColumnSummary, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().columnSummary;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.settings = this.hot.getSettings().columnSummary;
this.endpoints = new _endpoints.default(this, this.settings);
this.addHook('afterInit', function () {
return _this2.onAfterInit.apply(_this2, arguments);
});
this.addHook('afterChange', function () {
return _this2.onAfterChange.apply(_this2, arguments);
});
this.addHook('beforeCreateRow', function (index, amount, source) {
return _this2.endpoints.resetSetupBeforeStructureAlteration('insert_row', index, amount, null, source);
});
this.addHook('beforeCreateCol', function (index, amount, source) {
return _this2.endpoints.resetSetupBeforeStructureAlteration('insert_col', index, amount, null, source);
});
this.addHook('beforeRemoveRow', function () {
var _this2$endpoints;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return (_this2$endpoints = _this2.endpoints).resetSetupBeforeStructureAlteration.apply(_this2$endpoints, ['remove_row'].concat(args));
});
this.addHook('beforeRemoveCol', function () {
var _this2$endpoints2;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return (_this2$endpoints2 = _this2.endpoints).resetSetupBeforeStructureAlteration.apply(_this2$endpoints2, ['remove_col'].concat(args));
});
this.addHook('beforeRowMove', function () {
return _this2.onBeforeRowMove.apply(_this2, arguments);
});
this.addHook('afterCreateRow', function (index, amount, source) {
return _this2.endpoints.resetSetupAfterStructureAlteration('insert_row', index, amount, null, source);
});
this.addHook('afterCreateCol', function (index, amount, source) {
return _this2.endpoints.resetSetupAfterStructureAlteration('insert_col', index, amount, null, source);
});
this.addHook('afterRemoveRow', function () {
var _this2$endpoints3;
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return (_this2$endpoints3 = _this2.endpoints).resetSetupAfterStructureAlteration.apply(_this2$endpoints3, ['remove_row'].concat(args));
});
this.addHook('afterRemoveCol', function () {
var _this2$endpoints4;
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return (_this2$endpoints4 = _this2.endpoints).resetSetupAfterStructureAlteration.apply(_this2$endpoints4, ['remove_col'].concat(args));
});
this.addHook('afterRowMove', function () {
return _this2.onAfterRowMove.apply(_this2, arguments);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(ColumnSummary.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.endpoints = null;
this.settings = null;
this.currentEndpoint = null;
}
/**
* Calculates math for a single endpoint.
*
* @private
* @param {Object} endpoint Contains information about the endpoint.
*/
}, {
key: "calculate",
value: function calculate(endpoint) {
switch (endpoint.type.toLowerCase()) {
case 'sum':
endpoint.result = this.calculateSum(endpoint);
break;
case 'min':
endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
break;
case 'max':
endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
break;
case 'count':
endpoint.result = this.countEntries(endpoint);
break;
case 'average':
endpoint.result = this.calculateAverage(endpoint);
break;
case 'custom':
endpoint.result = endpoint.customFunction.call(this, endpoint);
break;
default:
break;
}
}
/**
* Calculates sum of the values contained in ranges provided in the plugin config.
*
* @private
* @param {Object} endpoint Contains the endpoint information.
* @returns {Number} Sum for the selected range
*/
}, {
key: "calculateSum",
value: function calculateSum(endpoint) {
var _this3 = this;
var sum = 0;
(0, _object.objectEach)(endpoint.ranges, function (range) {
sum += _this3.getPartialSum(range, endpoint.sourceColumn);
});
return sum;
}
/**
* Returns partial sum of values from a single row range
*
* @private
* @param {Array} rowRange Range for the sum.
* @param {Number} col Column index.
* @returns {Number} The partial sum.
*/
}, {
key: "getPartialSum",
value: function getPartialSum(rowRange, col) {
var sum = 0;
var i = rowRange[1] || rowRange[0];
var cellValue = null;
var biggestDecimalPlacesCount = 0;
do {
cellValue = this.getCellValue(i, col) || 0;
var decimalPlaces = ("".concat(cellValue).split('.')[1] || []).length || 1;
if (decimalPlaces > biggestDecimalPlacesCount) {
biggestDecimalPlacesCount = decimalPlaces;
}
sum += cellValue || 0;
i -= 1;
} while (i >= rowRange[0]); // Workaround for e.g. 802.2 + 1.1 = 803.3000000000001
return Math.round(sum * Math.pow(10, biggestDecimalPlacesCount)) / Math.pow(10, biggestDecimalPlacesCount);
}
/**
* Calculates the minimal value for the selected ranges
*
* @private
* @param {Object} endpoint Contains the endpoint information.
* @param {String} type `'min'` or `'max'`.
* @returns {Number} Min or Max value.
*/
}, {
key: "calculateMinMax",
value: function calculateMinMax(endpoint, type) {
var _this4 = this;
var result = null;
(0, _object.objectEach)(endpoint.ranges, function (range) {
var partialResult = _this4.getPartialMinMax(range, endpoint.sourceColumn, type);
if (result === null && partialResult !== null) {
result = partialResult;
}
if (partialResult !== null) {
switch (type) {
case 'min':
result = Math.min(result, partialResult);
break;
case 'max':
result = Math.max(result, partialResult);
break;
default:
break;
}
}
});
return result === null ? 'Not enough data' : result;
}
/**
* Returns a local minimum of the provided sub-range
*
* @private
* @param {Array} rowRange Range for the calculation.
* @param {Number} col Column index.
* @param {String} type `'min'` or `'max'`
* @returns {Number} Min or max value.
*/
}, {
key: "getPartialMinMax",
value: function getPartialMinMax(rowRange, col, type) {
var result = null;
var i = rowRange[1] || rowRange[0];
var cellValue;
do {
cellValue = this.getCellValue(i, col) || null;
if (result === null) {
result = cellValue;
} else if (cellValue !== null) {
switch (type) {
case 'min':
result = Math.min(result, cellValue);
break;
case 'max':
result = Math.max(result, cellValue);
break;
default:
break;
}
}
i -= 1;
} while (i >= rowRange[0]);
return result;
}
/**
* Counts empty cells in the provided row range.
*
* @private
* @param {Array} rowRange Row range for the calculation.
* @param {Number} col Column index.
* @returns {Number} Empty cells count.
*/
}, {
key: "countEmpty",
value: function countEmpty(rowRange, col) {
var cellValue;
var counter = 0;
var i = rowRange[1] || rowRange[0];
do {
cellValue = this.getCellValue(i, col);
if (!cellValue) {
counter += 1;
}
i -= 1;
} while (i >= rowRange[0]);
return counter;
}
/**
* Counts non-empty cells in the provided row range.
*
* @private
* @param {Object} endpoint Contains the endpoint information.
* @returns {Number} Entry count.
*/
}, {
key: "countEntries",
value: function countEntries(endpoint) {
var _this5 = this;
var result = 0;
var ranges = endpoint.ranges;
(0, _object.objectEach)(ranges, function (range) {
var partial = range[1] === void 0 ? 1 : range[1] - range[0] + 1;
var emptyCount = _this5.countEmpty(range, endpoint.sourceColumn);
result += partial;
result -= emptyCount;
});
return result;
}
/**
* Calculates the average value from the cells in the range.
*
* @private
* @param {Object} endpoint Contains the endpoint information.
* @returns {Number} Avarage value.
*/
}, {
key: "calculateAverage",
value: function calculateAverage(endpoint) {
var sum = this.calculateSum(endpoint);
var entriesCount = this.countEntries(endpoint);
return sum / entriesCount;
}
/**
* Returns a cell value, taking into consideration a basic validation.
*
* @private
* @param {Number} row Row index.
* @param {Number} col Column index.
* @returns {String} The cell value.
*/
}, {
key: "getCellValue",
value: function getCellValue(row, col) {
var visualRowIndex = this.endpoints.getVisualRowIndex(row);
var visualColumnIndex = this.endpoints.getVisualColumnIndex(col);
var cellValue = this.hot.getSourceDataAtCell(row, col);
var cellClassName = this.hot.getCellMeta(visualRowIndex, visualColumnIndex).className || '';
if (cellClassName.indexOf('columnSummaryResult') > -1) {
return null;
}
if (this.endpoints.currentEndpoint.forceNumeric) {
if (typeof cellValue === 'string') {
cellValue = cellValue.replace(/,/, '.');
}
cellValue = parseFloat(cellValue);
}
if (isNaN(cellValue)) {
if (!this.endpoints.currentEndpoint.suppressDataTypeErrors) {
throw new Error("ColumnSummary plugin: cell at (".concat(row, ", ").concat(col, ") is not in a numeric format. Cannot do the calculation."));
}
}
return cellValue;
}
/**
* `afterInit` hook callback.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
this.endpoints.endpoints = this.endpoints.parseSettings();
this.endpoints.refreshAllEndpoints(true);
}
/**
* `afterChange` hook callback.
*
* @private
* @param {Array} changes
* @param {String} source
*/
}, {
key: "onAfterChange",
value: function onAfterChange(changes, source) {
if (changes && source !== 'ColumnSummary.reset' && source !== 'ColumnSummary.set' && source !== 'loadData') {
this.endpoints.refreshChangedEndpoints(changes);
}
}
/**
* `beforeRowMove` hook callback.
*
* @private
* @param {Array} rows Array of logical rows to be moved.
*/
}, {
key: "onBeforeRowMove",
value: function onBeforeRowMove(rows) {
this.endpoints.resetSetupBeforeStructureAlteration('move_row', rows[0], rows.length, rows, this.pluginName);
}
/**
* `afterRowMove` hook callback.
*
* @private
* @param {Array} rows Array of logical rows that were moved.
* @param {Number} target Index of the destination row.
*/
}, {
key: "onAfterRowMove",
value: function onAfterRowMove(rows, target) {
this.endpoints.resetSetupAfterStructureAlteration('move_row', target, rows.length, rows, this.pluginName);
}
}]);
return ColumnSummary;
}(_base.default);
(0, _plugins.registerPlugin)('columnSummary', ColumnSummary);
var _default = ColumnSummary;
exports.default = _default;
/***/ }),
/* 439 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(440);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _array = __webpack_require__(3);
var _console = __webpack_require__(55);
var _recordTranslator = __webpack_require__(90);
/**
* Class used to make all endpoint-related operations.
*
* @class Endpoints
* @plugin ColumnSummary
*/
var Endpoints =
/*#__PURE__*/
function () {
function Endpoints(plugin, settings) {
(0, _classCallCheck2.default)(this, Endpoints);
/**
* The main plugin instance.
*/
this.plugin = plugin;
/**
* Handsontable instance.
*
* @type {Object}
*/
this.hot = this.plugin.hot;
/**
* Array of declared plugin endpoints (calculation destination points).
*
* @type {Array}
* @default {Array} Empty array.
*/
this.endpoints = [];
/**
* The plugin settings, taken from Handsontable configuration.
*
* @type {Object|Function}
* @default null
*/
this.settings = settings;
/**
* Settings type. Can be either 'array' or 'function.
*
* @type {string}
* @default {'array'}
*/
this.settingsType = 'array';
/**
* The current endpoint (calculation destination point) in question.
*
* @type {Object}
* @default null
*/
this.currentEndpoint = null;
/**
* Array containing a list of changes to be applied.
*
* @private
* @type {Array}
* @default {[]}
*/
this.cellsToSetCache = [];
/**
* A `recordTranslator` instance.
* @private
* @type {Object}
*/
this.recordTranslator = (0, _recordTranslator.getTranslator)(this.hot);
}
/**
* Get a single endpoint object.
*
* @param {Number} index Index of the endpoint.
* @returns {Object}
*/
(0, _createClass2.default)(Endpoints, [{
key: "getEndpoint",
value: function getEndpoint(index) {
if (this.settingsType === 'function') {
return this.fillMissingEndpointData(this.settings)[index];
}
return this.endpoints[index];
}
/**
* Get an array with all the endpoints.
*
* @returns {Array}
*/
}, {
key: "getAllEndpoints",
value: function getAllEndpoints() {
if (this.settingsType === 'function') {
return this.fillMissingEndpointData(this.settings);
}
return this.endpoints;
}
/**
* Used to fill the blanks in the endpoint data provided by a settings function.
*
* @private
* @param {Function} func Function provided in the HOT settings.
* @returns {Array} An array of endpoints.
*/
}, {
key: "fillMissingEndpointData",
value: function fillMissingEndpointData(func) {
return this.parseSettings(func.call(this));
}
/**
* Parse plugin's settings.
*
* @param {Array} settings The settings array.
*/
}, {
key: "parseSettings",
value: function parseSettings(settings) {
var _this = this;
var endpointsArray = [];
var settingsArray = settings;
if (!settingsArray && typeof this.settings === 'function') {
this.settingsType = 'function';
return;
}
if (!settingsArray) {
settingsArray = this.settings;
}
(0, _array.arrayEach)(settingsArray, function (val) {
var newEndpoint = {};
_this.assignSetting(val, newEndpoint, 'ranges', [[0, _this.hot.countRows() - 1]]);
_this.assignSetting(val, newEndpoint, 'reversedRowCoords', false);
_this.assignSetting(val, newEndpoint, 'destinationRow', new Error("\n You must provide a destination row for the Column Summary plugin in order to work properly!\n "));
_this.assignSetting(val, newEndpoint, 'destinationColumn', new Error("\n You must provide a destination column for the Column Summary plugin in order to work properly!\n "));
_this.assignSetting(val, newEndpoint, 'sourceColumn', val.destinationColumn);
_this.assignSetting(val, newEndpoint, 'type', 'sum');
_this.assignSetting(val, newEndpoint, 'forceNumeric', false);
_this.assignSetting(val, newEndpoint, 'suppressDataTypeErrors', true);
_this.assignSetting(val, newEndpoint, 'suppressDataTypeErrors', true);
_this.assignSetting(val, newEndpoint, 'customFunction', null);
_this.assignSetting(val, newEndpoint, 'readOnly', true);
_this.assignSetting(val, newEndpoint, 'roundFloat', false);
endpointsArray.push(newEndpoint);
});
return endpointsArray;
}
/**
* Setter for the internal setting objects.
*
* @param {Object} settings Object with the settings.
* @param {Object} endpoint Contains information about the endpoint for the the calculation.
* @param {String} name Settings name.
* @param defaultValue Default value for the settings.
*/
}, {
key: "assignSetting",
value: function assignSetting(settings, endpoint, name, defaultValue) {
if (name === 'ranges' && settings[name] === void 0) {
endpoint[name] = defaultValue;
return;
} else if (name === 'ranges' && settings[name].length === 0) {
return;
}
if (settings[name] === void 0) {
if (defaultValue instanceof Error) {
throw defaultValue;
}
endpoint[name] = defaultValue;
} else {
/* eslint-disable no-lonely-if */
if (name === 'destinationRow' && endpoint.reversedRowCoords) {
endpoint[name] = this.hot.countRows() - settings[name] - 1;
} else {
endpoint[name] = settings[name];
}
}
}
/**
* Resets the endpoint setup before the structure alteration (like inserting or removing rows/columns). Used for settings provided as a function.
*
* @private
* @param {String} action Type of the action performed.
* @param {Number} index Row/column index.
* @param {Number} number Number of rows/columns added/removed.
*/
}, {
key: "resetSetupBeforeStructureAlteration",
value: function resetSetupBeforeStructureAlteration(action, index, number) {
if (this.settingsType !== 'function') {
return;
}
var type = action.indexOf('row') > -1 ? 'row' : 'col';
var endpoints = this.getAllEndpoints();
(0, _array.arrayEach)(endpoints, function (val) {
if (type === 'row' && val.destinationRow >= index) {
if (action === 'insert_row') {
val.alterRowOffset = number;
} else if (action === 'remove_row') {
val.alterRowOffset = -1 * number;
}
}
if (type === 'col' && val.destinationColumn >= index) {
if (action === 'insert_col') {
val.alterColumnOffset = number;
} else if (action === 'remove_col') {
val.alterColumnOffset = -1 * number;
}
}
});
this.resetAllEndpoints(endpoints, false);
}
/**
* afterCreateRow/afterCreateRow/afterRemoveRow/afterRemoveCol hook callback. Reset and reenables the summary functionality
* after changing the table structure.
*
* @private
* @param {String} action Type of the action performed.
* @param {Number} index Row/column index.
* @param {Number} number Number of rows/columns added/removed.
* @param {Array} [logicRows] Array of the logical indexes.
* @param {String} [source] Source of change.
* @param {Boolean} [forceRefresh] `true` of the endpoints should refresh after completing the function.
*/
}, {
key: "resetSetupAfterStructureAlteration",
value: function resetSetupAfterStructureAlteration(action, index, number, logicRows, source) {
var _this2 = this;
var forceRefresh = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
if (this.settingsType === 'function') {
// We need to run it on a next avaiable hook, because the TrimRows' `afterCreateRow` hook triggers after this one,
// and it needs to be run to properly calculate the endpoint value.
var beforeRenderCallback = function beforeRenderCallback() {
_this2.hot.removeHook('beforeRender', beforeRenderCallback);
return _this2.refreshAllEndpoints();
};
this.hot.addHookOnce('beforeRender', beforeRenderCallback);
return;
}
var type = action.indexOf('row') > -1 ? 'row' : 'col';
var multiplier = action.indexOf('remove') > -1 ? -1 : 1;
var endpoints = this.getAllEndpoints();
var rowMoving = action.indexOf('move_row') === 0;
var placeOfAlteration = index;
(0, _array.arrayEach)(endpoints, function (val) {
if (type === 'row' && val.destinationRow >= placeOfAlteration) {
val.alterRowOffset = multiplier * number;
}
if (type === 'col' && val.destinationColumn >= placeOfAlteration) {
val.alterColumnOffset = multiplier * number;
}
});
this.resetAllEndpoints(endpoints, !rowMoving);
if (rowMoving) {
(0, _array.arrayEach)(endpoints, function (endpoint) {
_this2.extendEndpointRanges(endpoint, placeOfAlteration, logicRows[0], logicRows.length);
_this2.recreatePhysicalRanges(endpoint);
_this2.clearOffsetInformation(endpoint);
});
} else {
(0, _array.arrayEach)(endpoints, function (endpoint) {
_this2.shiftEndpointCoordinates(endpoint, placeOfAlteration);
});
}
if (forceRefresh) {
this.refreshAllEndpoints();
}
}
/**
* Clear the offset information from the endpoint object.
*
* @private
* @param {Object} endpoint And endpoint object.
*/
}, {
key: "clearOffsetInformation",
value: function clearOffsetInformation(endpoint) {
endpoint.alterRowOffset = void 0;
endpoint.alterColumnOffset = void 0;
}
/**
* Extend the row ranges for the provided endpoint.
*
* @private
* @param {Object} endpoint The endpoint object.
* @param {Number} placeOfAlteration Index of the row where the alteration takes place.
* @param {Number} previousPosition Previous endpoint result position.
* @param {Number} offset Offset generated by the alteration.
*/
}, {
key: "extendEndpointRanges",
value: function extendEndpointRanges(endpoint, placeOfAlteration, previousPosition, offset) {
(0, _array.arrayEach)(endpoint.ranges, function (range) {
// is a range, not a single row
if (range[1]) {
if (placeOfAlteration >= range[0] && placeOfAlteration <= range[1]) {
if (previousPosition > range[1]) {
range[1] += offset;
} else if (previousPosition < range[0]) {
range[0] -= offset;
}
} else if (previousPosition >= range[0] && previousPosition <= range[1]) {
range[1] -= offset;
if (placeOfAlteration <= range[0]) {
range[0] += 1;
range[1] += 1;
}
}
}
});
}
/**
* Recreate the physical ranges for the provided endpoint. Used (for example) when a row gets moved and extends an existing range.
*
* @private
* @param {Object} endpoint An endpoint object.
*/
}, {
key: "recreatePhysicalRanges",
value: function recreatePhysicalRanges(endpoint) {
var _this3 = this;
var ranges = endpoint.ranges;
var newRanges = [];
var allIndexes = [];
(0, _array.arrayEach)(ranges, function (range) {
var newRange = [];
if (range[1]) {
for (var i = range[0]; i <= range[1]; i++) {
newRange.push(_this3.recordTranslator.toPhysicalRow(i));
}
} else {
newRange.push(_this3.recordTranslator.toPhysicalRow(range[0]));
}
allIndexes.push(newRange);
});
(0, _array.arrayEach)(allIndexes, function (range) {
var newRange = [];
(0, _array.arrayEach)(range, function (coord, index) {
if (index === 0) {
newRange.push(coord);
} else if (range[index] !== range[index - 1] + 1) {
newRange.push(range[index - 1]);
newRanges.push(newRange);
newRange = [];
newRange.push(coord);
}
if (index === range.length - 1) {
newRange.push(coord);
newRanges.push(newRange);
}
});
});
endpoint.ranges = newRanges;
}
/**
* Shifts the endpoint coordinates by the defined offset.
*
* @private
* @param {Object} endpoint Endpoint object.
* @param {Number} offsetStartIndex Index of the performed change (if the change is located after the endpoint, nothing about the endpoint has to be changed.
*/
}, {
key: "shiftEndpointCoordinates",
value: function shiftEndpointCoordinates(endpoint, offsetStartIndex) {
if (endpoint.alterRowOffset && endpoint.alterRowOffset !== 0) {
endpoint.destinationRow += endpoint.alterRowOffset || 0;
(0, _array.arrayEach)(endpoint.ranges, function (element) {
(0, _array.arrayEach)(element, function (subElement, j) {
if (subElement >= offsetStartIndex) {
element[j] += endpoint.alterRowOffset || 0;
}
});
});
} else if (endpoint.alterColumnOffset && endpoint.alterColumnOffset !== 0) {
endpoint.destinationColumn += endpoint.alterColumnOffset || 0;
endpoint.sourceColumn += endpoint.alterColumnOffset || 0;
}
}
/**
* Resets (removes) the endpoints from the table.
*
* @param {Array} endpoints Array containing the endpoints.
* @param {Boolean} [useOffset=true] Use the cell offset value.
*/
}, {
key: "resetAllEndpoints",
value: function resetAllEndpoints(endpoints) {
var _this4 = this;
var useOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var endpointsArray = endpoints;
this.cellsToSetCache = [];
if (!endpointsArray) {
endpointsArray = this.getAllEndpoints();
}
(0, _array.arrayEach)(endpointsArray, function (value) {
_this4.resetEndpointValue(value, useOffset);
});
this.hot.setDataAtCell(this.cellsToSetCache, 'ColumnSummary.reset');
this.cellsToSetCache = [];
}
/**
* Calculate and refresh all defined endpoints.
*/
}, {
key: "refreshAllEndpoints",
value: function refreshAllEndpoints() {
var _this5 = this;
this.cellsToSetCache = [];
(0, _array.arrayEach)(this.getAllEndpoints(), function (value) {
_this5.currentEndpoint = value;
_this5.plugin.calculate(value);
_this5.setEndpointValue(value, 'init');
});
this.currentEndpoint = null;
this.hot.setDataAtCell(this.cellsToSetCache, 'ColumnSummary.reset');
this.cellsToSetCache = [];
}
/**
* Calculate and refresh endpoints only in the changed columns.
*
* @param {Array} changes Array of changes from the `afterChange` hook.
*/
}, {
key: "refreshChangedEndpoints",
value: function refreshChangedEndpoints(changes) {
var _this6 = this;
var needToRefresh = [];
this.cellsToSetCache = [];
(0, _array.arrayEach)(changes, function (value, key, changesObj) {
// if nothing changed, dont update anything
if ("".concat(value[2] || '') === "".concat(value[3])) {
return;
}
(0, _array.arrayEach)(_this6.getAllEndpoints(), function (endpoint, j) {
if (_this6.hot.propToCol(changesObj[key][1]) === endpoint.sourceColumn && needToRefresh.indexOf(j) === -1) {
needToRefresh.push(j);
}
});
});
(0, _array.arrayEach)(needToRefresh, function (value) {
_this6.refreshEndpoint(_this6.getEndpoint(value));
});
this.hot.setDataAtCell(this.cellsToSetCache, 'ColumnSummary.reset');
this.cellsToSetCache = [];
}
/**
* Calculate and refresh a single endpoint.
*
* @param {Object} endpoint Contains the endpoint information.
*/
}, {
key: "refreshEndpoint",
value: function refreshEndpoint(endpoint) {
this.currentEndpoint = endpoint;
this.plugin.calculate(endpoint);
this.setEndpointValue(endpoint);
this.currentEndpoint = null;
}
/**
* Reset the endpoint value.
*
* @param {Object} endpoint Contains the endpoint information.
* @param {Boolean} [useOffset=true] Use the cell offset value.
*/
}, {
key: "resetEndpointValue",
value: function resetEndpointValue(endpoint) {
var useOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var alterRowOffset = endpoint.alterRowOffset || 0;
var alterColOffset = endpoint.alterColumnOffset || 0;
var _this$recordTranslato = this.recordTranslator.toVisual(endpoint.destinationRow, endpoint.destinationColumn),
_this$recordTranslato2 = (0, _slicedToArray2.default)(_this$recordTranslato, 2),
visualRowIndex = _this$recordTranslato2[0],
visualColumnIndex = _this$recordTranslato2[1]; // Clear the meta on the "old" indexes
var cellMeta = this.hot.getCellMeta(visualRowIndex, visualColumnIndex);
cellMeta.readOnly = false;
cellMeta.className = '';
this.cellsToSetCache.push([this.recordTranslator.toVisualRow(endpoint.destinationRow + (useOffset ? alterRowOffset : 0)), this.recordTranslator.toVisualColumn(endpoint.destinationColumn + (useOffset ? alterColOffset : 0)), '']);
}
/**
* Set the endpoint value.
*
* @param {Object} endpoint Contains the endpoint information.
* @param {String} [source] Source of the call information.
* @param {Boolean} [render=false] `true` if it needs to render the table afterwards.
*/
}, {
key: "setEndpointValue",
value: function setEndpointValue(endpoint, source) {
var render = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
// We'll need the reversed offset values, because cellMeta will be shifted AGAIN afterwards.
var reverseRowOffset = -1 * endpoint.alterRowOffset || 0;
var reverseColOffset = -1 * endpoint.alterColumnOffset || 0;
var visualEndpointRowIndex = this.getVisualRowIndex(endpoint.destinationRow);
var cellMeta = this.hot.getCellMeta(this.getVisualRowIndex(endpoint.destinationRow + reverseRowOffset), endpoint.destinationColumn + reverseColOffset);
if (visualEndpointRowIndex > this.hot.countRows() || endpoint.destinationColumn > this.hot.countCols()) {
this.throwOutOfBoundsWarning();
return;
}
if (source === 'init' || cellMeta.readOnly !== endpoint.readOnly) {
cellMeta.readOnly = endpoint.readOnly;
cellMeta.className = 'columnSummaryResult';
}
if (endpoint.roundFloat && !isNaN(endpoint.result)) {
endpoint.result = endpoint.result.toFixed(endpoint.roundFloat);
}
if (render) {
this.hot.setDataAtCell(visualEndpointRowIndex, endpoint.destinationColumn, endpoint.result, 'ColumnSummary.set');
} else {
this.cellsToSetCache.push([visualEndpointRowIndex, endpoint.destinationColumn, endpoint.result]);
}
endpoint.alterRowOffset = void 0;
endpoint.alterColumnOffset = void 0;
}
/**
* Get the visual row index for the provided row. Uses the `umodifyRow` hook.
*
* @private
* @param {Number} row Row index.
* @returns {Number}
*/
}, {
key: "getVisualRowIndex",
value: function getVisualRowIndex(row) {
return this.hot.runHooks('unmodifyRow', row, 'columnSummary');
}
/**
* Get the visual column index for the provided column. Uses the `umodifyColumn` hook.
*
* @private
* @param {Number} column Column index.
* @returns {Number}
*/
}, {
key: "getVisualColumnIndex",
value: function getVisualColumnIndex(column) {
return this.hot.runHooks('unmodifyCol', column, 'columnSummary');
}
/**
* Throw an error for the calculation range being out of boundaries.
*
* @private
*/
}, {
key: "throwOutOfBoundsWarning",
value: function throwOutOfBoundsWarning() {
(0, _console.warn)('One of the Column Summary plugins\' destination points you provided is beyond the table boundaries!');
}
}]);
return Endpoints;
}();
var _default = Endpoints;
exports.default = _default;
/***/ }),
/* 440 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var toInteger = __webpack_require__(86);
var thisNumberValue = __webpack_require__(441);
var repeat = __webpack_require__(205);
var nativeToFixed = 1.0.toFixed;
var floor = Math.floor;
var data = [0, 0, 0, 0, 0, 0];
var multiply = function (n, c) {
var i = -1;
var c2 = c;
while (++i < 6) {
c2 += n * data[i];
data[i] = c2 % 1e7;
c2 = floor(c2 / 1e7);
}
};
var divide = function (n) {
var i = 6;
var c = 0;
while (--i >= 0) {
c += data[i];
data[i] = floor(c / n);
c = (c % n) * 1e7;
}
};
var numToString = function () {
var i = 6;
var s = '';
while (--i >= 0) {
if (s !== '' || i === 0 || data[i] !== 0) {
var t = String(data[i]);
s = s === '' ? t : s + repeat.call('0', 7 - t.length) + t;
}
} return s;
};
var pow = function (x, n, acc) {
return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
};
var log = function (x) {
var n = 0;
var x2 = x;
while (x2 >= 4096) {
n += 12;
x2 /= 4096;
}
while (x2 >= 2) {
n += 1;
x2 /= 2;
} return n;
};
// `Number.prototype.toFixed` method
// https://tc39.github.io/ecma262/#sec-number.prototype.tofixed
__webpack_require__(22)({ target: 'Number', proto: true, forced: nativeToFixed && (
0.00008.toFixed(3) !== '0.000' ||
0.9.toFixed(0) !== '1' ||
1.255.toFixed(2) !== '1.25' ||
1000000000000000128.0.toFixed(0) !== '1000000000000000128'
) || !__webpack_require__(29)(function () {
// V8 ~ Android 4.3-
nativeToFixed.call({});
}) }, {
toFixed: function toFixed(fractionDigits) {
var x = thisNumberValue(this);
var f = toInteger(fractionDigits);
var s = '';
var m = '0';
var e, z, j, k;
if (f < 0 || f > 20) throw RangeError('Incorrect fraction digits');
// eslint-disable-next-line no-self-compare
if (x != x) return 'NaN';
if (x <= -1e21 || x >= 1e21) return String(x);
if (x < 0) {
s = '-';
x = -x;
}
if (x > 1e-21) {
e = log(x * pow(2, 69, 1)) - 69;
z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);
z *= 0x10000000000000;
e = 52 - e;
if (e > 0) {
multiply(0, z);
j = f;
while (j >= 7) {
multiply(1e7, 0);
j -= 7;
}
multiply(pow(10, j, 1), 0);
j = e - 1;
while (j >= 23) {
divide(1 << 23);
j -= 23;
}
divide(1 << j);
multiply(1, 1);
divide(2);
m = numToString();
} else {
multiply(0, z);
multiply(1 << -e, 0);
m = numToString() + repeat.call('0', f);
}
}
if (f > 0) {
k = m.length;
m = s + (k <= f ? '0.' + repeat.call('0', f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));
} else {
m = s + m;
} return m;
}
});
/***/ }),
/* 441 */
/***/ (function(module, exports, __webpack_require__) {
var classof = __webpack_require__(77);
// `thisNumberValue` abstract operation
// https://tc39.github.io/ecma262/#sec-thisnumbervalue
module.exports = function (value) {
if (typeof value != 'number' && classof(value) != 'Number') {
throw TypeError('Incorrect invocation');
}
return +value;
};
/***/ }),
/* 442 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(12);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _array = __webpack_require__(3);
var _commandExecutor = _interopRequireDefault(__webpack_require__(240));
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _element = __webpack_require__(5);
var _itemsFactory = _interopRequireDefault(__webpack_require__(241));
var _menu = _interopRequireDefault(__webpack_require__(167));
var _plugins = __webpack_require__(20);
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _event = __webpack_require__(31);
var _predefinedItems = __webpack_require__(83);
__webpack_require__(443);
_pluginHooks.default.getSingleton().register('afterDropdownMenuDefaultOptions');
_pluginHooks.default.getSingleton().register('beforeDropdownMenuShow');
_pluginHooks.default.getSingleton().register('afterDropdownMenuShow');
_pluginHooks.default.getSingleton().register('afterDropdownMenuHide');
_pluginHooks.default.getSingleton().register('afterDropdownMenuExecute');
var BUTTON_CLASS_NAME = 'changeType';
/**
* @plugin DropdownMenu
* @dependencies ContextMenu
*
* @description
* This plugin creates the Handsontable Dropdown Menu. It allows to create a new row or column at any place in the grid
* among [other features](http://docs.handsontable.com/demo-context-menu.html).
* Possible values:
* * `true` (to enable default options),
* * `false` (to disable completely)
*
* or array of any available strings:
* * `["row_above", "row_below", "col_left", "col_right",
* "remove_row", "remove_col", "---------", "undo", "redo"]`.
*
* See [the dropdown menu demo](http://docs.handsontable.com/demo-dropdown-menu.html) for examples.
*
* @example
* ```
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* data: data,
* colHeaders: true,
* // enable dropdown menu
* dropdownMenu: true
* });
*
* // or
* const hot = new Handsontable(container, {
* data: data,
* colHeaders: true,
* // enable and configure dropdown menu
* dropdownMenu: ['remove_col', '---------', 'make_read_only', 'alignment']
* });
* ```
*/
var DropdownMenu =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(DropdownMenu, _BasePlugin);
(0, _createClass2.default)(DropdownMenu, null, [{
key: "DEFAULT_ITEMS",
/**
* Default menu items order when `dropdownMenu` is enabled by setting the config item to `true`.
*
* @returns {Array}
*/
get: function get() {
return [_predefinedItems.COLUMN_LEFT, _predefinedItems.COLUMN_RIGHT, _predefinedItems.SEPARATOR, _predefinedItems.REMOVE_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.CLEAR_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.READ_ONLY, _predefinedItems.SEPARATOR, _predefinedItems.ALIGNMENT];
}
}]);
function DropdownMenu(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, DropdownMenu);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(DropdownMenu).call(this, hotInstance));
/**
* Instance of {@link EventManager}.
*
* @private
* @type {EventManager}
*/
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
/**
* Instance of {@link CommandExecutor}.
*
* @private
* @type {CommandExecutor}
*/
_this.commandExecutor = new _commandExecutor.default(_this.hot);
/**
* Instance of {@link ItemsFactory}.
*
* @private
* @type {ItemsFactory}
*/
_this.itemsFactory = null;
/**
* Instance of {@link Menu}.
*
* @private
* @type {Menu}
*/
_this.menu = null; // One listener for enable/disable functionality
_this.hot.addHook('afterGetColHeader', function (col, TH) {
return _this.onAfterGetColHeader(col, TH);
});
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link DropdownMenu#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(DropdownMenu, [{
key: "isEnabled",
value: function isEnabled() {
return this.hot.getSettings().dropdownMenu;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*
* @fires Hooks#afterDropdownMenuDefaultOptions
* @fires Hooks#beforeDropdownMenuSetItems
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.itemsFactory = new _itemsFactory.default(this.hot, DropdownMenu.DEFAULT_ITEMS);
var settings = this.hot.getSettings().dropdownMenu;
var predefinedItems = {
items: this.itemsFactory.getItems(settings)
};
this.registerEvents();
if (typeof settings.callback === 'function') {
this.commandExecutor.setCommonCallback(settings.callback);
}
(0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "enablePlugin", this).call(this);
this.callOnPluginsReady(function () {
_this2.hot.runHooks('afterDropdownMenuDefaultOptions', predefinedItems);
_this2.itemsFactory.setPredefinedItems(predefinedItems.items);
var menuItems = _this2.itemsFactory.getItems(settings);
if (_this2.menu) {
_this2.menu.destroy();
}
_this2.menu = new _menu.default(_this2.hot, {
className: 'htDropdownMenu',
keepInViewport: true
});
_this2.hot.runHooks('beforeDropdownMenuSetItems', menuItems);
_this2.menu.setMenuItems(menuItems);
_this2.menu.addLocalHook('beforeOpen', function () {
return _this2.onMenuBeforeOpen();
});
_this2.menu.addLocalHook('afterOpen', function () {
return _this2.onMenuAfterOpen();
});
_this2.menu.addLocalHook('afterClose', function () {
return _this2.onMenuAfterClose();
});
_this2.menu.addLocalHook('executeCommand', function () {
var _this2$executeCommand;
for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
params[_key] = arguments[_key];
}
return (_this2$executeCommand = _this2.executeCommand).call.apply(_this2$executeCommand, [_this2].concat(params));
}); // Register all commands. Predefined and added by user or by plugins
(0, _array.arrayEach)(menuItems, function (command) {
return _this2.commandExecutor.registerCommand(command.key, command);
});
});
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.close();
if (this.menu) {
this.menu.destroy();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "disablePlugin", this).call(this);
}
/**
* Registers the DOM listeners.
*
* @private
*/
}, {
key: "registerEvents",
value: function registerEvents() {
var _this3 = this;
this.eventManager.addEventListener(this.hot.rootElement, 'click', function (event) {
return _this3.onTableClick(event);
});
}
/**
* Opens menu and re-position it based on the passed coordinates.
*
* @param {Object|Event} position An object with `pageX` and `pageY` properties which contains values relative to
* the top left of the fully rendered content area in the browser or with `clientX`
* and `clientY` properties which contains values relative to the upper left edge
* of the content area (the viewport) of the browser window. This object is structurally
* compatible with native mouse event so it can be used either.
* @fires Hooks#beforeDropdownMenuShow
* @fires Hooks#afterDropdownMenuShow
*/
}, {
key: "open",
value: function open(position) {
if (!this.menu) {
return;
}
this.menu.open();
if (position.width) {
this.menu.setOffset('left', position.width);
}
this.menu.setPosition(position); // ContextMenu is not detected HotTableEnv correctly because is injected outside hot-table
this.menu.hotMenu.isHotTableEnv = this.hot.isHotTableEnv; // Handsontable.eventManager.isHotTableEnv = this.hot.isHotTableEnv;
}
/**
* Closes dropdown menu.
*/
}, {
key: "close",
value: function close() {
if (!this.menu) {
return;
}
this.menu.close();
}
/**
* Executes context menu command.
*
* You can execute all predefined commands:
* * `'row_above'` - Insert row above
* * `'row_below'` - Insert row below
* * `'col_left'` - Insert column left
* * `'col_right'` - Insert column right
* * `'clear_column'` - Clear selected column
* * `'remove_row'` - Remove row
* * `'remove_col'` - Remove column
* * `'undo'` - Undo last action
* * `'redo'` - Redo last action
* * `'make_read_only'` - Make cell read only
* * `'alignment:left'` - Alignment to the left
* * `'alignment:top'` - Alignment to the top
* * `'alignment:right'` - Alignment to the right
* * `'alignment:bottom'` - Alignment to the bottom
* * `'alignment:middle'` - Alignment to the middle
* * `'alignment:center'` - Alignment to the center (justify)
*
* Or you can execute command registered in settings where `key` is your command name.
*
* @param {String} commandName Command name to execute.
* @param {*} params
*/
}, {
key: "executeCommand",
value: function executeCommand(commandName) {
var _this$commandExecutor;
for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
params[_key2 - 1] = arguments[_key2];
}
(_this$commandExecutor = this.commandExecutor).execute.apply(_this$commandExecutor, [commandName].concat(params));
}
/**
* Turns on / off listening on dropdown menu
*
* @private
* @param {Boolean} listen Turn on listening when value is set to true, otherwise turn it off.
*/
}, {
key: "setListening",
value: function setListening() {
var listen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
if (this.menu.isOpened()) {
if (listen) {
this.menu.hotMenu.listen();
} else {
this.menu.hotMenu.unlisten();
}
}
}
/**
* Table click listener.
*
* @private
* @param {Event} event
*/
}, {
key: "onTableClick",
value: function onTableClick(event) {
(0, _event.stopPropagation)(event);
if ((0, _element.hasClass)(event.target, BUTTON_CLASS_NAME) && !this.menu.isOpened()) {
var rect = event.target.getBoundingClientRect();
this.open({
left: rect.left,
top: rect.top + event.target.offsetHeight + 3,
width: rect.width,
height: rect.height
});
}
}
/**
* On after get column header listener.
*
* @private
* @param {Number} col
* @param {HTMLTableCellElement} TH
*/
}, {
key: "onAfterGetColHeader",
value: function onAfterGetColHeader(col, TH) {
// Corner or a higher-level header
var headerRow = TH.parentNode;
if (!headerRow) {
return;
}
var headerRowList = headerRow.parentNode.childNodes;
var level = Array.prototype.indexOf.call(headerRowList, headerRow);
if (col < 0 || level !== headerRowList.length - 1) {
return;
}
var existingButton = TH.querySelector(".".concat(BUTTON_CLASS_NAME)); // Plugin enabled and buttons already exists, return.
if (this.enabled && existingButton) {
return;
} // Plugin disabled and buttons still exists, so remove them.
if (!this.enabled) {
if (existingButton) {
existingButton.parentNode.removeChild(existingButton);
}
return;
}
var button = this.hot.rootDocument.createElement('button');
button.className = BUTTON_CLASS_NAME; // prevent page reload on button click
button.onclick = function () {
return false;
};
TH.firstChild.insertBefore(button, TH.firstChild.firstChild);
}
/**
* On menu before open listener.
*
* @private
* @fires Hooks#beforeDropdownMenuShow
*/
}, {
key: "onMenuBeforeOpen",
value: function onMenuBeforeOpen() {
this.hot.runHooks('beforeDropdownMenuShow', this);
}
/**
* On menu after open listener.
*
* @private
* @fires Hooks#afterDropdownMenuShow
*/
}, {
key: "onMenuAfterOpen",
value: function onMenuAfterOpen() {
this.hot.runHooks('afterDropdownMenuShow', this);
}
/**
* On menu after close listener.
*
* @private
* @fires Hooks#afterDropdownMenuHide
*/
}, {
key: "onMenuAfterClose",
value: function onMenuAfterClose() {
this.hot.listen();
this.hot.runHooks('afterDropdownMenuHide', this);
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.close();
if (this.menu) {
this.menu.destroy();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(DropdownMenu.prototype), "destroy", this).call(this);
}
}]);
return DropdownMenu;
}(_base.default);
DropdownMenu.SEPARATOR = {
name: _predefinedItems.SEPARATOR
};
(0, _plugins.registerPlugin)('dropdownMenu', DropdownMenu);
var _default = DropdownMenu;
exports.default = _default;
/***/ }),
/* 443 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 444 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _plugins = __webpack_require__(20);
var _dataProvider = _interopRequireDefault(__webpack_require__(445));
var _typeFactory = _interopRequireWildcard(__webpack_require__(446));
/**
* @plugin ExportFile
*
* @description
* The plugin enables exporting table data to file. It allows to export data as a string, blob or a downloadable file in
* CSV format.
*
* See [the export file demo](https://docs.handsontable.com/demo-export-file.html) for examples.
*
* @example
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* data: getData()
* });
*
* // access to exportFile plugin instance
* const exportPlugin = hot.getPlugin('exportFile');
*
* // export as a string
* exportPlugin.exportAsString('csv');
*
* // export as a blob object
* exportPlugin.exportAsBlob('csv');
*
* // export to downloadable file (named: MyFile.csv)
* exportPlugin.downloadFile('csv', {filename: 'MyFile'});
*
* // export as a string (with specified data range):
* exportPlugin.exportAsString('csv', {
* exportHiddenRows: true, // default false
* exportHiddenColumns: true, // default false
* columnHeaders: true, // default false
* rowHeaders: true, // default false
* columnDelimiter: ';', // default ','
* range: [1, 1, 6, 6] // [startRow, endRow, startColumn, endColumn]
* });
* ```
*/
var ExportFile =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(ExportFile, _BasePlugin);
function ExportFile() {
(0, _classCallCheck2.default)(this, ExportFile);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ExportFile).apply(this, arguments));
}
(0, _createClass2.default)(ExportFile, [{
key: "isEnabled",
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link ExportFile#enablePlugin} method is called.
*
* @returns {Boolean}
*/
value: function isEnabled() {
return true;
}
/**
* @typedef ExportOptions
* @memberof ExportFile
* @type {object}
* @property {boolean} [exportHiddenRows=false] Include hidden rows in the exported file.
* @property {boolean} [exportHiddenColumns=false] Include hidden columns in the exported file.
* @property {boolean} [columnHeaders=false] Include column headers in the exported file.
* @property {boolean} [rowHeaders=false] Include row headers in the exported file.
* @property {string} [columnDelimiter=','] Column delimiter.
* @property {string} [range=[]] Cell range that will be exported to file.
*/
/**
* Exports table data as a string.
*
* @param {String} format Export format type eq. `'csv'`.
* @param {ExportOptions} options Export options.
*/
}, {
key: "exportAsString",
value: function exportAsString(format) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return this._createTypeFormatter(format, options).export();
}
/**
* Exports table data as a blob object.
*
* @param {String} format Export format type eq. `'csv'`.
* @param {ExportOptions} options Export options.
*/
}, {
key: "exportAsBlob",
value: function exportAsBlob(format) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return this._createBlob(this._createTypeFormatter(format, options));
}
/**
* Exports table data as a downloadable file.
*
* @param {String} format Export format type eq. `'csv'`.
* @param {ExportOptions} options Export options.
*/
}, {
key: "downloadFile",
value: function downloadFile(format) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _this$hot = this.hot,
rootDocument = _this$hot.rootDocument,
rootWindow = _this$hot.rootWindow;
var formatter = this._createTypeFormatter(format, options);
var blob = this._createBlob(formatter);
var URL = rootWindow.URL || rootWindow.webkitURL;
var a = rootDocument.createElement('a');
var name = "".concat(formatter.options.filename, ".").concat(formatter.options.fileExtension);
if (a.download !== void 0) {
var url = URL.createObjectURL(blob);
a.style.display = 'none';
a.setAttribute('href', url);
a.setAttribute('download', name);
rootDocument.body.appendChild(a);
a.dispatchEvent(new MouseEvent('click'));
rootDocument.body.removeChild(a);
setTimeout(function () {
URL.revokeObjectURL(url);
}, 100);
} else if (navigator.msSaveOrOpenBlob) {
// IE10+
navigator.msSaveOrOpenBlob(blob, name);
}
}
/**
* Creates and returns class formatter for specified export type.
*
* @private
* @param {String} format Export format type eq. `'csv'`.
* @param {ExportOptions} options Export options.
*/
}, {
key: "_createTypeFormatter",
value: function _createTypeFormatter(format) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!_typeFactory.EXPORT_TYPES[format]) {
throw new Error("Export format type \"".concat(format, "\" is not supported."));
}
return (0, _typeFactory.default)(format, new _dataProvider.default(this.hot), options);
}
/**
* Creates blob object based on provided type formatter class.
*
* @private
* @param {BaseType} typeFormatter
* @returns {Blob}
*/
}, {
key: "_createBlob",
value: function _createBlob(typeFormatter) {
var formatter = null;
if (typeof Blob !== 'undefined') {
formatter = new Blob([typeFormatter.export()], {
type: "".concat(typeFormatter.options.mimeType, ";charset=").concat(typeFormatter.options.encoding)
});
}
return formatter;
}
}]);
return ExportFile;
}(_base.default);
(0, _plugins.registerPlugin)('exportFile', ExportFile);
var _default = ExportFile;
exports.default = _default;
/***/ }),
/* 445 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _number = __webpack_require__(15);
// Waiting for jshint >=2.9.0 where they added support for destructing
// jshint ignore: start
/**
* @plugin ExportFile
* @private
*/
var DataProvider =
/*#__PURE__*/
function () {
function DataProvider(hotInstance) {
(0, _classCallCheck2.default)(this, DataProvider);
/**
* Handsontable instance.
*
* @type {Core}
*/
this.hot = hotInstance;
/**
* Format type class options.
*
* @type {Object}
*/
this.options = {};
}
/**
* Set options for data provider.
*
* @param {Object} options Object with specified options.
*/
(0, _createClass2.default)(DataProvider, [{
key: "setOptions",
value: function setOptions(options) {
this.options = options;
}
/**
* Get table data based on provided settings to the class constructor.
*
* @returns {Array}
*/
}, {
key: "getData",
value: function getData() {
var _this = this;
var _this$_getDataRange = this._getDataRange(),
startRow = _this$_getDataRange.startRow,
startCol = _this$_getDataRange.startCol,
endRow = _this$_getDataRange.endRow,
endCol = _this$_getDataRange.endCol;
var options = this.options;
var data = [];
(0, _number.rangeEach)(startRow, endRow, function (rowIndex) {
var row = [];
if (!options.exportHiddenRows && _this._isHiddenRow(rowIndex)) {
return;
}
(0, _number.rangeEach)(startCol, endCol, function (colIndex) {
if (!options.exportHiddenColumns && _this._isHiddenColumn(colIndex)) {
return;
}
row.push(_this.hot.getDataAtCell(rowIndex, colIndex));
});
data.push(row);
});
return data;
}
/**
* Gets list of row headers.
*
* @return {Array}
*/
}, {
key: "getRowHeaders",
value: function getRowHeaders() {
var _this2 = this;
var headers = [];
if (this.options.rowHeaders) {
var _this$_getDataRange2 = this._getDataRange(),
startRow = _this$_getDataRange2.startRow,
endRow = _this$_getDataRange2.endRow;
var rowHeaders = this.hot.getRowHeader();
(0, _number.rangeEach)(startRow, endRow, function (row) {
if (!_this2.options.exportHiddenRows && _this2._isHiddenRow(row)) {
return;
}
headers.push(rowHeaders[row]);
});
}
return headers;
}
/**
* Gets list of columns headers.
*
* @return {Array}
*/
}, {
key: "getColumnHeaders",
value: function getColumnHeaders() {
var _this3 = this;
var headers = [];
if (this.options.columnHeaders) {
var _this$_getDataRange3 = this._getDataRange(),
startCol = _this$_getDataRange3.startCol,
endCol = _this$_getDataRange3.endCol;
var colHeaders = this.hot.getColHeader();
(0, _number.rangeEach)(startCol, endCol, function (column) {
if (!_this3.options.exportHiddenColumns && _this3._isHiddenColumn(column)) {
return;
}
headers.push(colHeaders[column]);
});
}
return headers;
}
/**
* Get data range object based on settings provided in the class constructor.
*
* @private
* @returns {Object} Returns object with keys `startRow`, `startCol`, `endRow` and `endCol`.
*/
}, {
key: "_getDataRange",
value: function _getDataRange() {
var cols = this.hot.countCols() - 1;
var rows = this.hot.countRows() - 1;
var _this$options$range = (0, _slicedToArray2.default)(this.options.range, 4),
_this$options$range$ = _this$options$range[0],
startRow = _this$options$range$ === void 0 ? 0 : _this$options$range$,
_this$options$range$2 = _this$options$range[1],
startCol = _this$options$range$2 === void 0 ? 0 : _this$options$range$2,
_this$options$range$3 = _this$options$range[2],
endRow = _this$options$range$3 === void 0 ? rows : _this$options$range$3,
_this$options$range$4 = _this$options$range[3],
endCol = _this$options$range$4 === void 0 ? cols : _this$options$range$4;
startRow = Math.max(startRow, 0);
startCol = Math.max(startCol, 0);
endRow = Math.min(endRow, rows);
endCol = Math.min(endCol, cols);
return {
startRow: startRow,
startCol: startCol,
endRow: endRow,
endCol: endCol
};
}
/**
* Check if row at specified row index is hidden.
*
* @private
* @param {Number} row Row index.
* @returns {Boolean}
*/
}, {
key: "_isHiddenRow",
value: function _isHiddenRow(row) {
return this.hot.hasHook('hiddenRow') && this.hot.runHooks('hiddenRow', row);
}
/**
* Check if column at specified column index is hidden.
*
* @private
* @param {Number} column Column index.
* @returns {Boolean}
*/
}, {
key: "_isHiddenColumn",
value: function _isHiddenColumn(column) {
return this.hot.hasHook('hiddenColumn') && this.hot.runHooks('hiddenColumn', column);
}
}]);
return DataProvider;
}();
var _default = DataProvider;
exports.default = _default;
/***/ }),
/* 446 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = typeFactory;
exports.EXPORT_TYPES = exports.TYPE_PDF = exports.TYPE_EXCEL = exports.TYPE_CSV = void 0;
var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));
var _csv = _interopRequireDefault(__webpack_require__(447));
var TYPE_CSV = 'csv';
exports.TYPE_CSV = TYPE_CSV;
var TYPE_EXCEL = 'excel'; // TODO
exports.TYPE_EXCEL = TYPE_EXCEL;
var TYPE_PDF = 'pdf'; // TODO
exports.TYPE_PDF = TYPE_PDF;
var EXPORT_TYPES = (0, _defineProperty2.default)({}, TYPE_CSV, _csv.default);
exports.EXPORT_TYPES = EXPORT_TYPES;
function typeFactory(type, dataProvider, options) {
if (typeof EXPORT_TYPES[type] === 'function') {
return new EXPORT_TYPES[type](dataProvider, options);
}
return null;
}
/***/ }),
/* 447 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(54);
__webpack_require__(164);
__webpack_require__(130);
__webpack_require__(36);
__webpack_require__(37);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _array = __webpack_require__(3);
var _mixed = __webpack_require__(27);
var _base = _interopRequireDefault(__webpack_require__(448));
var CHAR_CARRIAGE_RETURN = String.fromCharCode(13);
var CHAR_DOUBLE_QUOTES = String.fromCharCode(34);
var CHAR_LINE_FEED = String.fromCharCode(10);
/**
* @plugin ExportFile
* @private
*/
var Csv =
/*#__PURE__*/
function (_BaseType) {
(0, _inherits2.default)(Csv, _BaseType);
function Csv() {
(0, _classCallCheck2.default)(this, Csv);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Csv).apply(this, arguments));
}
(0, _createClass2.default)(Csv, [{
key: "export",
/**
* Create string body in desired format.
*
* @return {String}
*/
value: function _export() {
var _this = this;
var options = this.options;
var data = this.dataProvider.getData();
var columnHeaders = this.dataProvider.getColumnHeaders();
var hasColumnHeaders = columnHeaders.length > 0;
var rowHeaders = this.dataProvider.getRowHeaders();
var hasRowHeaders = rowHeaders.length > 0;
var result = options.bom ? String.fromCharCode(0xFEFF) : '';
if (hasColumnHeaders) {
columnHeaders = (0, _array.arrayMap)(columnHeaders, function (value) {
return _this._escapeCell(value, true);
});
if (hasRowHeaders) {
result += options.columnDelimiter;
}
result += columnHeaders.join(options.columnDelimiter);
result += options.rowDelimiter;
}
(0, _array.arrayEach)(data, function (value, index) {
if (index > 0) {
result += options.rowDelimiter;
}
if (hasRowHeaders) {
result += _this._escapeCell(rowHeaders[index]) + options.columnDelimiter;
}
result += value.map(function (cellValue) {
return _this._escapeCell(cellValue);
}).join(options.columnDelimiter);
});
return result;
}
/**
* Escape cell value.
*
* @param {*} value Cell value.
* @param {Boolean} [force=false] Indicates if cell value will be escaped forcefully.
* @return {String}
*/
}, {
key: "_escapeCell",
value: function _escapeCell(value) {
var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var escapedValue = (0, _mixed.stringify)(value);
if (escapedValue !== '' && (force || escapedValue.indexOf(CHAR_CARRIAGE_RETURN) >= 0 || escapedValue.indexOf(CHAR_DOUBLE_QUOTES) >= 0 || escapedValue.indexOf(CHAR_LINE_FEED) >= 0 || escapedValue.indexOf(this.options.columnDelimiter) >= 0)) {
escapedValue = escapedValue.replace(new RegExp('"', 'g'), '""');
escapedValue = "\"".concat(escapedValue, "\"");
}
return escapedValue;
}
}], [{
key: "DEFAULT_OPTIONS",
/**
* Default options for exporting CSV format.
*
* @returns {Object}
*/
get: function get() {
return {
mimeType: 'text/csv',
fileExtension: 'csv',
bom: true,
columnDelimiter: ',',
rowDelimiter: '\r\n'
};
}
}]);
return Csv;
}(_base.default);
var _default = Csv;
exports.default = _default;
/***/ }),
/* 448 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(204);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _object = __webpack_require__(4);
var _string = __webpack_require__(68);
/**
* @plugin ExportFile
* @private
*/
var BaseType =
/*#__PURE__*/
function () {
(0, _createClass2.default)(BaseType, null, [{
key: "DEFAULT_OPTIONS",
/**
* Default options.
*
* @returns {Object}
*/
get: function get() {
return {
mimeType: 'text/plain',
fileExtension: 'txt',
filename: 'Handsontable [YYYY]-[MM]-[DD]',
encoding: 'utf-8',
bom: false,
columnHeaders: false,
rowHeaders: false,
exportHiddenColumns: false,
exportHiddenRows: false,
range: []
};
}
}]);
function BaseType(dataProvider, options) {
(0, _classCallCheck2.default)(this, BaseType);
/**
* Data provider.
*
* @type {DataProvider}
*/
this.dataProvider = dataProvider;
/**
* Format type class options.
*
* @type {Object}
*/
this.options = this._mergeOptions(options);
this.dataProvider.setOptions(this.options);
}
/**
* Merge options provided by users with defaults.
*
* @return {Object} Returns new options object.
*/
(0, _createClass2.default)(BaseType, [{
key: "_mergeOptions",
value: function _mergeOptions(options) {
var _options = (0, _object.clone)(this.constructor.DEFAULT_OPTIONS);
var date = new Date();
_options = (0, _object.extend)((0, _object.clone)(BaseType.DEFAULT_OPTIONS), _options);
_options = (0, _object.extend)(_options, options);
_options.filename = (0, _string.substitute)(_options.filename, {
YYYY: date.getFullYear(),
MM: "".concat(date.getMonth() + 1).padStart(2, '0'),
DD: "".concat(date.getDate()).padStart(2, '0')
});
return _options;
}
}]);
return BaseType;
}();
var _default = BaseType;
exports.default = _default;
/***/ }),
/* 449 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(63);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get3 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _columnSorting = _interopRequireDefault(__webpack_require__(236));
var _sortService = __webpack_require__(88);
var _utils = __webpack_require__(165);
var _plugins = __webpack_require__(20);
var _keyStateObserver = __webpack_require__(136);
var _element = __webpack_require__(5);
var _rootComparator = __webpack_require__(450);
var _utils2 = __webpack_require__(451);
var _domHelpers = __webpack_require__(452);
__webpack_require__(453);
var APPEND_COLUMN_CONFIG_STRATEGY = 'append';
var PLUGIN_KEY = 'multiColumnSorting';
var CONFLICTED_PLUGIN_KEY = 'columnSorting';
(0, _sortService.registerRootComparator)(PLUGIN_KEY, _rootComparator.rootComparator);
/**
* @plugin MultiColumnSorting
* @dependencies ColumnSorting
*
* @description
* This plugin sorts the view by columns (but does not sort the data source!). To enable the plugin, set the
* {@link Options#multiColumnSorting} property to the correct value (see the examples below).
*
* @example
* ```js
* // as boolean
* multiColumnSorting: true
*
* // as an object with initial sort config (sort ascending for column at index 1 and then sort descending for column at index 0)
* multiColumnSorting: {
* initialConfig: [{
* column: 1,
* sortOrder: 'asc'
* }, {
* column: 0,
* sortOrder: 'desc'
* }]
* }
*
* // as an object which define specific sorting options for all columns
* multiColumnSorting: {
* sortEmptyCells: true, // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table (by default)
* indicator: true, // true = shows indicator for all columns (by default), false = don't show indicator for columns
* headerAction: true, // true = allow to click on the headers to sort (by default), false = turn off possibility to click on the headers to sort
* compareFunctionFactory: function(sortOrder, columnMeta) {
* return function(value, nextValue) {
* // Some value comparisons which will return -1, 0 or 1...
* }
* }
* }
*
* // as an object passed to the `column` property, allows specifying a custom options for the desired column.
* // please take a look at documentation of `column` property: https://docs.handsontable.com/pro/Options.html#columns
* columns: [{
* multiColumnSorting: {
* indicator: false, // disable indicator for the first column,
* sortEmptyCells: true,
* headerAction: false, // clicks on the first column won't sort
* compareFunctionFactory: function(sortOrder, columnMeta) {
* return function(value, nextValue) {
* return 0; // Custom compare function for the first column (don't sort)
* }
* }
* }
* }]```
*
* @dependencies ObserveChanges
*/
var MultiColumnSorting =
/*#__PURE__*/
function (_ColumnSorting) {
(0, _inherits2.default)(MultiColumnSorting, _ColumnSorting);
function MultiColumnSorting(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, MultiColumnSorting);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MultiColumnSorting).call(this, hotInstance));
/**
* Main settings key designed for the plugin.
*
* @private
* @type {String}
*/
_this.pluginKey = PLUGIN_KEY;
return _this;
}
/**
* Checks if the plugin is enabled in the Handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link MultiColumnSorting#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(MultiColumnSorting, [{
key: "isEnabled",
value: function isEnabled() {
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "isEnabled", this).call(this);
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
if (!this.enabled && this.hot.getSettings()[this.pluginKey] && this.hot.getSettings()[CONFLICTED_PLUGIN_KEY]) {
(0, _utils2.warnAboutPluginsConflict)();
}
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "disablePlugin", this).call(this);
}
/**
* Sorts the table by chosen columns and orders.
*
* @param {undefined|Object|Array} sortConfig Single column sort configuration or full sort configuration (for all sorted columns).
* The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
* sort order (`asc` for ascending, `desc` for descending).
*
* **Note**: Please keep in mind that every call of `sort` function set an entirely new sort order. Previous sort configs aren't preserved.
*
* @example
* ```js
* // sort ascending first visual column
* hot.getPlugin('multiColumnSorting').sort({ column: 0, sortOrder: 'asc' });
*
* // sort first two visual column in the defined sequence
* hot.getPlugin('multiColumnSorting').sort([{
* column: 1, sortOrder: 'asc'
* }, {
* column: 0, sortOrder: 'desc'
* }]);
* ```
*
* @fires Hooks#beforeColumnSort
* @fires Hooks#afterColumnSort
*/
}, {
key: "sort",
value: function sort(sortConfig) {
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "sort", this).call(this, sortConfig);
}
/**
* Clear the sort performed on the table.
*/
}, {
key: "clearSort",
value: function clearSort() {
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "clearSort", this).call(this);
}
/**
* Checks if the table is sorted (any column have to be sorted).
*
* @returns {Boolean}
*/
}, {
key: "isSorted",
value: function isSorted() {
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "isSorted", this).call(this);
}
/**
* Get sort configuration for particular column or for all sorted columns. Objects contain `column` and `sortOrder` properties.
*
* **Note**: Please keep in mind that returned objects expose **visual** column index under the `column` key. They are handled by the `sort` function.
*
* @param {Number} [column] Visual column index.
* @returns {undefined|Object|Array}
*/
}, {
key: "getSortConfig",
value: function getSortConfig(column) {
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "getSortConfig", this).call(this, column);
}
/**
* @description
* Warn: Useful mainly for providing server side sort implementation (see in the example below). It doesn't sort the data set. It just sets sort configuration for all sorted columns.
* Note: Please keep in mind that this method doesn't re-render the table.
*
* @example
* ```js
* beforeColumnSort: function(currentSortConfig, destinationSortConfigs) {
* const columnSortPlugin = this.getPlugin('multiColumnSorting');
*
* columnSortPlugin.setSortConfig(destinationSortConfigs);
*
* // const newData = ... // Calculated data set, ie. from an AJAX call.
*
* this.loadData(newData); // Load new data set and re-render the table.
*
* return false; // The blockade for the default sort action.
* }```
*
* @param {undefined|Object|Array} sortConfig Single column sort configuration or full sort configuration (for all sorted columns).
* The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
* sort order (`asc` for ascending, `desc` for descending).
*/
}, {
key: "setSortConfig",
value: function setSortConfig(sortConfig) {
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "setSortConfig", this).call(this, sortConfig);
}
/**
* Get normalized sort configs.
*
* @private
* @param {Object|Array} [sortConfig=[]] Single column sort configuration or full sort configuration (for all sorted columns).
* The configuration object contains `column` and `sortOrder` properties. First of them contains visual column index, the second one contains
* sort order (`asc` for ascending, `desc` for descending).
* @returns {Array}
*/
}, {
key: "getNormalizedSortConfigs",
value: function getNormalizedSortConfigs() {
var sortConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
if (Array.isArray(sortConfig)) {
return sortConfig;
}
return [sortConfig];
}
/**
* Update header classes.
*
* @private
* @param {HTMLElement} headerSpanElement Header span element.
* @param {...*} args Extra arguments for helpers.
*/
}, {
key: "updateHeaderClasses",
value: function updateHeaderClasses(headerSpanElement) {
var _get2;
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
(_get2 = (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "updateHeaderClasses", this)).call.apply(_get2, [this, headerSpanElement].concat(args));
(0, _element.removeClass)(headerSpanElement, (0, _domHelpers.getClassedToRemove)(headerSpanElement));
if (this.enabled !== false) {
(0, _element.addClass)(headerSpanElement, _domHelpers.getClassesToAdd.apply(void 0, args));
}
}
/**
* Overwriting base plugin's `onUpdateSettings` method. Please keep in mind that `onAfterUpdateSettings` isn't called
* for `updateSettings` in specific situations.
*
* @private
* @param {Object} newSettings New settings object.
*/
}, {
key: "onUpdateSettings",
value: function onUpdateSettings(newSettings) {
if (this.hot.getSettings()[this.pluginKey] && this.hot.getSettings()[CONFLICTED_PLUGIN_KEY]) {
(0, _utils2.warnAboutPluginsConflict)();
}
return (0, _get3.default)((0, _getPrototypeOf2.default)(MultiColumnSorting.prototype), "onUpdateSettings", this).call(this, newSettings);
}
/**
* Callback for the `onAfterOnCellMouseDown` hook.
*
* @private
* @param {Event} event Event which are provided by hook.
* @param {CellCoords} coords Visual coords of the selected cell.
*/
}, {
key: "onAfterOnCellMouseDown",
value: function onAfterOnCellMouseDown(event, coords) {
if ((0, _utils.wasHeaderClickedProperly)(coords.row, coords.col, event) === false) {
return;
}
if (this.wasClickableHeaderClicked(event, coords.col)) {
if ((0, _keyStateObserver.isPressedCtrlKey)()) {
this.hot.deselectCell();
this.hot.selectColumns(coords.col);
this.sort(this.getNextSortConfig(coords.col, APPEND_COLUMN_CONFIG_STRATEGY));
} else {
this.sort(this.getColumnNextConfig(coords.col));
}
}
}
}]);
return MultiColumnSorting;
}(_columnSorting.default);
(0, _plugins.registerPlugin)(PLUGIN_KEY, MultiColumnSorting);
var _default = MultiColumnSorting;
exports.default = _default;
/***/ }),
/* 450 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(40);
exports.__esModule = true;
exports.rootComparator = rootComparator;
var _toArray2 = _interopRequireDefault(__webpack_require__(238));
var _sortService = __webpack_require__(88);
/* eslint-disable import/prefer-default-export */
/**
* Sort comparator handled by conventional sort algorithm.
*
* @param {Array} sortOrders Sort orders (`asc` for ascending, `desc` for descending).
* @param {Array} columnMetas Column meta objects.
* @returns {Function}
*/
function rootComparator(sortingOrders, columnMetas) {
return function (rowIndexWithValues, nextRowIndexWithValues) {
// We sort array of arrays. Single array is in form [rowIndex, ...values].
// We compare just values, stored at second index of array.
var _rowIndexWithValues = (0, _toArray2.default)(rowIndexWithValues),
values = _rowIndexWithValues.slice(1);
var _nextRowIndexWithValu = (0, _toArray2.default)(nextRowIndexWithValues),
nextValues = _nextRowIndexWithValu.slice(1);
return function getCompareResult(column) {
var sortingOrder = sortingOrders[column];
var columnMeta = columnMetas[column];
var value = values[column];
var nextValue = nextValues[column];
var pluginSettings = columnMeta.multiColumnSorting;
var compareFunctionFactory = pluginSettings.compareFunctionFactory ? pluginSettings.compareFunctionFactory : (0, _sortService.getCompareFunctionFactory)(columnMeta.type);
var compareResult = compareFunctionFactory(sortingOrder, columnMeta, pluginSettings)(value, nextValue);
if (compareResult === _sortService.DO_NOT_SWAP) {
var nextSortedColumn = column + 1;
if (typeof columnMetas[nextSortedColumn] !== 'undefined') {
return getCompareResult(nextSortedColumn);
}
}
return compareResult;
}(0);
};
}
/***/ }),
/* 451 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.warnAboutPluginsConflict = warnAboutPluginsConflict;
var _console = __webpack_require__(55);
/* eslint-disable import/prefer-default-export */
/**
* Warn users about problems when using `columnSorting` and `multiColumnSorting` plugins simultaneously.
*/
function warnAboutPluginsConflict() {
(0, _console.warn)('Plugins `columnSorting` and `multiColumnSorting` should not be enabled simultaneously.');
}
/***/ }),
/* 452 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
__webpack_require__(56);
__webpack_require__(130);
__webpack_require__(36);
__webpack_require__(46);
exports.__esModule = true;
exports.getClassesToAdd = getClassesToAdd;
exports.getClassedToRemove = getClassedToRemove;
/* eslint-disable import/prefer-default-export */
var COLUMN_ORDER_PREFIX = 'sort';
/**
* Get CSS classes which should be added to particular column header.
*
* @param {Object} columnStatesManager Instance of column state manager.
* @param {Number} column Physical column index.
* @param {Boolean} showSortIndicator Indicates if indicator should be shown for the particular column.
* @returns {Array} Array of CSS classes.
*/
function getClassesToAdd(columnStatesManager, column, showSortIndicator) {
var cssClasses = [];
if (showSortIndicator === false) {
return cssClasses;
}
if (columnStatesManager.isColumnSorted(column) && columnStatesManager.getNumberOfSortedColumns() > 1) {
cssClasses.push("".concat(COLUMN_ORDER_PREFIX, "-").concat(columnStatesManager.getIndexOfColumnInSortQueue(column) + 1));
}
return cssClasses;
}
/**
* Get CSS classes which should be removed from column header.
*
* @param {HTMLElement} htmlElement
* @returns {Array} Array of CSS classes.
*/
function getClassedToRemove(htmlElement) {
var cssClasses = htmlElement.className.split(' ');
var sortSequenceRegExp = new RegExp("^".concat(COLUMN_ORDER_PREFIX, "-[0-9]{1,2}$"));
return cssClasses.filter(function (cssClass) {
return sortSequenceRegExp.test(cssClass);
});
}
/***/ }),
/* 453 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 454 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(56);
__webpack_require__(34);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(33);
__webpack_require__(51);
__webpack_require__(70);
__webpack_require__(10);
__webpack_require__(39);
__webpack_require__(14);
__webpack_require__(234);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(65));
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _array = __webpack_require__(3);
var _templateLiteralTag = __webpack_require__(67);
var _console = __webpack_require__(55);
var _number = __webpack_require__(15);
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _element = __webpack_require__(5);
var _plugins = __webpack_require__(20);
var _predefinedItems = __webpack_require__(83);
var constants = _interopRequireWildcard(__webpack_require__(11));
var _condition = _interopRequireDefault(__webpack_require__(455));
var _operators = _interopRequireDefault(__webpack_require__(476));
var _value = _interopRequireDefault(__webpack_require__(478));
var _actionBar = _interopRequireDefault(__webpack_require__(484));
var _conditionCollection = _interopRequireDefault(__webpack_require__(253));
var _dataFilter = _interopRequireDefault(__webpack_require__(254));
var _conditionUpdateObserver = _interopRequireDefault(__webpack_require__(485));
var _utils = __webpack_require__(108);
var _constants2 = __webpack_require__(169);
__webpack_require__(486);
function _templateObject() {
var data = (0, _taggedTemplateLiteral2.default)(["The filter conditions have been applied properly, but couldn\u2019t be displayed visually.\n The overall amount of conditions exceed the capability of the dropdown menu.\n For more details see the documentation."]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
/**
* @plugin Filters
* @dependencies DropdownMenu TrimRows HiddenRows
*
* @description
* The plugin allows filtering the table data either by the built-in component or with the API.
*
* See [the filtering demo](https://docs.handsontable.com/pro/demo-filtering.html) for examples.
*
* @example
* ```
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* data: getData(),
* colHeaders: true,
* rowHeaders: true,
* dropdownMenu: true,
* filters: true
* });
* ```
*/
var Filters =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(Filters, _BasePlugin);
function Filters(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, Filters);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Filters).call(this, hotInstance));
/**
* Instance of {@link EventManager}.
*
* @private
* @type {EventManager}
*/
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
/**
* Instance of {@link TrimRows}.
*
* @private
* @type {TrimRows}
*/
_this.trimRowsPlugin = null;
/**
* Instance of {@link DropdownMenu}.
*
* @private
* @type {DropdownMenu}
*/
_this.dropdownMenuPlugin = null;
/**
* Instance of {@link ConditionCollection}.
*
* @private
* @type {ConditionCollection}
*/
_this.conditionCollection = null;
/**
* Instance of {@link ConditionUpdateObserver}.
*
* @private
* @type {ConditionUpdateObserver}
*/
_this.conditionUpdateObserver = null;
/**
* Map, where key is component identifier and value represent `BaseComponent` element or it derivatives.
*
* @private
* @type {Map}
*/
_this.components = new Map([['filter_by_condition', null], ['filter_operators', null], ['filter_by_condition2', null], ['filter_by_value', null], ['filter_action_bar', null]]);
/**
* Object containing information about last selected column physical and visual index for added filter conditions.
*
* @private
* @type {Object}
* @default null
*/
_this.lastSelectedColumn = null;
/**
* Hidden menu rows indexed by physical column index
*
* @private
* @type {Map}
*/
_this.hiddenRowsCache = new Map(); // One listener for the enable/disable functionality
_this.hot.addHook('afterGetColHeader', function (col, TH) {
return _this.onAfterGetColHeader(col, TH);
});
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link Filters#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(Filters, [{
key: "isEnabled",
value: function isEnabled() {
/* eslint-disable no-unneeded-ternary */
return this.hot.getSettings().filters ? true : false;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.trimRowsPlugin = this.hot.getPlugin('trimRows');
this.dropdownMenuPlugin = this.hot.getPlugin('dropdownMenu');
var addConfirmationHooks = function addConfirmationHooks(component) {
component.addLocalHook('accept', function () {
return _this2.onActionBarSubmit('accept');
});
component.addLocalHook('cancel', function () {
return _this2.onActionBarSubmit('cancel');
});
component.addLocalHook('change', function (command) {
return _this2.onComponentChange(component, command);
});
return component;
};
var filterByConditionLabel = function filterByConditionLabel() {
return "".concat(_this2.hot.getTranslatedPhrase(constants.FILTERS_DIVS_FILTER_BY_CONDITION), ":");
};
var filterValueLabel = function filterValueLabel() {
return "".concat(_this2.hot.getTranslatedPhrase(constants.FILTERS_DIVS_FILTER_BY_VALUE), ":");
};
if (!this.components.get('filter_by_condition')) {
var conditionComponent = new _condition.default(this.hot, {
id: 'filter_by_condition',
name: filterByConditionLabel,
addSeparator: false
});
conditionComponent.addLocalHook('afterClose', function () {
return _this2.onSelectUIClosed();
});
this.components.set('filter_by_condition', addConfirmationHooks(conditionComponent));
}
if (!this.components.get('filter_operators')) {
this.components.set('filter_operators', new _operators.default(this.hot, {
id: 'filter_operators',
name: 'Operators'
}));
}
if (!this.components.get('filter_by_condition2')) {
var _conditionComponent = new _condition.default(this.hot, {
id: 'filter_by_condition2',
name: '',
addSeparator: true
});
_conditionComponent.addLocalHook('afterClose', function () {
return _this2.onSelectUIClosed();
});
this.components.set('filter_by_condition2', addConfirmationHooks(_conditionComponent));
}
if (!this.components.get('filter_by_value')) {
this.components.set('filter_by_value', addConfirmationHooks(new _value.default(this.hot, {
id: 'filter_by_value',
name: filterValueLabel
})));
}
if (!this.components.get('filter_action_bar')) {
this.components.set('filter_action_bar', addConfirmationHooks(new _actionBar.default(this.hot, {
id: 'filter_action_bar',
name: 'Action bar'
})));
}
if (!this.conditionCollection) {
this.conditionCollection = new _conditionCollection.default();
}
if (!this.conditionUpdateObserver) {
this.conditionUpdateObserver = new _conditionUpdateObserver.default(this.conditionCollection, function (column) {
return _this2.getDataMapAtColumn(column);
});
this.conditionUpdateObserver.addLocalHook('update', function (conditionState) {
return _this2.updateComponents(conditionState);
});
}
this.components.forEach(function (component) {
component.show();
});
this.registerEvents();
this.addHook('beforeDropdownMenuSetItems', function (items) {
return _this2.onBeforeDropdownMenuSetItems(items);
});
this.addHook('afterDropdownMenuDefaultOptions', function (defaultOptions) {
return _this2.onAfterDropdownMenuDefaultOptions(defaultOptions);
});
this.addHook('afterDropdownMenuShow', function () {
return _this2.onAfterDropdownMenuShow();
});
this.addHook('afterDropdownMenuHide', function () {
return _this2.onAfterDropdownMenuHide();
});
this.addHook('afterChange', function (changes) {
return _this2.onAfterChange(changes);
}); // force to enable dependent plugins
this.hot.getSettings().trimRows = true;
this.trimRowsPlugin.enablePlugin(); // Temp. solution (extending menu items bug in contextMenu/dropdownMenu)
if (this.hot.getSettings().dropdownMenu) {
this.dropdownMenuPlugin.disablePlugin();
this.dropdownMenuPlugin.enablePlugin();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(Filters.prototype), "enablePlugin", this).call(this);
}
/**
* Registers the DOM listeners.
*
* @private
*/
}, {
key: "registerEvents",
value: function registerEvents() {
var _this3 = this;
this.eventManager.addEventListener(this.hot.rootElement, 'click', function (event) {
return _this3.onTableClick(event);
});
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
if (this.enabled) {
if (this.dropdownMenuPlugin.enabled) {
this.dropdownMenuPlugin.menu.clearLocalHooks();
}
this.components.forEach(function (component) {
component.hide();
});
this.conditionCollection.clean();
this.trimRowsPlugin.untrimAll();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(Filters.prototype), "disablePlugin", this).call(this);
}
/**
* @description
* Adds condition to the conditions collection at specified column index.
*
* Possible predefined conditions:
* * `begins_with` - Begins with
* * `between` - Between
* * `by_value` - By value
* * `contains` - Contains
* * `empty` - Empty
* * `ends_with` - Ends with
* * `eq` - Equal
* * `gt` - Greater than
* * `gte` - Greater than or equal
* * `lt` - Less than
* * `lte` - Less than or equal
* * `none` - None (no filter)
* * `not_between` - Not between
* * `not_contains` - Not contains
* * `not_empty` - Not empty
* * `neq` - Not equal
*
* Possible operations on collection of conditions:
* * `conjunction` - [**Conjunction**](https://en.wikipedia.org/wiki/Logical_conjunction) on conditions collection (by default), i.e. for such operation: c1 AND c2 AND c3 AND c4 ... AND cn === TRUE, where c1 ... cn are conditions.
* * `disjunction` - [**Disjunction**](https://en.wikipedia.org/wiki/Logical_disjunction) on conditions collection, i.e. for such operation: `c1 OR c2 OR c3 OR c4 ... OR cn` === TRUE, where c1, c2, c3, c4 ... cn are conditions.
* * `disjunctionWithExtraCondition` - **Disjunction** on first `n - 1`\* conditions from collection with an extra requirement computed from the last condition, i.e. for such operation: `c1 OR c2 OR c3 OR c4 ... OR cn-1 AND cn` === TRUE, where c1, c2, c3, c4 ... cn are conditions.
*
* \* when `n` is collection size; it's used i.e. for one operation introduced from UI (when choosing from filter's drop-down menu two conditions with OR operator between them, mixed with choosing values from the multiple choice select)
*
* **Note**: Mind that you cannot mix different types of operations (for instance, if you use `conjunction`, use it consequently for a particular column).
*
* @example
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* date: getData(),
* filters: true
* });
*
* // access to filters plugin instance
* const filtersPlugin = hot.getPlugin('filters');
*
* // add filter "Greater than" 95 to column at index 1
* filtersPlugin.addCondition(1, 'gt', [95]);
* filtersPlugin.filter();
*
* // add filter "By value" to column at index 1
* // in this case all value's that don't match will be filtered.
* filtersPlugin.addCondition(1, 'by_value', [['ing', 'ed', 'as', 'on']]);
* filtersPlugin.filter();
*
* // add filter "Begins with" with value "de" AND "Not contains" with value "ing"
* filtersPlugin.addCondition(1, 'begins_with', ['de'], 'conjunction');
* filtersPlugin.addCondition(1, 'not_contains', ['ing'], 'conjunction');
* filtersPlugin.filter();
*
* // add filter "Begins with" with value "de" OR "Not contains" with value "ing"
* filtersPlugin.addCondition(1, 'begins_with', ['de'], 'disjunction');
* filtersPlugin.addCondition(1, 'not_contains', ['ing'], 'disjunction');
* filtersPlugin.filter();
* ```
* @param {Number} column Visual column index.
* @param {String} name Condition short name.
* @param {Array} args Condition arguments.
* @param {String} operationId `id` of operation which is performed on the column
*/
}, {
key: "addCondition",
value: function addCondition(column, name, args) {
var operationId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _constants2.OPERATION_AND;
var physicalColumn = this.t.toPhysicalColumn(column);
this.conditionCollection.addCondition(physicalColumn, {
command: {
key: name
},
args: args
}, operationId);
}
/**
* Removes conditions at specified column index.
*
* @param {Number} column Visual column index.
*/
}, {
key: "removeConditions",
value: function removeConditions(column) {
var physicalColumn = this.t.toPhysicalColumn(column);
this.conditionCollection.removeConditions(physicalColumn);
}
/**
* Clears all conditions previously added to the collection for the specified column index or, if the column index
* was not passed, clear the conditions for all columns.
*
* @param {Number} [column] Visual column index.
*/
}, {
key: "clearConditions",
value: function clearConditions(column) {
if (column === void 0) {
this.conditionCollection.clean();
} else {
var physicalColumn = this.t.toPhysicalColumn(column);
this.conditionCollection.clearConditions(physicalColumn);
}
}
/**
* Filters data based on added filter conditions.
*
* @fires Hooks#beforeFilter
* @fires Hooks#afterFilter
*/
}, {
key: "filter",
value: function filter() {
var dataFilter = this._createDataFilter();
var needToFilter = !this.conditionCollection.isEmpty();
var visibleVisualRows = [];
var conditions = this.conditionCollection.exportAllConditions();
var allowFiltering = this.hot.runHooks('beforeFilter', conditions);
if (allowFiltering !== false) {
if (needToFilter) {
var trimmedRows = [];
this.trimRowsPlugin.trimmedRows.length = 0;
visibleVisualRows = (0, _array.arrayMap)(dataFilter.filter(), function (rowData) {
return rowData.meta.visualRow;
});
var visibleVisualRowsAssertion = (0, _utils.createArrayAssertion)(visibleVisualRows);
(0, _number.rangeEach)(this.hot.countSourceRows() - 1, function (row) {
if (!visibleVisualRowsAssertion(row)) {
trimmedRows.push(row);
}
});
this.trimRowsPlugin.trimRows(trimmedRows);
if (!visibleVisualRows.length) {
this.hot.deselectCell();
}
} else {
this.trimRowsPlugin.untrimAll();
}
}
this.hot.view.wt.wtOverlays.adjustElementsSize(true);
this.hot.render();
this.clearColumnSelection();
this.hot.runHooks('afterFilter', conditions);
}
/**
* Gets last selected column index.
*
* @returns {Object|null} Return `null` when column isn't selected otherwise
* object containing information about selected column with keys `visualIndex` and `physicalIndex`
*/
}, {
key: "getSelectedColumn",
value: function getSelectedColumn() {
return this.lastSelectedColumn;
}
/**
* Clears column selection.
*
* @private
*/
}, {
key: "clearColumnSelection",
value: function clearColumnSelection() {
var _ref = this.hot.getSelectedLast() || [],
_ref2 = (0, _slicedToArray2.default)(_ref, 2),
row = _ref2[0],
col = _ref2[1];
if (row !== void 0 && col !== void 0) {
this.hot.selectCell(row, col);
}
}
/**
* Returns handsontable source data with cell meta based on current selection.
*
* @param {Number} [column] Column index. By default column index accept the value of the selected column.
* @returns {Array} Returns array of objects where keys as row index.
*/
}, {
key: "getDataMapAtColumn",
value: function getDataMapAtColumn(column) {
var _this4 = this;
var visualIndex = this.t.toVisualColumn(column);
var data = [];
(0, _array.arrayEach)(this.hot.getSourceDataAtCol(visualIndex), function (value, rowIndex) {
var _this4$hot$getCellMet = _this4.hot.getCellMeta(rowIndex, visualIndex),
row = _this4$hot$getCellMet.row,
col = _this4$hot$getCellMet.col,
visualCol = _this4$hot$getCellMet.visualCol,
visualRow = _this4$hot$getCellMet.visualRow,
type = _this4$hot$getCellMet.type,
instance = _this4$hot$getCellMet.instance,
dateFormat = _this4$hot$getCellMet.dateFormat;
data.push({
meta: {
row: row,
col: col,
visualCol: visualCol,
visualRow: visualRow,
type: type,
instance: instance,
dateFormat: dateFormat
},
value: (0, _utils.toEmptyString)(value)
});
});
return data;
}
/**
* `afterChange` listener.
*
* @private
* @param {Array} changes Array of changes.
*/
}, {
key: "onAfterChange",
value: function onAfterChange(changes) {
var _this5 = this;
if (changes) {
(0, _array.arrayEach)(changes, function (change) {
var _change = (0, _slicedToArray2.default)(change, 2),
prop = _change[1];
var columnIndex = _this5.hot.propToCol(prop);
if (_this5.conditionCollection.hasConditions(columnIndex)) {
_this5.updateValueComponentCondition(columnIndex);
}
});
}
}
/**
* Update condition of ValueComponent basing on handled changes
*
* @private
* @param {Number} columnIndex Column index of handled ValueComponent condition
*/
}, {
key: "updateValueComponentCondition",
value: function updateValueComponentCondition(columnIndex) {
var dataAtCol = this.hot.getDataAtCol(columnIndex);
var selectedValues = (0, _utils.unifyColumnValues)(dataAtCol);
this.conditionUpdateObserver.updateStatesAtColumn(columnIndex, selectedValues);
}
/**
* Restores components to their cached state.
*
* @private
* @param {Array} components List of components.
*/
}, {
key: "restoreComponents",
value: function restoreComponents(components) {
var selectedColumn = this.getSelectedColumn();
var physicalIndex = selectedColumn && selectedColumn.physicalIndex;
components.forEach(function (component) {
if (component.isHidden() === false) {
component.restoreState(physicalIndex);
}
});
}
/**
* After dropdown menu show listener.
*
* @private
*/
}, {
key: "onAfterDropdownMenuShow",
value: function onAfterDropdownMenuShow() {
this.restoreComponents([this.components.get('filter_by_condition'), this.components.get('filter_operators'), this.components.get('filter_by_condition2'), this.components.get('filter_by_value')]);
}
/**
* After dropdown menu hide listener.
*
* @private
*/
}, {
key: "onAfterDropdownMenuHide",
value: function onAfterDropdownMenuHide() {
this.components.get('filter_by_condition').getSelectElement().closeOptions();
this.components.get('filter_by_condition2').getSelectElement().closeOptions();
}
/**
* Before dropdown menu set menu items listener.
*
* @private
* @param {Array} items DropdownMenu items created based on predefined items and settings provided by user.
*/
}, {
key: "onBeforeDropdownMenuSetItems",
value: function onBeforeDropdownMenuSetItems(items) {
var menuKeys = (0, _array.arrayMap)(items, function (item) {
return item.key;
});
this.components.forEach(function (component) {
component[menuKeys.indexOf(component.getMenuItemDescriptor().key) === -1 ? 'hide' : 'show']();
});
this.initHiddenRowsCache();
}
/**
* After dropdown menu default options listener.
*
* @private
* @param {Object} defaultOptions ContextMenu default item options.
*/
}, {
key: "onAfterDropdownMenuDefaultOptions",
value: function onAfterDropdownMenuDefaultOptions(defaultOptions) {
defaultOptions.items.push({
name: _predefinedItems.SEPARATOR
});
this.components.forEach(function (component) {
defaultOptions.items.push(component.getMenuItemDescriptor());
});
}
/**
* Get operation basing on number and type of arguments (where arguments are states of components)
*
* @param {String} suggestedOperation operation which was chosen by user from UI
* @param {Object} byConditionState1 state of first condition component
* @param {Object} byConditionState2 state of second condition component
* @param {Object} byValueState state of value component
* @private
* @returns {String}
*/
}, {
key: "getOperationBasedOnArguments",
value: function getOperationBasedOnArguments(suggestedOperation, byConditionState1, byConditionState2, byValueState) {
var operation = suggestedOperation;
if (operation === _constants2.OPERATION_OR && byConditionState1.command.key !== _constants2.CONDITION_NONE && byConditionState2.command.key !== _constants2.CONDITION_NONE && byValueState.command.key !== _constants2.CONDITION_NONE) {
operation = _constants2.OPERATION_OR_THEN_VARIABLE;
} else if (byValueState.command.key !== _constants2.CONDITION_NONE) {
if (byConditionState1.command.key === _constants2.CONDITION_NONE || byConditionState2.command.key === _constants2.CONDITION_NONE) {
operation = _constants2.OPERATION_AND;
}
}
return operation;
}
/**
* On action bar submit listener.
*
* @private
* @param {String} submitType
*/
}, {
key: "onActionBarSubmit",
value: function onActionBarSubmit(submitType) {
if (submitType === 'accept') {
var selectedColumn = this.getSelectedColumn();
var physicalIndex = selectedColumn && selectedColumn.physicalIndex;
var byConditionState1 = this.components.get('filter_by_condition').getState();
var byConditionState2 = this.components.get('filter_by_condition2').getState();
var byValueState = this.components.get('filter_by_value').getState();
var operation = this.getOperationBasedOnArguments(this.components.get('filter_operators').getActiveOperationId(), byConditionState1, byConditionState2, byValueState);
this.conditionUpdateObserver.groupChanges();
this.conditionCollection.clearConditions(physicalIndex);
if (byConditionState1.command.key === _constants2.CONDITION_NONE && byConditionState2.command.key === _constants2.CONDITION_NONE && byValueState.command.key === _constants2.CONDITION_NONE) {
this.conditionCollection.removeConditions(physicalIndex);
} else {
if (byConditionState1.command.key !== _constants2.CONDITION_NONE) {
this.conditionCollection.addCondition(physicalIndex, byConditionState1, operation);
if (byConditionState2.command.key !== _constants2.CONDITION_NONE) {
this.conditionCollection.addCondition(physicalIndex, byConditionState2, operation);
}
}
if (byValueState.command.key !== _constants2.CONDITION_NONE) {
this.conditionCollection.addCondition(physicalIndex, byValueState, operation);
}
}
this.conditionUpdateObserver.flush();
this.components.get('filter_operators').saveState(physicalIndex);
this.components.get('filter_by_value').saveState(physicalIndex);
this.saveHiddenRowsCache(physicalIndex);
this.trimRowsPlugin.trimmedRows.length = 0;
this.filter();
}
this.dropdownMenuPlugin.close();
}
/**
* On component change listener.
*
* @private
* @param {BaseComponent} component Component inheriting BaseComponent
* @param {Object} command Menu item object (command).
*/
}, {
key: "onComponentChange",
value: function onComponentChange(component, command) {
if (component === this.components.get('filter_by_condition')) {
if (command.showOperators) {
this.showComponents(this.components.get('filter_by_condition2'), this.components.get('filter_operators'));
} else {
this.hideComponents(this.components.get('filter_by_condition2'), this.components.get('filter_operators'));
}
}
if (component.constructor === _condition.default && !command.inputsCount) {
this.setListeningDropdownMenu();
}
}
/**
* On component SelectUI closed listener.
*
* @private
*/
}, {
key: "onSelectUIClosed",
value: function onSelectUIClosed() {
this.setListeningDropdownMenu();
}
/**
* Listen to the keyboard input on document body and forward events to instance of Handsontable
* created by DropdownMenu plugin
*
* @private
*/
}, {
key: "setListeningDropdownMenu",
value: function setListeningDropdownMenu() {
this.dropdownMenuPlugin.setListening();
}
/**
* On after get column header listener.
*
* @private
* @param {Number} col
* @param {HTMLTableCellElement} TH
*/
}, {
key: "onAfterGetColHeader",
value: function onAfterGetColHeader(col, TH) {
var physicalColumn = this.t.toPhysicalColumn(col);
if (this.enabled && this.conditionCollection.hasConditions(physicalColumn)) {
(0, _element.addClass)(TH, 'htFiltersActive');
} else {
(0, _element.removeClass)(TH, 'htFiltersActive');
}
}
/**
* On table click listener.
*
* @private
* @param {Event} event DOM Event.
*/
}, {
key: "onTableClick",
value: function onTableClick(event) {
var th = (0, _element.closest)(event.target, 'TH');
if (th) {
var visualIndex = this.hot.getCoords(th).col;
var physicalIndex = this.t.toPhysicalColumn(visualIndex);
this.lastSelectedColumn = {
visualIndex: visualIndex,
physicalIndex: physicalIndex
};
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
if (this.enabled) {
this.components.forEach(function (component) {
component.destroy();
});
this.conditionCollection.destroy();
this.conditionUpdateObserver.destroy();
this.hiddenRowsCache.clear();
this.trimRowsPlugin.disablePlugin();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(Filters.prototype), "destroy", this).call(this);
}
/**
* Creates DataFilter instance based on condition collection.
*
* @private
* @param {ConditionCollection} conditionCollection Condition collection object.
* @returns {DataFilter}
*/
}, {
key: "_createDataFilter",
value: function _createDataFilter() {
var _this6 = this;
var conditionCollection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.conditionCollection;
return new _dataFilter.default(conditionCollection, function (column) {
return _this6.getDataMapAtColumn(column);
});
}
/**
* Updates components basing on conditions state.
*
* @private
* @param {Object} conditionsState
*/
}, {
key: "updateComponents",
value: function updateComponents(conditionsState) {
if (!this.dropdownMenuPlugin.enabled) {
return;
}
var conditions = conditionsState.editedConditionStack.conditions;
var column = conditionsState.editedConditionStack.column;
var conditionsByValue = conditions.filter(function (condition) {
return condition.name === _constants2.CONDITION_BY_VALUE;
});
var conditionsWithoutByValue = conditions.filter(function (condition) {
return condition.name !== _constants2.CONDITION_BY_VALUE;
});
var operationType = this.conditionCollection.columnTypes[column];
if (conditionsByValue.length === 2 || conditionsWithoutByValue.length === 3) {
(0, _console.warn)((0, _templateLiteralTag.toSingleLine)(_templateObject()));
} else {
if (conditionsWithoutByValue.length > 0) {
this.showComponentForParticularColumn(this.components.get('filter_operators'), column);
}
this.components.get('filter_by_condition').updateState(conditionsWithoutByValue[0], column);
this.components.get('filter_by_condition2').updateState(conditionsWithoutByValue[1], column);
this.components.get('filter_by_value').updateState(conditionsState);
this.components.get('filter_operators').updateState(operationType, column);
}
}
/**
* Shows component for particular column.
*
* @private
* @param {BaseComponent} component `BaseComponent` element or it derivatives.
* @param {Number} column Physical column index.
*/
}, {
key: "showComponentForParticularColumn",
value: function showComponentForParticularColumn(component, column) {
if (!this.hiddenRowsCache.has(column)) {
this.hiddenRowsCache.set(column, []);
} else {
var indexes = this.getIndexesOfComponents(component);
this.removeIndexesFromHiddenRowsCache(column, indexes);
}
}
/**
* Removes specific rows from `hiddenRows` cache for particular column.
*
* @private
* @param {Number} column Physical column index.
* @param {Array} indexes Physical indexes of rows which will be removed from `hiddenRows` cache
*/
}, {
key: "removeIndexesFromHiddenRowsCache",
value: function removeIndexesFromHiddenRowsCache(column, indexes) {
var hiddenRowsForColumn = this.hiddenRowsCache.get(column);
(0, _array.arrayEach)(indexes, function (index) {
if (hiddenRowsForColumn.includes(index)) {
hiddenRowsForColumn.splice(hiddenRowsForColumn.indexOf(index), 1);
}
});
}
/**
* Returns indexes of passed components inside list of `dropdownMenu` items.
*
* @private
* @param {...BaseComponent} components List of components.
* @returns {Array}
*/
}, {
key: "getIndexesOfComponents",
value: function getIndexesOfComponents() {
var menu = this.dropdownMenuPlugin.menu;
var indexes = [];
for (var _len = arguments.length, components = new Array(_len), _key = 0; _key < _len; _key++) {
components[_key] = arguments[_key];
}
(0, _array.arrayEach)(components, function (component) {
(0, _array.arrayEach)(menu.menuItems, function (item, index) {
if (item.key === component.getMenuItemDescriptor().key) {
indexes.push(index);
}
});
});
return indexes;
}
/**
* Changes visibility of component.
*
* @private
* @param {Boolean} visible Determine if components should be visible.
* @param {...BaseComponent} components List of components.
*/
}, {
key: "changeComponentsVisibility",
value: function changeComponentsVisibility() {
var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var menu = this.dropdownMenuPlugin.menu;
var hotMenu = menu.hotMenu;
var hiddenRows = hotMenu.getPlugin('hiddenRows');
for (var _len2 = arguments.length, components = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
components[_key2 - 1] = arguments[_key2];
}
var indexes = this.getIndexesOfComponents.apply(this, components);
if (visible) {
hiddenRows.showRows(indexes);
} else {
hiddenRows.hideRows(indexes);
}
hotMenu.render();
}
/**
* Initializes `hiddenRows` cache.
*
* @private
*/
}, {
key: "initHiddenRowsCache",
value: function initHiddenRowsCache() {
var _this7 = this;
this.dropdownMenuPlugin.menu.addLocalHook('afterOpen', function () {
var index = _this7.lastSelectedColumn.physicalIndex;
if (!_this7.hiddenRowsCache.has(index)) {
_this7.hiddenRowsCache.set(index, _this7.getIndexesOfComponents(_this7.components.get('filter_operators'), _this7.components.get('filter_by_condition2')));
}
_this7.dropdownMenuPlugin.menu.hotMenu.updateSettings({
hiddenRows: {
rows: _this7.hiddenRowsCache.get(index)
}
});
});
}
/**
* Saves `hiddenRows` cache for particular row.
*
* @private
* @param rowIndex Physical row index
*/
}, {
key: "saveHiddenRowsCache",
value: function saveHiddenRowsCache(rowIndex) {
this.hiddenRowsCache.set(rowIndex, this.dropdownMenuPlugin.menu.hotMenu.getPlugin('hiddenRows').hiddenRows);
}
/**
* Hides components of filters `dropdownMenu`.
*
* @private
* @param {...BaseComponent} components List of components.
*/
}, {
key: "hideComponents",
value: function hideComponents() {
for (var _len3 = arguments.length, components = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
components[_key3] = arguments[_key3];
}
this.changeComponentsVisibility.apply(this, [false].concat(components));
}
/**
* Shows components of filters `dropdownMenu`.
*
* @private
* @param {...BaseComponent} components List of components.
*/
}, {
key: "showComponents",
value: function showComponents() {
for (var _len4 = arguments.length, components = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
components[_key4] = arguments[_key4];
}
this.changeComponentsVisibility.apply(this, [true].concat(components));
}
}]);
return Filters;
}(_base.default);
(0, _plugins.registerPlugin)('filters', Filters);
var _default = Filters;
exports.default = _default;
/***/ }),
/* 455 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(56);
__webpack_require__(51);
__webpack_require__(138);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _event = __webpack_require__(31);
var _array = __webpack_require__(3);
var _unicode = __webpack_require__(50);
var _object = __webpack_require__(4);
var C = _interopRequireWildcard(__webpack_require__(11));
var _base = _interopRequireDefault(__webpack_require__(139));
var _constants2 = _interopRequireWildcard(__webpack_require__(169));
var _input = _interopRequireDefault(__webpack_require__(171));
var _select = _interopRequireDefault(__webpack_require__(475));
var _conditionRegisterer = __webpack_require__(28);
/**
* @class ConditionComponent
* @plugin Filters
*/
var ConditionComponent =
/*#__PURE__*/
function (_BaseComponent) {
(0, _inherits2.default)(ConditionComponent, _BaseComponent);
function ConditionComponent(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, ConditionComponent);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ConditionComponent).call(this, hotInstance));
_this.id = options.id;
_this.name = options.name;
_this.addSeparator = options.addSeparator;
_this.elements.push(new _select.default(_this.hot));
_this.elements.push(new _input.default(_this.hot, {
placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_VALUE
}));
_this.elements.push(new _input.default(_this.hot, {
placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_SECOND_VALUE
}));
_this.registerHooks();
return _this;
}
/**
* Register all necessary hooks.
*
* @private
*/
(0, _createClass2.default)(ConditionComponent, [{
key: "registerHooks",
value: function registerHooks() {
var _this2 = this;
this.getSelectElement().addLocalHook('select', function (command) {
return _this2.onConditionSelect(command);
});
this.getSelectElement().addLocalHook('afterClose', function () {
return _this2.onSelectUIClosed();
});
(0, _array.arrayEach)(this.getInputElements(), function (input) {
input.addLocalHook('keydown', function (event) {
return _this2.onInputKeyDown(event);
});
});
}
/**
* Set state of the component.
*
* @param {Object} value State to restore.
*/
}, {
key: "setState",
value: function setState(value) {
var _this3 = this;
this.reset();
if (value) {
var copyOfCommand = (0, _object.clone)(value.command);
if (copyOfCommand.name.startsWith(C.FILTERS_CONDITIONS_NAMESPACE)) {
copyOfCommand.name = this.hot.getTranslatedPhrase(copyOfCommand.name);
}
this.getSelectElement().setValue(copyOfCommand);
(0, _array.arrayEach)(value.args, function (arg, index) {
if (index > copyOfCommand.inputsCount - 1) {
return false;
}
var element = _this3.getInputElement(index);
element.setValue(arg);
element[copyOfCommand.inputsCount > index ? 'show' : 'hide']();
if (!index) {
setTimeout(function () {
return element.focus();
}, 10);
}
});
}
}
/**
* Export state of the component (get selected filter and filter arguments).
*
* @returns {Object} Returns object where `command` key keeps used condition filter and `args` key its arguments.
*/
}, {
key: "getState",
value: function getState() {
var command = this.getSelectElement().getValue() || (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
var args = [];
(0, _array.arrayEach)(this.getInputElements(), function (element, index) {
if (command.inputsCount > index) {
args.push(element.getValue());
}
});
return {
command: command,
args: args
};
}
/**
* Update state of component.
* @param {Object} condition Object with keys:
* * `command` Object, Command object with condition name as `key` property.
* * `args` Array, Condition arguments.
* @param column Physical column index.
*/
}, {
key: "updateState",
value: function updateState(condition, column) {
var command = condition ? (0, _conditionRegisterer.getConditionDescriptor)(condition.name) : (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
this.setCachedState(column, {
command: command,
args: condition ? condition.args : []
});
if (!condition) {
(0, _array.arrayEach)(this.getInputElements(), function (element) {
return element.setValue(null);
});
}
}
/**
* Get select element.
*
* @returns {SelectUI}
*/
}, {
key: "getSelectElement",
value: function getSelectElement() {
return this.elements.filter(function (element) {
return element instanceof _select.default;
})[0];
}
/**
* Get input element.
*
* @param {Number} index Index an array of elements.
* @returns {InputUI}
*/
}, {
key: "getInputElement",
value: function getInputElement() {
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return this.getInputElements()[index];
}
/**
* Get input elements.
*
* @returns {Array}
*/
}, {
key: "getInputElements",
value: function getInputElements() {
return this.elements.filter(function (element) {
return element instanceof _input.default;
});
}
/**
* Get menu object descriptor.
*
* @returns {Object}
*/
}, {
key: "getMenuItemDescriptor",
value: function getMenuItemDescriptor() {
var _this4 = this;
return {
key: this.id,
name: this.name,
isCommand: false,
disableSelection: true,
hidden: function hidden() {
return _this4.isHidden();
},
renderer: function renderer(hot, wrapper, row, col, prop, value) {
(0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuCondition');
if (_this4.addSeparator) {
(0, _element.addClass)(wrapper.parentNode, 'border');
}
var label = _this4.hot.rootDocument.createElement('div');
(0, _element.addClass)(label, 'htFiltersMenuLabel');
label.textContent = value;
wrapper.appendChild(label);
if (!wrapper.parentNode.hasAttribute('ghost-table')) {
(0, _array.arrayEach)(_this4.elements, function (ui) {
return wrapper.appendChild(ui.element);
});
}
return wrapper;
}
};
}
/**
* Reset elements to their initial state.
*/
}, {
key: "reset",
value: function reset() {
var _this$hot;
var lastSelectedColumn = this.hot.getPlugin('filters').getSelectedColumn();
var visualIndex = lastSelectedColumn && lastSelectedColumn.visualIndex;
var columnType = (_this$hot = this.hot).getDataType.apply(_this$hot, (0, _toConsumableArray2.default)(this.hot.getSelectedLast() || [0, visualIndex]));
var items = (0, _constants2.default)(columnType);
(0, _array.arrayEach)(this.getInputElements(), function (element) {
return element.hide();
});
this.getSelectElement().setItems(items);
(0, _get2.default)((0, _getPrototypeOf2.default)(ConditionComponent.prototype), "reset", this).call(this); // Select element as default 'None'
this.getSelectElement().setValue(items[0]);
}
/**
* On condition select listener.
*
* @private
* @param {Object} command Menu item object (command).
*/
}, {
key: "onConditionSelect",
value: function onConditionSelect(command) {
(0, _array.arrayEach)(this.getInputElements(), function (element, index) {
element[command.inputsCount > index ? 'show' : 'hide']();
if (!index) {
setTimeout(function () {
return element.focus();
}, 10);
}
});
this.runLocalHooks('change', command);
}
/**
* On component SelectUI closed listener.
*
* @private
*/
}, {
key: "onSelectUIClosed",
value: function onSelectUIClosed() {
this.runLocalHooks('afterClose');
}
/**
* Key down listener.
*
* @private
* @param {Event} event DOM event object.
*/
}, {
key: "onInputKeyDown",
value: function onInputKeyDown(event) {
if ((0, _unicode.isKey)(event.keyCode, 'ENTER')) {
this.runLocalHooks('accept');
(0, _event.stopImmediatePropagation)(event);
} else if ((0, _unicode.isKey)(event.keyCode, 'ESCAPE')) {
this.runLocalHooks('cancel');
(0, _event.stopImmediatePropagation)(event);
}
}
}]);
return ConditionComponent;
}(_base.default);
var _default = ConditionComponent;
exports.default = _default;
/***/ }),
/* 456 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(__webpack_require__(71));
var _object = __webpack_require__(4);
var _stateSaver;
var MIXIN_NAME = 'stateSaver';
var STATE_PREFIX = 'state_';
var PROP_PREFIX = '_states';
var getState = function getState(object, stateId) {
return object[PROP_PREFIX][STATE_PREFIX + stateId];
};
var setState = function setState(object, stateId, value) {
object[PROP_PREFIX][STATE_PREFIX + stateId] = value;
};
/**
* Mixin object to extend functionality for save/restore object state.
*
* @type {Object}
*/
var stateSaver = (_stateSaver = {}, (0, _defineProperty2.default)(_stateSaver, PROP_PREFIX, {}), (0, _defineProperty2.default)(_stateSaver, "getCachedState", function getCachedState(stateId) {
return getState(this, stateId);
}), (0, _defineProperty2.default)(_stateSaver, "setCachedState", function setCachedState(stateId, value) {
setState(this, stateId, value);
}), (0, _defineProperty2.default)(_stateSaver, "saveState", function saveState(stateId) {
setState(this, stateId, this.getState());
}), (0, _defineProperty2.default)(_stateSaver, "restoreState", function restoreState(stateId) {
this.setState(getState(this, stateId));
}), (0, _defineProperty2.default)(_stateSaver, "hasSavedState", function hasSavedState(stateId) {
return getState(this, stateId) !== void 0;
}), (0, _defineProperty2.default)(_stateSaver, "clearState", function clearState(stateId) {
setState(this, stateId);
}), (0, _defineProperty2.default)(_stateSaver, "clearStates", function clearStates() {
this[PROP_PREFIX] = {};
}), _stateSaver);
(0, _object.defineGetter)(stateSaver, 'MIXIN_NAME', MIXIN_NAME, {
writable: false,
enumerable: false
});
var _default = stateSaver;
exports.default = _default;
/***/ }),
/* 457 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'none';
exports.CONDITION_NAME = CONDITION_NAME;
function condition() {
return true;
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_NONE,
inputsCount: 0,
showOperators: false
});
/***/ }),
/* 458 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var _empty = __webpack_require__(245);
var CONDITION_NAME = 'not_empty';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, inputValues) {
return !(0, _conditionRegisterer.getCondition)(_empty.CONDITION_NAME, inputValues)(dataRow);
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_NOT_EMPTY,
inputsCount: 0,
showOperators: true
});
/***/ }),
/* 459 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var _equal = __webpack_require__(246);
var CONDITION_NAME = 'neq';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, inputValues) {
return !(0, _conditionRegisterer.getCondition)(_equal.CONDITION_NAME, inputValues)(dataRow);
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_NOT_EQUAL,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 460 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'gt';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, _ref) {
var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
value = _ref2[0];
var conditionValue = value;
if (dataRow.meta.type === 'numeric') {
conditionValue = parseFloat(conditionValue, 10);
}
return dataRow.value > conditionValue;
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_GREATER_THAN,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 461 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'gte';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, _ref) {
var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
value = _ref2[0];
var conditionValue = value;
if (dataRow.meta.type === 'numeric') {
conditionValue = parseFloat(conditionValue, 10);
}
return dataRow.value >= conditionValue;
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_GREATER_THAN_OR_EQUAL,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 462 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'lt';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, _ref) {
var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
value = _ref2[0];
var conditionValue = value;
if (dataRow.meta.type === 'numeric') {
conditionValue = parseFloat(conditionValue, 10);
}
return dataRow.value < conditionValue;
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_LESS_THAN,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 463 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'lte';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, _ref) {
var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
value = _ref2[0];
var conditionValue = value;
if (dataRow.meta.type === 'numeric') {
conditionValue = parseFloat(conditionValue, 10);
}
return dataRow.value <= conditionValue;
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_LESS_THAN_OR_EQUAL,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 464 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var _between = __webpack_require__(247);
var CONDITION_NAME = 'not_between';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, inputValues) {
return !(0, _conditionRegisterer.getCondition)(_between.CONDITION_NAME, inputValues)(dataRow);
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_NOT_BETWEEN,
inputsCount: 2,
showOperators: true
});
/***/ }),
/* 465 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(138);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
var _mixed = __webpack_require__(27);
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'begins_with';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, _ref) {
var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
value = _ref2[0];
return (0, _mixed.stringify)(dataRow.value).toLowerCase().startsWith((0, _mixed.stringify)(value));
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_BEGINS_WITH,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 466 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(467);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var C = _interopRequireWildcard(__webpack_require__(11));
var _mixed = __webpack_require__(27);
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'ends_with';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, _ref) {
var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
value = _ref2[0];
return (0, _mixed.stringify)(dataRow.value).toLowerCase().endsWith((0, _mixed.stringify)(value));
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_ENDS_WITH,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 467 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var toLength = __webpack_require__(48);
var validateArguments = __webpack_require__(157);
var ENDS_WITH = 'endsWith';
var nativeEndsWith = ''[ENDS_WITH];
var min = Math.min;
var CORRECT_IS_REGEXP_LOGIC = __webpack_require__(158)(ENDS_WITH);
// `String.prototype.endsWith` method
// https://tc39.github.io/ecma262/#sec-string.prototype.endswith
__webpack_require__(22)({ target: 'String', proto: true, forced: !CORRECT_IS_REGEXP_LOGIC }, {
endsWith: function endsWith(searchString /* , endPosition = @length */) {
var that = validateArguments(this, searchString, ENDS_WITH);
var endPosition = arguments.length > 1 ? arguments[1] : undefined;
var len = toLength(that.length);
var end = endPosition === undefined ? len : min(toLength(endPosition), len);
var search = String(searchString);
return nativeEndsWith
? nativeEndsWith.call(that, search, end)
: that.slice(end - search.length, end) === search;
}
});
/***/ }),
/* 468 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var _contains = __webpack_require__(250);
var CONDITION_NAME = 'not_contains';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, inputValues) {
return !(0, _conditionRegisterer.getCondition)(_contains.CONDITION_NAME, inputValues)(dataRow);
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_NOT_CONTAIN,
inputsCount: 1,
showOperators: true
});
/***/ }),
/* 469 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _moment = _interopRequireDefault(__webpack_require__(66));
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'date_tomorrow';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow) {
var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);
if (!date.isValid()) {
return false;
}
return date.isSame((0, _moment.default)().subtract(-1, 'days').startOf('day'), 'd');
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_TOMORROW,
inputsCount: 0
});
/***/ }),
/* 470 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _moment = _interopRequireDefault(__webpack_require__(66));
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'date_today';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow) {
var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);
if (!date.isValid()) {
return false;
}
return date.isSame((0, _moment.default)().startOf('day'), 'd');
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_TODAY,
inputsCount: 0
});
/***/ }),
/* 471 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _moment = _interopRequireDefault(__webpack_require__(66));
var C = _interopRequireWildcard(__webpack_require__(11));
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'date_yesterday';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow) {
var date = (0, _moment.default)(dataRow.value, dataRow.meta.dateFormat);
if (!date.isValid()) {
return false;
}
return date.isSame((0, _moment.default)().subtract(1, 'days').startOf('day'), 'd');
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: C.FILTERS_CONDITIONS_YESTERDAY,
inputsCount: 0
});
/***/ }),
/* 472 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _conditionRegisterer = __webpack_require__(28);
var _utils = __webpack_require__(108);
var CONDITION_NAME = 'by_value';
exports.CONDITION_NAME = CONDITION_NAME;
function condition(dataRow, _ref) {
var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
value = _ref2[0];
return value(dataRow.value);
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: 'By value',
inputsCount: 0,
inputValuesDecorator: function inputValuesDecorator(_ref3) {
var _ref4 = (0, _slicedToArray2.default)(_ref3, 1),
data = _ref4[0];
return [(0, _utils.createArrayAssertion)(data)];
},
showOperators: false
});
/***/ }),
/* 473 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'true';
exports.CONDITION_NAME = CONDITION_NAME;
function condition() {
return true;
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: 'True'
});
/***/ }),
/* 474 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.__esModule = true;
exports.condition = condition;
exports.CONDITION_NAME = void 0;
var _conditionRegisterer = __webpack_require__(28);
var CONDITION_NAME = 'false';
exports.CONDITION_NAME = CONDITION_NAME;
function condition() {
return false;
}
(0, _conditionRegisterer.registerCondition)(CONDITION_NAME, condition, {
name: 'False'
});
/***/ }),
/* 475 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(51);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _menu = _interopRequireDefault(__webpack_require__(167));
var _object = __webpack_require__(4);
var _array = __webpack_require__(3);
var C = _interopRequireWildcard(__webpack_require__(11));
var _predefinedItems = __webpack_require__(83);
var _base = _interopRequireDefault(__webpack_require__(110));
var privatePool = new WeakMap();
/**
* @class SelectUI
* @util
*/
var SelectUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(SelectUI, _BaseUI);
(0, _createClass2.default)(SelectUI, null, [{
key: "DEFAULTS",
get: function get() {
return (0, _object.clone)({
className: 'htUISelect',
wrapIt: false
});
}
}]);
function SelectUI(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, SelectUI);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(SelectUI).call(this, hotInstance, (0, _object.extend)(SelectUI.DEFAULTS, options)));
privatePool.set((0, _assertThisInitialized2.default)(_this), {});
/**
* Instance of {@link Menu}.
*
* @type {Menu}
*/
_this.menu = null;
/**
* List of available select options.
*
* @type {Array}
*/
_this.items = [];
_this.registerHooks();
return _this;
}
/**
* Register all necessary hooks.
*/
(0, _createClass2.default)(SelectUI, [{
key: "registerHooks",
value: function registerHooks() {
var _this2 = this;
this.addLocalHook('click', function () {
return _this2.onClick();
});
}
/**
* Set options which can be selected in the list.
*
* @param {Array} items Array of objects with required keys `key` and `name`.
*/
}, {
key: "setItems",
value: function setItems(items) {
this.items = this.translateNames(items);
if (this.menu) {
this.menu.setMenuItems(this.items);
}
}
/**
* Translate names of menu items.
*
* @param {Array} items Array of objects with required keys `key` and `name`.
* @returns {Array} Items with translated `name` keys.
*/
}, {
key: "translateNames",
value: function translateNames(items) {
var _this3 = this;
(0, _array.arrayEach)(items, function (item) {
item.name = _this3.translateIfPossible(item.name);
});
return items;
}
/**
* Build DOM structure.
*/
}, {
key: "build",
value: function build() {
var _this4 = this;
(0, _get2.default)((0, _getPrototypeOf2.default)(SelectUI.prototype), "build", this).call(this);
this.menu = new _menu.default(this.hot, {
className: 'htSelectUI htFiltersConditionsMenu',
keepInViewport: false,
standalone: true
});
this.menu.setMenuItems(this.items);
var caption = new _base.default(this.hot, {
className: 'htUISelectCaption'
});
var dropdown = new _base.default(this.hot, {
className: 'htUISelectDropdown'
});
var priv = privatePool.get(this);
priv.caption = caption;
priv.captionElement = caption.element;
priv.dropdown = dropdown;
(0, _array.arrayEach)([caption, dropdown], function (element) {
return _this4._element.appendChild(element.element);
});
this.menu.addLocalHook('select', function (command) {
return _this4.onMenuSelect(command);
});
this.menu.addLocalHook('afterClose', function () {
return _this4.onMenuClosed();
});
this.update();
}
/**
* Update DOM structure.
*/
}, {
key: "update",
value: function update() {
if (!this.isBuilt()) {
return;
}
var conditionName;
if (this.options.value) {
conditionName = this.options.value.name;
} else {
conditionName = this.menu.hot.getTranslatedPhrase(C.FILTERS_CONDITIONS_NONE);
}
privatePool.get(this).captionElement.textContent = conditionName;
(0, _get2.default)((0, _getPrototypeOf2.default)(SelectUI.prototype), "update", this).call(this);
}
/**
* Open select dropdown menu with available options.
*/
}, {
key: "openOptions",
value: function openOptions() {
var rect = this.element.getBoundingClientRect();
if (this.menu) {
this.menu.open();
this.menu.setPosition({
left: rect.left - 5,
top: rect.top,
width: rect.width,
height: rect.height
});
}
}
/**
* Close select dropdown menu.
*/
}, {
key: "closeOptions",
value: function closeOptions() {
if (this.menu) {
this.menu.close();
}
}
/**
* On menu selected listener.
*
* @private
* @param {Object} command Selected item
*/
}, {
key: "onMenuSelect",
value: function onMenuSelect(command) {
if (command.name !== _predefinedItems.SEPARATOR) {
this.options.value = command;
this.closeOptions();
this.update();
this.runLocalHooks('select', this.options.value);
}
}
/**
* On menu closed listener.
*
* @private
*/
}, {
key: "onMenuClosed",
value: function onMenuClosed() {
this.runLocalHooks('afterClose');
}
/**
* On element click listener.
*
* @private
*/
}, {
key: "onClick",
value: function onClick() {
this.openOptions();
}
/**
* Destroy instance.
*/
}, {
key: "destroy",
value: function destroy() {
if (this.menu) {
this.menu.destroy();
this.menu = null;
}
var _privatePool$get = privatePool.get(this),
caption = _privatePool$get.caption,
dropdown = _privatePool$get.dropdown;
if (caption) {
caption.destroy();
}
if (dropdown) {
dropdown.destroy();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(SelectUI.prototype), "destroy", this).call(this);
}
}]);
return SelectUI;
}(_base.default);
var _default = SelectUI;
exports.default = _default;
/***/ }),
/* 476 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(159);
__webpack_require__(51);
exports.__esModule = true;
exports.default = void 0;
var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(65));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _array = __webpack_require__(3);
var _templateLiteralTag = __webpack_require__(67);
var _base = _interopRequireDefault(__webpack_require__(139));
var _logicalOperationRegisterer = __webpack_require__(109);
var _conjunction = __webpack_require__(170);
var _disjunction = __webpack_require__(251);
var _disjunctionWithExtraCondition = __webpack_require__(252);
var _radioInput = _interopRequireDefault(__webpack_require__(477));
function _templateObject() {
var data = (0, _taggedTemplateLiteral2.default)(["Radio button with index ", " doesn't exist."]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
var SELECTED_AT_START_ELEMENT_INDEX = 0;
/**
* @class OperatorsComponent
* @plugin Filters
*/
var OperatorsComponent =
/*#__PURE__*/
function (_BaseComponent) {
(0, _inherits2.default)(OperatorsComponent, _BaseComponent);
function OperatorsComponent(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, OperatorsComponent);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(OperatorsComponent).call(this, hotInstance));
_this.id = options.id;
_this.name = options.name;
_this.buildOperatorsElement();
return _this;
}
/**
* Get menu object descriptor.
*
* @returns {Object}
*/
(0, _createClass2.default)(OperatorsComponent, [{
key: "getMenuItemDescriptor",
value: function getMenuItemDescriptor() {
var _this2 = this;
return {
key: this.id,
name: this.name,
isCommand: false,
disableSelection: true,
hidden: function hidden() {
return _this2.isHidden();
},
renderer: function renderer(hot, wrapper) {
(0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuOperators');
if (!wrapper.parentNode.hasAttribute('ghost-table')) {
(0, _array.arrayEach)(_this2.elements, function (ui) {
return wrapper.appendChild(ui.element);
});
}
return wrapper;
}
};
}
/**
* Add RadioInputUI elements to component
*
* @private
*/
}, {
key: "buildOperatorsElement",
value: function buildOperatorsElement() {
var _this3 = this;
var operationKeys = [_conjunction.OPERATION_ID, _disjunction.OPERATION_ID];
(0, _array.arrayEach)(operationKeys, function (operation) {
var radioInput = new _radioInput.default(_this3.hot, {
name: 'operator',
label: {
htmlFor: operation,
textContent: (0, _logicalOperationRegisterer.getOperationName)(operation)
},
value: operation,
checked: operation === operationKeys[SELECTED_AT_START_ELEMENT_INDEX],
id: operation
});
radioInput.addLocalHook('change', function (event) {
return _this3.onRadioInputChange(event);
});
_this3.elements.push(radioInput);
});
}
/**
* Set state of operators component to check radio input at specific `index`.
*
* @param searchedIndex Index of radio input to check.
*/
}, {
key: "setChecked",
value: function setChecked(searchedIndex) {
if (this.elements.length < searchedIndex) {
throw Error((0, _templateLiteralTag.toSingleLine)(_templateObject(), searchedIndex));
}
(0, _array.arrayEach)(this.elements, function (element, index) {
element.setChecked(index === searchedIndex);
});
}
/**
* Get `id` of active operator
*
* @returns {String}
*/
}, {
key: "getActiveOperationId",
value: function getActiveOperationId() {
var operationElement = this.elements.find(function (element) {
return element instanceof _radioInput.default && element.isChecked();
});
if (operationElement) {
return operationElement.getValue();
}
return _conjunction.OPERATION_ID;
}
/**
* Export state of the component (get selected operator).
*
* @returns {String} Returns `id` of selected operator.
*/
}, {
key: "getState",
value: function getState() {
return this.getActiveOperationId();
}
/**
* Set state of the component.
*
* @param {Object} value State to restore.
*/
}, {
key: "setState",
value: function setState(value) {
this.reset();
if (value && this.getActiveOperationId() !== value) {
(0, _array.arrayEach)(this.elements, function (element) {
element.setChecked(element.getValue() === value);
});
}
}
/**
* Update state of component.
* @param [operationId='conjunction'] Id of selected operation.
* @param column Physical column index.
*/
}, {
key: "updateState",
value: function updateState() {
var operationId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _conjunction.OPERATION_ID;
var column = arguments.length > 1 ? arguments[1] : undefined;
var selectedOperationId = operationId;
if (selectedOperationId === _disjunctionWithExtraCondition.OPERATION_ID) {
selectedOperationId = _disjunction.OPERATION_ID;
}
this.setCachedState(column, selectedOperationId);
}
/**
* Reset elements to their initial state.
*/
}, {
key: "reset",
value: function reset() {
this.setChecked(SELECTED_AT_START_ELEMENT_INDEX);
}
/**
* OnChange listener.
*
* @private
* @param {Event} event DOM event
*/
}, {
key: "onRadioInputChange",
value: function onRadioInputChange(event) {
this.setState(event.realTarget.value);
}
}]);
return OperatorsComponent;
}(_base.default);
var _default = OperatorsComponent;
exports.default = _default;
/***/ }),
/* 477 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _object = __webpack_require__(4);
var _base = _interopRequireDefault(__webpack_require__(110));
var privatePool = new WeakMap();
/**
* @class RadioInputUI
* @util
*/
var RadioInputUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(RadioInputUI, _BaseUI);
(0, _createClass2.default)(RadioInputUI, null, [{
key: "DEFAULTS",
get: function get() {
return (0, _object.clone)({
type: 'radio',
tagName: 'input',
className: 'htUIRadio',
label: {}
});
}
}]);
function RadioInputUI(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, RadioInputUI);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(RadioInputUI).call(this, hotInstance, (0, _object.extend)(RadioInputUI.DEFAULTS, options)));
privatePool.set((0, _assertThisInitialized2.default)(_this), {});
return _this;
}
/**
* Build DOM structure.
*/
(0, _createClass2.default)(RadioInputUI, [{
key: "build",
value: function build() {
(0, _get2.default)((0, _getPrototypeOf2.default)(RadioInputUI.prototype), "build", this).call(this);
var priv = privatePool.get(this);
priv.input = this._element.firstChild;
var label = this.hot.rootDocument.createElement('label');
label.textContent = this.translateIfPossible(this.options.label.textContent);
label.htmlFor = this.translateIfPossible(this.options.label.htmlFor);
priv.label = label;
this._element.appendChild(label);
this.update();
}
/**
* Update element.
*/
}, {
key: "update",
value: function update() {
if (!this.isBuilt()) {
return;
}
var priv = privatePool.get(this);
priv.input.checked = this.options.checked;
priv.label.textContent = this.translateIfPossible(this.options.label.textContent);
}
/**
* Check if radio button is checked.
*
* @returns {Boolean}
*/
}, {
key: "isChecked",
value: function isChecked() {
return this.options.checked;
}
/**
* Set input checked attribute
*
* @param value {Boolean} value
*/
}, {
key: "setChecked",
value: function setChecked() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
this.options.checked = value;
this.update();
}
/**
* Focus element.
*/
}, {
key: "focus",
value: function focus() {
if (this.isBuilt()) {
privatePool.get(this).input.focus();
}
}
}]);
return RadioInputUI;
}(_base.default);
var _default = RadioInputUI;
exports.default = _default;
/***/ }),
/* 478 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(56);
__webpack_require__(51);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _event = __webpack_require__(31);
var _array = __webpack_require__(3);
var _unicode = __webpack_require__(50);
var C = _interopRequireWildcard(__webpack_require__(11));
var _utils = __webpack_require__(108);
var _base = _interopRequireDefault(__webpack_require__(139));
var _multipleSelect = _interopRequireDefault(__webpack_require__(479));
var _constants2 = __webpack_require__(169);
var _conditionRegisterer = __webpack_require__(28);
/**
* @class ValueComponent
* @plugin Filters
*/
var ValueComponent =
/*#__PURE__*/
function (_BaseComponent) {
(0, _inherits2.default)(ValueComponent, _BaseComponent);
function ValueComponent(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, ValueComponent);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ValueComponent).call(this, hotInstance));
_this.id = options.id;
_this.name = options.name;
_this.elements.push(new _multipleSelect.default(_this.hot));
_this.registerHooks();
return _this;
}
/**
* Register all necessary hooks.
*
* @private
*/
(0, _createClass2.default)(ValueComponent, [{
key: "registerHooks",
value: function registerHooks() {
var _this2 = this;
this.getMultipleSelectElement().addLocalHook('keydown', function (event) {
return _this2.onInputKeyDown(event);
});
}
/**
* Set state of the component.
*
* @param {Object} value
*/
}, {
key: "setState",
value: function setState(value) {
this.reset();
if (value && value.command.key === _constants2.CONDITION_BY_VALUE) {
var select = this.getMultipleSelectElement();
select.setItems(value.itemsSnapshot);
select.setValue(value.args[0]);
}
}
/**
* Export state of the component (get selected filter and filter arguments).
*
* @returns {Object} Returns object where `command` key keeps used condition filter and `args` key its arguments.
*/
}, {
key: "getState",
value: function getState() {
var select = this.getMultipleSelectElement();
var availableItems = select.getItems();
return {
command: {
key: select.isSelectedAllValues() || !availableItems.length ? _constants2.CONDITION_NONE : _constants2.CONDITION_BY_VALUE
},
args: [select.getValue()],
itemsSnapshot: availableItems
};
}
/**
* Update state of component.
*
* @param {Object} stateInfo Information about state containing stack of edited column,
* stack of dependent conditions, data factory and optional condition arguments change. It's described by object containing keys:
* `editedConditionStack`, `dependentConditionStacks`, `visibleDataFactory` and `conditionArgsChange`.
*/
}, {
key: "updateState",
value: function updateState(stateInfo) {
var _this3 = this;
var updateColumnState = function updateColumnState(column, conditions, conditionArgsChange, filteredRowsFactory, conditionsStack) {
var _arrayFilter = (0, _array.arrayFilter)(conditions, function (condition) {
return condition.name === _constants2.CONDITION_BY_VALUE;
}),
_arrayFilter2 = (0, _slicedToArray2.default)(_arrayFilter, 1),
firstByValueCondition = _arrayFilter2[0];
var state = {};
var defaultBlankCellValue = _this3.hot.getTranslatedPhrase(C.FILTERS_VALUES_BLANK_CELLS);
if (firstByValueCondition) {
var rowValues = (0, _array.arrayMap)(filteredRowsFactory(column, conditionsStack), function (row) {
return row.value;
});
rowValues = (0, _utils.unifyColumnValues)(rowValues);
if (conditionArgsChange) {
firstByValueCondition.args[0] = conditionArgsChange;
}
var selectedValues = [];
var itemsSnapshot = (0, _utils.intersectValues)(rowValues, firstByValueCondition.args[0], defaultBlankCellValue, function (item) {
if (item.checked) {
selectedValues.push(item.value);
}
});
state.args = [selectedValues];
state.command = (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_BY_VALUE);
state.itemsSnapshot = itemsSnapshot;
} else {
state.args = [];
state.command = (0, _conditionRegisterer.getConditionDescriptor)(_constants2.CONDITION_NONE);
}
_this3.setCachedState(column, state);
};
updateColumnState(stateInfo.editedConditionStack.column, stateInfo.editedConditionStack.conditions, stateInfo.conditionArgsChange, stateInfo.filteredRowsFactory); // Shallow deep update of component state
if (stateInfo.dependentConditionStacks.length) {
updateColumnState(stateInfo.dependentConditionStacks[0].column, stateInfo.dependentConditionStacks[0].conditions, stateInfo.conditionArgsChange, stateInfo.filteredRowsFactory, stateInfo.editedConditionStack);
}
}
/**
* Get multiple select element.
*
* @returns {MultipleSelectUI}
*/
}, {
key: "getMultipleSelectElement",
value: function getMultipleSelectElement() {
return this.elements.filter(function (element) {
return element instanceof _multipleSelect.default;
})[0];
}
/**
* Get object descriptor for menu item entry.
*
* @returns {Object}
*/
}, {
key: "getMenuItemDescriptor",
value: function getMenuItemDescriptor() {
var _this4 = this;
return {
key: this.id,
name: this.name,
isCommand: false,
disableSelection: true,
hidden: function hidden() {
return _this4.isHidden();
},
renderer: function renderer(hot, wrapper, row, col, prop, value) {
(0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuValue');
var label = _this4.hot.rootDocument.createElement('div');
(0, _element.addClass)(label, 'htFiltersMenuLabel');
label.textContent = value;
wrapper.appendChild(label);
if (!wrapper.parentNode.hasAttribute('ghost-table')) {
(0, _array.arrayEach)(_this4.elements, function (ui) {
return wrapper.appendChild(ui.element);
});
}
return wrapper;
}
};
}
/**
* Reset elements to their initial state.
*/
}, {
key: "reset",
value: function reset() {
var defaultBlankCellValue = this.hot.getTranslatedPhrase(C.FILTERS_VALUES_BLANK_CELLS);
var values = (0, _utils.unifyColumnValues)(this._getColumnVisibleValues());
var items = (0, _utils.intersectValues)(values, values, defaultBlankCellValue);
this.getMultipleSelectElement().setItems(items);
(0, _get2.default)((0, _getPrototypeOf2.default)(ValueComponent.prototype), "reset", this).call(this);
this.getMultipleSelectElement().setValue(values);
}
/**
* Key down listener.
*
* @private
* @param {Event} event DOM event object.
*/
}, {
key: "onInputKeyDown",
value: function onInputKeyDown(event) {
if ((0, _unicode.isKey)(event.keyCode, 'ESCAPE')) {
this.runLocalHooks('cancel');
(0, _event.stopImmediatePropagation)(event);
}
}
/**
* Get data for currently selected column.
*
* @returns {Array}
* @private
*/
}, {
key: "_getColumnVisibleValues",
value: function _getColumnVisibleValues() {
var lastSelectedColumn = this.hot.getPlugin('filters').getSelectedColumn();
var visualIndex = lastSelectedColumn && lastSelectedColumn.visualIndex;
return (0, _array.arrayMap)(this.hot.getDataAtCol(visualIndex), function (v) {
return (0, _utils.toEmptyString)(v);
});
}
}]);
return ValueComponent;
}(_base.default);
var _default = ValueComponent;
exports.default = _default;
/***/ }),
/* 479 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _object = __webpack_require__(4);
var _array = __webpack_require__(3);
var _unicode = __webpack_require__(50);
var _function = __webpack_require__(75);
var C = _interopRequireWildcard(__webpack_require__(11));
var _event = __webpack_require__(31);
var _base = _interopRequireDefault(__webpack_require__(110));
var _input = _interopRequireDefault(__webpack_require__(171));
var _link = _interopRequireDefault(__webpack_require__(480));
var _utils = __webpack_require__(108);
var privatePool = new WeakMap();
/**
* @class MultipleSelectUI
* @util
*/
var MultipleSelectUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(MultipleSelectUI, _BaseUI);
(0, _createClass2.default)(MultipleSelectUI, null, [{
key: "DEFAULTS",
get: function get() {
return (0, _object.clone)({
className: 'htUIMultipleSelect',
value: []
});
}
}]);
function MultipleSelectUI(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, MultipleSelectUI);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(MultipleSelectUI).call(this, hotInstance, (0, _object.extend)(MultipleSelectUI.DEFAULTS, options)));
privatePool.set((0, _assertThisInitialized2.default)(_this), {});
/**
* Input element.
*
* @type {InputUI}
*/
_this.searchInput = new _input.default(_this.hot, {
placeholder: C.FILTERS_BUTTONS_PLACEHOLDER_SEARCH,
className: 'htUIMultipleSelectSearch'
});
/**
* "Select all" UI element.
*
* @type {BaseUI}
*/
_this.selectAllUI = new _link.default(_this.hot, {
textContent: C.FILTERS_BUTTONS_SELECT_ALL,
className: 'htUISelectAll'
});
/**
* "Clear" UI element.
*
* @type {BaseUI}
*/
_this.clearAllUI = new _link.default(_this.hot, {
textContent: C.FILTERS_BUTTONS_CLEAR,
className: 'htUIClearAll'
});
/**
* List of available select options.
*
* @type {Array}
*/
_this.items = [];
/**
* Handsontable instance used as items list element.
*
* @type {Handsontable}
*/
_this.itemsBox = null;
_this.registerHooks();
return _this;
}
/**
* Register all necessary hooks.
*/
(0, _createClass2.default)(MultipleSelectUI, [{
key: "registerHooks",
value: function registerHooks() {
var _this2 = this;
this.searchInput.addLocalHook('keydown', function (event) {
return _this2.onInputKeyDown(event);
});
this.searchInput.addLocalHook('input', function (event) {
return _this2.onInput(event);
});
this.selectAllUI.addLocalHook('click', function (event) {
return _this2.onSelectAllClick(event);
});
this.clearAllUI.addLocalHook('click', function (event) {
return _this2.onClearAllClick(event);
});
}
/**
* Set available options.
*
* @param {Array} items Array of objects with `checked` and `label` property.
*/
}, {
key: "setItems",
value: function setItems(items) {
this.items = items;
if (this.itemsBox) {
this.itemsBox.loadData(this.items);
}
}
/**
* Get all available options.
*
* @returns {Array}
*/
}, {
key: "getItems",
value: function getItems() {
return (0, _toConsumableArray2.default)(this.items);
}
/**
* Get element value.
*
* @returns {Array} Array of selected values.
*/
}, {
key: "getValue",
value: function getValue() {
return itemsToValue(this.items);
}
/**
* Check if all values listed in element are selected.
*
* @returns {Boolean}
*/
}, {
key: "isSelectedAllValues",
value: function isSelectedAllValues() {
return this.items.length === this.getValue().length;
}
/**
* Build DOM structure.
*/
}, {
key: "build",
value: function build() {
var _this3 = this;
(0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectUI.prototype), "build", this).call(this);
var rootDocument = this.hot.rootDocument;
var itemsBoxWrapper = rootDocument.createElement('div');
var selectionControl = new _base.default(this.hot, {
className: 'htUISelectionControls',
children: [this.selectAllUI, this.clearAllUI]
});
this._element.appendChild(this.searchInput.element);
this._element.appendChild(selectionControl.element);
this._element.appendChild(itemsBoxWrapper);
var hotInitializer = function hotInitializer(wrapper) {
if (!_this3._element) {
return;
}
if (_this3.itemsBox) {
_this3.itemsBox.destroy();
}
(0, _element.addClass)(wrapper, 'htUIMultipleSelectHot'); // Construct and initialise a new Handsontable
_this3.itemsBox = new _this3.hot.constructor(wrapper, {
data: _this3.items,
columns: [{
data: 'checked',
type: 'checkbox',
label: {
property: 'visualValue',
position: 'after'
}
}],
beforeRenderer: function beforeRenderer(TD, row, col, prop, value, cellProperties) {
TD.title = cellProperties.instance.getDataAtRowProp(row, cellProperties.label.property);
},
autoWrapCol: true,
height: 110,
// Workaround for #151.
colWidths: function colWidths() {
return _this3.itemsBox.container.scrollWidth - (0, _element.getScrollbarWidth)(rootDocument);
},
copyPaste: false,
disableVisualSelection: 'area',
fillHandle: false,
fragmentSelection: 'cell',
tabMoves: {
row: 1,
col: 0
},
beforeKeyDown: function beforeKeyDown(event) {
return _this3.onItemsBoxBeforeKeyDown(event);
}
});
_this3.itemsBox.init();
};
hotInitializer(itemsBoxWrapper);
setTimeout(function () {
return hotInitializer(itemsBoxWrapper);
}, 100);
}
/**
* Reset DOM structure.
*/
}, {
key: "reset",
value: function reset() {
this.searchInput.reset();
this.selectAllUI.reset();
this.clearAllUI.reset();
}
/**
* Update DOM structure.
*/
}, {
key: "update",
value: function update() {
if (!this.isBuilt()) {
return;
}
this.itemsBox.loadData(valueToItems(this.items, this.options.value));
(0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectUI.prototype), "update", this).call(this);
}
/**
* Destroy instance.
*/
}, {
key: "destroy",
value: function destroy() {
if (this.itemsBox) {
this.itemsBox.destroy();
}
this.searchInput.destroy();
this.clearAllUI.destroy();
this.selectAllUI.destroy();
this.searchInput = null;
this.clearAllUI = null;
this.selectAllUI = null;
this.itemsBox = null;
this.items = null;
(0, _get2.default)((0, _getPrototypeOf2.default)(MultipleSelectUI.prototype), "destroy", this).call(this);
}
/**
* 'input' event listener for input element.
*
* @private
* @param {Event} event DOM event.
*/
}, {
key: "onInput",
value: function onInput(event) {
var value = event.target.value.toLowerCase();
var filteredItems;
if (value === '') {
filteredItems = (0, _toConsumableArray2.default)(this.items);
} else {
filteredItems = (0, _array.arrayFilter)(this.items, function (item) {
return "".concat(item.value).toLowerCase().indexOf(value) >= 0;
});
}
this.itemsBox.loadData(filteredItems);
}
/**
* 'keydown' event listener for input element.
*
* @private
* @param {Event} event DOM event.
*/
}, {
key: "onInputKeyDown",
value: function onInputKeyDown(event) {
this.runLocalHooks('keydown', event, this);
var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode);
if (isKeyCode('ARROW_DOWN|TAB') && !this.itemsBox.isListening()) {
(0, _event.stopImmediatePropagation)(event);
this.itemsBox.listen();
this.itemsBox.selectCell(0, 0);
}
}
/**
* On before key down listener (internal Handsontable).
*
* @private
* @param {Event} event DOM event.
*/
}, {
key: "onItemsBoxBeforeKeyDown",
value: function onItemsBoxBeforeKeyDown(event) {
var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode);
if (isKeyCode('ESCAPE')) {
this.runLocalHooks('keydown', event, this);
} // for keys different than below, unfocus Handsontable and focus search input
if (!isKeyCode('ARROW_UP|ARROW_DOWN|ARROW_LEFT|ARROW_RIGHT|TAB|SPACE|ENTER')) {
(0, _event.stopImmediatePropagation)(event);
this.itemsBox.unlisten();
this.itemsBox.deselectCell();
this.searchInput.focus();
}
}
/**
* On click listener for "Select all" link.
*
* @private
* @param {DOMEvent} event
*/
}, {
key: "onSelectAllClick",
value: function onSelectAllClick(event) {
event.preventDefault();
(0, _array.arrayEach)(this.itemsBox.getSourceData(), function (row) {
row.checked = true;
});
this.itemsBox.render();
}
/**
* On click listener for "Clear" link.
*
* @private
* @param {DOMEvent} event
*/
}, {
key: "onClearAllClick",
value: function onClearAllClick(event) {
event.preventDefault();
(0, _array.arrayEach)(this.itemsBox.getSourceData(), function (row) {
row.checked = false;
});
this.itemsBox.render();
}
}]);
return MultipleSelectUI;
}(_base.default);
var _default = MultipleSelectUI;
/**
* Pick up object items based on selected values.
*
* @param {Array} availableItems Base collection to compare values.
* @param selectedValue Flat array with selected values.
* @returns {Array}
*/
exports.default = _default;
function valueToItems(availableItems, selectedValue) {
var arrayAssertion = (0, _utils.createArrayAssertion)(selectedValue);
return (0, _array.arrayMap)(availableItems, function (item) {
item.checked = arrayAssertion(item.value);
return item;
});
}
/**
* Convert all checked items into flat array.
*
* @param {Array} availableItems Base collection.
* @returns {Array}
*/
function itemsToValue(availableItems) {
var items = [];
(0, _array.arrayEach)(availableItems, function (item) {
if (item.checked) {
items.push(item.value);
}
});
return items;
}
/***/ }),
/* 480 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(481);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _object = __webpack_require__(4);
var _base = _interopRequireDefault(__webpack_require__(110));
var privatePool = new WeakMap();
/**
* @class LinkUI
* @util
*/
var LinkUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(LinkUI, _BaseUI);
(0, _createClass2.default)(LinkUI, null, [{
key: "DEFAULTS",
get: function get() {
return (0, _object.clone)({
href: '#',
tagName: 'a'
});
}
}]);
function LinkUI(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, LinkUI);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(LinkUI).call(this, hotInstance, (0, _object.extend)(LinkUI.DEFAULTS, options)));
privatePool.set((0, _assertThisInitialized2.default)(_this), {});
return _this;
}
/**
* Build DOM structure.
*/
(0, _createClass2.default)(LinkUI, [{
key: "build",
value: function build() {
(0, _get2.default)((0, _getPrototypeOf2.default)(LinkUI.prototype), "build", this).call(this);
var priv = privatePool.get(this);
priv.link = this._element.firstChild;
}
/**
* Update element.
*/
}, {
key: "update",
value: function update() {
if (!this.isBuilt()) {
return;
}
privatePool.get(this).link.textContent = this.translateIfPossible(this.options.textContent);
}
}]);
return LinkUI;
}(_base.default);
var _default = LinkUI;
exports.default = _default;
/***/ }),
/* 481 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var createHTML = __webpack_require__(482);
var FORCED = __webpack_require__(483)('link');
// `String.prototype.link` method
// https://tc39.github.io/ecma262/#sec-string.prototype.link
__webpack_require__(22)({ target: 'String', proto: true, forced: FORCED }, {
link: function link(url) {
return createHTML(this, 'a', 'href', url);
}
});
/***/ }),
/* 482 */
/***/ (function(module, exports, __webpack_require__) {
var requireObjectCoercible = __webpack_require__(58);
var quot = /"/g;
// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
// https://tc39.github.io/ecma262/#sec-createhtml
module.exports = function (string, tag, attribute, value) {
var S = String(requireObjectCoercible(string));
var p1 = '<' + tag;
if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '"') + '"';
return p1 + '>' + S + '' + tag + '>';
};
/***/ }),
/* 483 */
/***/ (function(module, exports, __webpack_require__) {
var fails = __webpack_require__(29);
// check the existence of a method, lowercase
// of a tag and escaping quotes in arguments
module.exports = function (METHOD_NAME) {
return fails(function () {
var test = ''[METHOD_NAME]('"');
return test !== test.toLowerCase() || test.split('"').length > 3;
});
};
/***/ }),
/* 484 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(51);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _array = __webpack_require__(3);
var C = _interopRequireWildcard(__webpack_require__(11));
var _base = _interopRequireDefault(__webpack_require__(139));
var _input = _interopRequireDefault(__webpack_require__(171));
/**
* @class ActionBarComponent
* @plugin Filters
*/
var ActionBarComponent =
/*#__PURE__*/
function (_BaseComponent) {
(0, _inherits2.default)(ActionBarComponent, _BaseComponent);
(0, _createClass2.default)(ActionBarComponent, null, [{
key: "BUTTON_OK",
get: function get() {
return 'ok';
}
}, {
key: "BUTTON_CANCEL",
get: function get() {
return 'cancel';
}
}]);
function ActionBarComponent(hotInstance, options) {
var _this;
(0, _classCallCheck2.default)(this, ActionBarComponent);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ActionBarComponent).call(this, hotInstance));
_this.id = options.id;
_this.name = options.name;
_this.elements.push(new _input.default(_this.hot, {
type: 'button',
value: C.FILTERS_BUTTONS_OK,
className: 'htUIButton htUIButtonOK',
identifier: ActionBarComponent.BUTTON_OK
}));
_this.elements.push(new _input.default(_this.hot, {
type: 'button',
value: C.FILTERS_BUTTONS_CANCEL,
className: 'htUIButton htUIButtonCancel',
identifier: ActionBarComponent.BUTTON_CANCEL
}));
_this.registerHooks();
return _this;
}
/**
* Register all necessary hooks.
*
* @private
*/
(0, _createClass2.default)(ActionBarComponent, [{
key: "registerHooks",
value: function registerHooks() {
var _this2 = this;
(0, _array.arrayEach)(this.elements, function (element) {
element.addLocalHook('click', function (event, button) {
return _this2.onButtonClick(event, button);
});
});
}
/**
* Get menu object descriptor.
*
* @returns {Object}
*/
}, {
key: "getMenuItemDescriptor",
value: function getMenuItemDescriptor() {
var _this3 = this;
return {
key: this.id,
name: this.name,
isCommand: false,
disableSelection: true,
hidden: function hidden() {
return _this3.isHidden();
},
renderer: function renderer(hot, wrapper) {
(0, _element.addClass)(wrapper.parentNode, 'htFiltersMenuActionBar');
if (!wrapper.parentNode.hasAttribute('ghost-table')) {
(0, _array.arrayEach)(_this3.elements, function (ui) {
return wrapper.appendChild(ui.element);
});
}
return wrapper;
}
};
}
/**
* Fire accept event.
*/
}, {
key: "accept",
value: function accept() {
this.runLocalHooks('accept');
}
/**
* Fire cancel event.
*/
}, {
key: "cancel",
value: function cancel() {
this.runLocalHooks('cancel');
}
/**
* On button click listener.
*
* @private
* @param {Event} event DOM event
* @param {InputUI} button InputUI object.
*/
}, {
key: "onButtonClick",
value: function onButtonClick(event, button) {
if (button.options.identifier === ActionBarComponent.BUTTON_OK) {
this.accept();
} else {
this.cancel();
}
}
}]);
return ActionBarComponent;
}(_base.default);
var _default = ActionBarComponent;
exports.default = _default;
/***/ }),
/* 485 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(56);
__webpack_require__(12);
__webpack_require__(40);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var _function = __webpack_require__(75);
var _localHooks = _interopRequireDefault(__webpack_require__(57));
var _conditionCollection = _interopRequireDefault(__webpack_require__(253));
var _dataFilter = _interopRequireDefault(__webpack_require__(254));
var _utils = __webpack_require__(108);
/**
* Class which is designed for observing changes in condition collection. When condition is changed by user at specified
* column it's necessary to update all conditions defined after this edited one.
*
* Object fires `update` hook for every column conditions change.
*
* @class ConditionUpdateObserver
* @plugin Filters
*/
var ConditionUpdateObserver =
/*#__PURE__*/
function () {
function ConditionUpdateObserver(conditionCollection) {
var _this = this;
var columnDataFactory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
return [];
};
(0, _classCallCheck2.default)(this, ConditionUpdateObserver);
/**
* Reference to the instance of {@link ConditionCollection}.
*
* @type {ConditionCollection}
*/
this.conditionCollection = conditionCollection;
/**
* Function which provide source data factory for specified column.
*
* @type {Function}
*/
this.columnDataFactory = columnDataFactory;
/**
* Collected changes when grouping is enabled.
*
* @type {Array}
* @default []
*/
this.changes = [];
/**
* Flag which determines if grouping events is enabled.
*
* @type {Boolean}
*/
this.grouping = false;
/**
* The latest known position of edited conditions at specified column index.
*
* @type {Number}
* @default -1
*/
this.latestEditedColumnPosition = -1;
/**
* The latest known order of conditions stack.
*
* @type {Array}
*/
this.latestOrderStack = [];
this.conditionCollection.addLocalHook('beforeRemove', function (column) {
return _this._onConditionBeforeModify(column);
});
this.conditionCollection.addLocalHook('afterAdd', function (column) {
return _this.updateStatesAtColumn(column);
});
this.conditionCollection.addLocalHook('afterClear', function (column) {
return _this.updateStatesAtColumn(column);
});
this.conditionCollection.addLocalHook('beforeClean', function () {
return _this._onConditionBeforeClean();
});
this.conditionCollection.addLocalHook('afterClean', function () {
return _this._onConditionAfterClean();
});
}
/**
* Enable grouping changes. Grouping is helpful in situations when a lot of conditions is added in one moment. Instead of
* trigger `update` hook for every condition by adding/removing you can group this changes and call `flush` method to trigger
* it once.
*/
(0, _createClass2.default)(ConditionUpdateObserver, [{
key: "groupChanges",
value: function groupChanges() {
this.grouping = true;
}
/**
* Flush all collected changes. This trigger `update` hook for every previously collected change from condition collection.
*/
}, {
key: "flush",
value: function flush() {
var _this2 = this;
this.grouping = false;
(0, _array.arrayEach)(this.changes, function (column) {
_this2.updateStatesAtColumn(column);
});
this.changes.length = 0;
}
/**
* On before modify condition (add or remove from collection),
*
* @param {Number} column Column index.
* @private
*/
}, {
key: "_onConditionBeforeModify",
value: function _onConditionBeforeModify(column) {
this.latestEditedColumnPosition = this.conditionCollection.orderStack.indexOf(column);
}
/**
* Update all related states which should be changed after invoking changes applied to current column.
*
* @param column
* @param {Object} conditionArgsChange Object describing condition changes which can be handled by filters on `update` hook.
* It contains keys `conditionKey` and `conditionValue` which refers to change specified key of condition to specified value
* based on referred keys.
*/
}, {
key: "updateStatesAtColumn",
value: function updateStatesAtColumn(column, conditionArgsChange) {
var _this3 = this;
if (this.grouping) {
if (this.changes.indexOf(column) === -1) {
this.changes.push(column);
}
return;
}
var allConditions = this.conditionCollection.exportAllConditions();
var editedColumnPosition = this.conditionCollection.orderStack.indexOf(column);
if (editedColumnPosition === -1) {
editedColumnPosition = this.latestEditedColumnPosition;
} // Collection of all conditions defined before currently edited `column` (without edited one)
var conditionsBefore = allConditions.slice(0, editedColumnPosition); // Collection of all conditions defined after currently edited `column` (without edited one)
var conditionsAfter = allConditions.slice(editedColumnPosition); // Make sure that conditionAfter doesn't contain edited column conditions
if (conditionsAfter.length && conditionsAfter[0].column === column) {
conditionsAfter.shift();
}
var visibleDataFactory = (0, _function.curry)(function (curriedConditionsBefore, curriedColumn) {
var conditionsStack = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var splitConditionCollection = new _conditionCollection.default();
var curriedConditionsBeforeArray = [].concat(curriedConditionsBefore, conditionsStack); // Create new condition collection to determine what rows should be visible in "filter by value" box in the next conditions in the chain
splitConditionCollection.importAllConditions(curriedConditionsBeforeArray);
var allRows = _this3.columnDataFactory(curriedColumn);
var visibleRows;
if (splitConditionCollection.isEmpty()) {
visibleRows = allRows;
} else {
visibleRows = new _dataFilter.default(splitConditionCollection, function (columnData) {
return _this3.columnDataFactory(columnData);
}).filter();
}
visibleRows = (0, _array.arrayMap)(visibleRows, function (rowData) {
return rowData.meta.visualRow;
});
var visibleRowsAssertion = (0, _utils.createArrayAssertion)(visibleRows);
return (0, _array.arrayFilter)(allRows, function (rowData) {
return visibleRowsAssertion(rowData.meta.visualRow);
});
})(conditionsBefore);
var editedConditions = [].concat(this.conditionCollection.getConditions(column));
this.runLocalHooks('update', {
editedConditionStack: {
column: column,
conditions: editedConditions
},
dependentConditionStacks: conditionsAfter,
filteredRowsFactory: visibleDataFactory,
conditionArgsChange: conditionArgsChange
});
}
/**
* On before conditions clean listener.
*
* @private
*/
}, {
key: "_onConditionBeforeClean",
value: function _onConditionBeforeClean() {
this.latestOrderStack = [].concat(this.conditionCollection.orderStack);
}
/**
* On after conditions clean listener.
*
* @private
*/
}, {
key: "_onConditionAfterClean",
value: function _onConditionAfterClean() {
var _this4 = this;
(0, _array.arrayEach)(this.latestOrderStack, function (column) {
_this4.updateStatesAtColumn(column);
});
}
/**
* Destroy instance.
*/
}, {
key: "destroy",
value: function destroy() {
var _this5 = this;
this.clearLocalHooks();
(0, _object.objectEach)(this, function (value, property) {
_this5[property] = null;
});
}
}]);
return ConditionUpdateObserver;
}();
(0, _object.mixin)(ConditionUpdateObserver, _localHooks.default);
var _default = ConditionUpdateObserver;
exports.default = _default;
/***/ }),
/* 486 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 487 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var _eventManager = _interopRequireDefault(__webpack_require__(23));
var _plugins = __webpack_require__(20);
var _utils = __webpack_require__(84);
var _sheet = _interopRequireDefault(__webpack_require__(488));
var _dataProvider = _interopRequireDefault(__webpack_require__(497));
var _undoRedoSnapshot = _interopRequireDefault(__webpack_require__(498));
/**
* The formulas plugin.
*
* @plugin Formulas
* @experimental
*/
var Formulas =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(Formulas, _BasePlugin);
function Formulas(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, Formulas);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Formulas).call(this, hotInstance));
/**
* Instance of {@link EventManager}.
*
* @private
* @type {EventManager}
*/
_this.eventManager = new _eventManager.default((0, _assertThisInitialized2.default)(_this));
/**
* Instance of {@link DataProvider}.
*
* @private
* @type {DataProvider}
*/
_this.dataProvider = new _dataProvider.default(_this.hot);
/**
* Instance of {@link Sheet}.
*
* @private
* @type {Sheet}
*/
_this.sheet = new _sheet.default(_this.hot, _this.dataProvider);
/**
* Instance of {@link UndoRedoSnapshot}.
*
* @private
* @type {UndoRedoSnapshot}
*/
_this.undoRedoSnapshot = new _undoRedoSnapshot.default(_this.sheet);
/**
* Flag which indicates if table should be re-render after sheet recalculations.
*
* @type {Boolean}
* @default false
* @private
*/
_this._skipRendering = false;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link Formulas#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(Formulas, [{
key: "isEnabled",
value: function isEnabled() {
/* eslint-disable no-unneeded-ternary */
return this.hot.getSettings().formulas ? true : false;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
var settings = this.hot.getSettings().formulas;
if ((0, _object.isObject)(settings)) {
if ((0, _object.isObject)(settings.variables)) {
(0, _object.objectEach)(settings.variables, function (value, name) {
return _this2.setVariable(name, value);
});
}
}
this.addHook('afterColumnSort', function () {
return _this2.onAfterColumnSort.apply(_this2, arguments);
});
this.addHook('afterCreateCol', function () {
return _this2.onAfterCreateCol.apply(_this2, arguments);
});
this.addHook('afterCreateRow', function () {
return _this2.onAfterCreateRow.apply(_this2, arguments);
});
this.addHook('afterLoadData', function () {
return _this2.onAfterLoadData();
});
this.addHook('afterRemoveCol', function () {
return _this2.onAfterRemoveCol.apply(_this2, arguments);
});
this.addHook('afterRemoveRow', function () {
return _this2.onAfterRemoveRow.apply(_this2, arguments);
});
this.addHook('afterSetDataAtCell', function () {
return _this2.onAfterSetDataAtCell.apply(_this2, arguments);
});
this.addHook('afterSetDataAtRowProp', function () {
return _this2.onAfterSetDataAtCell.apply(_this2, arguments);
});
this.addHook('beforeColumnSort', function () {
return _this2.onBeforeColumnSort.apply(_this2, arguments);
});
this.addHook('beforeCreateCol', function () {
return _this2.onBeforeCreateCol.apply(_this2, arguments);
});
this.addHook('beforeCreateRow', function () {
return _this2.onBeforeCreateRow.apply(_this2, arguments);
});
this.addHook('beforeRemoveCol', function () {
return _this2.onBeforeRemoveCol.apply(_this2, arguments);
});
this.addHook('beforeRemoveRow', function () {
return _this2.onBeforeRemoveRow.apply(_this2, arguments);
});
this.addHook('beforeValidate', function () {
return _this2.onBeforeValidate.apply(_this2, arguments);
});
this.addHook('beforeValueRender', function () {
return _this2.onBeforeValueRender.apply(_this2, arguments);
});
this.addHook('modifyData', function () {
return _this2.onModifyData.apply(_this2, arguments);
});
this.sheet.addLocalHook('afterRecalculate', function () {
return _this2.onSheetAfterRecalculate.apply(_this2, arguments);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(Formulas.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
(0, _get2.default)((0, _getPrototypeOf2.default)(Formulas.prototype), "disablePlugin", this).call(this);
}
/**
* Returns cell value (evaluated from formula expression) at specified cell coords.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {*}
*/
}, {
key: "getCellValue",
value: function getCellValue(row, column) {
var cell = this.sheet.getCellAt(row, column);
return cell ? cell.getError() || cell.getValue() : void 0;
}
/**
* Checks if there are any formula evaluations made under specific cell coords.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {Boolean}
*/
}, {
key: "hasComputedCellValue",
value: function hasComputedCellValue(row, column) {
return this.sheet.getCellAt(row, column) !== null;
}
/**
* Recalculates all formulas (an algorithm will choose the best method of calculation).
*/
}, {
key: "recalculate",
value: function recalculate() {
this.sheet.recalculate();
}
/**
* Recalculates all formulas (rebuild dependencies from scratch - slow approach).
*/
}, {
key: "recalculateFull",
value: function recalculateFull() {
this.sheet.recalculateFull();
}
/**
* Recalculates all formulas (recalculate only changed cells - fast approach).
*/
}, {
key: "recalculateOptimized",
value: function recalculateOptimized() {
this.sheet.recalculateOptimized();
}
/**
* Sets predefined variable name which can be visible while parsing formula expression.
*
* @param {String} name Variable name.
* @param {*} value Variable value.
*/
}, {
key: "setVariable",
value: function setVariable(name, value) {
this.sheet.setVariable(name, value);
}
/**
* Returns variable name.
*
* @param {String} name Variable name.
* @returns {*}
*/
}, {
key: "getVariable",
value: function getVariable(name) {
return this.sheet.getVariable(name);
}
/**
* Local hook listener for after sheet recalculation.
*
* @private
* @param {Array} cells An array of recalculated/changed cells.
*/
}, {
key: "onSheetAfterRecalculate",
value: function onSheetAfterRecalculate(cells) {
if (this._skipRendering) {
this._skipRendering = false;
return;
}
var hot = this.hot;
(0, _array.arrayEach)(cells, function (_ref) {
var row = _ref.row,
column = _ref.column;
hot.validateCell(hot.getDataAtCell(row, column), hot.getCellMeta(row, column), function () {});
});
hot.render();
}
/**
* On modify row data listener. It overwrites raw values into calculated ones and force upper case all formula expressions.
*
* @private
* @param {Number} row Row index.
* @param {Number} column Column index.
* @param {Object} valueHolder Value holder as an object to change value by reference.
* @param {String} ioMode IO operation (`get` or `set`).
* @returns {Array|undefined} Returns modified row data.
*/
}, {
key: "onModifyData",
value: function onModifyData(row, column, valueHolder, ioMode) {
if (ioMode === 'get' && this.hasComputedCellValue(row, column)) {
valueHolder.value = this.getCellValue(row, column);
} else if (ioMode === 'set' && (0, _utils.isFormulaExpression)(valueHolder.value)) {
valueHolder.value = (0, _utils.toUpperCaseFormula)(valueHolder.value);
}
}
/**
* On before value render listener.
*
* @private
* @param {*} value Value to render.
* @returns {*}
*/
}, {
key: "onBeforeValueRender",
value: function onBeforeValueRender(value) {
var renderValue = value;
if ((0, _utils.isFormulaExpressionEscaped)(renderValue)) {
renderValue = (0, _utils.unescapeFormulaExpression)(renderValue);
}
return renderValue;
}
/**
* On before validate listener.
*
* @private
* @param {*} value Value to validate.
* @param {Number} row Row index.
* @param {Number} prop Column property.
*/
}, {
key: "onBeforeValidate",
value: function onBeforeValidate(value, row, prop) {
var column = this.hot.propToCol(prop);
var validateValue = value;
if (this.hasComputedCellValue(row, column)) {
validateValue = this.getCellValue(row, column);
}
return validateValue;
}
/**
* `afterSetDataAtCell` listener.
*
* @private
* @param {Array} changes Array of changes.
* @param {String} [source] Source of changes.
*/
}, {
key: "onAfterSetDataAtCell",
value: function onAfterSetDataAtCell(changes, source) {
var _this3 = this;
if (source === 'loadData') {
return;
}
this.dataProvider.clearChanges();
(0, _array.arrayEach)(changes, function (_ref2) {
var _ref3 = (0, _slicedToArray2.default)(_ref2, 4),
row = _ref3[0],
column = _ref3[1],
oldValue = _ref3[2],
newValue = _ref3[3];
var physicalColumn = _this3.hot.propToCol(column);
var physicalRow = _this3.t.toPhysicalRow(row);
var value = newValue;
if ((0, _utils.isFormulaExpression)(value)) {
value = (0, _utils.toUpperCaseFormula)(value);
}
_this3.dataProvider.collectChanges(physicalRow, physicalColumn, value);
if (oldValue !== value) {
_this3.sheet.applyChanges(physicalRow, physicalColumn, value);
}
});
this.recalculate();
}
/**
* On before create row listener.
*
* @private
* @param {Number} row Row index.
* @param {Number} amount An amount of removed rows.
* @param {String} source Source of method call.
*/
}, {
key: "onBeforeCreateRow",
value: function onBeforeCreateRow(row, amount, source) {
if (source === 'UndoRedo.undo') {
this.undoRedoSnapshot.restore();
}
}
/**
* On after create row listener.
*
* @private
* @param {Number} row Row index.
* @param {Number} amount An amount of created rows.
* @param {String} source Source of method call.
*/
}, {
key: "onAfterCreateRow",
value: function onAfterCreateRow(row, amount, source) {
this.sheet.alterManager.triggerAlter('insert_row', row, amount, source !== 'UndoRedo.undo');
}
/**
* On before remove row listener.
*
* @private
* @param {Number} row Row index.
* @param {Number} amount An amount of removed rows.
*/
}, {
key: "onBeforeRemoveRow",
value: function onBeforeRemoveRow(row, amount) {
this.undoRedoSnapshot.save('row', row, amount);
}
/**
* On after remove row listener.
*
* @private
* @param {Number} row Row index.
* @param {Number} amount An amount of removed rows.
*/
}, {
key: "onAfterRemoveRow",
value: function onAfterRemoveRow(row, amount) {
this.sheet.alterManager.triggerAlter('remove_row', row, amount);
}
/**
* On before create column listener.
*
* @private
* @param {Number} column Column index.
* @param {Number} amount An amount of removed columns.
* @param {String} source Source of method call.
*/
}, {
key: "onBeforeCreateCol",
value: function onBeforeCreateCol(column, amount, source) {
if (source === 'UndoRedo.undo') {
this.undoRedoSnapshot.restore();
}
}
/**
* On after create column listener.
*
* @private
* @param {Number} column Column index.
* @param {Number} amount An amount of created columns.
* @param {String} source Source of method call.
*/
}, {
key: "onAfterCreateCol",
value: function onAfterCreateCol(column, amount, source) {
this.sheet.alterManager.triggerAlter('insert_column', column, amount, source !== 'UndoRedo.undo');
}
/**
* On before remove column listener.
*
* @private
* @param {Number} column Column index.
* @param {Number} amount An amount of removed columns.
*/
}, {
key: "onBeforeRemoveCol",
value: function onBeforeRemoveCol(column, amount) {
this.undoRedoSnapshot.save('column', column, amount);
}
/**
* On after remove column listener.
*
* @private
* @param {Number} column Column index.
* @param {Number} amount An amount of created columns.
*/
}, {
key: "onAfterRemoveCol",
value: function onAfterRemoveCol(column, amount) {
this.sheet.alterManager.triggerAlter('remove_column', column, amount);
}
/**
* On before column sorting listener.
*
* @private
* @param {Number} column Sorted column index.
* @param {Boolean} order Order type.
*/
}, {
key: "onBeforeColumnSort",
value: function onBeforeColumnSort(column, order) {
this.sheet.alterManager.prepareAlter('column_sorting', column, order);
}
/**
* On after column sorting listener.
*
* @private
* @param {Number} column Sorted column index.
* @param {Boolean} order Order type.
*/
}, {
key: "onAfterColumnSort",
value: function onAfterColumnSort(column, order) {
this.sheet.alterManager.triggerAlter('column_sorting', column, order);
}
/**
* On after load data listener.
*
* @private
*/
}, {
key: "onAfterLoadData",
value: function onAfterLoadData() {
this._skipRendering = true;
this.recalculateFull();
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.dataProvider.destroy();
this.dataProvider = null;
this.sheet.destroy();
this.sheet = null;
(0, _get2.default)((0, _getPrototypeOf2.default)(Formulas.prototype), "destroy", this).call(this);
}
}]);
return Formulas;
}(_base.default);
(0, _plugins.registerPlugin)('formulas', Formulas);
var _default = Formulas;
exports.default = _default;
/***/ }),
/* 488 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _hotFormulaParser = __webpack_require__(111);
var _array = __webpack_require__(3);
var _localHooks = _interopRequireDefault(__webpack_require__(57));
var _recordTranslator = __webpack_require__(90);
var _object = __webpack_require__(4);
var _value = _interopRequireDefault(__webpack_require__(85));
var _reference = _interopRequireDefault(__webpack_require__(489));
var _utils = __webpack_require__(84);
var _matrix = _interopRequireDefault(__webpack_require__(490));
var _alterManager = _interopRequireDefault(__webpack_require__(491));
var STATE_UP_TO_DATE = 1;
var STATE_NEED_REBUILD = 2;
var STATE_NEED_FULL_REBUILD = 3;
/**
* Sheet component responsible for whole spreadsheet calculations.
*
* @class Sheet
* @util
*/
var Sheet =
/*#__PURE__*/
function () {
function Sheet(hot, dataProvider) {
var _this = this;
(0, _classCallCheck2.default)(this, Sheet);
/**
* Handsontable instance.
*
* @type {Core}
*/
this.hot = hot;
/**
* Record translator for translating visual records into psychical and vice versa.
*
* @type {RecordTranslator}
*/
this.t = (0, _recordTranslator.getTranslator)(this.hot);
/**
* Data provider for sheet calculations.
*
* @type {DataProvider}
*/
this.dataProvider = dataProvider;
/**
* Instance of {@link https://github.com/handsontable/formula-parser}.
*
* @type {Parser}
*/
this.parser = new _hotFormulaParser.Parser();
/**
* Instance of {@link Matrix}.
*
* @type {Matrix}
*/
this.matrix = new _matrix.default(this.t);
/**
* Instance of {@link AlterManager}.
*
* @type {AlterManager}
*/
this.alterManager = new _alterManager.default(this);
/**
* Cell object which indicates which cell is currently processing.
*
* @private
* @type {null}
*/
this._processingCell = null;
/**
* State of the sheet.
*
* @type {Number}
* @private
*/
this._state = STATE_NEED_FULL_REBUILD;
this.parser.on('callCellValue', function () {
return _this._onCallCellValue.apply(_this, arguments);
});
this.parser.on('callRangeValue', function () {
return _this._onCallRangeValue.apply(_this, arguments);
});
this.alterManager.addLocalHook('afterAlter', function () {
return _this._onAfterAlter.apply(_this, arguments);
});
}
/**
* Recalculate sheet.
*/
(0, _createClass2.default)(Sheet, [{
key: "recalculate",
value: function recalculate() {
switch (this._state) {
case STATE_NEED_FULL_REBUILD:
this.recalculateFull();
break;
case STATE_NEED_REBUILD:
this.recalculateOptimized();
break;
default:
break;
}
}
/**
* Recalculate sheet using optimized methods (fast recalculation).
*/
}, {
key: "recalculateOptimized",
value: function recalculateOptimized() {
var _this2 = this;
var cells = this.matrix.getOutOfDateCells();
(0, _array.arrayEach)(cells, function (cellValue) {
var value = _this2.dataProvider.getSourceDataAtCell(cellValue.row, cellValue.column);
if ((0, _utils.isFormulaExpression)(value)) {
_this2.parseExpression(cellValue, value.substr(1));
}
});
this._state = STATE_UP_TO_DATE;
this.runLocalHooks('afterRecalculate', cells, 'optimized');
}
/**
* Recalculate whole table by building dependencies from scratch (slow recalculation).
*/
}, {
key: "recalculateFull",
value: function recalculateFull() {
var _this3 = this;
var cells = this.dataProvider.getSourceDataByRange();
this.matrix.reset();
(0, _array.arrayEach)(cells, function (rowData, row) {
(0, _array.arrayEach)(rowData, function (value, column) {
if ((0, _utils.isFormulaExpression)(value)) {
_this3.parseExpression(new _value.default(row, column), value.substr(1));
}
});
});
this._state = STATE_UP_TO_DATE;
this.runLocalHooks('afterRecalculate', cells, 'full');
}
/**
* Set predefined variable name which can be visible while parsing formula expression.
*
* @param {String} name Variable name.
* @param {*} value Variable value.
*/
}, {
key: "setVariable",
value: function setVariable(name, value) {
this.parser.setVariable(name, value);
}
/**
* Get variable name.
*
* @param {String} name Variable name.
* @returns {*}
*/
}, {
key: "getVariable",
value: function getVariable(name) {
return this.parser.getVariable(name);
}
/**
* Apply changes to the sheet.
*
* @param {Number} row Physical row index.
* @param {Number} column Physical column index.
* @param {*} newValue Current cell value.
*/
}, {
key: "applyChanges",
value: function applyChanges(row, column, newValue) {
// Remove formula description for old expression
// TODO: Move this to recalculate()
this.matrix.remove({
row: row,
column: column
}); // TODO: Move this to recalculate()
if ((0, _utils.isFormulaExpression)(newValue)) {
// ...and create new for new changed formula expression
this.parseExpression(new _value.default(row, column), newValue.substr(1));
}
var deps = this.getCellDependencies.apply(this, (0, _toConsumableArray2.default)(this.t.toVisual(row, column)));
(0, _array.arrayEach)(deps, function (cellValue) {
cellValue.setState(_value.default.STATE_OUT_OFF_DATE);
});
this._state = STATE_NEED_REBUILD;
}
/**
* Parse and evaluate formula for provided cell.
*
* @param {CellValue|Object} cellValue Cell value object.
* @param {String} formula Value to evaluate.
*/
}, {
key: "parseExpression",
value: function parseExpression(cellValue, formula) {
cellValue.setState(_value.default.STATE_COMPUTING);
this._processingCell = cellValue;
var _this$parser$parse = this.parser.parse((0, _utils.toUpperCaseFormula)(formula)),
error = _this$parser$parse.error,
result = _this$parser$parse.result;
if ((0, _utils.isFormulaExpression)(result)) {
this.parseExpression(cellValue, result.substr(1));
} else {
cellValue.setValue(result);
cellValue.setError(error);
cellValue.setState(_value.default.STATE_UP_TO_DATE);
}
this.matrix.add(cellValue);
this._processingCell = null;
}
/**
* Get cell value object at specified physical coordinates.
*
* @param {Number} row Physical row index.
* @param {Number} column Physical column index.
* @returns {CellValue|undefined}
*/
}, {
key: "getCellAt",
value: function getCellAt(row, column) {
return this.matrix.getCellAt(row, column);
}
/**
* Get cell dependencies at specified physical coordinates.
*
* @param {Number} row Physical row index.
* @param {Number} column Physical column index.
* @returns {Array}
*/
}, {
key: "getCellDependencies",
value: function getCellDependencies(row, column) {
return this.matrix.getDependencies({
row: row,
column: column
});
}
/**
* Listener for parser cell value.
*
* @private
* @param {Object} cellCoords Cell coordinates.
* @param {Function} done Function to call with valid cell value.
*/
}, {
key: "_onCallCellValue",
value: function _onCallCellValue(_ref, done) {
var row = _ref.row,
column = _ref.column;
var cell = new _reference.default(row, column);
if (!this.dataProvider.isInDataRange(cell.row, cell.column)) {
throw Error(_hotFormulaParser.ERROR_REF);
}
this.matrix.registerCellRef(cell);
this._processingCell.addPrecedent(cell);
var cellValue = this.dataProvider.getRawDataAtCell(row.index, column.index);
if ((0, _hotFormulaParser.error)(cellValue)) {
var computedCell = this.matrix.getCellAt(row.index, column.index);
if (computedCell && computedCell.hasError()) {
throw Error(cellValue);
}
}
if ((0, _utils.isFormulaExpression)(cellValue)) {
var _this$parser$parse2 = this.parser.parse(cellValue.substr(1)),
error = _this$parser$parse2.error,
result = _this$parser$parse2.result;
if (error) {
throw Error(error);
}
done(result);
} else {
done(cellValue);
}
}
/**
* Listener for parser cells (range) value.
*
* @private
* @param {Object} startCell Cell coordinates (top-left corner coordinate).
* @param {Object} endCell Cell coordinates (bottom-right corner coordinate).
* @param {Function} done Function to call with valid cells values.
*/
}, {
key: "_onCallRangeValue",
value: function _onCallRangeValue(_ref2, _ref3, done) {
var _this4 = this;
var startRow = _ref2.row,
startColumn = _ref2.column;
var endRow = _ref3.row,
endColumn = _ref3.column;
var cellValues = this.dataProvider.getRawDataByRange(startRow.index, startColumn.index, endRow.index, endColumn.index);
var mapRowData = function mapRowData(rowData, rowIndex) {
return (0, _array.arrayMap)(rowData, function (cellData, columnIndex) {
var rowCellCoord = startRow.index + rowIndex;
var columnCellCoord = startColumn.index + columnIndex;
var cell = new _reference.default(rowCellCoord, columnCellCoord);
if (!_this4.dataProvider.isInDataRange(cell.row, cell.column)) {
throw Error(_hotFormulaParser.ERROR_REF);
}
_this4.matrix.registerCellRef(cell);
_this4._processingCell.addPrecedent(cell);
var newCellData = cellData;
if ((0, _hotFormulaParser.error)(newCellData)) {
var computedCell = _this4.matrix.getCellAt(cell.row, cell.column);
if (computedCell && computedCell.hasError()) {
throw Error(newCellData);
}
}
if ((0, _utils.isFormulaExpression)(newCellData)) {
var _this4$parser$parse = _this4.parser.parse(newCellData.substr(1)),
error = _this4$parser$parse.error,
result = _this4$parser$parse.result;
if (error) {
throw Error(error);
}
newCellData = result;
}
return newCellData;
});
};
var calculatedCellValues = (0, _array.arrayMap)(cellValues, function (rowData, rowIndex) {
return mapRowData(rowData, rowIndex);
});
done(calculatedCellValues);
}
/**
* On after alter sheet listener.
*
* @private
*/
}, {
key: "_onAfterAlter",
value: function _onAfterAlter() {
this.recalculateOptimized();
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
this.hot = null;
this.t = null;
this.dataProvider.destroy();
this.dataProvider = null;
this.alterManager.destroy();
this.alterManager = null;
this.parser = null;
this.matrix.reset();
this.matrix = null;
}
}]);
return Sheet;
}();
(0, _object.mixin)(Sheet, _localHooks.default);
var _default = Sheet;
exports.default = _default;
/***/ }),
/* 489 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _hotFormulaParser = __webpack_require__(111);
var _base = _interopRequireDefault(__webpack_require__(255));
/**
* Class which indicates formula expression precedents cells at specified cell
* coordinates (CellValue). This object uses visual cell coordinates.
*
* @class CellReference
* @util
*/
var CellReference =
/*#__PURE__*/
function (_BaseCell) {
(0, _inherits2.default)(CellReference, _BaseCell);
function CellReference() {
(0, _classCallCheck2.default)(this, CellReference);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CellReference).apply(this, arguments));
}
(0, _createClass2.default)(CellReference, [{
key: "toString",
/**
* Stringify object.
*
* @returns {String}
*/
value: function toString() {
return (0, _hotFormulaParser.toLabel)({
index: this.row,
isAbsolute: false
}, {
index: this.column,
isAbsolute: false
});
}
}]);
return CellReference;
}(_base.default);
var _default = CellReference;
exports.default = _default;
/***/ }),
/* 490 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(12);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _array = __webpack_require__(3);
var _value = _interopRequireDefault(__webpack_require__(85));
/**
* This component is responsible for storing all calculated cells which contain formula expressions (CellValue) and
* register for all cell references (CellReference).
*
* CellValue is an object which represents a formula expression. It contains a calculated value of that formula,
* an error if applied and cell references. Cell references are CellReference object instances which represent a cell
* in a spreadsheet. One CellReference can be assigned to multiple CellValues as a precedent cell. Each cell
* modification triggers a search through CellValues that are dependent of the CellReference. After
* the match, the cells are marked as 'out of date'. In the next render cycle, all CellValues marked with
* that state are recalculated.
*
* @class Matrix
* @util
*/
var Matrix =
/*#__PURE__*/
function () {
function Matrix(recordTranslator) {
(0, _classCallCheck2.default)(this, Matrix);
/**
* Record translator for translating visual records into psychical and vice versa.
*
* @type {RecordTranslator}
*/
this.t = recordTranslator;
/**
* List of all cell values with theirs precedents.
*
* @type {Array}
*/
this.data = [];
/**
* List of all created and registered cell references.
*
* @type {Array}
*/
this.cellReferences = [];
}
/**
* Get cell value at given row and column index.
*
* @param {Number} row Physical row index.
* @param {Number} column Physical column index.
* @returns {CellValue|null} Returns CellValue instance or `null` if cell not found.
*/
(0, _createClass2.default)(Matrix, [{
key: "getCellAt",
value: function getCellAt(row, column) {
var result = null;
(0, _array.arrayEach)(this.data, function (cell) {
if (cell.row === row && cell.column === column) {
result = cell;
return false;
}
});
return result;
}
/**
* Get all out of date cells.
*
* @returns {Array}
*/
}, {
key: "getOutOfDateCells",
value: function getOutOfDateCells() {
return (0, _array.arrayFilter)(this.data, function (cell) {
return cell.isState(_value.default.STATE_OUT_OFF_DATE);
});
}
/**
* Add cell value to the collection.
*
* @param {CellValue|Object} cellValue Cell value object.
*/
}, {
key: "add",
value: function add(cellValue) {
if (!(0, _array.arrayFilter)(this.data, function (cell) {
return cell.isEqual(cellValue);
}).length) {
this.data.push(cellValue);
}
}
/**
* Remove cell value from the collection.
*
* @param {CellValue|Object|Array} cellValue Cell value object.
*/
}, {
key: "remove",
value: function remove(cellValue) {
var isArray = Array.isArray(cellValue);
var isEqual = function isEqual(cell, values) {
var result = false;
if (isArray) {
(0, _array.arrayEach)(values, function (value) {
if (cell.isEqual(value)) {
result = true;
return false;
}
});
} else {
result = cell.isEqual(values);
}
return result;
};
this.data = (0, _array.arrayFilter)(this.data, function (cell) {
return !isEqual(cell, cellValue);
});
}
/**
* Get cell dependencies using visual coordinates.
*
* @param {Object} cellCoord Visual cell coordinates object.
*/
}, {
key: "getDependencies",
value: function getDependencies(cellCoord) {
var _this = this;
/* eslint-disable arrow-body-style */
var getDependencies = function getDependencies(cell) {
return (0, _array.arrayReduce)(_this.data, function (acc, cellValue) {
if (cellValue.hasPrecedent(cell) && acc.indexOf(cellValue) === -1) {
acc.push(cellValue);
}
return acc;
}, []);
};
var getTotalDependencies = function getTotalDependencies(cell) {
var deps = getDependencies(cell);
if (deps.length) {
(0, _array.arrayEach)(deps, function (cellValue) {
if (cellValue.hasPrecedents()) {
deps = deps.concat(getTotalDependencies(_this.t.toVisual(cellValue)));
}
});
}
return deps;
};
return getTotalDependencies(cellCoord);
}
/**
* Register cell reference to the collection.
*
* @param {CellReference|Object} cellReference Cell reference object.
*/
}, {
key: "registerCellRef",
value: function registerCellRef(cellReference) {
if (!(0, _array.arrayFilter)(this.cellReferences, function (cell) {
return cell.isEqual(cellReference);
}).length) {
this.cellReferences.push(cellReference);
}
}
/**
* Remove cell references from the collection.
*
* @param {Object} start Start visual coordinate.
* @param {Object} end End visual coordinate.
* @returns {Array} Returns removed cell references.
*/
}, {
key: "removeCellRefsAtRange",
value: function removeCellRefsAtRange(_ref, _ref2) {
var startRow = _ref.row,
startColumn = _ref.column;
var endRow = _ref2.row,
endColumn = _ref2.column;
var removed = [];
var rowMatch = function rowMatch(cell) {
return startRow === void 0 ? true : cell.row >= startRow && cell.row <= endRow;
};
var colMatch = function colMatch(cell) {
return startColumn === void 0 ? true : cell.column >= startColumn && cell.column <= endColumn;
};
this.cellReferences = (0, _array.arrayFilter)(this.cellReferences, function (cell) {
if (rowMatch(cell) && colMatch(cell)) {
removed.push(cell);
return false;
}
return true;
});
return removed;
}
/**
* Reset matrix data.
*/
}, {
key: "reset",
value: function reset() {
this.data.length = 0;
this.cellReferences.length = 0;
}
}]);
return Matrix;
}();
var _default = Matrix;
exports.default = _default;
/***/ }),
/* 491 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(16);
__webpack_require__(70);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(17);
exports.__esModule = true;
exports.registerOperation = registerOperation;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _object = __webpack_require__(4);
var _localHooks = _interopRequireDefault(__webpack_require__(57));
var columnSorting = _interopRequireWildcard(__webpack_require__(492));
var insertColumn = _interopRequireWildcard(__webpack_require__(493));
var insertRow = _interopRequireWildcard(__webpack_require__(494));
var removeColumn = _interopRequireWildcard(__webpack_require__(495));
var removeRow = _interopRequireWildcard(__webpack_require__(496));
var operations = new Map();
registerOperation(columnSorting.OPERATION_NAME, columnSorting);
registerOperation(insertColumn.OPERATION_NAME, insertColumn);
registerOperation(insertRow.OPERATION_NAME, insertRow);
registerOperation(removeColumn.OPERATION_NAME, removeColumn);
registerOperation(removeRow.OPERATION_NAME, removeRow);
/**
* Alter Manager is a service that is responsible for changing the formula expressions (especially cell coordinates)
* based on specific alter operation applied into the table.
*
* For example, when a user adds a new row the algorithm that moves all the cells below the added row down by one row
* should be triggered (eq: cell A5 become A6 etc).
*
* All alter operations are defined in the "alterOperation/" directory.
*
* @class AlterManager
* @util
*/
var AlterManager =
/*#__PURE__*/
function () {
function AlterManager(sheet) {
(0, _classCallCheck2.default)(this, AlterManager);
/**
* Instance of {@link Sheet}.
*
* @type {Sheet}
*/
this.sheet = sheet;
/**
* Handsontable instance.
*
* @type {Core}
*/
this.hot = sheet.hot;
/**
* Instance of {@link DataProvider}.
*
* @type {DataProvider}
*/
this.dataProvider = sheet.dataProvider;
/**
* Instance of {@link Matrix}.
*
* @type {Matrix}
*/
this.matrix = sheet.matrix;
}
/**
* Prepare to execute an alter algorithm. This preparation can be useful for collecting some variables and
* states before specific algorithm will be executed.
*
* @param {String} action One of the action defined in alterOperation.
* @param {*} args Arguments pass to alter operation.
*/
(0, _createClass2.default)(AlterManager, [{
key: "prepareAlter",
value: function prepareAlter(action) {
if (!operations.has(action)) {
throw Error("Alter operation \"".concat(action, "\" not exist."));
}
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
operations.get(action).prepare.apply(this, args);
}
/**
* Trigger an alter algorithm and after executing code trigger local hook ("afterAlter").
*
* @param {String} action One of the action defined in alterOperation.
* @param {*} args Arguments pass to alter operation.
*/
}, {
key: "triggerAlter",
value: function triggerAlter(action) {
if (!operations.has(action)) {
throw Error("Alter operation \"".concat(action, "\" not exist."));
}
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
operations.get(action).operate.apply(this, args);
this.runLocalHooks.apply(this, ['afterAlter'].concat(args));
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
this.sheet = null;
this.hot = null;
this.dataProvider = null;
this.matrix = null;
}
}]);
return AlterManager;
}();
(0, _object.mixin)(AlterManager, _localHooks.default);
var _default = AlterManager;
exports.default = _default;
var empty = function empty() {};
function registerOperation(name, descriptor) {
if (!operations.has(name)) {
operations.set(name, {
prepare: descriptor.prepare || empty,
operate: descriptor.operate || empty
});
}
}
/***/ }),
/* 492 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.prepare = prepare;
exports.operate = operate;
exports.OPERATION_NAME = void 0;
var _array = __webpack_require__(3);
var _utils = __webpack_require__(84);
var _value = _interopRequireDefault(__webpack_require__(85));
var _expressionModifier = _interopRequireDefault(__webpack_require__(112));
/**
* When "column_sorting" is triggered the following operations must be performed:
*
* - All formulas which contain cell coordinates must be updated and saved into source data - Column must be changed
* (decreased or increased) depends on new target position - previous position.
* - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
*/
var OPERATION_NAME = 'column_sorting';
exports.OPERATION_NAME = OPERATION_NAME;
var visualRows;
/**
* Collect all previous visual rows from CellValues.
*/
function prepare() {
var matrix = this.matrix,
dataProvider = this.dataProvider;
visualRows = new WeakMap();
(0, _array.arrayEach)(matrix.data, function (cell) {
visualRows.set(cell, dataProvider.t.toVisualRow(cell.row));
});
}
/**
* Translate all CellValues depends on previous position.
*/
function operate() {
var matrix = this.matrix,
dataProvider = this.dataProvider;
matrix.cellReferences.length = 0;
(0, _array.arrayEach)(matrix.data, function (cell) {
cell.setState(_value.default.STATE_OUT_OFF_DATE);
cell.clearPrecedents();
var row = cell.row,
column = cell.column;
var value = dataProvider.getSourceDataAtCell(row, column);
if ((0, _utils.isFormulaExpression)(value)) {
var prevRow = visualRows.get(cell);
var expModifier = new _expressionModifier.default(value);
expModifier.translate({
row: dataProvider.t.toVisualRow(row) - prevRow
});
dataProvider.updateSourceData(row, column, expModifier.toString());
}
});
visualRows = null;
}
/***/ }),
/* 493 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;
var _array = __webpack_require__(3);
var _utils = __webpack_require__(84);
var _value = _interopRequireDefault(__webpack_require__(85));
var _expressionModifier = _interopRequireDefault(__webpack_require__(112));
/**
* When "inser_column" is triggered the following operations must be performed:
*
* - All formulas which contain cell coordinates must be updated and saved into source data - Column must be increased
* by "amount" of times (eq: D4 to E4, $F$5 to $G$5);
* - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
*/
var OPERATION_NAME = 'insert_column';
/**
* Execute changes.
*
* @param {Number} start Index column from which the operation starts.
* @param {Number} amount Count of columns to be inserted.
* @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
* `false` value is used by UndoRedo plugin which saves snapshoots before alter
* operation so it doesn't have to modify formulas if "undo" action was triggered.
*/
exports.OPERATION_NAME = OPERATION_NAME;
function operate(start, amount) {
var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var matrix = this.matrix,
dataProvider = this.dataProvider;
var translate = [0, amount];
(0, _array.arrayEach)(matrix.cellReferences, function (cell) {
if (cell.column >= start) {
cell.translateTo.apply(cell, translate);
}
});
(0, _array.arrayEach)(matrix.data, function (cell) {
var origRow = cell.row,
origColumn = cell.column;
if (cell.column >= start) {
cell.translateTo.apply(cell, translate);
cell.setState(_value.default.STATE_OUT_OFF_DATE);
}
if (modifyFormula) {
var row = cell.row,
column = cell.column;
var value = dataProvider.getSourceDataAtCell(row, column);
if ((0, _utils.isFormulaExpression)(value)) {
var startCoord = (0, _utils.cellCoordFactory)('column', start);
var expModifier = new _expressionModifier.default(value);
expModifier.useCustomModifier(customTranslateModifier);
expModifier.translate({
column: amount
}, startCoord({
row: origRow,
column: origColumn
}));
dataProvider.updateSourceData(row, column, expModifier.toString());
}
}
});
}
function customTranslateModifier(cell, axis, delta, startFromIndex) {
var start = cell.start,
end = cell.end;
var startIndex = start[axis].index;
var endIndex = end[axis].index;
var deltaStart = delta;
var deltaEnd = delta; // Do not translate cells above inserted row or on the left of inserted column
if (startFromIndex > startIndex) {
deltaStart = 0;
}
if (startFromIndex > endIndex) {
deltaEnd = 0;
}
return [deltaStart, deltaEnd, false];
}
/***/ }),
/* 494 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;
var _array = __webpack_require__(3);
var _utils = __webpack_require__(84);
var _value = _interopRequireDefault(__webpack_require__(85));
var _expressionModifier = _interopRequireDefault(__webpack_require__(112));
/**
* When "insert_row" is triggered the following operations must be performed:
*
* - All formulas which contain cell coordinates must be updated and saved into source data - Row must be increased
* by "amount" of times (eq: D4 to D5, $F$5 to $F$6);
* - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
*/
var OPERATION_NAME = 'insert_row';
/**
* Execute changes.
*
* @param {Number} start Index row from which the operation starts.
* @param {Number} amount Count of rows to be inserted.
* @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
* `false` value is used by UndoRedo plugin which saves snapshoots before alter
* operation so it doesn't modify formulas if undo action is triggered.
*/
exports.OPERATION_NAME = OPERATION_NAME;
function operate(start, amount) {
var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var matrix = this.matrix,
dataProvider = this.dataProvider;
var translate = [amount, 0];
(0, _array.arrayEach)(matrix.cellReferences, function (cell) {
if (cell.row >= start) {
cell.translateTo.apply(cell, translate);
}
});
(0, _array.arrayEach)(matrix.data, function (cell) {
var origRow = cell.row,
origColumn = cell.column;
if (cell.row >= start) {
cell.translateTo.apply(cell, translate);
cell.setState(_value.default.STATE_OUT_OFF_DATE);
}
if (modifyFormula) {
var row = cell.row,
column = cell.column;
var value = dataProvider.getSourceDataAtCell(row, column);
if ((0, _utils.isFormulaExpression)(value)) {
var startCoord = (0, _utils.cellCoordFactory)('row', start);
var expModifier = new _expressionModifier.default(value);
expModifier.useCustomModifier(customTranslateModifier);
expModifier.translate({
row: amount
}, startCoord({
row: origRow,
column: origColumn
}));
dataProvider.updateSourceData(row, column, expModifier.toString());
}
}
});
}
function customTranslateModifier(cell, axis, delta, startFromIndex) {
var start = cell.start,
end = cell.end;
var startIndex = start[axis].index;
var endIndex = end[axis].index;
var deltaStart = delta;
var deltaEnd = delta; // Do not translate cells above inserted row or on the left of inserted column
if (startFromIndex > startIndex) {
deltaStart = 0;
}
if (startFromIndex > endIndex) {
deltaEnd = 0;
}
return [deltaStart, deltaEnd, false];
}
/***/ }),
/* 495 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;
var _array = __webpack_require__(3);
var _utils = __webpack_require__(84);
var _value = _interopRequireDefault(__webpack_require__(85));
var _expressionModifier = _interopRequireDefault(__webpack_require__(112));
/**
* When "remove_column" is triggered the following operations must be performed:
*
* - All formulas which contain cell coordinates must be updated and saved into source data - Column must be decreased
* by "amount" of times (eq: D4 to C4, $F$5 to $E$5);
* - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
*/
var OPERATION_NAME = 'remove_column';
/**
* Execute changes.
*
* @param {Number} start Index column from which the operation starts.
* @param {Number} amount Count of columns to be removed.
* @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
* `false` value is used by UndoRedo plugin which saves snapshoots before alter
* operation so it doesn't modify formulas if undo action is triggered.
*/
exports.OPERATION_NAME = OPERATION_NAME;
function operate(start, amount) {
var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var columnsAmount = -amount;
var matrix = this.matrix,
dataProvider = this.dataProvider,
sheet = this.sheet;
var translate = [0, columnsAmount];
var indexOffset = Math.abs(columnsAmount) - 1;
var removedCellRef = matrix.removeCellRefsAtRange({
column: start
}, {
column: start + indexOffset
});
var toRemove = [];
(0, _array.arrayEach)(matrix.data, function (cell) {
(0, _array.arrayEach)(removedCellRef, function (cellRef) {
if (!cell.hasPrecedent(cellRef)) {
return;
}
cell.removePrecedent(cellRef);
cell.setState(_value.default.STATE_OUT_OFF_DATE);
(0, _array.arrayEach)(sheet.getCellDependencies(cell.row, cell.column), function (cellValue) {
cellValue.setState(_value.default.STATE_OUT_OFF_DATE);
});
});
if (cell.column >= start && cell.column <= start + indexOffset) {
toRemove.push(cell);
}
});
matrix.remove(toRemove);
(0, _array.arrayEach)(matrix.cellReferences, function (cell) {
if (cell.column >= start) {
cell.translateTo.apply(cell, translate);
}
});
(0, _array.arrayEach)(matrix.data, function (cell) {
var origRow = cell.row,
origColumn = cell.column;
if (cell.column >= start) {
cell.translateTo.apply(cell, translate);
cell.setState(_value.default.STATE_OUT_OFF_DATE);
}
if (modifyFormula) {
var row = cell.row,
column = cell.column;
var value = dataProvider.getSourceDataAtCell(row, column);
if ((0, _utils.isFormulaExpression)(value)) {
var startCoord = (0, _utils.cellCoordFactory)('column', start);
var expModifier = new _expressionModifier.default(value);
expModifier.useCustomModifier(customTranslateModifier);
expModifier.translate({
column: columnsAmount
}, startCoord({
row: origRow,
column: origColumn
}));
dataProvider.updateSourceData(row, column, expModifier.toString());
}
}
});
}
function customTranslateModifier(cell, axis, delta, startFromIndex) {
var start = cell.start,
end = cell.end,
type = cell.type;
var startIndex = start[axis].index;
var endIndex = end[axis].index;
var indexOffset = Math.abs(delta) - 1;
var deltaStart = delta;
var deltaEnd = delta;
var refError = false; // Mark all cells as #REF! which refer to removed cells between startFromIndex and startFromIndex + delta
if (startIndex >= startFromIndex && endIndex <= startFromIndex + indexOffset) {
refError = true;
} // Decrement all cells below startFromIndex
if (!refError && type === 'cell') {
if (startFromIndex >= startIndex) {
deltaStart = 0;
deltaEnd = 0;
}
}
if (!refError && type === 'range') {
if (startFromIndex >= startIndex) {
deltaStart = 0;
}
if (startFromIndex > endIndex) {
deltaEnd = 0;
} else if (endIndex <= startFromIndex + indexOffset) {
deltaEnd -= Math.min(endIndex - (startFromIndex + indexOffset), 0);
}
}
if (startIndex + deltaStart < 0) {
deltaStart -= startIndex + deltaStart;
}
return [deltaStart, deltaEnd, refError];
}
/***/ }),
/* 496 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(10);
__webpack_require__(36);
exports.__esModule = true;
exports.operate = operate;
exports.OPERATION_NAME = void 0;
var _array = __webpack_require__(3);
var _utils = __webpack_require__(84);
var _value = _interopRequireDefault(__webpack_require__(85));
var _expressionModifier = _interopRequireDefault(__webpack_require__(112));
/**
* When "remove_row" is triggered the following operations must be performed:
*
* - All formulas which contain cell coordinates must be updated and saved into source data - Row must be decreased
* by "amount" of times (eq: D4 to D3, $F$5 to $F$4);
* - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
*/
var OPERATION_NAME = 'remove_row';
/**
* Execute changes.
*
* @param {Number} start Index row from which the operation starts.
* @param {Number} amount Count of rows to be removed.
* @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
* `false` value is used by UndoRedo plugin which saves snapshoots before alter
* operation so it doesn't modify formulas if undo action is triggered.
*/
exports.OPERATION_NAME = OPERATION_NAME;
function operate(start, amount) {
var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var rowsAmount = -amount;
var matrix = this.matrix,
dataProvider = this.dataProvider,
sheet = this.sheet;
var translate = [rowsAmount, 0];
var indexOffset = Math.abs(rowsAmount) - 1;
var removedCellRef = matrix.removeCellRefsAtRange({
row: start
}, {
row: start + indexOffset
});
var toRemove = [];
(0, _array.arrayEach)(matrix.data, function (cell) {
(0, _array.arrayEach)(removedCellRef, function (cellRef) {
if (!cell.hasPrecedent(cellRef)) {
return;
}
cell.removePrecedent(cellRef);
cell.setState(_value.default.STATE_OUT_OFF_DATE);
(0, _array.arrayEach)(sheet.getCellDependencies(cell.row, cell.column), function (cellValue) {
cellValue.setState(_value.default.STATE_OUT_OFF_DATE);
});
});
if (cell.row >= start && cell.row <= start + indexOffset) {
toRemove.push(cell);
}
});
matrix.remove(toRemove);
(0, _array.arrayEach)(matrix.cellReferences, function (cell) {
if (cell.row >= start) {
cell.translateTo.apply(cell, translate);
}
});
(0, _array.arrayEach)(matrix.data, function (cell) {
var origRow = cell.row,
origColumn = cell.column;
if (cell.row >= start) {
cell.translateTo.apply(cell, translate);
cell.setState(_value.default.STATE_OUT_OFF_DATE);
}
if (modifyFormula) {
var row = cell.row,
column = cell.column;
var value = dataProvider.getSourceDataAtCell(row, column);
if ((0, _utils.isFormulaExpression)(value)) {
var startCoord = (0, _utils.cellCoordFactory)('row', start);
var expModifier = new _expressionModifier.default(value);
expModifier.useCustomModifier(customTranslateModifier);
expModifier.translate({
row: rowsAmount
}, startCoord({
row: origRow,
column: origColumn
}));
dataProvider.updateSourceData(row, column, expModifier.toString());
}
}
});
}
function customTranslateModifier(cell, axis, delta, startFromIndex) {
var start = cell.start,
end = cell.end,
type = cell.type;
var startIndex = start[axis].index;
var endIndex = end[axis].index;
var indexOffset = Math.abs(delta) - 1;
var deltaStart = delta;
var deltaEnd = delta;
var refError = false; // Mark all cells as #REF! which refer to removed cells between startFromIndex and startFromIndex + delta
if (startIndex >= startFromIndex && endIndex <= startFromIndex + indexOffset) {
refError = true;
} // Decrement all cells below startFromIndex
if (!refError && type === 'cell') {
if (startFromIndex >= startIndex) {
deltaStart = 0;
deltaEnd = 0;
}
}
if (!refError && type === 'range') {
if (startFromIndex >= startIndex) {
deltaStart = 0;
}
if (startFromIndex > endIndex) {
deltaEnd = 0;
} else if (endIndex <= startFromIndex + indexOffset) {
deltaEnd -= Math.min(endIndex - (startFromIndex + indexOffset), 0);
}
}
if (startIndex + deltaStart < 0) {
deltaStart -= startIndex + deltaStart;
}
return [deltaStart, deltaEnd, refError];
}
/***/ }),
/* 497 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _array = __webpack_require__(3);
var _number = __webpack_require__(15);
var _object = __webpack_require__(4);
var _recordTranslator = __webpack_require__(90);
/**
* Data class provider responsible for providing a set of range data types, necessary for calculating formulas.
* Those methods strongly using hot.getData and hot.getSourceData methods with some changes. Data provider additionally
* collects all changes added to the data source to make them available faster than by using
* hot.getData and hot.getSourceData methods.
*
* @class DataProvider
* @util
*/
var DataProvider =
/*#__PURE__*/
function () {
function DataProvider(hot) {
(0, _classCallCheck2.default)(this, DataProvider);
/**
* Handsontable instance.
*
* @type {Core}
*/
this.hot = hot;
/**
* Collected changes applied into editors or by calling public Handsontable API. This is require to provide
* fresh data applied into spreadsheet before they will be available from the public API.
*
* @type {Object}
*/
this.changes = {};
/**
* Record translator for translating visual records into psychical and vice versa.
*
* @type {RecordTranslator}
*/
this.t = (0, _recordTranslator.getTranslator)(this.hot);
}
/**
* Collect all data changes applied to the Handsontable to make them available later.
*
* @param {Number} row Physical row index.
* @param {Number} column Physical column index.
* @param {*} value Value to store.
*/
(0, _createClass2.default)(DataProvider, [{
key: "collectChanges",
value: function collectChanges(row, column, value) {
this.changes[this._coordId(row, column)] = value;
}
/**
* Clear all collected changes.
*/
}, {
key: "clearChanges",
value: function clearChanges() {
this.changes = {};
}
/**
* Check if provided coordinates match to the table range data.
*
* @param {Number} visualRow Visual row index.
* @param {Number} visualColumn Visual row index.
* @returns {Boolean}
*/
}, {
key: "isInDataRange",
value: function isInDataRange(visualRow, visualColumn) {
return visualRow >= 0 && visualRow < this.hot.countRows() && visualColumn >= 0 && visualColumn < this.hot.countCols();
}
/**
* Get calculated data at specified cell.
*
* @param {Number} visualRow Visual row index.
* @param {Number} visualColumn Visual column index.
* @returns {*}
*/
}, {
key: "getDataAtCell",
value: function getDataAtCell(visualRow, visualColumn) {
var id = this._coordId.apply(this, (0, _toConsumableArray2.default)(this.t.toPhysical(visualRow, visualColumn)));
var result;
if ((0, _object.hasOwnProperty)(this.changes, id)) {
result = this.changes[id];
} else {
result = this.hot.getDataAtCell(visualRow, visualColumn);
}
return result;
}
/**
* Get calculated data at specified range.
*
* @param {Number} [visualRow1] Visual row index.
* @param {Number} [visualColumn1] Visual column index.
* @param {Number} [visualRow2] Visual row index.
* @param {Number} [visualColumn2] Visual column index.
* @returns {Array}
*/
}, {
key: "getDataByRange",
value: function getDataByRange(visualRow1, visualColumn1, visualRow2, visualColumn2) {
var _this = this;
var result = this.hot.getData(visualRow1, visualColumn1, visualRow2, visualColumn2);
(0, _array.arrayEach)(result, function (rowData, rowIndex) {
(0, _array.arrayEach)(rowData, function (value, columnIndex) {
var id = _this._coordId.apply(_this, (0, _toConsumableArray2.default)(_this.t.toPhysical(rowIndex + visualRow1, columnIndex + visualColumn1)));
if ((0, _object.hasOwnProperty)(_this.changes, id)) {
result[rowIndex][columnIndex] = _this.changes[id];
}
});
});
return result;
}
/**
* Get source data at specified physical cell.
*
* @param {Number} physicalRow Physical row index.
* @param {Number} physicalColumn Physical column index.
* @returns {*}
*/
}, {
key: "getSourceDataAtCell",
value: function getSourceDataAtCell(physicalRow, physicalColumn) {
var id = this._coordId(physicalRow, physicalColumn);
var result;
if ((0, _object.hasOwnProperty)(this.changes, id)) {
result = this.changes[id];
} else {
result = this.hot.getSourceDataAtCell(physicalRow, physicalColumn);
}
return result;
}
/**
* Get source data at specified physical range.
*
* @param {Number} [physicalRow1] Physical row index.
* @param {Number} [physicalColumn1] Physical column index.
* @param {Number} [physicalRow2] Physical row index.
* @param {Number} [physicalColumn2] Physical column index.
* @returns {Array}
*/
}, {
key: "getSourceDataByRange",
value: function getSourceDataByRange(physicalRow1, physicalColumn1, physicalRow2, physicalColumn2) {
return this.hot.getSourceDataArray(physicalRow1, physicalColumn1, physicalRow2, physicalColumn2);
}
/**
* Get source data at specified visual cell.
*
* @param {Number} visualRow Visual row index.
* @param {Number} visualColumn Visual column index.
* @returns {*}
*/
}, {
key: "getRawDataAtCell",
value: function getRawDataAtCell(visualRow, visualColumn) {
return this.getSourceDataAtCell.apply(this, (0, _toConsumableArray2.default)(this.t.toPhysical(visualRow, visualColumn)));
}
/**
* Get source data at specified visual range.
*
* @param {Number} [visualRow1] Visual row index.
* @param {Number} [visualColumn1] Visual column index.
* @param {Number} [visualRow2] Visual row index.
* @param {Number} [visualColumn2] Visual column index.
* @returns {Array}
*/
}, {
key: "getRawDataByRange",
value: function getRawDataByRange(visualRow1, visualColumn1, visualRow2, visualColumn2) {
var _this2 = this;
var data = [];
(0, _number.rangeEach)(visualRow1, visualRow2, function (visualRow) {
var row = [];
(0, _number.rangeEach)(visualColumn1, visualColumn2, function (visualColumn) {
var _this2$t$toPhysical = _this2.t.toPhysical(visualRow, visualColumn),
_this2$t$toPhysical2 = (0, _slicedToArray2.default)(_this2$t$toPhysical, 2),
physicalRow = _this2$t$toPhysical2[0],
physicalColumn = _this2$t$toPhysical2[1];
var id = _this2._coordId(physicalRow, physicalColumn);
if ((0, _object.hasOwnProperty)(_this2.changes, id)) {
row.push(_this2.changes[id]);
} else {
row.push(_this2.getSourceDataAtCell(physicalRow, physicalColumn));
}
});
data.push(row);
});
return data;
}
/**
* Update source data.
*
* @param {Number} physicalRow Physical row index.
* @param {Number} physicalColumn Physical row index.
* @param {*} value Value to update.
*/
}, {
key: "updateSourceData",
value: function updateSourceData(physicalRow, physicalColumn, value) {
this.hot.getSourceData()[physicalRow][this.hot.colToProp(physicalColumn)] = value;
}
/**
* Generate cell coordinates id where the data changes will be stored.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {String}
* @private
*/
}, {
key: "_coordId",
value: function _coordId(row, column) {
return "".concat(row, ":").concat(column);
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
this.hot = null;
this.changes = null;
this.t = null;
}
}]);
return DataProvider;
}();
var _default = DataProvider;
exports.default = _default;
/***/ }),
/* 498 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _array = __webpack_require__(3);
var _stack = _interopRequireDefault(__webpack_require__(499));
var _value = _interopRequireDefault(__webpack_require__(85));
/**
* This components is a simple workaround to make Undo/Redo functionality work.
*
* @class UndoRedoSnapshot
* @util
*/
var UndoRedoSnapshot =
/*#__PURE__*/
function () {
function UndoRedoSnapshot(sheet) {
(0, _classCallCheck2.default)(this, UndoRedoSnapshot);
/**
* Instance of {@link Sheet}.
*
* @type {Sheet}
*/
this.sheet = sheet;
/**
* Stack instance for collecting undo/redo changes.
*
* @type {Stack}
*/
this.stack = new _stack.default();
}
/**
* Save snapshot for specified action.
*
* @param {String} axis Alter action which triggers snapshot.
* @param {Number} index Alter operation stared at.
* @param {Number} amount Amount of items to operate.
*/
(0, _createClass2.default)(UndoRedoSnapshot, [{
key: "save",
value: function save(axis, index, amount) {
var _this$sheet = this.sheet,
matrix = _this$sheet.matrix,
dataProvider = _this$sheet.dataProvider;
var changes = [];
(0, _array.arrayEach)(matrix.data, function (cellValue) {
var row = cellValue.row,
column = cellValue.column;
if (cellValue[axis] < index || cellValue[axis] > index + (amount - 1)) {
var value = dataProvider.getSourceDataAtCell(row, column);
changes.push({
row: row,
column: column,
value: value
});
}
});
this.stack.push({
axis: axis,
index: index,
amount: amount,
changes: changes
});
}
/**
* Restore state to the previous one.
*/
}, {
key: "restore",
value: function restore() {
var _this$sheet2 = this.sheet,
matrix = _this$sheet2.matrix,
dataProvider = _this$sheet2.dataProvider;
var _this$stack$pop = this.stack.pop(),
axis = _this$stack$pop.axis,
index = _this$stack$pop.index,
amount = _this$stack$pop.amount,
changes = _this$stack$pop.changes;
if (changes) {
(0, _array.arrayEach)(changes, function (change) {
if (change[axis] > index + (amount - 1)) {
change[axis] -= amount;
}
var row = change.row,
column = change.column,
value = change.value;
var rawValue = dataProvider.getSourceDataAtCell(row, column);
if (rawValue !== value) {
dataProvider.updateSourceData(row, column, value);
matrix.getCellAt(row, column).setState(_value.default.STATE_OUT_OFF_DATE);
}
});
}
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
this.sheet = null;
this.stack = null;
}
}]);
return UndoRedoSnapshot;
}();
var _default = UndoRedoSnapshot;
exports.default = _default;
/***/ }),
/* 499 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
/**
* @class Stack
* @util
*/
var Stack =
/*#__PURE__*/
function () {
function Stack() {
var initial = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
(0, _classCallCheck2.default)(this, Stack);
/**
* Items collection.
*
* @type {Array}
*/
this.items = initial;
}
/**
* Add new item or items at the back of the stack.
*
* @param {*} items An item to add.
*/
(0, _createClass2.default)(Stack, [{
key: "push",
value: function push() {
var _this$items;
(_this$items = this.items).push.apply(_this$items, arguments);
}
/**
* Remove the last element from the stack and returns it.
*
* @returns {*}
*/
}, {
key: "pop",
value: function pop() {
return this.items.pop();
}
/**
* Return the last element from the stack (without modification stack).
*
* @returns {*}
*/
}, {
key: "peek",
value: function peek() {
return this.isEmpty() ? void 0 : this.items[this.items.length - 1];
}
/**
* Check if the stack is empty.
*
* @returns {Boolean}
*/
}, {
key: "isEmpty",
value: function isEmpty() {
return !this.size();
}
/**
* Return number of elements in the stack.
*
* @returns {Number}
*/
}, {
key: "size",
value: function size() {
return this.items.length;
}
}]);
return Stack;
}();
var _default = Stack;
exports.default = _default;
/***/ }),
/* 500 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(40);
__webpack_require__(37);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _element = __webpack_require__(5);
var _object = __webpack_require__(4);
var _console = __webpack_require__(55);
var _data = __webpack_require__(132);
var _plugins = __webpack_require__(20);
var _utils = __webpack_require__(172);
var _dateCalculator = _interopRequireDefault(__webpack_require__(501));
var _ganttChartDataFeed = _interopRequireDefault(__webpack_require__(502));
__webpack_require__(503);
/**
* @plugin GanttChart
* @experimental
* @dependencies CollapsibleColumns
*
* @description
* GanttChart plugin enables a possibility to create a Gantt chart using a Handsontable instance.
* In this case, the whole table becomes read-only.
*
* @example
* ```js
* ganttChart: {
* dataSource: data,
* firstWeekDay: 'monday', // Sets the first day of the week to either 'monday' or 'sunday'.
* startYear: 2015 // Sets the displayed year to the provided value.
* weekHeaderGenerator: function(start, end) { return start + ' - ' + end; } // sets the label on the week column headers (optional). The `start` and `end` arguments are numbers representing the beginning and end day of the week.
* allowSplitWeeks: true, // If set to `true` (default), will allow splitting week columns between months. If not, plugin will generate "mixed" months, like "Jan/Feb".
* hideDaysBeforeFullWeeks: false, // If set to `true`, the plugin won't render the incomplete weeks before the "full" weeks inside months.
* hideDaysAfterFullWeeks: false, // If set to `true`, the plugin won't render the incomplete weeks after the "full" weeks inside months.
* }
*
* // Where data can be either an data object or an object containing information about another Handsontable instance, which
* // would feed the chart-enabled instance with data.
* // For example:
*
* // Handsontable-binding information
* var data = {
* instance: source, // reference to another Handsontable instance
* startDateColumn: 4, // index of a column, which contains information about start dates of data ranges
* endDateColumn: 5, // index of a column, which contains information about end dates of data ranges
* additionalData: { // information about additional data passed to the chart, in this example example:
* label: 0, // labels are stored in the first column
* quantity: 1 // quantity information is stored in the second column
* },
* asyncUpdates: true // if set to true, the updates from the source instance with be asynchronous. Defaults to false.
* }
*
* // Data object
* var data = [
* {
* additionalData: {label: 'Example label.', quantity: 'Four packs.'},
* startDate: '1/5/2015',
* endDate: '1/20/2015'
* },
* {
* additionalData: {label: 'Another label.', quantity: 'One pack.'},
* startDate: '1/11/2015',
* endDate: '1/29/2015'
* }
* ];
* ```
*/
var GanttChart =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(GanttChart, _BasePlugin);
function GanttChart(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, GanttChart);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(GanttChart).call(this, hotInstance));
/**
* Cached plugin settings.
*
* @private
* @type {Object}
*/
_this.settings = {};
/**
* Date Calculator object.
*
* @private
* @type {DateCalculator}
*/
_this.dateCalculator = null;
/**
* Currently loaded year.
*
* @private
* @type {Number}
*/
_this.currentYear = null;
/**
* List of months and their corresponding day counts.
*
* @private
* @type {Array}
*/
_this.monthList = [];
/**
* Array of data for the month headers.
*
* @private
* @type {Array}
*/
_this.monthHeadersArray = [];
/**
* Array of data for the week headers.
*
* @private
* @type {Array}
*/
_this.weekHeadersArray = [];
/**
* Object containing the currently created range bars, along with their corresponding parameters.
*
* @private
* @type {Object}
*/
_this.rangeBars = {};
/**
* Object containing the currently created ranges with coordinates to their range bars.
* It's structure is categorized by years, so to get range bar information for a year, one must use `this.rangeList[year]`.
*
* @private
* @type {Object}
*/
_this.rangeList = {};
/**
* Reference to the Nested Headers plugin.
*
* @private
* @type {NestedHeaders}
*/
_this.nestedHeadersPlugin = null;
/**
* Object containing properties of the source Handsontable instance (the data source).
*
* @private
* @type {Object}
*/
_this.hotSource = null;
/**
* Number of week 'blocks' in the nested headers.
*
* @private
* @type {Number}
*/
_this.overallWeekSectionCount = null;
/**
* Initial instance settings - used to rollback the gantt-specific settings during the disabling of the plugin.
*
* @private
* @type {Object}
*/
_this.initialSettings = null;
/**
* Data feed controller for this plugin.
*
* @private
* @type {GanttChartDataFeed}
*/
_this.dataFeed = null;
/**
* Color information set after applying colors to the chart.
*
* @private
* @type {Object}
*/
_this.colorData = {};
/**
* Metadata of the range bars, used to re-apply meta after updating HOT settings.
*
* @private
* @type {Object}
*/
_this.rangeBarMeta = Object.create(null);
return _this;
}
/**
* Check if the dependencies are met, if not, throws a warning.
*/
(0, _createClass2.default)(GanttChart, [{
key: "checkDependencies",
value: function checkDependencies() {
if (!this.hot.getSettings().colHeaders) {
(0, _console.warn)('You need to enable the colHeaders property in your Gantt Chart Handsontable in order for it to work properly.');
}
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link GanttChart#enablePlugin} method is called.
*
* @returns {Boolean}
*/
}, {
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().ganttChart;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.checkDependencies();
this.parseSettings();
this.currentYear = this.settings.startYear || new Date().getFullYear();
this.dateCalculator = new _dateCalculator.default({
year: this.currentYear,
allowSplitWeeks: this.settings.allowSplitWeeks,
hideDaysBeforeFullWeeks: this.settings.hideDaysBeforeFullWeeks,
hideDaysAfterFullWeeks: this.settings.hideDaysAfterFullWeeks
});
this.dateCalculator.setFirstWeekDay(this.settings.firstWeekDay);
this.monthList = this.dateCalculator.getMonthList();
this.monthHeadersArray = this.generateMonthHeaders();
this.weekHeadersArray = this.generateWeekHeaders();
this.overallWeekSectionCount = this.dateCalculator.countWeekSections();
this.assignGanttSettings();
if (this.nestedHeadersPlugin) {
this.applyDataSource();
if (this.colorData) {
this.setRangeBarColors(this.colorData);
}
}
this.addHook('afterInit', function () {
return _this2.onAfterInit();
});
(0, _element.addClass)(this.hot.rootElement, 'ganttChart');
(0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
if (this.internalUpdateSettings) {
return;
}
if (this.dataFeed && this.dataFeed.hotSource) {
this.dataFeed.removeSourceHotHooks(this.dataFeed.hotSource);
}
this.settings = {};
this.dataFeed = {};
this.currentYear = null;
this.monthList = [];
this.rangeBars = {};
this.rangeList = {};
this.rangeBarMeta = {};
this.hotSource = null;
this.deassignGanttSettings();
(0, _element.removeClass)(this.hot.rootElement, 'ganttChart');
(0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "disablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "updatePlugin", this).call(this);
}
/**
* Parses the plugin settings.
*
* @private
*/
}, {
key: "parseSettings",
value: function parseSettings() {
this.settings = this.hot.getSettings().ganttChart;
if (typeof this.settings === 'boolean') {
this.settings = {};
}
if (!this.settings.firstWeekDay) {
this.settings.firstWeekDay = 'monday';
}
if (this.settings.allowSplitWeeks === void 0) {
this.settings.allowSplitWeeks = true;
}
if (typeof this.settings.weekHeaderGenerator !== 'function') {
this.settings.weekHeaderGenerator = null;
}
}
/**
* Applies the data source provided in the plugin settings.
*
* @private
*/
}, {
key: "applyDataSource",
value: function applyDataSource() {
if (this.settings.dataSource) {
var source = this.settings.dataSource;
if (source.instance) {
this.loadData(source.instance, source.startDateColumn, source.endDateColumn, source.additionalData, source.asyncUpdates);
} else {
this.loadData(source);
}
}
}
/**
* Loads chart data to the Handsontable instance.
*
* @private
* @param {Array|Object} data Array of objects containing the range data OR another Handsontable instance, to be used as the data feed
* @param {Number} [startDateColumn] Index of the start date column (Needed only if the data argument is a HOT instance).
* @param {Number} [endDateColumn] Index of the end date column (Needed only if the data argument is a HOT instance).
* @param {Object} [additionalData] Object containing additional data labels and their corresponding column indexes (Needed only if the data argument is a HOT instance).
*
*/
}, {
key: "loadData",
value: function loadData(data, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
this.dataFeed = new _ganttChartDataFeed.default(this.hot, data, startDateColumn, endDateColumn, additionalData, asyncUpdates);
this.hot.render();
}
/**
* Clears the range bars list.
*
* @private
*/
}, {
key: "clearRangeBars",
value: function clearRangeBars() {
this.rangeBars = {};
}
/**
* Clears the range list.
*
* @private
*/
}, {
key: "clearRangeList",
value: function clearRangeList() {
this.rangeList = {};
}
/**
* Returns a range bar coordinates by the provided row.
*
* @param {Number} row Range bar's row.
* @returns {Object}
*/
}, {
key: "getRangeBarCoordinates",
value: function getRangeBarCoordinates(row) {
return this.rangeList[row];
}
/**
* Generates the month header structure.
*
* @private
*/
}, {
key: "generateMonthHeaders",
value: function generateMonthHeaders() {
var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentYear;
return this.dateCalculator.generateHeaderSet('months', this.settings.weekHeaderGenerator, year);
}
/**
* Generates the week header structure.
*
* @private
*/
}, {
key: "generateWeekHeaders",
value: function generateWeekHeaders() {
var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.currentYear;
return this.dateCalculator.generateHeaderSet('weeks', this.settings.weekHeaderGenerator, year);
}
/**
* Assigns the settings needed for the Gantt Chart plugin into the Handsontable instance.
*
* @private
*/
}, {
key: "assignGanttSettings",
value: function assignGanttSettings() {
var _this3 = this;
// TODO: commented out temporarily, to be fixed in #68, there's a problem with re-enabling the gantt settings after resetting them
// this.initialSettings = {
// data: this.hot.getSettings().data,
// readOnly: this.hot.getSettings().readOnly,
// renderer: this.hot.getSettings().renderer,
// colWidths: this.hot.getSettings().colWidths,
// hiddenColumns: this.hot.getSettings().hiddenColumns,
// nestedHeaders: this.hot.getSettings().nestedHeaders,
// collapsibleColumns: this.hot.getSettings().collapsibleColumns,
// columnSorting: this.hot.getSettings().columnSorting,
// };
this.initialSettings = (0, _object.deepClone)(this.hot.getSettings());
var additionalSettings = {
data: (0, _data.createEmptySpreadsheetData)(1, this.overallWeekSectionCount),
readOnly: true,
renderer: function renderer(instance, TD, row, col, prop, value, cellProperties) {
return _this3.uniformBackgroundRenderer(instance, TD, row, col, prop, value, cellProperties);
},
colWidths: 60,
hiddenColumns: this.hot.getSettings().hiddenColumns ? this.hot.getSettings().hiddenColumns : true,
nestedHeaders: [this.monthHeadersArray.slice(), this.weekHeadersArray.slice()],
collapsibleColumns: this.hot.getSettings().collapsibleColumns ? this.hot.getSettings().collapsibleColumns : true,
columnSorting: false,
copyPaste: false
};
this.internalUpdateSettings = true;
this.hot.updateSettings(additionalSettings);
this.internalUpdateSettings = void 0;
}
/**
* Deassigns the Gantt Chart plugin settings (revert to initial settings).
*
* @private
*/
}, {
key: "deassignGanttSettings",
value: function deassignGanttSettings() {
this.internalUpdateSettings = true;
if (this.initialSettings) {
this.hot.updateSettings(this.initialSettings);
}
this.internalUpdateSettings = void 0;
}
/**
* Add rangebar meta data to the cache.
*
* @param {Number} row
* @param {Number} col
* @param {String} key
* @param {String|Number|Object|Array} value
*/
}, {
key: "cacheRangeBarMeta",
value: function cacheRangeBarMeta(row, col, key, value) {
if (!this.rangeBarMeta[row]) {
this.rangeBarMeta[row] = {};
}
if (!this.rangeBarMeta[row][col]) {
this.rangeBarMeta[row][col] = {};
}
this.rangeBarMeta[row][col][key] = value;
}
/**
* Applies the cached cell meta.
*
* @private
*/
}, {
key: "applyRangeBarMetaCache",
value: function applyRangeBarMetaCache() {
var _this4 = this;
(0, _object.objectEach)(this.rangeBarMeta, function (rowArr, row) {
(0, _object.objectEach)(rowArr, function (cell, col) {
(0, _object.objectEach)(cell, function (value, key) {
_this4.hot.setCellMeta(row, col, key, value);
});
});
});
}
/**
* Get the column index of the adjacent week.
*
* @private
* @param {Date|String} date The date object/string.
* @param {Boolean} following `true` if the following week is needed.
* @param {Boolean} previous `true` if the previous week is needed.
*/
}, {
key: "getAdjacentWeekColumn",
value: function getAdjacentWeekColumn(date, following, previous) {
var convertedDate = (0, _utils.parseDate)(date);
var delta = previous === true ? -7 : 7;
var adjacentWeek = convertedDate.setDate(convertedDate.getDate() + delta);
return this.dateCalculator.dateToColumn(adjacentWeek);
}
/**
* Create a new range bar.
*
* @param {Number} row Row index.
* @param {Date|String} startDate Start date object/string.
* @param {Date|String} endDate End date object/string.
* @param {Object} additionalData Additional range data.
* @returns {Array|Boolean} Array of the bar's row and column.
*/
}, {
key: "addRangeBar",
value: function addRangeBar(row, startDate, endDate, additionalData) {
var _this5 = this;
if (startDate !== null && endDate !== null) {
this.prepareDaysInColumnsInfo((0, _utils.parseDate)(startDate), (0, _utils.parseDate)(endDate));
}
var startDateColumn = this.dateCalculator.dateToColumn(startDate);
var endDateColumn = this.dateCalculator.dateToColumn(endDate);
var year = (0, _utils.getDateYear)(startDate); // every range bar should not exceed the limits of one year
var startMoved = false;
var endMoved = false;
if (startDateColumn === null && this.settings.hideDaysBeforeFullWeeks) {
startDateColumn = this.getAdjacentWeekColumn(startDate, true, false);
if (startDateColumn !== false) {
startMoved = true;
}
}
if (endDateColumn === null && this.settings.hideDaysAfterFullWeeks) {
endDateColumn = this.getAdjacentWeekColumn(endDate, false, true);
if (endDateColumn !== false) {
endMoved = true;
}
}
if (!this.dateCalculator.isValidRangeBarData(startDate, endDate) || startDateColumn === false || endDateColumn === false) {
return false;
}
if (!this.rangeBars[year]) {
this.rangeBars[year] = {};
}
if (!this.rangeBars[year][row]) {
this.rangeBars[year][row] = {};
}
this.rangeBars[year][row][startDateColumn] = {
barLength: endDateColumn - startDateColumn + 1,
partialStart: startMoved ? false : !this.dateCalculator.isOnTheEdgeOfWeek(startDate)[0],
partialEnd: endMoved ? false : !this.dateCalculator.isOnTheEdgeOfWeek(endDate)[1],
additionalData: {}
};
(0, _object.objectEach)(additionalData, function (prop, i) {
_this5.rangeBars[year][row][startDateColumn].additionalData[i] = prop;
});
if (year === this.dateCalculator.getYear()) {
if (this.colorData[row]) {
this.rangeBars[year][row][startDateColumn].colors = this.colorData[row];
}
this.rangeList[row] = [row, startDateColumn];
this.renderRangeBar(row, startDateColumn, endDateColumn, additionalData);
}
return [row, startDateColumn];
}
/**
* Generates the information about which date is represented in which column.
*
* @private
* @param {Date} startDate Start date.
* @param {Date} endDate End Date.
*/
}, {
key: "prepareDaysInColumnsInfo",
value: function prepareDaysInColumnsInfo(startDate, endDate) {
for (var i = startDate.getFullYear(); i <= endDate.getFullYear(); i++) {
if (this.dateCalculator.daysInColumns[i] === void 0) {
this.dateCalculator.calculateWeekStructure(i);
this.dateCalculator.generateHeaderSet('weeks', null, i);
}
}
}
/**
* Returns the range bar data of the provided row and column.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {Object|Boolean} Returns false if no bar is found.
*/
}, {
key: "getRangeBarData",
value: function getRangeBarData(row, column) {
var year = this.dateCalculator.getYear();
var rangeBarCoords = this.getRangeBarCoordinates(row);
if (!rangeBarCoords) {
return false;
}
var rangeBarData = this.rangeBars[year][rangeBarCoords[0]][rangeBarCoords[1]];
if (rangeBarData && row === rangeBarCoords[0] && (column === rangeBarCoords[1] || column > rangeBarCoords[1] && column < rangeBarCoords[1] + rangeBarData.barLength)) {
return rangeBarData;
}
return false;
}
/**
* Updates the range bar data by the provided object.
*
* @param {Number} row Row index.
* @param {Number} column Column index.
* @param {Object} data Object with the updated data.
*/
}, {
key: "updateRangeBarData",
value: function updateRangeBarData(row, column, data) {
var rangeBar = this.getRangeBarData(row, column);
(0, _object.objectEach)(data, function (val, prop) {
if (rangeBar[prop] !== val) {
rangeBar[prop] = val;
}
});
}
/**
* Adds a range bar to the table.
*
* @private
* @param {Number} row Row index.
* @param {Number} startDateColumn Start column index.
* @param {Number} endDateColumn End column index.
*/
}, {
key: "renderRangeBar",
value: function renderRangeBar(row, startDateColumn, endDateColumn) {
var year = this.dateCalculator.getYear();
var currentBar = this.rangeBars[year][row][startDateColumn];
for (var i = startDateColumn; i <= endDateColumn; i++) {
var cellMeta = this.hot.getCellMeta(row, i);
var newClassName = "".concat(cellMeta.className || '', " rangeBar");
if (i === startDateColumn && currentBar.partialStart || i === endDateColumn && currentBar.partialEnd) {
newClassName += ' partial';
}
if (i === endDateColumn) {
newClassName += ' last';
}
this.hot.setCellMeta(row, i, 'originalClassName', cellMeta.className);
this.hot.setCellMeta(row, i, 'className', newClassName);
this.hot.setCellMeta(row, i, 'additionalData', currentBar.additionalData); // cache cell meta, used for updateSettings, related with a cell meta bug
this.cacheRangeBarMeta(row, i, 'originalClassName', cellMeta.className);
this.cacheRangeBarMeta(row, i, 'className', newClassName);
this.cacheRangeBarMeta(row, i, 'additionalData', currentBar.additionalData);
}
}
/**
* Removes a range bar of the provided start date and row.
*
* @param {Number} row Row index.
* @param {Date|String} startDate Start date.
*/
}, {
key: "removeRangeBarByDate",
value: function removeRangeBarByDate(row, startDate) {
var startDateColumn = this.dateCalculator.dateToColumn(startDate);
this.removeRangeBarByColumn(row, startDateColumn);
}
/**
* Removes a range bar of the provided row and start column.
*
* @param {Number} row Row index.
* @param {Number} startDateColumn Column index.
*/
}, {
key: "removeRangeBarByColumn",
value: function removeRangeBarByColumn(row, startDateColumn) {
var _this6 = this;
var year = this.dateCalculator.getYear();
var rangeBar = this.rangeBars[year][row][startDateColumn];
if (!rangeBar) {
return;
}
this.unrenderRangeBar(row, startDateColumn, startDateColumn + rangeBar.barLength - 1);
this.rangeBars[year][row][startDateColumn] = null;
(0, _object.objectEach)(this.rangeList, function (prop, i) {
var id = parseInt(i, 10);
if (JSON.stringify(prop) === JSON.stringify([row, startDateColumn])) {
_this6.rangeList[id] = null;
}
});
}
/**
* Removes all range bars from the chart-enabled Handsontable instance.
*/
}, {
key: "removeAllRangeBars",
value: function removeAllRangeBars() {
var _this7 = this;
(0, _object.objectEach)(this.rangeBars, function (row, i) {
(0, _object.objectEach)(row, function (bar, j) {
_this7.removeRangeBarByColumn(i, j);
});
});
}
/**
* Removes a range bar from the table.
*
* @private
* @param {Number} row Row index.
* @param {Number} startDateColumn Start column index.
* @param {Number} endDateColumn End column index.
*/
}, {
key: "unrenderRangeBar",
value: function unrenderRangeBar(row, startDateColumn, endDateColumn) {
for (var i = startDateColumn; i <= endDateColumn; i++) {
var cellMeta = this.hot.getCellMeta(row, i);
this.hot.setCellMeta(row, i, 'className', cellMeta.originalClassName);
this.hot.setCellMeta(row, i, 'originalClassName', void 0);
this.cacheRangeBarMeta(row, i, 'className', cellMeta.originalClassName);
this.cacheRangeBarMeta(row, i, 'originalClassName', void 0);
}
this.hot.render();
}
/**
* A default renderer of the range bars.
*
* @private
* @param {Object} instance HOT instance.
* @param {HTMLElement} TD TD element.
* @param {Number} row Row index.
* @param {Number} col Column index.
* @param {String|Number} prop Object data property.
* @param {String|Number} value Value to pass to the cell.
* @param {Object} cellProperties Current cell properties.
*/
}, {
key: "uniformBackgroundRenderer",
value: function uniformBackgroundRenderer(instance, TD, row, col, prop, value, cellProperties) {
var rangeBarInfo = this.getRangeBarData(row, col);
var rangeBarCoords = this.getRangeBarCoordinates(row);
TD.innerHTML = '';
if (cellProperties.className) {
TD.className = cellProperties.className;
}
var titleValue = '';
(0, _object.objectEach)(cellProperties.additionalData, function (cellMeta, i) {
titleValue += "".concat(i, ": ").concat(cellMeta, "\n");
});
titleValue = titleValue.replace(/\n$/, '');
TD.title = titleValue;
if (rangeBarInfo && rangeBarInfo.colors) {
if (col === rangeBarCoords[1] && rangeBarInfo.partialStart || col === rangeBarCoords[1] + rangeBarInfo.barLength - 1 && rangeBarInfo.partialEnd) {
TD.style.background = rangeBarInfo.colors[1];
} else {
TD.style.background = rangeBarInfo.colors[0];
}
} else {
TD.style.background = '';
}
}
/**
* Sets range bar colors.
*
* @param {Object} rows Object containing row color data, see example.
* @example
* ```js
* hot.getPlugin('ganttChart').setRangeBarColors({
* 0: ['blue', 'lightblue'] // paints the bar in the first row blue, with partial sections colored light blue
* 2: ['#2A74D0', '#588DD0'] // paints the bar in the thrid row with #2A74D0, with partial sections colored with #588DD0
* });
* ```
*/
}, {
key: "setRangeBarColors",
value: function setRangeBarColors(rows) {
var _this8 = this;
this.colorData = rows;
(0, _object.objectEach)(rows, function (colors, i) {
var barCoords = _this8.getRangeBarCoordinates(i);
if (barCoords) {
_this8.updateRangeBarData(barCoords[0], barCoords[1], {
colors: colors
});
}
});
this.hot.render();
}
/**
* Updates the chart with a new year.
*
* @param {Number} year New chart year.
*/
}, {
key: "setYear",
value: function setYear(year) {
var newSettings = (0, _object.extend)(this.hot.getSettings().ganttChart, {
startYear: year
});
this.hot.updateSettings({
ganttChart: newSettings
});
}
/**
* AfterInit hook callback.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
this.nestedHeadersPlugin = this.hot.getPlugin('nestedHeaders');
this.applyDataSource();
}
/**
* Prevents update settings loop when assigning the additional internal settings.
*
* @private
*/
}, {
key: "onUpdateSettings",
value: function onUpdateSettings() {
if (this.internalUpdateSettings) {
this.applyRangeBarMetaCache();
return;
}
(0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "onUpdateSettings", this).call(this);
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
if (this.hotSource) {
this.dataFeed.removeSourceHotHooks(this.hotSource);
}
(0, _get2.default)((0, _getPrototypeOf2.default)(GanttChart.prototype), "destroy", this).call(this);
}
}]);
return GanttChart;
}(_base.default);
(0, _plugins.registerPlugin)('ganttChart', GanttChart);
var _default = GanttChart;
exports.default = _default;
/***/ }),
/* 501 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(12);
__webpack_require__(40);
__webpack_require__(33);
__webpack_require__(51);
__webpack_require__(76);
exports.__esModule = true;
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var _console = __webpack_require__(55);
var _utils = __webpack_require__(172);
/**
* This class handles the date-related calculations for the GanttChart plugin.
*
* @plugin GanttChart
*/
var DateCalculator =
/*#__PURE__*/
function () {
function DateCalculator(_ref) {
var year = _ref.year,
_ref$allowSplitWeeks = _ref.allowSplitWeeks,
allowSplitWeeks = _ref$allowSplitWeeks === void 0 ? true : _ref$allowSplitWeeks,
_ref$hideDaysBeforeFu = _ref.hideDaysBeforeFullWeeks,
hideDaysBeforeFullWeeks = _ref$hideDaysBeforeFu === void 0 ? false : _ref$hideDaysBeforeFu,
_ref$hideDaysAfterFul = _ref.hideDaysAfterFullWeeks,
hideDaysAfterFullWeeks = _ref$hideDaysAfterFul === void 0 ? false : _ref$hideDaysAfterFul;
(0, _classCallCheck2.default)(this, DateCalculator);
/**
* Year to base calculations on.
*
* @type {Number}
*/
this.year = year;
/**
* First day of the week.
*
* @type {String}
*/
this.firstWeekDay = 'monday';
/**
* The current `allowSplitWeeks` option state.
*/
this.allowSplitWeeks = allowSplitWeeks;
/**
* The current `hideDaysBeforeFullWeeks` option state.
*/
this.hideDaysBeforeFullWeeks = hideDaysBeforeFullWeeks;
/**
* The current `hideDaysAfterFullWeeks` option state.
*/
this.hideDaysAfterFullWeeks = hideDaysAfterFullWeeks;
/**
* Number of week sections (full weeks + incomplete week blocks in months).
*
* @type {Number}
*/
this.weekSectionCount = 0;
/**
* Cache of lists of months and their week/day related information.
* It's categorized by year, so month information for a certain year is stored under `this.monthListCache[year]`.
*
* @type {Object}
*/
this.monthListCache = {};
/**
* Object containing references to the year days and their corresponding columns.
*
* @type {Object}
*/
this.daysInColumns = {};
this.calculateWeekStructure();
}
/**
* Set the year as a base for calculations.
*
* @param {Number} year
*/
(0, _createClass2.default)(DateCalculator, [{
key: "setYear",
value: function setYear(year) {
this.year = year;
this.monthListCache[year] = this.calculateMonthData(year);
this.calculateWeekStructure(year);
}
/**
* Set the first week day.
*
* @param {String} day Day of the week. Available options: 'monday' or 'sunday'.
*/
}, {
key: "setFirstWeekDay",
value: function setFirstWeekDay(day) {
var lowercaseDay = day.toLowerCase();
if (lowercaseDay !== 'monday' && lowercaseDay !== 'sunday') {
(0, _console.warn)('First day of the week must be set to either Monday or Sunday');
}
this.firstWeekDay = lowercaseDay;
this.calculateWeekStructure();
}
/**
* Count week sections (full weeks + incomplete weeks in the months).
*
* @returns {Number} Week section count.
*/
}, {
key: "countWeekSections",
value: function countWeekSections() {
return this.weekSectionCount;
}
/**
* Get the first week day.
*
* @returns {String}
*/
}, {
key: "getFirstWeekDay",
value: function getFirstWeekDay() {
return this.firstWeekDay;
}
/**
* Get the currently applied year.
*
* @returns {Number}
*/
}, {
key: "getYear",
value: function getYear() {
return this.year;
}
/**
* Get month list along with the month information.
*
* @param {Number} [year] Year for the calculation.
* @returns {Array}
*/
}, {
key: "getMonthList",
value: function getMonthList() {
var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.year;
if (!this.monthListCache[year]) {
this.monthListCache[year] = this.calculateMonthData(year);
}
return this.monthListCache[year];
}
/**
* Get month lists for all years declared in the range bars.
*
* @returns {Object}
*/
}, {
key: "getFullMonthList",
value: function getFullMonthList() {
return this.monthListCache;
}
/**
* Convert a date to a column number.
*
* @param {String|Date} date
* @returns {Number|Boolean}
*/
}, {
key: "dateToColumn",
value: function dateToColumn(date) {
var convertedDate = (0, _utils.parseDate)(date);
if (!convertedDate) {
return false;
}
var month = convertedDate.getMonth();
var day = convertedDate.getDate() - 1;
var year = convertedDate.getFullYear();
return this.getWeekColumn(day, month, year);
}
/**
* Get the column index for the provided day and month indexes.
*
* @private
* @param {Number} dayIndex The index of the day.
* @param {Number} monthIndex The index of the month.
* @param {Number} [year] Year for the calculation.
* @returns {Number} Returns the column index.
*/
}, {
key: "getWeekColumn",
value: function getWeekColumn(dayIndex, monthIndex) {
var year = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getYear();
var resultColumn = null;
var monthCacheArray = this.getMonthCacheArray(monthIndex, year);
(0, _array.arrayEach)(monthCacheArray, function (monthCache) {
(0, _object.objectEach)(monthCache, function (column, index) {
if (column.indexOf(dayIndex + 1) > -1) {
resultColumn = parseInt(index, 10);
return false;
}
});
if (resultColumn) {
return false;
}
});
return resultColumn;
}
/**
* Get the cached day array for the provided month.
*
* @private
* @param {Number} monthIndex Index of the Month.
* @param {Number} [year] Year for the calculation.
* @returns {Array}
*/
}, {
key: "getMonthCacheArray",
value: function getMonthCacheArray(monthIndex) {
var _this = this;
var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
var monthList = this.getMonthList(year);
var resultArray = [];
if (this.allowSplitWeeks) {
resultArray.push(this.daysInColumns[year][monthIndex]);
} else {
var fullMonthCount = -1;
(0, _object.objectEach)(this.daysInColumns[year], function (month, i) {
var monthObject = monthList[i];
if (Object.keys(month).length > 1) {
fullMonthCount += 1;
}
if (fullMonthCount === monthIndex) {
if (monthObject.daysBeforeFullWeeks > 0) {
resultArray.push(_this.daysInColumns[year][parseInt(i, 10) - 1]);
}
resultArray.push(month);
if (monthObject.daysAfterFullWeeks > 0) {
resultArray.push(_this.daysInColumns[year][parseInt(i, 10) + 1]);
}
return false;
}
});
}
return resultArray;
}
/**
* Convert a column index to a certain date.
*
* @param {Number} column Column index.
* @param {Number} [year] Year to be used.
* @returns {Object} Object in a form of {start: startDate, end: endDate}
*/
}, {
key: "columnToDate",
value: function columnToDate(column) {
var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
var month = null;
(0, _object.objectEach)(this.daysInColumns[year], function (monthCache, index) {
if (monthCache[column]) {
month = index;
return false;
}
});
var monthSection = this.daysInColumns[year][month][column];
if (monthSection.length === 1) {
var resultingDate = new Date(year, month, monthSection[0]);
return {
start: resultingDate,
end: resultingDate
};
}
return {
start: new Date(year, month, monthSection[0]),
end: new Date(year, month, monthSection[monthSection.length - 1])
};
}
/**
* Check if the provided date is a starting or an ending day of a week.
*
* @private
* @param {Date|String} date
* @returns {Array|Boolean} Returns null, if an invalid date was provided or an array of results ( [1,0] => is on the beginning of the week, [0,1] => is on the end of the week).
*/
}, {
key: "isOnTheEdgeOfWeek",
value: function isOnTheEdgeOfWeek(date) {
var _this2 = this;
var convertedDate = (0, _utils.parseDate)(date);
if (!convertedDate) {
return null;
}
var month = convertedDate.getMonth();
var day = convertedDate.getDate() - 1;
var year = convertedDate.getFullYear();
var monthCacheArray = this.getMonthCacheArray(month, year);
var isOnTheEdgeOfWeek = false;
(0, _array.arrayEach)(monthCacheArray, function (monthCache) {
(0, _object.objectEach)(monthCache, function (column) {
if (!_this2.allowSplitWeeks && column.length !== 7) {
if (day === 0 || day === new Date(convertedDate.getYear(), convertedDate.getMonth() + 1, 0).getDate() - 1) {
return true;
}
}
var indexOfDay = column.indexOf(day + 1);
if (indexOfDay === 0) {
isOnTheEdgeOfWeek = [1, 0];
return false;
} else if (indexOfDay === column.length - 1) {
isOnTheEdgeOfWeek = [0, 1];
return false;
}
}); // break the iteration
if (isOnTheEdgeOfWeek) {
return false;
}
});
return isOnTheEdgeOfWeek;
}
/**
* Generate headers for the year structure.
*
* @private
* @param {String} type Granulation type ('months'/'weeks'/'days')
* @param {Function|null} weekHeaderGenerator Function generating the looks of the week headers.
* @param {Number} [year=this.year] The year for the calculation.
* @returns {Array} The header array
*/
}, {
key: "generateHeaderSet",
value: function generateHeaderSet(type, weekHeaderGenerator) {
var _this3 = this;
var year = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.year;
var monthList = this.getMonthList(year);
var headers = [];
(0, _object.objectEach)(monthList, function (month, index) {
var areDaysBeforeFullWeeks = month.daysBeforeFullWeeks > 0 ? 1 : 0;
var areDaysAfterFullWeeks = month.daysAfterFullWeeks > 0 ? 1 : 0;
var areDaysBeforeFullWeeksVisible = _this3.hideDaysBeforeFullWeeks ? 0 : areDaysBeforeFullWeeks;
var areDaysAfterFullWeeksVisible = _this3.hideDaysAfterFullWeeks ? 0 : areDaysAfterFullWeeks;
var headerCount = month.fullWeeks + (_this3.allowSplitWeeks ? areDaysBeforeFullWeeksVisible + areDaysAfterFullWeeksVisible : 0);
var monthNumber = parseInt(index, 10);
var headerLabel = '';
if (type === 'months') {
headers.push({
label: month.name,
colspan: headerCount
});
} else if (type === 'weeks') {
for (var i = 0; i < headerCount; i++) {
var start = null;
var end = null; // Mixed month's only column
if (!_this3.allowSplitWeeks && month.fullWeeks === 1) {
var _this3$getWeekColumnR = _this3.getWeekColumnRange({
monthObject: month,
monthNumber: monthNumber,
headerIndex: i,
headerCount: headerCount,
areDaysBeforeFullWeeksVisible: areDaysBeforeFullWeeksVisible,
areDaysAfterFullWeeksVisible: areDaysAfterFullWeeksVisible,
mixedMonth: true,
year: year
});
var _this3$getWeekColumnR2 = (0, _slicedToArray2.default)(_this3$getWeekColumnR, 2);
start = _this3$getWeekColumnR2[0];
end = _this3$getWeekColumnR2[1];
} else {
var _this3$getWeekColumnR3 = _this3.getWeekColumnRange({
monthObject: month,
monthNumber: monthNumber,
headerIndex: i,
areDaysBeforeFullWeeksVisible: areDaysBeforeFullWeeksVisible,
areDaysAfterFullWeeksVisible: areDaysAfterFullWeeksVisible,
headerCount: headerCount,
year: year
});
var _this3$getWeekColumnR4 = (0, _slicedToArray2.default)(_this3$getWeekColumnR3, 2);
start = _this3$getWeekColumnR4[0];
end = _this3$getWeekColumnR4[1];
}
if (start === end) {
headerLabel = "".concat(start);
} else {
headerLabel = "".concat(start, " - ").concat(end);
}
headers.push(weekHeaderGenerator ? weekHeaderGenerator.call(_this3, start, end) : headerLabel);
_this3.addDaysToCache(monthNumber, headers.length - 1, start, end, year);
}
}
});
return headers;
}
/**
* Get the week column range.
*
* @private
* @param {Object} options The options object.
* @param {Object} options.monthObject The month object.
* @param {Number} options.monthNumber Index of the month.
* @param {Number} options.headerIndex Index of the header.
* @param {Boolean} options.areDaysBeforeFullWeeksVisible `true` if the days before full weeks are to be visible.
* @param {Boolean} options.areDaysAfterFullWeeksVisible `true` if the days after full weeks are to be visible.
* @param {Number} options.headerCount Number of headers to be generated for the provided month.
* @param {Boolean} [options.mixedMonth=false] `true` if the header is the single header of a mixed month.
* @param {Number} [year] Year for the calculation.
* @returns {Array}
*/
}, {
key: "getWeekColumnRange",
value: function getWeekColumnRange(_ref2) {
var monthObject = _ref2.monthObject,
monthNumber = _ref2.monthNumber,
headerIndex = _ref2.headerIndex,
headerCount = _ref2.headerCount,
areDaysBeforeFullWeeksVisible = _ref2.areDaysBeforeFullWeeksVisible,
areDaysAfterFullWeeksVisible = _ref2.areDaysAfterFullWeeksVisible,
_ref2$mixedMonth = _ref2.mixedMonth,
mixedMonth = _ref2$mixedMonth === void 0 ? false : _ref2$mixedMonth,
_ref2$year = _ref2.year,
year = _ref2$year === void 0 ? this.year : _ref2$year;
var monthList = this.getMonthList(year);
var allowSplitWeeks = this.allowSplitWeeks;
var start = null;
var end = null;
if (mixedMonth) {
if (monthNumber === 0) {
end = monthList[monthNumber + 1].daysBeforeFullWeeks;
start = _utils.DEC_LENGTH - (_utils.WEEK_LENGTH - end) + 1;
} else if (monthNumber === monthList.length - 1) {
end = _utils.WEEK_LENGTH - monthList[monthNumber - 1].daysAfterFullWeeks;
start = monthList[monthNumber - 1].days - monthList[monthNumber - 1].daysAfterFullWeeks + 1;
} else {
end = monthList[monthNumber + 1].daysBeforeFullWeeks;
start = monthList[monthNumber - 1].days - (_utils.WEEK_LENGTH - end) + 1;
}
} else if (allowSplitWeeks && areDaysBeforeFullWeeksVisible && headerIndex === 0) {
start = headerIndex + 1;
end = monthObject.daysBeforeFullWeeks;
} else if (allowSplitWeeks && areDaysAfterFullWeeksVisible && headerIndex === headerCount - 1) {
start = monthObject.days - monthObject.daysAfterFullWeeks + 1;
end = monthObject.days;
} else {
start = null;
if (allowSplitWeeks) {
start = monthObject.daysBeforeFullWeeks + (headerIndex - areDaysBeforeFullWeeksVisible) * _utils.WEEK_LENGTH + 1;
} else {
start = monthObject.daysBeforeFullWeeks + headerIndex * _utils.WEEK_LENGTH + 1;
}
end = start + _utils.WEEK_LENGTH - 1;
}
return [start, end];
}
/**
* Add days to the column/day cache.
*
* @private
* @param {Number} monthNumber Index of the month.
* @param {Number} columnNumber Index of the column.
* @param {Number} start First day in the column.
* @param {Number} end Last day in the column.
* @param {Number} [year] Year to process.
*/
}, {
key: "addDaysToCache",
value: function addDaysToCache(monthNumber, columnNumber, start, end) {
var year = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.getYear();
if (!this.daysInColumns[year]) {
this.daysInColumns[year] = {};
}
if (!this.daysInColumns[year][monthNumber]) {
this.daysInColumns[year][monthNumber] = {};
}
if (!this.daysInColumns[year][monthNumber][columnNumber]) {
this.daysInColumns[year][monthNumber][columnNumber] = [];
}
if (start <= end) {
for (var dayIndex = start; dayIndex <= end; dayIndex++) {
this.daysInColumns[year][monthNumber][columnNumber].push(dayIndex);
}
} else {
var previousMonthDaysCount = monthNumber - 1 >= 0 ? this.countMonthDays(monthNumber) : 31;
for (var _dayIndex = start; _dayIndex <= previousMonthDaysCount; _dayIndex++) {
this.daysInColumns[year][monthNumber][columnNumber].push(_dayIndex);
}
for (var _dayIndex2 = 1; _dayIndex2 <= end; _dayIndex2++) {
this.daysInColumns[year][monthNumber][columnNumber].push(_dayIndex2);
}
}
}
/**
* Check if the provided dates can be used in a range bar.
*
* @param {Date|String} startDate Range start date.
* @param {Date|String} endDate Range end date.
* @returns {Boolean}
*/
}, {
key: "isValidRangeBarData",
value: function isValidRangeBarData(startDate, endDate) {
var startDateParsed = (0, _utils.parseDate)(startDate);
var endDateParsed = (0, _utils.parseDate)(endDate);
return startDateParsed && endDateParsed && startDateParsed.getTime() <= endDateParsed.getTime();
}
/**
* Calculate the month/day related information.
*
* @param {Number} [year] Year to be used.
* @returns {Array}
*/
}, {
key: "calculateMonthData",
value: function calculateMonthData() {
var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.year;
return [{
name: 'January',
days: 31
}, {
name: 'February',
days: new Date(year, 2, 0).getDate()
}, {
name: 'March',
days: 31
}, {
name: 'April',
days: 30
}, {
name: 'May',
days: 31
}, {
name: 'June',
days: 30
}, {
name: 'July',
days: 31
}, {
name: 'August',
days: 31
}, {
name: 'September',
days: 30
}, {
name: 'October',
days: 31
}, {
name: 'November',
days: 30
}, {
name: 'December',
days: 31
}].slice(0);
}
/**
* Count the number of months.
*
* @param {Number} [year] Year to be used.
* @returns {Number}
*/
}, {
key: "countMonths",
value: function countMonths() {
var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getYear();
return this.monthListCache[year].length;
}
/**
* Count days in a month.
*
* @param {Number} month Month index, where January = 1, February = 2, etc.
* @param {Number} [year] Year to be used.
* @returns {Number}
*/
}, {
key: "countMonthDays",
value: function countMonthDays(month) {
var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
return this.monthListCache[year][month - 1].days;
}
/**
* Count full weeks in a month.
*
* @param {Number} month Month index, where January = 1, February = 2, etc.
* @param {Number} [year] Year to be used.
* @returns {Number}
*/
}, {
key: "countMonthFullWeeks",
value: function countMonthFullWeeks(month) {
var year = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getYear();
return this.monthListCache[year][month - 1].fullWeeks;
}
/**
* Calculate week structure within defined months.
*
* @private
* @param {Number} [year] Year for the calculation.
*/
}, {
key: "calculateWeekStructure",
value: function calculateWeekStructure() {
var _this4 = this;
var year = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getYear();
this.monthListCache[year] = this.calculateMonthData(year);
var firstWeekDay = this.getFirstWeekDay();
var monthList = this.getMonthList(year);
var mixedMonthToAdd = [];
var daysBeforeFullWeeksRatio = this.hideDaysBeforeFullWeeks ? 0 : 1;
var daysAfterFullWeeksRatio = this.hideDaysAfterFullWeeks ? 0 : 1;
var weekOffset = 0;
var weekSectionCount = 0;
if (firstWeekDay === 'monday') {
weekOffset = 1;
}
(0, _array.arrayEach)(monthList, function (currentMonth, monthIndex) {
var firstMonthDay = new Date(year, monthIndex, 1).getDay();
var mixedMonthsAdded = 0;
currentMonth.daysBeforeFullWeeks = (7 - firstMonthDay + weekOffset) % 7;
if (!_this4.allowSplitWeeks && currentMonth.daysBeforeFullWeeks) {
mixedMonthToAdd.push((0, _utils.getMixedMonthObject)((0, _utils.getMixedMonthName)(monthIndex, monthList), monthIndex));
mixedMonthsAdded += 1;
}
currentMonth.fullWeeks = Math.floor((currentMonth.days - currentMonth.daysBeforeFullWeeks) / 7);
currentMonth.daysAfterFullWeeks = currentMonth.days - currentMonth.daysBeforeFullWeeks - 7 * currentMonth.fullWeeks;
if (!_this4.allowSplitWeeks) {
if (monthIndex === monthList.length - 1 && currentMonth.daysAfterFullWeeks) {
mixedMonthToAdd.push((0, _utils.getMixedMonthObject)((0, _utils.getMixedMonthName)(monthIndex, monthList), null));
mixedMonthsAdded += 1;
}
weekSectionCount += currentMonth.fullWeeks + mixedMonthsAdded;
} else {
var numberOfPartialWeeksBefore = daysBeforeFullWeeksRatio * (currentMonth.daysBeforeFullWeeks ? 1 : 0);
var numberOfPartialWeeksAfter = daysAfterFullWeeksRatio * (currentMonth.daysAfterFullWeeks ? 1 : 0);
weekSectionCount += currentMonth.fullWeeks + numberOfPartialWeeksBefore + numberOfPartialWeeksAfter;
}
});
(0, _array.arrayEach)(mixedMonthToAdd, function (monthObject, monthIndex) {
var index = monthObject.index;
delete monthObject.index;
_this4.addMixedMonth(index === null ? index : monthIndex + index, monthObject, year);
});
if (year === this.getYear()) {
this.weekSectionCount = weekSectionCount;
}
}
/**
* Add a mixed (e.g. 'Jan/Feb') month to the month list.
*
* @private
* @param {Number} index Index for the month.
* @param {Object} monthObject The month object.
* @param {Number} [year] Year for the calculation.
*/
}, {
key: "addMixedMonth",
value: function addMixedMonth(index, monthObject, year) {
if (index === null) {
this.monthListCache[year].push(monthObject);
} else {
this.monthListCache[year].splice(index, 0, monthObject);
}
}
}]);
return DateCalculator;
}();
var _default = DateCalculator;
exports.default = _default;
/***/ }),
/* 502 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(10);
__webpack_require__(36);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _object = __webpack_require__(4);
var _array = __webpack_require__(3);
var _number = __webpack_require__(15);
var _utils = __webpack_require__(172);
/**
* This class handles the data-related calculations for the GanttChart plugin.
*
* @plugin GanttChart
*/
var GanttChartDataFeed =
/*#__PURE__*/
function () {
function GanttChartDataFeed(chartInstance, data, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
(0, _classCallCheck2.default)(this, GanttChartDataFeed);
this.data = data;
this.chartInstance = chartInstance;
this.chartPlugin = this.chartInstance.getPlugin('ganttChart');
this.hotSource = null;
this.sourceHooks = {};
this.ongoingAsync = false;
this.applyData(data, startDateColumn, endDateColumn, additionalData, asyncUpdates || false);
}
/**
* Parse data accordingly to it's type (HOT instance / data object).
*
* @param {Object} data The source Handsontable instance or a data object.
* @param {Number} startDateColumn Index of the column containing the start dates.
* @param {Number} endDateColumn Index of the column containing the end dates.
* @param {Object} additionalData Object containing column and label information about additional data passed to the Gantt Plugin.
* @param {Boolean} asyncUpdates If set to true, the source instance updates will be applied asynchronously.
*/
(0, _createClass2.default)(GanttChartDataFeed, [{
key: "applyData",
value: function applyData(data, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
if (Object.prototype.toString.call(data) === '[object Array]') {
if (data.length > 1) {
this.chartInstance.alter('insert_row', 0, data.length - 1, "".concat(this.pluginName, ".loadData"));
}
this.loadData(data);
} else if (data instanceof this.chartInstance.constructor) {
var sourceRowCount = data.countRows();
if (sourceRowCount > 1) {
this.chartInstance.alter('insert_row', 0, sourceRowCount - 1, "".concat(this.pluginName, ".loadData"));
}
this.bindWithHotInstance(data, startDateColumn, endDateColumn, additionalData, asyncUpdates);
}
}
/**
* Make another Handsontable instance be a live feed for the gantt chart.
*
* @param {Object} instance The source Handsontable instance.
* @param {Number} startDateColumn Index of the column containing the start dates.
* @param {Number} endDateColumn Index of the column containing the end dates.
* @param {Object} additionalData Object containing column and label information about additional data passed to the
* Gantt Plugin. See the example for more details.
* @param {Boolean} asyncUpdates If set to true, the source instance updates will be applied asynchronously.
*
* @example
* ```js
* hot.getPlugin('ganttChart').bindWithHotInstance(sourceInstance, 4, 5, {
* vendor: 0, // data labeled 'vendor' is stored in the first sourceInstance column.
* format: 1, // data labeled 'format' is stored in the second sourceInstance column.
* market: 2 // data labeled 'market' is stored in the third sourceInstance column.
* });
* ```
*/
}, {
key: "bindWithHotInstance",
value: function bindWithHotInstance(instance, startDateColumn, endDateColumn, additionalData, asyncUpdates) {
this.hotSource = {
instance: instance,
startColumn: startDateColumn,
endColumn: endDateColumn,
additionalData: additionalData,
asyncUpdates: asyncUpdates
};
this.addSourceHotHooks();
this.asyncCall(this.updateFromSource);
}
/**
* Run the provided function asynchronously.
*
* @param {Function} func
*/
}, {
key: "asyncCall",
value: function asyncCall(func) {
var _this = this;
if (!this.hotSource.asyncUpdates) {
func.call(this);
return;
}
this.asyncStart();
setTimeout(function () {
func.call(_this);
_this.asyncEnd();
}, 0);
}
}, {
key: "asyncStart",
value: function asyncStart() {
this.ongoingAsync = true;
}
}, {
key: "asyncEnd",
value: function asyncEnd() {
this.ongoingAsync = false;
}
/**
* Add hooks to the source Handsontable instance.
*
* @private
*/
}, {
key: "addSourceHotHooks",
value: function addSourceHotHooks() {
var _this2 = this;
this.sourceHooks = {
afterLoadData: function afterLoadData() {
return _this2.onAfterSourceLoadData();
},
afterChange: function afterChange(changes) {
return _this2.onAfterSourceChange(changes);
},
afterColumnSort: function afterColumnSort() {
return _this2.onAfterColumnSort();
}
};
this.hotSource.instance.addHook('afterLoadData', this.sourceHooks.afterLoadData);
this.hotSource.instance.addHook('afterChange', this.sourceHooks.afterChange);
this.hotSource.instance.addHook('afterColumnSort', this.sourceHooks.afterColumnSort);
}
/**
* Remove hooks from the source Handsontable instance.
*
* @private
* @param {Object} hotSource The source Handsontable instance object.
*/
}, {
key: "removeSourceHotHooks",
value: function removeSourceHotHooks(hotSource) {
if (this.sourceHooks.afterLoadData) {
hotSource.instance.removeHook('afterLoadData', this.sourceHooks.afterLoadData);
}
if (this.sourceHooks.afterChange) {
hotSource.instance.removeHook('afterChange', this.sourceHooks.afterChange);
}
if (this.sourceHooks.afterColumnSort) {
hotSource.instance.removeHook('afterColumnSort', this.sourceHooks.afterColumnSort);
}
}
/**
* Get data from the source Handsontable instance.
*
* @param {Number} [row] Source Handsontable instance row.
* @returns {Array}
*/
}, {
key: "getDataFromSource",
value: function getDataFromSource(row) {
var additionalObjectData = {};
var hotSource = this.hotSource;
var sourceHotRows;
var rangeBarData = [];
if (row === void 0) {
sourceHotRows = hotSource.instance.getData(0, 0, hotSource.instance.countRows() - 1, hotSource.instance.countCols() - 1);
} else {
sourceHotRows = [];
sourceHotRows[row] = hotSource.instance.getDataAtRow(row);
}
var _loop = function _loop(i, dataLength) {
additionalObjectData = {};
var currentRow = sourceHotRows[i];
if (currentRow[hotSource.startColumn] === null || currentRow[hotSource.startColumn] === '') {
/* eslint-disable no-continue */
return "continue";
}
/* eslint-disable no-loop-func */
(0, _object.objectEach)(hotSource.additionalData, function (prop, j) {
additionalObjectData[j] = currentRow[prop];
});
rangeBarData.push([i, currentRow[hotSource.startColumn], currentRow[hotSource.endColumn], additionalObjectData, i]);
};
for (var i = row || 0, dataLength = sourceHotRows.length; i < (row ? row + 1 : dataLength); i++) {
var _ret = _loop(i, dataLength);
if (_ret === "continue") continue;
}
return rangeBarData;
}
/**
* Update the Gantt Chart-enabled Handsontable instance with the data from the source Handsontable instance.
*
* @param {Number} [row] Index of the row which needs updating.
*/
}, {
key: "updateFromSource",
value: function updateFromSource(row) {
var dataFromSource = this.getDataFromSource(row);
if (!row && isNaN(row)) {
this.chartPlugin.clearRangeBars();
this.chartPlugin.clearRangeList();
}
this.loadData(dataFromSource);
this.chartInstance.render();
}
/**
* Load chart data to the Handsontable instance.
*
* @param {Array} data Array of objects containing the range data.
*
* @example
* ```js
* [
* {
* additionalData: {vendor: 'Vendor One', format: 'Posters', market: 'New York, NY'},
* startDate: '1/5/2015',
* endDate: '1/20/2015'
* },
* {
* additionalData: {vendor: 'Vendor Two', format: 'Malls', market: 'Los Angeles, CA'},
* startDate: '1/11/2015',
* endDate: '1/29/2015'
* }
* ]
* ```
*/
}, {
key: "loadData",
value: function loadData(data) {
var _this3 = this;
var allBars = [];
(0, _array.arrayEach)(data, function (bar, i) {
bar.row = i;
var bars = _this3.splitRangeIfNeeded(bar);
allBars = allBars.concat(bars);
});
(0, _array.arrayEach)(allBars, function (bar) {
_this3.chartPlugin.addRangeBar(bar.row, (0, _utils.getStartDate)(bar), (0, _utils.getEndDate)(bar), (0, _utils.getAdditionalData)(bar));
delete bar.row;
});
}
/**
* Split the provided range into maximum-year-long chunks.
*
* @param {Object} bar The range bar object.
* @returns {Array} An array of slip chunks (or a single-element array, if no splicing occured)
*/
}, {
key: "splitRangeIfNeeded",
value: function splitRangeIfNeeded(bar) {
var splitBars = [];
var startDate = new Date((0, _utils.getStartDate)(bar));
var endDate = new Date((0, _utils.getEndDate)(bar));
if (typeof startDate === 'string' || typeof endDate === 'string') {
return false;
}
var startYear = startDate.getFullYear();
var endYear = endDate.getFullYear();
if (startYear === endYear) {
return [bar];
}
(0, _number.rangeEach)(startYear, endYear, function (year) {
var newBar = (0, _object.clone)(bar);
if (year !== startYear) {
(0, _utils.setStartDate)(newBar, "01/01/".concat(year));
}
if (year !== endYear) {
(0, _utils.setEndDate)(newBar, "12/31/".concat(year));
}
splitBars.push(newBar);
});
return splitBars;
}
/**
* afterChange hook callback for the source Handsontable instance.
*
* @private
* @param {Array} changes List of changes.
*/
}, {
key: "onAfterSourceChange",
value: function onAfterSourceChange(changes) {
var _this4 = this;
this.asyncCall(function () {
if (!changes) {
return;
}
var changesByRows = {};
for (var i = 0, changesLength = changes.length; i < changesLength; i++) {
var currentChange = changes[i];
var row = parseInt(currentChange[0], 10);
var col = parseInt(currentChange[1], 10);
if (!changesByRows[row]) {
changesByRows[row] = {};
}
changesByRows[row][col] = [currentChange[2], currentChange[3]];
}
(0, _object.objectEach)(changesByRows, function (prop, i) {
var row = parseInt(i, 10);
if (_this4.chartPlugin.getRangeBarCoordinates(row)) {
_this4.chartPlugin.removeRangeBarByColumn(row, _this4.chartPlugin.rangeList[row][1]);
}
_this4.updateFromSource(i);
});
});
}
/**
* afterLoadData hook callback for the source Handsontable instance.
*
* @private
*/
}, {
key: "onAfterSourceLoadData",
value: function onAfterSourceLoadData() {
var _this5 = this;
this.asyncCall(function () {
_this5.chartPlugin.removeAllRangeBars();
_this5.updateFromSource();
});
}
/**
* afterColumnSort hook callback for the source Handsontable instance.
*
* @private
*/
}, {
key: "onAfterColumnSort",
value: function onAfterColumnSort() {
var _this6 = this;
this.asyncCall(function () {
_this6.chartPlugin.removeAllRangeBars();
_this6.updateFromSource();
});
}
}]);
return GanttChartDataFeed;
}();
var _default = GanttChartDataFeed;
exports.default = _default;
/***/ }),
/* 503 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 504 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _plugins = __webpack_require__(20);
var _number = __webpack_require__(15);
var _base = _interopRequireDefault(__webpack_require__(21));
/**
* @plugin HeaderTooltips
*
* @description
* Allows to add a tooltip to the table headers.
*
* Available options:
* * the `rows` property defines if tooltips should be added to row headers,
* * the `columns` property defines if tooltips should be added to column headers,
* * the `onlyTrimmed` property defines if tooltips should be added only to headers, which content is trimmed by the header itself (the content being wider then the header).
*
* @example
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* date: getData(),
* // enable and configure header tooltips
* headerTooltips: {
* rows: true,
* columns: true,
* onlyTrimmed: false
* }
* });
* ```
*/
var HeaderTooltips =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(HeaderTooltips, _BasePlugin);
function HeaderTooltips(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, HeaderTooltips);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HeaderTooltips).call(this, hotInstance));
/**
* Cached plugin settings.
*
* @private
* @type {Boolean|Object}
*/
_this.settings = null;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link HeaderTooltips#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(HeaderTooltips, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().headerTooltips;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
this.settings = this.hot.getSettings().headerTooltips;
this.parseSettings();
this.addHook('afterGetColHeader', function (col, TH) {
return _this2.onAfterGetHeader(col, TH);
});
this.addHook('afterGetRowHeader', function (col, TH) {
return _this2.onAfterGetHeader(col, TH);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(HeaderTooltips.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.settings = null;
this.clearTitleAttributes();
(0, _get2.default)((0, _getPrototypeOf2.default)(HeaderTooltips.prototype), "disablePlugin", this).call(this);
}
/**
* Parses the plugin settings.
*
* @private
*/
}, {
key: "parseSettings",
value: function parseSettings() {
if (typeof this.settings === 'boolean') {
this.settings = {
rows: true,
columns: true,
onlyTrimmed: false
};
}
}
/**
* Clears the previously assigned title attributes.
*
* @private
*/
}, {
key: "clearTitleAttributes",
value: function clearTitleAttributes() {
var headerLevels = this.hot.view.wt.getSetting('columnHeaders').length;
var mainHeaders = this.hot.view.wt.wtTable.THEAD;
var topHeaders = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.THEAD;
var topLeftCornerOverlay = this.hot.view.wt.wtOverlays.topLeftCornerOverlay;
var topLeftCornerHeaders = topLeftCornerOverlay ? topLeftCornerOverlay.clone.wtTable.THEAD : null;
(0, _number.rangeEach)(0, headerLevels - 1, function (i) {
var masterLevel = mainHeaders.childNodes[i];
var topLevel = topHeaders.childNodes[i];
var topLeftCornerLevel = topLeftCornerHeaders ? topLeftCornerHeaders.childNodes[i] : null;
(0, _number.rangeEach)(0, masterLevel.childNodes.length - 1, function (j) {
masterLevel.childNodes[j].removeAttribute('title');
if (topLevel && topLevel.childNodes[j]) {
topLevel.childNodes[j].removeAttribute('title');
}
if (topLeftCornerHeaders && topLeftCornerLevel && topLeftCornerLevel.childNodes[j]) {
topLeftCornerLevel.childNodes[j].removeAttribute('title');
}
});
}, true);
}
/**
* Adds a tooltip to the headers.
*
* @private
* @param {Number} index
* @param {HTMLElement} TH
*/
}, {
key: "onAfterGetHeader",
value: function onAfterGetHeader(index, TH) {
var innerSpan = TH.querySelector('span');
var isColHeader = TH.parentNode.parentNode.nodeName === 'THEAD';
if (isColHeader && this.settings.columns || !isColHeader && this.settings.rows) {
if (this.settings.onlyTrimmed) {
if ((0, _element.outerWidth)(innerSpan) >= (0, _element.outerWidth)(TH) && (0, _element.outerWidth)(innerSpan) !== 0) {
TH.setAttribute('title', innerSpan.textContent);
}
} else {
TH.setAttribute('title', innerSpan.textContent);
}
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.settings = null;
(0, _get2.default)((0, _getPrototypeOf2.default)(HeaderTooltips.prototype), "destroy", this).call(this);
}
}]);
return HeaderTooltips;
}(_base.default);
(0, _plugins.registerPlugin)('headerTooltips', HeaderTooltips);
var _default = HeaderTooltips;
exports.default = _default;
/***/ }),
/* 505 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
exports.__esModule = true;
exports.default = void 0;
var _taggedTemplateLiteral2 = _interopRequireDefault(__webpack_require__(65));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _element = __webpack_require__(5);
var _number = __webpack_require__(15);
var _array = __webpack_require__(3);
var _object = __webpack_require__(4);
var _templateLiteralTag = __webpack_require__(67);
var _console = __webpack_require__(55);
var _plugins = __webpack_require__(20);
var _base = _interopRequireDefault(__webpack_require__(21));
var _src = __webpack_require__(25);
var _ghostTable = _interopRequireDefault(__webpack_require__(506));
__webpack_require__(507);
function _templateObject2() {
var data = (0, _taggedTemplateLiteral2.default)(["Your Nested Headers plugin setup contains overlapping headers. This kind of configuration\n is currently not supported and might result in glitches."]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = (0, _taggedTemplateLiteral2.default)(["You have declared a Nested Header overlapping the Fixed Columns section - it may lead to visual\n glitches. To prevent that kind of problems, split the nested headers between the fixed and non-fixed columns."]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
/**
* @plugin NestedHeaders
* @description
* The plugin allows to create a nested header structure, using the HTML's colspan attribute.
*
* To make any header wider (covering multiple table columns), it's corresponding configuration array element should be
* provided as an object with `label` and `colspan` properties. The `label` property defines the header's label,
* while the `colspan` property defines a number of columns that the header should cover.
*
* __Note__ that the plugin supports a *nested* structure, which means, any header cannot be wider than it's "parent". In
* other words, headers cannot overlap each other.
* @example
*
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* date: getData(),
* nestedHeaders: [
* ['A', {label: 'B', colspan: 8}, 'C'],
* ['D', {label: 'E', colspan: 4}, {label: 'F', colspan: 4}, 'G'],
* ['H', {label: 'I', colspan: 2}, {label: 'J', colspan: 2}, {label: 'K', colspan: 2}, {label: 'L', colspan: 2}, 'M'],
* ['N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W']
* ],
* ```
*/
var NestedHeaders =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(NestedHeaders, _BasePlugin);
function NestedHeaders(hotInstance) {
var _this2;
(0, _classCallCheck2.default)(this, NestedHeaders);
_this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(NestedHeaders).call(this, hotInstance));
/**
* Nasted headers cached settings.
*
* @private
* @type {Object}
*/
_this2.settings = [];
/**
* Cached number of column header levels.
*
* @private
* @type {Number}
*/
_this2.columnHeaderLevelCount = 0;
/**
* Array of nested headers' colspans.
*
* @private
* @type {Array}
*/
_this2.colspanArray = [];
/**
* Custom helper for getting widths of the nested headers.
* @TODO This should be changed after refactor handsontable/utils/ghostTable.
*
* @private
* @type {GhostTable}
*/
_this2.ghostTable = new _ghostTable.default((0, _assertThisInitialized2.default)(_this2));
return _this2;
}
/**
* Check if plugin is enabled
*
* @returns {Boolean}
*/
(0, _createClass2.default)(NestedHeaders, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().nestedHeaders;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this3 = this;
if (this.enabled) {
return;
}
this.settings = this.hot.getSettings().nestedHeaders;
this.addHook('afterGetColumnHeaderRenderers', function (array) {
return _this3.onAfterGetColumnHeaderRenderers(array);
});
this.addHook('afterInit', function () {
return _this3.onAfterInit();
});
this.addHook('afterOnCellMouseDown', function (event, coords) {
return _this3.onAfterOnCellMouseDown(event, coords);
});
this.addHook('beforeOnCellMouseOver', function (event, coords, TD, blockCalculations) {
return _this3.onBeforeOnCellMouseOver(event, coords, TD, blockCalculations);
});
this.addHook('afterViewportColumnCalculatorOverride', function (calc) {
return _this3.onAfterViewportColumnCalculatorOverride(calc);
});
this.addHook('modifyColWidth', function (width, column) {
return _this3.onModifyColWidth(width, column);
});
this.setupColspanArray();
this.checkForFixedColumnsCollision();
this.columnHeaderLevelCount = this.hot.view ? this.hot.view.wt.getSetting('columnHeaders').length : 0;
(0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.clearColspans();
this.settings = [];
this.columnHeaderLevelCount = 0;
this.colspanArray = [];
this.ghostTable.clear();
(0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "disablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "updatePlugin", this).call(this);
this.ghostTable.buildWidthsMapper();
}
/**
* Clear the colspans remaining after plugin usage.
*
* @private
*/
}, {
key: "clearColspans",
value: function clearColspans() {
if (!this.hot.view) {
return;
}
var headerLevels = this.hot.view.wt.getSetting('columnHeaders').length;
var mainHeaders = this.hot.view.wt.wtTable.THEAD;
var topHeaders = this.hot.view.wt.wtOverlays.topOverlay.clone.wtTable.THEAD;
var topLeftCornerHeaders = this.hot.view.wt.wtOverlays.topLeftCornerOverlay ? this.hot.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.THEAD : null;
for (var i = 0; i < headerLevels; i++) {
var masterLevel = mainHeaders.childNodes[i];
if (!masterLevel) {
break;
}
var topLevel = topHeaders.childNodes[i];
var topLeftCornerLevel = topLeftCornerHeaders ? topLeftCornerHeaders.childNodes[i] : null;
for (var j = 0, masterNodes = masterLevel.childNodes.length; j < masterNodes; j++) {
masterLevel.childNodes[j].removeAttribute('colspan');
if (topLevel && topLevel.childNodes[j]) {
topLevel.childNodes[j].removeAttribute('colspan');
}
if (topLeftCornerHeaders && topLeftCornerLevel && topLeftCornerLevel.childNodes[j]) {
topLeftCornerLevel.childNodes[j].removeAttribute('colspan');
}
}
}
}
/**
* Check if the nested headers overlap the fixed columns overlay, if so - display a warning.
*
* @private
*/
}, {
key: "checkForFixedColumnsCollision",
value: function checkForFixedColumnsCollision() {
var _this4 = this;
var fixedColumnsLeft = this.hot.getSettings().fixedColumnsLeft;
(0, _array.arrayEach)(this.colspanArray, function (value, i) {
if (_this4.getNestedParent(i, fixedColumnsLeft) !== fixedColumnsLeft) {
(0, _console.warn)((0, _templateLiteralTag.toSingleLine)(_templateObject()));
}
});
}
/**
* Check if the configuration contains overlapping headers.
*
* @private
*/
}, {
key: "checkForOverlappingHeaders",
value: function checkForOverlappingHeaders() {
var _this5 = this;
(0, _array.arrayEach)(this.colspanArray, function (level, i) {
(0, _array.arrayEach)(_this5.colspanArray[i], function (header, j) {
if (header.colspan > 1) {
var row = _this5.levelToRowCoords(i);
var childHeaders = _this5.getChildHeaders(row, j);
if (childHeaders.length > 0) {
var childColspanSum = 0;
(0, _array.arrayEach)(childHeaders, function (col) {
childColspanSum += _this5.getColspan(row + 1, col);
});
if (childColspanSum > header.colspan) {
(0, _console.warn)((0, _templateLiteralTag.toSingleLine)(_templateObject2()));
}
return false;
}
}
});
});
}
/**
* Create an internal array containing information of the headers with a colspan attribute.
*
* @private
*/
}, {
key: "setupColspanArray",
value: function setupColspanArray() {
var _this6 = this;
function checkIfExists(array, index) {
if (!array[index]) {
array[index] = [];
}
}
(0, _object.objectEach)(this.settings, function (levelValues, level) {
(0, _object.objectEach)(levelValues, function (val, col, levelValue) {
checkIfExists(_this6.colspanArray, level);
if (levelValue[col].colspan === void 0) {
_this6.colspanArray[level].push({
label: levelValue[col] || '',
colspan: 1,
hidden: false
});
} else {
var colspan = levelValue[col].colspan || 1;
_this6.colspanArray[level].push({
label: levelValue[col].label || '',
colspan: colspan,
hidden: false
});
_this6.fillColspanArrayWithDummies(colspan, level);
}
});
});
}
/**
* Fill the "colspan array" with default data for the dummy hidden headers.
*
* @private
* @param {Number} colspan The colspan value.
* @param {Number} level Header level.
*/
}, {
key: "fillColspanArrayWithDummies",
value: function fillColspanArrayWithDummies(colspan, level) {
var _this7 = this;
(0, _number.rangeEach)(0, colspan - 2, function () {
_this7.colspanArray[level].push({
label: '',
colspan: 1,
hidden: true
});
});
}
/**
* Generates the appropriate header renderer for a header row.
*
* @private
* @param {Number} headerRow The header row.
* @returns {Function}
*
* @fires Hooks#afterGetColHeader
*/
}, {
key: "headerRendererFactory",
value: function headerRendererFactory(headerRow) {
var _this = this;
return function (index, TH) {
var rootDocument = _this.hot.rootDocument;
TH.removeAttribute('colspan');
(0, _element.removeClass)(TH, 'hiddenHeader'); // header row is the index of header row counting from the top (=> positive values)
if (_this.colspanArray[headerRow][index] && _this.colspanArray[headerRow][index].colspan) {
var colspan = _this.colspanArray[headerRow][index].colspan;
var fixedColumnsLeft = _this.hot.getSettings().fixedColumnsLeft || 0;
var _this$hot$view$wt$wtO = _this.hot.view.wt.wtOverlays,
leftOverlay = _this$hot$view$wt$wtO.leftOverlay,
topLeftCornerOverlay = _this$hot$view$wt$wtO.topLeftCornerOverlay;
var isInTopLeftCornerOverlay = topLeftCornerOverlay ? topLeftCornerOverlay.clone.wtTable.THEAD.contains(TH) : false;
var isInLeftOverlay = leftOverlay ? leftOverlay.clone.wtTable.THEAD.contains(TH) : false;
if (colspan > 1) {
TH.setAttribute('colspan', isInTopLeftCornerOverlay || isInLeftOverlay ? Math.min(colspan, fixedColumnsLeft - index) : colspan);
}
if (isInTopLeftCornerOverlay || isInLeftOverlay && index === fixedColumnsLeft - 1) {
(0, _element.addClass)(TH, 'overlayEdge');
}
}
if (_this.colspanArray[headerRow][index] && _this.colspanArray[headerRow][index].hidden) {
(0, _element.addClass)(TH, 'hiddenHeader');
}
(0, _element.empty)(TH);
var divEl = rootDocument.createElement('DIV');
(0, _element.addClass)(divEl, 'relative');
var spanEl = rootDocument.createElement('SPAN');
(0, _element.addClass)(spanEl, 'colHeader');
(0, _element.fastInnerHTML)(spanEl, _this.colspanArray[headerRow][index] ? _this.colspanArray[headerRow][index].label || '' : '');
divEl.appendChild(spanEl);
TH.appendChild(divEl);
_this.hot.runHooks('afterGetColHeader', index, TH);
};
}
/**
* Returns the colspan for the provided coordinates.
*
* @private
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {Number}
*/
}, {
key: "getColspan",
value: function getColspan(row, column) {
var header = this.colspanArray[this.rowCoordsToLevel(row)][column];
return header ? header.colspan : 1;
}
/**
* Translates the level value (header row index from the top) to the row value (negative index).
*
* @private
* @param {Number} level Header level.
* @returns {Number}
*/
}, {
key: "levelToRowCoords",
value: function levelToRowCoords(level) {
return level - this.columnHeaderLevelCount;
}
/**
* Translates the row value (negative index) to the level value (header row index from the top).
*
* @private
* @param {Number} row Row index.
* @returns {Number}
*/
}, {
key: "rowCoordsToLevel",
value: function rowCoordsToLevel(row) {
return row + this.columnHeaderLevelCount;
}
/**
* Returns the column index of the "parent" nested header.
*
* @private
* @param {Number} level Header level.
* @param {Number} column Column index.
* @returns {*}
*/
}, {
key: "getNestedParent",
value: function getNestedParent(level, column) {
if (level < 0) {
return false;
}
var colspan = this.colspanArray[level][column] ? this.colspanArray[level][column].colspan : 1;
var hidden = this.colspanArray[level][column] ? this.colspanArray[level][column].hidden : false;
if (colspan > 1 || colspan === 1 && hidden === false) {
return column;
}
var parentCol = column - 1;
do {
if (this.colspanArray[level][parentCol].colspan > 1) {
break;
}
parentCol -= 1;
} while (column >= 0);
return parentCol;
}
/**
* Returns (physical) indexes of headers below the header with provided coordinates.
*
* @private
* @param {Number} row Row index.
* @param {Number} column Column index.
* @returns {Number[]}
*/
}, {
key: "getChildHeaders",
value: function getChildHeaders(row, column) {
var level = this.rowCoordsToLevel(row);
var childColspanLevel = this.colspanArray[level + 1];
var nestedParentCol = this.getNestedParent(level, column);
var colspan = this.colspanArray[level][column].colspan;
var childHeaderRange = [];
if (!childColspanLevel) {
return childHeaderRange;
}
(0, _number.rangeEach)(nestedParentCol, nestedParentCol + colspan - 1, function (i) {
if (childColspanLevel[i] && childColspanLevel[i].colspan > 1) {
colspan -= childColspanLevel[i].colspan - 1;
}
if (childColspanLevel[i] && !childColspanLevel[i].hidden && childHeaderRange.indexOf(i) === -1) {
childHeaderRange.push(i);
}
});
return childHeaderRange;
}
/**
* Fill the remaining colspanArray entries for the undeclared column headers.
*
* @private
*/
}, {
key: "fillTheRemainingColspans",
value: function fillTheRemainingColspans() {
var _this8 = this;
(0, _object.objectEach)(this.settings, function (levelValue, level) {
(0, _number.rangeEach)(_this8.colspanArray[level].length - 1, _this8.hot.countCols() - 1, function (col) {
_this8.colspanArray[level].push({
label: levelValue[col] || '',
colspan: 1,
hidden: false
});
}, true);
});
}
/**
* Updates headers highlight in nested structure.
*
* @private
*/
}, {
key: "updateHeadersHighlight",
value: function updateHeadersHighlight() {
var _this9 = this;
var selection = this.hot.getSelectedLast();
if (selection === void 0) {
return;
}
var wtOverlays = this.hot.view.wt.wtOverlays;
var selectionByHeader = this.hot.selection.isSelectedByColumnHeader();
var from = Math.min(selection[1], selection[3]);
var to = Math.max(selection[1], selection[3]);
var levelLimit = selectionByHeader ? -1 : this.columnHeaderLevelCount - 1;
var changes = [];
var classNameModifier = function classNameModifier(className) {
return function (TH, modifier) {
return function () {
return modifier(TH, className);
};
};
};
var highlightHeader = classNameModifier('ht__highlight');
var activeHeader = classNameModifier('ht__active_highlight');
(0, _number.rangeEach)(from, to, function (column) {
var _loop = function _loop(level) {
var visibleColumnIndex = _this9.getNestedParent(level, column);
var topTH = wtOverlays.topOverlay ? wtOverlays.topOverlay.clone.wtTable.getColumnHeader(visibleColumnIndex, level) : void 0;
var topLeftTH = wtOverlays.topLeftCornerOverlay ? wtOverlays.topLeftCornerOverlay.clone.wtTable.getColumnHeader(visibleColumnIndex, level) : void 0;
var listTH = [topTH, topLeftTH];
var colspanLen = _this9.getColspan(level - _this9.columnHeaderLevelCount, visibleColumnIndex);
var isInSelection = visibleColumnIndex >= from && visibleColumnIndex + colspanLen - 1 <= to;
(0, _array.arrayEach)(listTH, function (TH) {
if (TH === void 0) {
return false;
}
if (!selectionByHeader && level < levelLimit || selectionByHeader && !isInSelection) {
changes.push(highlightHeader(TH, _element.removeClass));
if (selectionByHeader) {
changes.push(activeHeader(TH, _element.removeClass));
}
} else {
changes.push(highlightHeader(TH, _element.addClass));
if (selectionByHeader) {
changes.push(activeHeader(TH, _element.addClass));
}
}
});
};
for (var level = _this9.columnHeaderLevelCount - 1; level > -1; level--) {
_loop(level);
}
});
(0, _array.arrayEach)(changes, function (fn) {
return void fn();
});
changes.length = 0;
}
/**
* Make the renderer render the first nested column in its entirety.
*
* @private
* @param {Object} calc Viewport column calculator.
*/
}, {
key: "onAfterViewportColumnCalculatorOverride",
value: function onAfterViewportColumnCalculatorOverride(calc) {
var _this10 = this;
var newStartColumn = calc.startColumn;
(0, _number.rangeEach)(0, Math.max(this.columnHeaderLevelCount - 1, 0), function (l) {
var startColumnNestedParent = _this10.getNestedParent(l, calc.startColumn);
if (startColumnNestedParent < calc.startColumn) {
newStartColumn = Math.min(newStartColumn, startColumnNestedParent);
}
});
calc.startColumn = newStartColumn;
}
/**
* Select all nested headers of clicked cell.
*
* @private
* @param {MouseEvent} event Mouse event.
* @param {Object} coords Clicked cell coords.
*/
}, {
key: "onAfterOnCellMouseDown",
value: function onAfterOnCellMouseDown(event, coords) {
if (coords.row < 0) {
var colspan = this.getColspan(coords.row, coords.col);
var lastColIndex = coords.col + colspan - 1;
if (colspan > 1) {
var lastRowIndex = this.hot.countRows() - 1;
this.hot.selection.setRangeEnd(new _src.CellCoords(lastRowIndex, lastColIndex));
}
}
}
/**
* Make the header-selection properly select the nested headers.
*
* @private
* @param {MouseEvent} event Mouse event.
* @param {Object} coords Clicked cell coords.
* @param {HTMLElement} TD
*/
}, {
key: "onBeforeOnCellMouseOver",
value: function onBeforeOnCellMouseOver(event, coords, TD, blockCalculations) {
if (coords.row >= 0 || coords.col < 0 || !this.hot.view.isMouseDown()) {
return;
}
var _this$hot$getSelected = this.hot.getSelectedRangeLast(),
from = _this$hot$getSelected.from,
to = _this$hot$getSelected.to;
var colspan = this.getColspan(coords.row, coords.col);
var lastColIndex = coords.col + colspan - 1;
var changeDirection = false;
if (from.col <= to.col) {
if (coords.col < from.col && lastColIndex === to.col || coords.col < from.col && lastColIndex < from.col || coords.col < from.col && lastColIndex >= from.col && lastColIndex < to.col) {
changeDirection = true;
}
} else if (coords.col < to.col && lastColIndex > from.col || coords.col > from.col || coords.col <= to.col && lastColIndex > from.col || coords.col > to.col && lastColIndex > from.col) {
changeDirection = true;
}
if (changeDirection) {
var _ref = [to.col, from.col];
from.col = _ref[0];
to.col = _ref[1];
}
if (colspan > 1) {
var _this$hot;
blockCalculations.column = true;
blockCalculations.cell = true;
var columnRange = [];
if (from.col === to.col) {
if (lastColIndex <= from.col && coords.col < from.col) {
columnRange.push(to.col, coords.col);
} else {
columnRange.push(coords.col < from.col ? coords.col : from.col, lastColIndex > to.col ? lastColIndex : to.col);
}
}
if (from.col < to.col) {
columnRange.push(coords.col < from.col ? coords.col : from.col, lastColIndex);
}
if (from.col > to.col) {
columnRange.push(from.col, coords.col);
}
(_this$hot = this.hot).selectColumns.apply(_this$hot, columnRange);
}
}
/**
* Cache column header count.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
this.columnHeaderLevelCount = this.hot.view.wt.getSetting('columnHeaders').length;
this.fillTheRemainingColspans();
this.checkForOverlappingHeaders();
this.ghostTable.buildWidthsMapper();
}
/**
* `afterGetColumnHeader` hook callback - prepares the header structure.
*
* @private
* @param {Array} renderersArray Array of renderers.
*/
}, {
key: "onAfterGetColumnHeaderRenderers",
value: function onAfterGetColumnHeaderRenderers(renderersArray) {
if (renderersArray) {
renderersArray.length = 0;
for (var headersCount = this.colspanArray.length, i = headersCount - 1; i >= 0; i--) {
renderersArray.push(this.headerRendererFactory(i));
}
renderersArray.reverse();
}
this.updateHeadersHighlight();
}
/**
* `modifyColWidth` hook callback - returns width from cache, when is greater than incoming from hook.
*
* @private
* @param width Width from hook.
* @param column Visual index of an column.
* @returns {Number}
*/
}, {
key: "onModifyColWidth",
value: function onModifyColWidth(width, column) {
var cachedWidth = this.ghostTable.widthsCache[column];
return width > cachedWidth ? width : cachedWidth;
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.settings = null;
this.columnHeaderLevelCount = null;
this.colspanArray = null;
(0, _get2.default)((0, _getPrototypeOf2.default)(NestedHeaders.prototype), "destroy", this).call(this);
}
}]);
return NestedHeaders;
}(_base.default);
(0, _plugins.registerPlugin)('nestedHeaders', NestedHeaders);
var _default = NestedHeaders;
exports.default = _default;
/***/ }),
/* 506 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _element = __webpack_require__(5);
var _object = __webpack_require__(4);
var GhostTable =
/*#__PURE__*/
function () {
function GhostTable(plugin) {
(0, _classCallCheck2.default)(this, GhostTable);
/**
* Reference to NestedHeaders plugin.
*
* @type {NestedHeaders}
*/
this.nestedHeaders = plugin;
/**
* Temporary element created to get minimal headers widths.
*
* @type {*}
*/
this.container = void 0;
/**
* Cached the headers widths.
*
* @type {Array}
*/
this.widthsCache = [];
}
/**
* Build cache of the headers widths.
*
* @private
*/
(0, _createClass2.default)(GhostTable, [{
key: "buildWidthsMapper",
value: function buildWidthsMapper() {
this.container = this.nestedHeaders.hot.rootDocument.createElement('div');
this.buildGhostTable(this.container);
this.nestedHeaders.hot.rootElement.appendChild(this.container);
var columns = this.container.querySelectorAll('tr:last-of-type th');
var maxColumns = columns.length;
for (var i = 0; i < maxColumns; i++) {
this.widthsCache.push(columns[i].offsetWidth);
}
this.container.parentNode.removeChild(this.container);
this.container = null;
this.nestedHeaders.hot.render();
}
/**
* Build temporary table for getting minimal columns widths.
*
* @private
* @param {HTMLElement} container
*/
}, {
key: "buildGhostTable",
value: function buildGhostTable(container) {
var rootDocument = this.nestedHeaders.hot.rootDocument;
var fragment = rootDocument.createDocumentFragment();
var table = rootDocument.createElement('table');
var lastRowColspan = false;
var isDropdownEnabled = !!this.nestedHeaders.hot.getSettings().dropdownMenu;
var maxRows = this.nestedHeaders.colspanArray.length;
var maxCols = this.nestedHeaders.hot.countCols();
var lastRowIndex = maxRows - 1;
for (var row = 0; row < maxRows; row++) {
var tr = rootDocument.createElement('tr');
lastRowColspan = false;
for (var col = 0; col < maxCols; col++) {
var td = rootDocument.createElement('th');
var headerObj = (0, _object.clone)(this.nestedHeaders.colspanArray[row][col]);
if (headerObj && !headerObj.hidden) {
if (row === lastRowIndex) {
if (headerObj.colspan > 1) {
lastRowColspan = true;
}
if (isDropdownEnabled) {
headerObj.label += '';
}
}
(0, _element.fastInnerHTML)(td, headerObj.label);
td.colSpan = headerObj.colspan;
tr.appendChild(td);
}
}
table.appendChild(tr);
} // We have to be sure the last row contains only the single columns.
if (lastRowColspan) {
{
var _tr = rootDocument.createElement('tr');
for (var _col = 0; _col < maxCols; _col++) {
var _td = rootDocument.createElement('th');
_tr.appendChild(_td);
}
table.appendChild(_tr);
}
}
fragment.appendChild(table);
container.appendChild(fragment);
}
/**
* Clear the widths cache.
*/
}, {
key: "clear",
value: function clear() {
this.container = null;
this.widthsCache.length = 0;
}
}]);
return GhostTable;
}();
var _default = GhostTable;
exports.default = _default;
/***/ }),
/* 507 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 508 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
__webpack_require__(30);
exports.__esModule = true;
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(__webpack_require__(38));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _plugins = __webpack_require__(20);
var _number = __webpack_require__(15);
var _array = __webpack_require__(3);
var _src = __webpack_require__(25);
var _dataManager = _interopRequireDefault(__webpack_require__(509));
var _collapsing = _interopRequireDefault(__webpack_require__(510));
var _headers = _interopRequireDefault(__webpack_require__(256));
var _contextMenu = _interopRequireDefault(__webpack_require__(511));
__webpack_require__(512);
var privatePool = new WeakMap();
/**
* @plugin NestedRows
* @experimental
*
* @description
* Plugin responsible for displaying and operating on data sources with nested structures.
*
* @dependencies TrimRows BindRowsWithHeaders
*/
var NestedRows =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(NestedRows, _BasePlugin);
function NestedRows(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, NestedRows);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(NestedRows).call(this, hotInstance));
/**
* Source data object.
*
* @private
* @type {Object}
*/
_this.sourceData = null;
/**
* Reference to the Trim Rows plugin.
*
* @private
* @type {Object}
*/
_this.trimRowsPlugin = null;
/**
* Reference to the BindRowsWithHeaders plugin.
*
* @private
* @type {Object}
*/
_this.bindRowsWithHeadersPlugin = null;
/**
* Reference to the DataManager instance.
*
* @private
* @type {Object}
*/
_this.dataManager = null;
/**
* Reference to the HeadersUI instance.
*
* @private
* @type {Object}
*/
_this.headersUI = null;
privatePool.set((0, _assertThisInitialized2.default)(_this), {
changeSelection: false,
movedToFirstChild: false,
movedToCollapsed: false,
skipRender: null
});
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link NestedRows#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(NestedRows, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().nestedRows;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
this.sourceData = this.hot.getSourceData();
this.trimRowsPlugin = this.hot.getPlugin('trimRows');
this.manualRowMovePlugin = this.hot.getPlugin('manualRowMove');
this.bindRowsWithHeadersPlugin = this.hot.getPlugin('bindRowsWithHeaders');
this.dataManager = new _dataManager.default(this, this.hot, this.sourceData);
this.collapsingUI = new _collapsing.default(this, this.hot, this.trimRowsPlugin);
this.headersUI = new _headers.default(this, this.hot);
this.contextMenuUI = new _contextMenu.default(this, this.hot);
this.dataManager.rewriteCache();
this.addHook('afterInit', function () {
return _this2.onAfterInit.apply(_this2, arguments);
});
this.addHook('beforeRender', function () {
return _this2.onBeforeRender.apply(_this2, arguments);
});
this.addHook('modifyRowData', function () {
return _this2.onModifyRowData.apply(_this2, arguments);
});
this.addHook('modifySourceLength', function () {
return _this2.onModifySourceLength.apply(_this2, arguments);
});
this.addHook('beforeDataSplice', function () {
return _this2.onBeforeDataSplice.apply(_this2, arguments);
});
this.addHook('beforeDataFilter', function () {
return _this2.onBeforeDataFilter.apply(_this2, arguments);
});
this.addHook('afterContextMenuDefaultOptions', function () {
return _this2.onAfterContextMenuDefaultOptions.apply(_this2, arguments);
});
this.addHook('afterGetRowHeader', function () {
return _this2.onAfterGetRowHeader.apply(_this2, arguments);
});
this.addHook('beforeOnCellMouseDown', function () {
return _this2.onBeforeOnCellMouseDown.apply(_this2, arguments);
});
this.addHook('afterRemoveRow', function () {
return _this2.onAfterRemoveRow.apply(_this2, arguments);
});
this.addHook('modifyRemovedAmount', function () {
return _this2.onModifyRemovedAmount.apply(_this2, arguments);
});
this.addHook('beforeAddChild', function () {
return _this2.onBeforeAddChild.apply(_this2, arguments);
});
this.addHook('afterAddChild', function () {
return _this2.onAfterAddChild.apply(_this2, arguments);
});
this.addHook('beforeDetachChild', function () {
return _this2.onBeforeDetachChild.apply(_this2, arguments);
});
this.addHook('afterDetachChild', function () {
return _this2.onAfterDetachChild.apply(_this2, arguments);
});
this.addHook('modifyRowHeaderWidth', function () {
return _this2.onModifyRowHeaderWidth.apply(_this2, arguments);
});
this.addHook('afterCreateRow', function () {
return _this2.onAfterCreateRow.apply(_this2, arguments);
});
this.addHook('beforeRowMove', function () {
return _this2.onBeforeRowMove.apply(_this2, arguments);
});
this.addHook('afterRowMove', function () {
return _this2.onAfterRowMove.apply(_this2, arguments);
});
if (!this.trimRowsPlugin.isEnabled()) {
// Workaround to prevent calling updateSetttings in the enablePlugin method, which causes many problems.
this.trimRowsPlugin.enablePlugin();
this.hot.getSettings().trimRows = true;
}
(0, _get2.default)((0, _getPrototypeOf2.default)(NestedRows.prototype), "enablePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
(0, _get2.default)((0, _getPrototypeOf2.default)(NestedRows.prototype), "disablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(NestedRows.prototype), "updatePlugin", this).call(this);
}
/**
* `beforeRowMove` hook callback.
*
* @private
* @param {Array} rows Array of row indexes to be moved.
* @param {Number} target Index of the target row.
*/
}, {
key: "onBeforeRowMove",
value: function onBeforeRowMove(rows, target) {
var priv = privatePool.get(this);
var rowsLen = rows.length;
var translatedStartIndexes = [];
var translatedTargetIndex = this.dataManager.translateTrimmedRow(target);
var allowMove = true;
var i;
var fromParent = null;
var toParent = null;
var sameParent = null;
for (i = 0; i < rowsLen; i++) {
translatedStartIndexes.push(this.dataManager.translateTrimmedRow(rows[i]));
if (this.dataManager.isParent(translatedStartIndexes[i])) {
allowMove = false;
}
}
if (translatedStartIndexes.indexOf(translatedTargetIndex) > -1 || !allowMove) {
return false;
}
fromParent = this.dataManager.getRowParent(translatedStartIndexes[0]);
toParent = this.dataManager.getRowParent(translatedTargetIndex);
if (toParent === null || toParent === void 0) {
toParent = this.dataManager.getRowParent(translatedTargetIndex - 1);
}
if (toParent === null || toParent === void 0) {
toParent = this.dataManager.getDataObject(translatedTargetIndex - 1);
priv.movedToFirstChild = true;
}
if (!toParent) {
return false;
}
sameParent = fromParent === toParent;
priv.movedToCollapsed = this.collapsingUI.areChildrenCollapsed(toParent);
this.collapsingUI.collapsedRowsStash.stash();
if (!sameParent) {
if (Math.max.apply(Math, translatedStartIndexes) <= translatedTargetIndex) {
this.collapsingUI.collapsedRowsStash.shiftStash(translatedStartIndexes[0], -1 * rows.length);
} else {
this.collapsingUI.collapsedRowsStash.shiftStash(translatedTargetIndex, rows.length);
}
}
priv.changeSelection = true;
if (translatedStartIndexes[rowsLen - 1] <= translatedTargetIndex && sameParent || priv.movedToFirstChild === true) {
rows.reverse();
translatedStartIndexes.reverse();
if (priv.movedToFirstChild !== true) {
translatedTargetIndex -= 1;
}
}
for (i = 0; i < rowsLen; i++) {
this.dataManager.moveRow(translatedStartIndexes[i], translatedTargetIndex);
}
var movingDown = translatedStartIndexes[translatedStartIndexes.length - 1] < translatedTargetIndex;
if (movingDown) {
for (i = rowsLen - 1; i >= 0; i--) {
this.dataManager.moveCellMeta(translatedStartIndexes[i], translatedTargetIndex);
}
} else {
for (i = 0; i < rowsLen; i++) {
this.dataManager.moveCellMeta(translatedStartIndexes[i], translatedTargetIndex);
}
}
if (translatedStartIndexes[rowsLen - 1] <= translatedTargetIndex && sameParent || this.dataManager.isParent(translatedTargetIndex)) {
rows.reverse();
}
this.dataManager.rewriteCache();
return false;
}
/**
* `afterRowMove` hook callback.
*
* @private
* @param {Array} rows Array of row indexes to be moved.
* @param {Number} target Index of the target row.
*/
}, {
key: "onAfterRowMove",
value: function onAfterRowMove(rows, target) {
var priv = privatePool.get(this);
if (!priv.changeSelection) {
return;
}
var rowsLen = rows.length;
var startRow = 0;
var endRow = 0;
var translatedTargetIndex = null;
var selection = null;
var lastColIndex = null;
this.collapsingUI.collapsedRowsStash.applyStash();
translatedTargetIndex = this.dataManager.translateTrimmedRow(target);
if (priv.movedToFirstChild) {
priv.movedToFirstChild = false;
startRow = target;
endRow = target + rowsLen - 1;
if (target >= Math.max.apply(Math, (0, _toConsumableArray2.default)(rows))) {
startRow -= rowsLen;
endRow -= rowsLen;
}
} else if (priv.movedToCollapsed) {
var parentObject = this.dataManager.getRowParent(translatedTargetIndex - 1);
if (parentObject === null || parentObject === void 0) {
parentObject = this.dataManager.getDataObject(translatedTargetIndex - 1);
}
var parentIndex = this.dataManager.getRowIndex(parentObject);
startRow = parentIndex;
endRow = startRow;
} else if (rows[rowsLen - 1] < target) {
endRow = target - 1;
startRow = endRow - rowsLen + 1;
} else {
startRow = target;
endRow = startRow + rowsLen - 1;
}
selection = this.hot.selection;
lastColIndex = this.hot.countCols() - 1;
selection.setRangeStart(new _src.CellCoords(startRow, 0));
selection.setRangeEnd(new _src.CellCoords(endRow, lastColIndex), true);
priv.changeSelection = false;
}
/**
* `beforeOnCellMousedown` hook callback.
*
* @private
* @param {MouseEvent} event Mousedown event.
* @param {Object} coords Cell coords.
* @param {HTMLElement} TD clicked cell.
*/
}, {
key: "onBeforeOnCellMouseDown",
value: function onBeforeOnCellMouseDown(event, coords, TD) {
this.collapsingUI.toggleState(event, coords, TD);
}
/**
* The modifyRowData hook callback.
*
* @private
* @param {Number} row Visual row index.
*/
}, {
key: "onModifyRowData",
value: function onModifyRowData(row) {
return this.dataManager.getDataObject(row);
}
/**
* Modify the source data length to match the length of the nested structure.
*
* @private
* @returns {Number}
*/
}, {
key: "onModifySourceLength",
value: function onModifySourceLength() {
return this.dataManager.countAllRows();
}
/**
* @private
* @param {Number} index
* @param {Number} amount
* @param {Object} element
* @returns {Boolean}
*/
}, {
key: "onBeforeDataSplice",
value: function onBeforeDataSplice(index, amount, element) {
this.dataManager.spliceData(index, amount, element);
return false;
}
/**
* Called before the source data filtering. Returning `false` stops the native filtering.
*
* @private
* @param {Number} index
* @param {Number} amount
* @returns {Boolean}
*/
}, {
key: "onBeforeDataFilter",
value: function onBeforeDataFilter(index, amount) {
var realLogicRows = [];
var startIndex = this.dataManager.translateTrimmedRow(index);
var priv = privatePool.get(this);
(0, _number.rangeEach)(startIndex, startIndex + amount - 1, function (i) {
realLogicRows.push(i);
});
this.collapsingUI.collapsedRowsStash.stash();
this.collapsingUI.collapsedRowsStash.trimStash(startIndex, amount);
this.collapsingUI.collapsedRowsStash.shiftStash(startIndex, -1 * amount);
this.dataManager.filterData(index, amount, realLogicRows);
priv.skipRender = true;
return false;
}
/**
* `afterContextMenuDefaultOptions` hook callback.
*
* @private
* @param {Object} defaultOptions
*/
}, {
key: "onAfterContextMenuDefaultOptions",
value: function onAfterContextMenuDefaultOptions(defaultOptions) {
return this.contextMenuUI.appendOptions(defaultOptions);
}
/**
* `afterGetRowHeader` hook callback.
*
* @private
* @param {Number} row Row index.
* @param {HTMLElement} TH row header element.
*/
}, {
key: "onAfterGetRowHeader",
value: function onAfterGetRowHeader(row, TH) {
this.headersUI.appendLevelIndicators(row, TH);
}
/**
* `modifyRowHeaderWidth` hook callback.
*
* @private
* @param {Number} rowHeaderWidth The initial row header width(s).
* @returns {Number}
*/
}, {
key: "onModifyRowHeaderWidth",
value: function onModifyRowHeaderWidth(rowHeaderWidth) {
return this.headersUI.rowHeaderWidthCache || rowHeaderWidth;
}
/**
* `onAfterRemoveRow` hook callback.
*
* @private
* @param {Number} index Removed row.
* @param {Number} amount Amount of removed rows.
* @param {Array} logicRows
* @param {String} source Source of action.
*/
}, {
key: "onAfterRemoveRow",
value: function onAfterRemoveRow(index, amount, logicRows, source) {
var _this3 = this;
if (source === this.pluginName) {
return;
}
var priv = privatePool.get(this);
setTimeout(function () {
priv.skipRender = null;
_this3.headersUI.updateRowHeaderWidth();
_this3.collapsingUI.collapsedRowsStash.applyStash();
}, 0);
}
/**
* `modifyRemovedAmount` hook callback.
*
* @private
* @param {Number} amount Initial amount.
* @param {Number} index Index of the starting row.
* @returns {Number} Modified amount.
*/
}, {
key: "onModifyRemovedAmount",
value: function onModifyRemovedAmount(amount, index) {
var _this4 = this;
var lastParents = [];
var childrenCount = 0;
(0, _number.rangeEach)(index, index + amount - 1, function (i) {
var isChild = false;
var translated = _this4.collapsingUI.translateTrimmedRow(i);
var currentDataObj = _this4.dataManager.getDataObject(translated);
if (_this4.dataManager.hasChildren(currentDataObj)) {
lastParents.push(currentDataObj);
(0, _array.arrayEach)(lastParents, function (elem) {
if (elem.__children.indexOf(currentDataObj) > -1) {
isChild = true;
return false;
}
});
if (!isChild) {
childrenCount += _this4.dataManager.countChildren(currentDataObj);
}
}
isChild = false;
(0, _array.arrayEach)(lastParents, function (elem) {
if (elem.__children.indexOf(currentDataObj) > -1) {
isChild = true;
return false;
}
});
if (isChild) {
childrenCount -= 1;
}
});
return amount + childrenCount;
}
/**
* `beforeAddChild` hook callback.
*
* @private
*/
}, {
key: "onBeforeAddChild",
value: function onBeforeAddChild() {
this.collapsingUI.collapsedRowsStash.stash();
}
/**
* `afterAddChild` hook callback.
*
* @private
* @param {Object} parent Parent element.
* @param {Object} element New child element.
*/
}, {
key: "onAfterAddChild",
value: function onAfterAddChild(parent, element) {
this.collapsingUI.collapsedRowsStash.shiftStash(this.dataManager.getRowIndex(element));
this.collapsingUI.collapsedRowsStash.applyStash();
this.headersUI.updateRowHeaderWidth();
}
/**
* `beforeDetachChild` hook callback.
*
* @private
*/
}, {
key: "onBeforeDetachChild",
value: function onBeforeDetachChild() {
this.collapsingUI.collapsedRowsStash.stash();
}
/**
* `afterDetachChild` hook callback.
*
* @private
* @param {Object} parent Parent element.
* @param {Object} element New child element.
*/
}, {
key: "onAfterDetachChild",
value: function onAfterDetachChild(parent, element) {
this.collapsingUI.collapsedRowsStash.shiftStash(this.dataManager.getRowIndex(element));
this.collapsingUI.collapsedRowsStash.applyStash();
this.headersUI.updateRowHeaderWidth();
}
/**
* `afterCreateRow` hook callback.
*
* @private
* @param {Number} index
* @param {Number} amount
* @param {String} source
*/
}, {
key: "onAfterCreateRow",
value: function onAfterCreateRow(index, amount, source) {
if (source === this.pluginName) {
return;
}
this.dataManager.rewriteCache();
}
/**
* `afterInit` hook callback.
*
* @private
*/
}, {
key: "onAfterInit",
value: function onAfterInit() {
// Workaround to fix an issue caused by the 'bindRowsWithHeaders' plugin loading before this one.
if (this.bindRowsWithHeadersPlugin.bindStrategy.strategy) {
this.bindRowsWithHeadersPlugin.bindStrategy.createMap(this.hot.countSourceRows());
}
var deepestLevel = Math.max.apply(Math, (0, _toConsumableArray2.default)(this.dataManager.cache.levels));
if (deepestLevel > 0) {
this.headersUI.updateRowHeaderWidth(deepestLevel);
}
}
/**
* `beforeRender` hook callback.
*
* @param {Boolean} force
* @param {Object} skipRender
* @private
*/
}, {
key: "onBeforeRender",
value: function onBeforeRender(force, skipRender) {
var priv = privatePool.get(this);
if (priv.skipRender) {
skipRender.skipRender = true;
}
}
}]);
return NestedRows;
}(_base.default);
(0, _plugins.registerPlugin)('nestedRows', NestedRows);
var _default = NestedRows;
exports.default = _default;
/***/ }),
/* 509 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(40);
__webpack_require__(33);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _number = __webpack_require__(15);
var _object = __webpack_require__(4);
var _array = __webpack_require__(3);
var _recordTranslator = __webpack_require__(90);
/**
* Class responsible for making data operations.
*
* @class
* @private
*/
var DataManager =
/*#__PURE__*/
function () {
function DataManager(nestedRowsPlugin, hotInstance, sourceData) {
(0, _classCallCheck2.default)(this, DataManager);
/**
* Main Handsontable instance reference.
*
* @type {Object}
*/
this.hot = hotInstance;
/**
* Reference to the source data object.
*
* @type {Object}
*/
this.data = sourceData;
/**
* Reference to the NestedRows plugin.
*
* @type {Object}
*/
this.plugin = nestedRowsPlugin;
/**
* Map of row object parents.
*
* @type {WeakMap}
*/
this.parentReference = new WeakMap();
/**
* Nested structure cache.
*
* @type {Object}
*/
this.cache = {
levels: [],
levelCount: 0,
rows: [],
nodeInfo: new WeakMap()
};
/**
* A `recordTranslator` instance.
*
* @private
* @type {Object}
*/
this.recordTranslator = (0, _recordTranslator.getTranslator)(this.hot);
}
/**
* Rewrite the nested structure cache.
*
* @private
*/
(0, _createClass2.default)(DataManager, [{
key: "rewriteCache",
value: function rewriteCache() {
var _this = this;
this.cache = {
levels: [],
levelCount: 0,
rows: [],
nodeInfo: new WeakMap()
};
(0, _number.rangeEach)(0, this.data.length - 1, function (i) {
_this.cacheNode(_this.data[i], 0, null);
});
}
/**
* Cache a data node.
*
* @private
* @param {Object} node Node to cache.
* @param {Number} level Level of the node.
* @param {Object} parent Parent of the node.
*/
}, {
key: "cacheNode",
value: function cacheNode(node, level, parent) {
var _this2 = this;
if (!this.cache.levels[level]) {
this.cache.levels[level] = [];
this.cache.levelCount += 1;
}
this.cache.levels[level].push(node);
this.cache.rows.push(node);
this.cache.nodeInfo.set(node, {
parent: parent,
row: this.cache.rows.length - 1,
level: level
});
if (this.hasChildren(node)) {
(0, _array.arrayEach)(node.__children, function (elem) {
_this2.cacheNode(elem, level + 1, node);
});
}
}
/**
* Get the date for the provided visual row number.
*
* @param {Number} row Row index.
*/
}, {
key: "getDataObject",
value: function getDataObject(row) {
return row === null || row === void 0 ? null : this.cache.rows[row];
}
/**
* Read the row tree in search for a specific row index or row object.
*
* @private
* @param {Object} parent The initial parent object.
* @param {Number} readCount Number of read nodes.
* @param {Number} neededIndex The row index we search for.
* @param {Object} neededObject The row object we search for.
* @returns {Number|Object}
*/
}, {
key: "readTreeNodes",
value: function readTreeNodes(parent, readCount, neededIndex, neededObject) {
var _this3 = this;
var rootLevel = false;
var readedNodesCount = readCount;
if (isNaN(readedNodesCount) && readedNodesCount.end) {
return readedNodesCount;
}
var parentObj = parent;
if (!parentObj) {
parentObj = {
__children: this.data
};
rootLevel = true;
readedNodesCount -= 1;
}
if (neededIndex !== null && neededIndex !== void 0 && readedNodesCount === neededIndex) {
return {
result: parentObj,
end: true
};
}
if (neededObject !== null && neededObject !== void 0 && parentObj === neededObject) {
return {
result: readedNodesCount,
end: true
};
}
readedNodesCount += 1;
if (parentObj.__children) {
(0, _array.arrayEach)(parentObj.__children, function (val) {
_this3.parentReference.set(val, rootLevel ? null : parentObj);
readedNodesCount = _this3.readTreeNodes(val, readedNodesCount, neededIndex, neededObject);
if (isNaN(readedNodesCount) && readedNodesCount.end) {
return false;
}
});
}
return readedNodesCount;
}
/**
* Update the parent reference map.
*
* @private
*/
}, {
key: "updateParentReference",
value: function updateParentReference() {
this.readTreeNodes({
__children: this.data
}, 0, this.hot.countRows());
}
/**
* Mock a parent node.
*
* @private
* @returns {*}
*/
}, {
key: "mockParent",
value: function mockParent() {
var fakeParent = this.mockNode();
fakeParent.__children = this.data;
return fakeParent;
}
/**
* Mock a data node.
*
* @private
* @returns {{}}
*/
}, {
key: "mockNode",
value: function mockNode() {
var fakeNode = {};
(0, _object.objectEach)(this.data[0], function (val, key) {
fakeNode[key] = null;
});
return fakeNode;
}
/**
* Get the row index for the provided row object.
*
* @param {Object} rowObj The row object.
* @returns {Number} Row index.
*/
}, {
key: "getRowIndex",
value: function getRowIndex(rowObj) {
return rowObj === null || rowObj === void 0 ? null : this.cache.nodeInfo.get(rowObj).row;
}
/**
* Get the index of the provided row index/row object within its parent.
*
* @param {Number|Object} row Row index / row object.
* @returns {Number}
*/
}, {
key: "getRowIndexWithinParent",
value: function getRowIndexWithinParent(row) {
var rowObj = null;
if (isNaN(row)) {
rowObj = row;
} else {
rowObj = this.getDataObject(row);
}
var parent = this.getRowParent(row);
if (parent === null || parent === void 0) {
return this.data.indexOf(rowObj);
}
return parent.__children.indexOf(rowObj);
}
/**
* Count all rows (including all parents and children).
*/
}, {
key: "countAllRows",
value: function countAllRows() {
var rootNodeMock = {
__children: this.data
};
return this.countChildren(rootNodeMock);
}
/**
* Count children of the provided parent.
*
* @param {Object|Number} parent Parent node.
* @returns {Number} Children count.
*/
}, {
key: "countChildren",
value: function countChildren(parent) {
var _this4 = this;
var rowCount = 0;
var parentNode = parent;
if (!isNaN(parentNode)) {
parentNode = this.getDataObject(parentNode);
}
if (!parentNode || !parentNode.__children) {
return 0;
}
(0, _array.arrayEach)(parentNode.__children, function (elem) {
rowCount += 1;
if (elem.__children) {
rowCount += _this4.countChildren(elem);
}
});
return rowCount;
}
/**
* Get the parent of the row at the provided index.
*
* @param {Number|Object} row Row index.
*/
}, {
key: "getRowParent",
value: function getRowParent(row) {
var rowObject;
if (isNaN(row)) {
rowObject = row;
} else {
rowObject = this.getDataObject(row);
}
return this.getRowObjectParent(rowObject);
}
/**
* Get the parent of the provided row object.
*
* @private
* @param {Object} rowObject The row object (tree node).
*/
}, {
key: "getRowObjectParent",
value: function getRowObjectParent(rowObject) {
if ((0, _typeof2.default)(rowObject) !== 'object') {
return null;
}
return this.cache.nodeInfo.get(rowObject).parent;
}
/**
* Get the nesting level for the row with the provided row index.
*
* @param {Number} row Row index.
* @returns {Number|null} Row level or null, when row doesn't exist.
*/
}, {
key: "getRowLevel",
value: function getRowLevel(row) {
var rowObject = null;
if (isNaN(row)) {
rowObject = row;
} else {
rowObject = this.getDataObject(row);
}
return rowObject ? this.getRowObjectLevel(rowObject) : null;
}
/**
* Get the nesting level for the row with the provided row index.
*
* @private
* @param {Object} rowObject Row object.
* @returns {Number} Row level.
*/
}, {
key: "getRowObjectLevel",
value: function getRowObjectLevel(rowObject) {
return rowObject === null || rowObject === void 0 ? null : this.cache.nodeInfo.get(rowObject).level;
}
/**
* Check if the provided row/row element has children.
*
* @param {Number|Object} row Row number or row element.
* @returns {Boolean}
*/
}, {
key: "hasChildren",
value: function hasChildren(row) {
var rowObj = row;
if (!isNaN(rowObj)) {
rowObj = this.getDataObject(rowObj);
}
return !!(rowObj.__children && rowObj.__children.length);
}
}, {
key: "isParent",
value: function isParent(row) {
var rowObj = row;
if (!isNaN(rowObj)) {
rowObj = this.getDataObject(rowObj);
}
return !!(0, _object.hasOwnProperty)(rowObj, '__children');
}
/**
* Add a child to the provided parent. It's optional to add a row object as the "element"
*
* @param {Object} parent The parent row object.
* @param {Object} [element] The element to add as a child.
*/
}, {
key: "addChild",
value: function addChild(parent, element) {
var childElement = element;
this.hot.runHooks('beforeAddChild', parent, childElement);
var parentIndex = null;
if (parent) {
parentIndex = this.getRowIndex(parent);
}
this.hot.runHooks('beforeCreateRow', parentIndex + this.countChildren(parent) + 1, 1);
var functionalParent = parent;
if (!parent) {
functionalParent = this.mockParent();
}
if (!functionalParent.__children) {
functionalParent.__children = [];
}
if (!childElement) {
childElement = this.mockNode();
}
functionalParent.__children.push(childElement);
this.rewriteCache();
var newRowIndex = this.getRowIndex(childElement);
this.hot.runHooks('afterCreateRow', newRowIndex, 1);
this.hot.runHooks('afterAddChild', parent, childElement);
}
/**
* Add a child node to the provided parent at a specified index.
*
* @param {Object} parent Parent node.
* @param {Number} index Index to insert the child element at.
* @param {Object} [element] Element (node) to insert.
* @param {Number} [globalIndex] Global index of the inserted row.
*/
}, {
key: "addChildAtIndex",
value: function addChildAtIndex(parent, index, element, globalIndex) {
var childElement = element;
this.hot.runHooks('beforeAddChild', parent, childElement, index);
this.hot.runHooks('beforeCreateRow', globalIndex + 1, 1);
var functionalParent = parent;
if (!parent) {
functionalParent = this.mockParent();
}
if (!functionalParent.__children) {
functionalParent.__children = [];
}
if (!childElement) {
childElement = this.mockNode();
}
functionalParent.__children.splice(index, null, childElement);
this.rewriteCache();
this.hot.runHooks('afterCreateRow', globalIndex + 1, 1);
this.hot.runHooks('afterAddChild', parent, childElement, index);
}
/**
* Add a sibling element at the specified index.
*
* @param {Number} index New element sibling's index.
* @param {('above'|'below')} where Direction in which the sibling is to be created.
*/
}, {
key: "addSibling",
value: function addSibling(index) {
var where = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'below';
var translatedIndex = this.translateTrimmedRow(index);
var parent = this.getRowParent(translatedIndex);
var indexWithinParent = this.getRowIndexWithinParent(translatedIndex);
switch (where) {
case 'below':
this.addChildAtIndex(parent, indexWithinParent + 1, null, index);
break;
case 'above':
this.addChildAtIndex(parent, indexWithinParent, null, index);
break;
default:
break;
}
}
/**
* Detach the provided element from its parent and add it right after it.
*
* @param {Object|Array} elements Row object or an array of selected coordinates.
* @param {Boolean} [forceRender=true] If true (default), it triggers render after finished.
*/
}, {
key: "detachFromParent",
value: function detachFromParent(elements) {
var _this5 = this;
var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var element = null;
var rowObjects = [];
if (Array.isArray(elements)) {
(0, _number.rangeEach)(elements[0], elements[2], function (i) {
var translatedIndex = _this5.translateTrimmedRow(i);
rowObjects.push(_this5.getDataObject(translatedIndex));
});
(0, _number.rangeEach)(0, rowObjects.length - 2, function (i) {
_this5.detachFromParent(rowObjects[i], false);
});
element = rowObjects[rowObjects.length - 1];
} else {
element = elements;
}
var childRowIndex = this.getRowIndex(element);
var indexWithinParent = this.getRowIndexWithinParent(element);
var parent = this.getRowParent(element);
var grandparent = this.getRowParent(parent);
var grandparentRowIndex = this.getRowIndex(grandparent);
var movedElementRowIndex = null;
this.hot.runHooks('beforeDetachChild', parent, element);
if (indexWithinParent !== null && indexWithinParent !== void 0) {
this.hot.runHooks('beforeRemoveRow', childRowIndex, 1, [childRowIndex], this.plugin.pluginName);
parent.__children.splice(indexWithinParent, 1);
this.rewriteCache();
this.hot.runHooks('afterRemoveRow', childRowIndex, 1, [childRowIndex], this.plugin.pluginName);
if (grandparent) {
movedElementRowIndex = grandparentRowIndex + this.countChildren(grandparent);
this.hot.runHooks('beforeCreateRow', movedElementRowIndex, 1, this.plugin.pluginName);
grandparent.__children.push(element);
} else {
movedElementRowIndex = this.hot.countRows() + 1;
this.hot.runHooks('beforeCreateRow', movedElementRowIndex, 1, this.plugin.pluginName);
this.data.push(element);
}
}
this.rewriteCache();
this.hot.runHooks('afterCreateRow', movedElementRowIndex, 1, this.plugin.pluginName);
if (forceRender) {
this.hot.render();
}
this.hot.runHooks('afterDetachChild', parent, element);
}
/**
* Filter the data by the `logicRows` array.
*
* @private
* @param {Number} index Index of the first row to remove.
* @param {Number} amount Number of elements to remove.
* @param {Array} logicRows Array of indexes to remove.
*/
}, {
key: "filterData",
value: function filterData(index, amount, logicRows) {
var _this6 = this;
var elementsToRemove = [];
(0, _array.arrayEach)(logicRows, function (elem) {
elementsToRemove.push(_this6.getDataObject(elem));
});
(0, _array.arrayEach)(elementsToRemove, function (elem) {
var indexWithinParent = _this6.getRowIndexWithinParent(elem);
var tempParent = _this6.getRowParent(elem);
if (tempParent === null) {
_this6.data.splice(indexWithinParent, 1);
} else {
tempParent.__children.splice(indexWithinParent, 1);
}
});
this.rewriteCache();
}
/**
* Used to splice the source data. Needed to properly modify the nested structure, which wouldn't work with the default script.
*
* @private
* @param {Number} index Index of the element at the splice beginning.
* @param {Number} amount Number of elements to be removed.
* @param {Object} element Row to add.
*/
}, {
key: "spliceData",
value: function spliceData(index, amount, element) {
var elementIndex = this.translateTrimmedRow(index);
if (elementIndex === null || elementIndex === void 0) {
return;
}
var previousElement = this.getDataObject(elementIndex - 1);
var newRowParent = null;
var indexWithinParent = null;
if (previousElement && previousElement.__children && previousElement.__children.length === 0) {
newRowParent = previousElement;
indexWithinParent = 0;
} else {
newRowParent = this.getRowParent(elementIndex);
indexWithinParent = this.getRowIndexWithinParent(elementIndex);
}
if (newRowParent) {
if (element) {
newRowParent.__children.splice(indexWithinParent, amount, element);
} else {
newRowParent.__children.splice(indexWithinParent, amount);
}
} else if (element) {
this.data.splice(indexWithinParent, amount, element);
} else {
this.data.splice(indexWithinParent, amount);
}
this.rewriteCache();
}
/**
* Move a single row.
*
* @param {Number} fromIndex Index of the row to be moved.
* @param {Number} toIndex Index of the destination.
*/
}, {
key: "moveRow",
value: function moveRow(fromIndex, toIndex) {
var targetIsParent = this.isParent(toIndex);
var fromParent = this.getRowParent(fromIndex);
var indexInFromParent = this.getRowIndexWithinParent(fromIndex);
var toParent = this.getRowParent(toIndex);
if (toParent === null || toParent === void 0) {
toParent = this.getRowParent(toIndex - 1);
}
if (toParent === null || toParent === void 0) {
toParent = this.getDataObject(toIndex - 1);
}
if (!toParent) {
toParent = this.getDataObject(toIndex);
toParent.__children = [];
} else if (!toParent.__children) {
toParent.__children = [];
}
var previousToTargetParent = this.getRowParent(toIndex - 1);
var indexInToParent = targetIsParent ? this.countChildren(previousToTargetParent) : this.getRowIndexWithinParent(toIndex);
var elemToMove = fromParent.__children.slice(indexInFromParent, indexInFromParent + 1);
fromParent.__children.splice(indexInFromParent, 1);
toParent.__children.splice(indexInToParent, 0, elemToMove[0]);
}
/**
* Move the cell meta
*
* @private
* @param {Number} fromIndex Index of the starting row.
* @param {Number} toIndex Index of the ending row.
*/
}, {
key: "moveCellMeta",
value: function moveCellMeta(fromIndex, toIndex) {
var rowOfMeta = this.hot.getCellMetaAtRow(fromIndex);
this.hot.spliceCellsMeta(toIndex, 0, rowOfMeta);
this.hot.spliceCellsMeta(fromIndex + (fromIndex < toIndex ? 0 : 1), 1);
}
/**
* Translate the row index according to the `TrimRows` plugin.
*
* @private
* @param {Number} row Row index.
* @returns {Number}
*/
}, {
key: "translateTrimmedRow",
value: function translateTrimmedRow(row) {
if (this.plugin.collapsingUI) {
return this.plugin.collapsingUI.translateTrimmedRow(row);
}
return row;
}
}]);
return DataManager;
}();
var _default = DataManager;
exports.default = _default;
/***/ }),
/* 510 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(12);
__webpack_require__(40);
__webpack_require__(33);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _event = __webpack_require__(31);
var _array = __webpack_require__(3);
var _number = __webpack_require__(15);
var _element = __webpack_require__(5);
var _base = _interopRequireDefault(__webpack_require__(173));
var _headers = _interopRequireDefault(__webpack_require__(256));
/**
* Class responsible for the UI for collapsing and expanding groups.
*
* @class
* @util
* @extends BaseUI
*/
var CollapsingUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(CollapsingUI, _BaseUI);
function CollapsingUI(nestedRowsPlugin, hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, CollapsingUI);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CollapsingUI).call(this, nestedRowsPlugin, hotInstance));
/**
* Reference to the Trim Rows plugin.
*/
_this.trimRowsPlugin = nestedRowsPlugin.trimRowsPlugin;
_this.dataManager = _this.plugin.dataManager;
_this.collapsedRows = [];
_this.collapsedRowsStash = {
stash: function stash() {
_this.lastCollapsedRows = _this.collapsedRows.slice(0); // Workaround for wrong indexes being set in the trimRows plugin
_this.expandMultipleChildren(_this.lastCollapsedRows, false);
},
shiftStash: function shiftStash(index) {
var delta = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
var elementIndex = _this.translateTrimmedRow(index);
(0, _array.arrayEach)(_this.lastCollapsedRows, function (elem, i) {
if (elem > elementIndex - 1) {
_this.lastCollapsedRows[i] = elem + delta;
}
});
},
applyStash: function applyStash() {
// Workaround for wrong indexes being set in the trimRows plugin
_this.hot.runHooks('skipLengthCache', 100);
_this.collapseMultipleChildren(_this.lastCollapsedRows, true);
_this.lastCollapsedRows = void 0;
},
trimStash: function trimStash(realElementIndex, amount) {
(0, _number.rangeEach)(realElementIndex, realElementIndex + amount - 1, function (i) {
var indexOfElement = _this.lastCollapsedRows.indexOf(i);
if (indexOfElement > -1) {
_this.lastCollapsedRows.splice(indexOfElement, 1);
}
});
}
};
return _this;
}
/**
* Collapse the children of the row passed as an argument.
*
* @param {Number|Object} row The parent row.
* @param {Boolean} [forceRender=true] Whether to render the table after the function ends.
*/
(0, _createClass2.default)(CollapsingUI, [{
key: "collapseChildren",
value: function collapseChildren(row) {
var _this2 = this;
var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var rowsToCollapse = [];
var rowObject = null;
var rowIndex = null;
var rowsToTrim = null;
if (isNaN(row)) {
rowObject = row;
rowIndex = this.dataManager.getRowIndex(rowObject);
} else {
rowObject = this.dataManager.getDataObject(row);
rowIndex = row;
}
if (this.dataManager.hasChildren(rowObject)) {
(0, _array.arrayEach)(rowObject.__children, function (elem) {
rowsToCollapse.push(_this2.dataManager.getRowIndex(elem));
});
}
rowsToTrim = this.collapseRows(rowsToCollapse, true, false);
if (doTrimming) {
this.trimRowsPlugin.trimRows(rowsToTrim);
}
if (forceRender) {
this.renderAndAdjust();
}
if (this.collapsedRows.indexOf(rowIndex) === -1) {
this.collapsedRows.push(rowIndex);
}
return rowsToTrim;
}
/**
* Collapse multiple children.
*
* @param {Array} rows Rows to collapse (including their children)
* @param {Boolean} [forceRender = true] `true` if the table should be rendered after finishing the function.
* @param {Boolean} [doTrimming = true] `true` if the table should trim the provided rows.
*/
}, {
key: "collapseMultipleChildren",
value: function collapseMultipleChildren(rows) {
var _this3 = this;
var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var rowsToTrim = [];
(0, _array.arrayEach)(rows, function (elem) {
rowsToTrim = rowsToTrim.concat(_this3.collapseChildren(elem, false, false));
});
if (doTrimming) {
this.trimRowsPlugin.trimRows(rowsToTrim);
}
if (forceRender) {
this.renderAndAdjust();
}
}
/**
* Collapse a single row.
*
* @param {Number} rowIndex Index of the row to collapse.
* @param {Boolean} [recursive = true] `true` if it should collapse the row's children.
*/
}, {
key: "collapseRow",
value: function collapseRow(rowIndex) {
var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
this.collapseRows([rowIndex], recursive);
}
/**
* Collapse multiple rows.
*
* @param {Array} rowIndexes Array of row indexes to collapse.
* @param {Boolean} [recursive = true] `true` if it should collapse the rows' children.
* @param {Boolean} [doTrimming = false] `true` if the provided rows should be collapsed.
* @returns {Array} Rows prepared for trimming (or trimmed, if doTrimming == true)
*/
}, {
key: "collapseRows",
value: function collapseRows(rowIndexes) {
var _this4 = this;
var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var rowsToTrim = [];
(0, _array.arrayEach)(rowIndexes, function (elem) {
rowsToTrim.push(elem);
if (recursive) {
_this4.collapseChildRows(elem, rowsToTrim);
}
});
if (doTrimming) {
this.trimRowsPlugin.trimRows(rowsToTrim);
}
return rowsToTrim;
}
/**
* Collapse child rows of the row at the provided index.
*
* @param {Number} parentIndex Index of the parent node.
* @param {Array} [rowsToTrim = []] Array of rows to trim. Defaults to an empty array.
* @param {Boolean} [recursive] `true` if the collapsing process should be recursive.
* @param {Boolean} [doTrimming = false] `true` if rows should be trimmed.
*/
}, {
key: "collapseChildRows",
value: function collapseChildRows(parentIndex) {
var _this5 = this;
var rowsToTrim = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var recursive = arguments.length > 2 ? arguments[2] : undefined;
var doTrimming = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (this.dataManager.hasChildren(parentIndex)) {
var parentObject = this.dataManager.getDataObject(parentIndex);
(0, _array.arrayEach)(parentObject.__children, function (elem) {
var elemIndex = _this5.dataManager.getRowIndex(elem);
rowsToTrim.push(elemIndex);
_this5.collapseChildRows(elemIndex, rowsToTrim);
});
}
if (doTrimming) {
this.trimRowsPlugin.trimRows(rowsToTrim);
}
}
/**
* Expand a single row.
*
* @param {Number} rowIndex Index of the row to expand.
* @param {Boolean} [recursive = true] `true` if it should expand the row's children recursively.
*/
}, {
key: "expandRow",
value: function expandRow(rowIndex) {
var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
this.expandRows([rowIndex], recursive);
}
/**
* Expand multiple rows.
*
* @param {Array} rowIndexes Array of indexes of the rows to expand.
* @param {Boolean} [recursive = true] `true` if it should expand the rows' children recursively.
* @param {Boolean} [doTrimming = false] `true` if rows should be untrimmed.
* @returns {Array} Array of row indexes to be untrimmed.
*/
}, {
key: "expandRows",
value: function expandRows(rowIndexes) {
var _this6 = this;
var recursive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var rowsToUntrim = [];
(0, _array.arrayEach)(rowIndexes, function (elem) {
rowsToUntrim.push(elem);
if (recursive) {
_this6.expandChildRows(elem, rowsToUntrim);
}
});
if (doTrimming) {
this.trimRowsPlugin.untrimRows(rowsToUntrim);
}
return rowsToUntrim;
}
/**
* Expand child rows of the provided index.
*
* @param {Number} parentIndex Index of the parent row.
* @param {Array} [rowsToUntrim = []] Array of the rows to be untrimmed.
* @param {Boolean} [recursive] `true` if it should expand the rows' children recursively.
* @param {Boolean} [doTrimming = false] `true` if rows should be untrimmed.
*/
}, {
key: "expandChildRows",
value: function expandChildRows(parentIndex) {
var _this7 = this;
var rowsToUntrim = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var recursive = arguments.length > 2 ? arguments[2] : undefined;
var doTrimming = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (this.dataManager.hasChildren(parentIndex)) {
var parentObject = this.dataManager.getDataObject(parentIndex);
(0, _array.arrayEach)(parentObject.__children, function (elem) {
if (!_this7.isAnyParentCollapsed(elem)) {
var elemIndex = _this7.dataManager.getRowIndex(elem);
rowsToUntrim.push(elemIndex);
_this7.expandChildRows(elemIndex, rowsToUntrim);
}
});
}
if (doTrimming) {
this.trimRowsPlugin.untrimRows(rowsToUntrim);
}
}
/**
* Expand the children of the row passed as an argument.
*
* @param {Number|Object} row Parent row.
* @param {Boolean} [forceRender=true] Whether to render the table after the function ends.
* @param {Boolean} [doTrimming=true] If set to `true`, the trimming will be applied when the function finishes.
*/
}, {
key: "expandChildren",
value: function expandChildren(row) {
var _this8 = this;
var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var rowsToExpand = [];
var rowObject = null;
var rowIndex = null;
var rowsToUntrim = null;
if (isNaN(row)) {
rowObject = row;
rowIndex = this.dataManager.getRowIndex(row);
} else {
rowObject = this.dataManager.getDataObject(row);
rowIndex = row;
}
this.collapsedRows.splice(this.collapsedRows.indexOf(rowIndex), 1);
if (this.dataManager.hasChildren(rowObject)) {
(0, _array.arrayEach)(rowObject.__children, function (elem) {
var childIndex = _this8.dataManager.getRowIndex(elem);
rowsToExpand.push(childIndex);
});
}
rowsToUntrim = this.expandRows(rowsToExpand, true, false);
if (doTrimming) {
this.trimRowsPlugin.untrimRows(rowsToUntrim);
}
if (forceRender) {
this.renderAndAdjust();
}
return rowsToUntrim;
}
/**
* Expand multiple rows' children.
*
* @param {Array} rows Array of rows which children are about to be expanded.
* @param {Boolean} [forceRender = true] `true` if the table should render after finishing the function.
* @param {Boolean} [doTrimming = true] `true` if the rows should be untrimmed after finishing the function.
*/
}, {
key: "expandMultipleChildren",
value: function expandMultipleChildren(rows) {
var _this9 = this;
var forceRender = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var doTrimming = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var rowsToUntrim = [];
(0, _array.arrayEach)(rows, function (elem) {
rowsToUntrim = rowsToUntrim.concat(_this9.expandChildren(elem, false, false));
});
if (doTrimming) {
this.trimRowsPlugin.untrimRows(rowsToUntrim);
}
if (forceRender) {
this.renderAndAdjust();
}
}
/**
* Collapse all collapsable rows.
*/
}, {
key: "collapseAll",
value: function collapseAll() {
var _this10 = this;
var sourceData = this.hot.getSourceData();
var parentsToCollapse = [];
(0, _array.arrayEach)(sourceData, function (elem) {
if (_this10.dataManager.hasChildren(elem)) {
parentsToCollapse.push(elem);
}
});
this.collapseMultipleChildren(parentsToCollapse);
this.renderAndAdjust();
}
/**
* Expand all collapsable rows.
*/
}, {
key: "expandAll",
value: function expandAll() {
var _this11 = this;
var sourceData = this.hot.getSourceData();
var parentsToExpand = [];
(0, _array.arrayEach)(sourceData, function (elem) {
if (_this11.dataManager.hasChildren(elem)) {
parentsToExpand.push(elem);
}
});
this.expandMultipleChildren(parentsToExpand);
this.renderAndAdjust();
}
/**
* Check if all child rows are collapsed.
*
* @param {Number|Object} row The parent row.
* @private
*/
}, {
key: "areChildrenCollapsed",
value: function areChildrenCollapsed(row) {
var _this12 = this;
var rowObj = null;
var allCollapsed = true;
if (isNaN(row)) {
rowObj = row;
} else {
rowObj = this.dataManager.getDataObject(row);
}
if (this.dataManager.hasChildren(rowObj)) {
(0, _array.arrayEach)(rowObj.__children, function (elem) {
var rowIndex = _this12.dataManager.getRowIndex(elem);
if (!_this12.trimRowsPlugin.isTrimmed(rowIndex)) {
allCollapsed = false;
return false;
}
});
}
return allCollapsed;
}
/**
* Check if any of the row object parents are collapsed.
*
* @private
* @param {Object} rowObj Row object.
* @returns {Boolean}
*/
}, {
key: "isAnyParentCollapsed",
value: function isAnyParentCollapsed(rowObj) {
var parent = rowObj;
while (parent !== null) {
parent = this.dataManager.getRowParent(parent);
var parentIndex = this.dataManager.getRowIndex(parent);
if (this.collapsedRows.indexOf(parentIndex) > -1) {
return true;
}
}
return false;
}
/**
* Toggle collapsed state. Callback for the `beforeOnCellMousedown` hook.
*
* @private
* @param {MouseEvent} event `mousedown` event
* @param {Object} coords Coordinates of the clicked cell/header.
*/
}, {
key: "toggleState",
value: function toggleState(event, coords) {
if (coords.col >= 0) {
return;
}
var row = this.translateTrimmedRow(coords.row);
if ((0, _element.hasClass)(event.target, _headers.default.CSS_CLASSES.button)) {
if (this.areChildrenCollapsed(row)) {
this.expandChildren(row);
} else {
this.collapseChildren(row);
}
(0, _event.stopImmediatePropagation)(event);
}
}
/**
* Translate physical row after trimming to physical base row index.
*
* @private
* @param {Number} row Row index.
* @returns {Number} Base row index.
*/
}, {
key: "translateTrimmedRow",
value: function translateTrimmedRow(row) {
return this.trimRowsPlugin.rowsMapper.getValueByIndex(row);
}
/**
* Helper function to render the table and call the `adjustElementsSize` method.
*
* @private
*/
}, {
key: "renderAndAdjust",
value: function renderAndAdjust() {
this.hot.render(); // Dirty workaround to prevent scroll height not adjusting to the table height. Needs refactoring in the future.
this.hot.view.wt.wtOverlays.adjustElementsSize();
}
}]);
return CollapsingUI;
}(_base.default);
var _default = CollapsingUI;
exports.default = _default;
/***/ }),
/* 511 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(16);
__webpack_require__(33);
__webpack_require__(10);
__webpack_require__(14);
__webpack_require__(24);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _number = __webpack_require__(15);
var _array = __webpack_require__(3);
var C = _interopRequireWildcard(__webpack_require__(11));
var _base = _interopRequireDefault(__webpack_require__(173));
var privatePool = new WeakMap();
/**
* Class responsible for the Context Menu entries for the Nested Rows plugin.
*
* @class ContextMenuUI
* @util
* @extends BaseUI
*/
var ContextMenuUI =
/*#__PURE__*/
function (_BaseUI) {
(0, _inherits2.default)(ContextMenuUI, _BaseUI);
function ContextMenuUI(nestedRowsPlugin, hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, ContextMenuUI);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ContextMenuUI).call(this, nestedRowsPlugin, hotInstance));
privatePool.set((0, _assertThisInitialized2.default)(_this), {
row_above: function row_above(key, selection) {
_this.dataManager.addSibling(selection.start.row, 'above');
},
row_below: function row_below(key, selection) {
_this.dataManager.addSibling(selection.start.row, 'below');
}
});
/**
* Reference to the DataManager instance connected with the Nested Rows plugin.
*
* @type {DataManager}
*/
_this.dataManager = _this.plugin.dataManager;
return _this;
}
/**
* Append options to the context menu. (Propagated from the `afterContextMenuDefaultOptions` hook callback)
* f
* @private
* @param {Object} defaultOptions Default context menu options.
* @returns {*}
*/
(0, _createClass2.default)(ContextMenuUI, [{
key: "appendOptions",
value: function appendOptions(defaultOptions) {
var _this2 = this;
var newEntries = [{
key: 'add_child',
name: function name() {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_NESTED_ROWS_INSERT_CHILD);
},
callback: function callback() {
var translatedRowIndex = _this2.dataManager.translateTrimmedRow(_this2.hot.getSelectedLast()[0]);
var parent = _this2.dataManager.getDataObject(translatedRowIndex);
_this2.dataManager.addChild(parent);
},
disabled: function disabled() {
var selected = _this2.hot.getSelectedLast();
return !selected || selected[0] < 0 || _this2.hot.selection.isSelectedByColumnHeader() || _this2.hot.countRows() >= _this2.hot.getSettings().maxRows;
}
}, {
key: 'detach_from_parent',
name: function name() {
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_NESTED_ROWS_DETACH_CHILD);
},
callback: function callback() {
_this2.dataManager.detachFromParent(_this2.hot.getSelectedLast());
},
disabled: function disabled() {
var selected = _this2.hot.getSelectedLast();
var translatedRowIndex = _this2.dataManager.translateTrimmedRow(selected[0]);
var parent = _this2.dataManager.getRowParent(translatedRowIndex);
return !parent || !selected || selected[0] < 0 || _this2.hot.selection.isSelectedByColumnHeader() || _this2.hot.countRows() >= _this2.hot.getSettings().maxRows;
}
}, {
name: '---------'
}];
(0, _number.rangeEach)(0, defaultOptions.items.length - 1, function (i) {
if (i === 0) {
(0, _array.arrayEach)(newEntries, function (val, j) {
defaultOptions.items.splice(i + j, 0, val);
});
return false;
}
});
return this.modifyRowInsertingOptions(defaultOptions);
}
/**
* Modify how the row inserting options work.
*
* @private
* @param {Object} defaultOptions Default context menu items.
* @returns {*}
*/
}, {
key: "modifyRowInsertingOptions",
value: function modifyRowInsertingOptions(defaultOptions) {
var priv = privatePool.get(this);
(0, _number.rangeEach)(0, defaultOptions.items.length - 1, function (i) {
var option = priv[defaultOptions.items[i].key];
if (option !== null && option !== void 0) {
defaultOptions.items[i].callback = option;
}
});
return defaultOptions;
}
}]);
return ContextMenuUI;
}(_base.default);
var _default = ContextMenuUI;
exports.default = _default;
/***/ }),
/* 512 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 513 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(56);
__webpack_require__(59);
__webpack_require__(34);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(54);
__webpack_require__(33);
__webpack_require__(80);
__webpack_require__(81);
__webpack_require__(10);
__webpack_require__(82);
__webpack_require__(39);
__webpack_require__(14);
__webpack_require__(46);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _element = __webpack_require__(5);
var _number = __webpack_require__(15);
var _array = __webpack_require__(3);
var _plugins = __webpack_require__(20);
var _predefinedItems = __webpack_require__(83);
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _hideColumn = _interopRequireDefault(__webpack_require__(514));
var _showColumn = _interopRequireDefault(__webpack_require__(515));
__webpack_require__(516);
_pluginHooks.default.getSingleton().register('beforeHideColumns');
_pluginHooks.default.getSingleton().register('afterHideColumns');
_pluginHooks.default.getSingleton().register('beforeUnhideColumns');
_pluginHooks.default.getSingleton().register('afterUnhideColumns');
/**
* @plugin HiddenColumns
*
* @description
* Plugin allows to hide certain columns. The hiding is achieved by rendering the columns with width set as 0px.
* The plugin not modifies the source data and do not participate in data transformation (the shape of data returned
* by `getData*` methods stays intact).
*
* Possible plugin settings:
* * `copyPasteEnabled` as `Boolean` (default `true`)
* * `columns` as `Array`
* * `indicators` as `Boolean` (default `false`)
*
* @example
*
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* date: getData(),
* hiddenColumns: {
* copyPasteEnabled: true,
* indicators: true,
* columns: [1, 2, 5]
* }
* });
*
* // access to hiddenColumns plugin instance:
* const hiddenColumnsPlugin = hot.getPlugin('hiddenColumns');
*
* // show single row
* hiddenColumnsPlugin.showColumn(1);
*
* // show multiple columns
* hiddenColumnsPlugin.showColumn(1, 2, 9);
*
* // or as an array
* hiddenColumnsPlugin.showColumns([1, 2, 9]);
*
* // hide single row
* hiddenColumnsPlugin.hideColumn(1);
*
* // hide multiple columns
* hiddenColumnsPlugin.hideColumn(1, 2, 9);
*
* // or as an array
* hiddenColumnsPlugin.hideColumns([1, 2, 9]);
*
* // rerender the table to see all changes
* hot.render();
* ```
*/
var HiddenColumns =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(HiddenColumns, _BasePlugin);
function HiddenColumns(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, HiddenColumns);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HiddenColumns).call(this, hotInstance));
/**
* Cached plugin settings.
*
* @private
* @type {Object}
*/
_this.settings = {};
/**
* List of currently hidden columns
*
* @private
* @type {Number[]}
*/
_this.hiddenColumns = [];
/**
* Last selected column index.
*
* @private
* @type {Number}
* @default -1
*/
_this.lastSelectedColumn = -1;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link HiddenColumns#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(HiddenColumns, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().hiddenColumns;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
if (this.hot.hasColHeaders()) {
this.addHook('afterGetColHeader', function (col, TH) {
return _this2.onAfterGetColHeader(col, TH);
});
} else {
this.addHook('afterRenderer', function (TD, row, col) {
return _this2.onAfterGetColHeader(col, TD);
});
}
this.addHook('afterContextMenuDefaultOptions', function (options) {
return _this2.onAfterContextMenuDefaultOptions(options);
});
this.addHook('afterGetCellMeta', function (row, col, cellProperties) {
return _this2.onAfterGetCellMeta(row, col, cellProperties);
});
this.addHook('modifyColWidth', function (width, col) {
return _this2.onModifyColWidth(width, col);
});
this.addHook('beforeSetRangeStartOnly', function (coords) {
return _this2.onBeforeSetRangeStart(coords);
});
this.addHook('beforeSetRangeEnd', function (coords) {
return _this2.onBeforeSetRangeEnd(coords);
});
this.addHook('hiddenColumn', function (column) {
return _this2.isHidden(column);
});
this.addHook('beforeStretchingColumnWidth', function (width, column) {
return _this2.onBeforeStretchingColumnWidth(width, column);
});
this.addHook('afterCreateCol', function (index, amount) {
return _this2.onAfterCreateCol(index, amount);
});
this.addHook('afterRemoveCol', function (index, amount) {
return _this2.onAfterRemoveCol(index, amount);
});
this.addHook('init', function () {
return _this2.onInit();
}); // Dirty workaround - the section below runs only if the HOT instance is already prepared.
if (this.hot.view) {
this.onInit();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.settings = {};
this.hiddenColumns = [];
this.lastSelectedColumn = -1;
this.hot.render();
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "disablePlugin", this).call(this);
this.resetCellsMeta();
}
/**
* Shows the provided columns.
*
* @param {Number[]} columns Array of column indexes.
*/
}, {
key: "showColumns",
value: function showColumns(columns) {
var currentHideConfig = this.hiddenColumns;
var validColumns = this.isColumnDataValid(columns);
var destinationHideConfig = currentHideConfig;
if (validColumns) {
destinationHideConfig = this.hiddenColumns.filter(function (hiddenColumn) {
return columns.includes(hiddenColumn) === false;
});
}
var continueHiding = this.hot.runHooks('beforeUnhideColumns', currentHideConfig, destinationHideConfig, validColumns);
if (continueHiding === false) {
return;
}
if (validColumns) {
this.hiddenColumns = destinationHideConfig;
}
this.hot.runHooks('afterUnhideColumns', currentHideConfig, destinationHideConfig, validColumns, validColumns && destinationHideConfig.length < currentHideConfig.length);
}
/**
* Shows a single column.
*
* @param {...Number} column Visual column index.
*/
}, {
key: "showColumn",
value: function showColumn() {
for (var _len = arguments.length, column = new Array(_len), _key = 0; _key < _len; _key++) {
column[_key] = arguments[_key];
}
this.showColumns(column);
}
/**
* Hides the columns provided in the array.
*
* @param {Number[]} columns Array of visual column indexes.
*/
}, {
key: "hideColumns",
value: function hideColumns(columns) {
var currentHideConfig = this.hiddenColumns;
var validColumns = this.isColumnDataValid(columns);
var destinationHideConfig = currentHideConfig;
if (validColumns) {
destinationHideConfig = Array.from(new Set(currentHideConfig.concat(columns)));
}
var continueHiding = this.hot.runHooks('beforeHideColumns', currentHideConfig, destinationHideConfig, validColumns);
if (continueHiding === false) {
return;
}
if (validColumns) {
this.hiddenColumns = destinationHideConfig;
}
this.hot.runHooks('afterHideColumns', currentHideConfig, destinationHideConfig, validColumns, validColumns && destinationHideConfig.length > currentHideConfig.length);
}
/**
* Hides a single column.
*
* @param {...Number} column Visual column index.
*/
}, {
key: "hideColumn",
value: function hideColumn() {
for (var _len2 = arguments.length, column = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
column[_key2] = arguments[_key2];
}
this.hideColumns(column);
}
/**
* Checks if the provided column is hidden.
*
* @param {Number} column Column index.
* @param {Boolean} isPhysicalIndex flag which determines type of index.
* @returns {Boolean}
*/
}, {
key: "isHidden",
value: function isHidden(column) {
var isPhysicalIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var physicalColumn = column;
if (!isPhysicalIndex) {
physicalColumn = this.hot.toPhysicalColumn(column);
}
return this.hiddenColumns.includes(physicalColumn);
}
/**
* Check whether all of the provided column indexes are within the bounds of the table.
*
* @param {Array} columns Array of column indexes.
*/
}, {
key: "isColumnDataValid",
value: function isColumnDataValid(columns) {
var _this3 = this;
return columns.every(function (column) {
return Number.isInteger(column) && column >= 0 && column < _this3.hot.countCols();
});
}
/**
* Reset all rendered cells meta.
*
* @private
*/
}, {
key: "resetCellsMeta",
value: function resetCellsMeta() {
(0, _array.arrayEach)(this.hot.getCellsMeta(), function (meta) {
if (meta) {
meta.skipColumnOnPaste = false;
if (meta.baseRenderer !== null) {
meta.renderer = meta.baseRenderer;
meta.baseRenderer = null;
}
}
});
}
/**
* Sets width hidden columns on 0
*
* @private
* @param {Number} width Column width.
* @param {Number} column Column index.
* @returns {Number}
*/
}, {
key: "onBeforeStretchingColumnWidth",
value: function onBeforeStretchingColumnWidth(width, column) {
var stretchedWidth = width;
if (this.isHidden(column)) {
stretchedWidth = 0;
}
return stretchedWidth;
}
/**
* Adds the additional column width for the hidden column indicators.
*
* @private
* @param {Number} width
* @param {Number} col
* @returns {Number}
*/
}, {
key: "onModifyColWidth",
value: function onModifyColWidth(width, col) {
if (this.isHidden(col)) {
return 0.1;
} else if (this.settings.indicators && (this.isHidden(col + 1) || this.isHidden(col - 1))) {
// add additional space for hidden column indicator
return width + (this.hot.hasColHeaders() ? 15 : 0);
}
}
/**
* Sets the copy-related cell meta.
*
* @private
* @param {Number} row
* @param {Number} col
* @param {Object} cellProperties
*
* @fires Hooks#unmodifyCol
*/
}, {
key: "onAfterGetCellMeta",
value: function onAfterGetCellMeta(row, col, cellProperties) {
var colIndex = this.hot.runHooks('unmodifyCol', col);
if (this.settings.copyPasteEnabled === false && this.isHidden(col)) {
cellProperties.skipColumnOnPaste = true;
}
if (this.isHidden(colIndex)) {
if (cellProperties.renderer !== hiddenRenderer) {
cellProperties.baseRenderer = cellProperties.renderer;
}
cellProperties.renderer = hiddenRenderer;
} else if (cellProperties.baseRenderer !== null) {
// We must pass undefined value too (for the purposes of inheritance cell/column settings).
cellProperties.renderer = cellProperties.baseRenderer;
cellProperties.baseRenderer = null;
}
if (this.isHidden(cellProperties.visualCol - 1)) {
var firstSectionHidden = true;
var i = cellProperties.visualCol - 1;
cellProperties.className = cellProperties.className || '';
if (cellProperties.className.indexOf('afterHiddenColumn') === -1) {
cellProperties.className += ' afterHiddenColumn';
}
do {
if (!this.isHidden(i)) {
firstSectionHidden = false;
break;
}
i -= 1;
} while (i >= 0);
if (firstSectionHidden && cellProperties.className.indexOf('firstVisibleColumn') === -1) {
cellProperties.className += ' firstVisibleColumn';
}
} else if (cellProperties.className) {
var classArr = cellProperties.className.split(' ');
if (classArr.length) {
var containAfterHiddenColumn = classArr.indexOf('afterHiddenColumn');
if (containAfterHiddenColumn > -1) {
classArr.splice(containAfterHiddenColumn, 1);
}
var containFirstVisible = classArr.indexOf('firstVisibleColumn');
if (containFirstVisible > -1) {
classArr.splice(containFirstVisible, 1);
}
cellProperties.className = classArr.join(' ');
}
}
}
/**
* Modifies the copyable range, accordingly to the provided config.
*
* @private
* @param {Array} ranges
* @returns {Array}
*/
}, {
key: "onModifyCopyableRange",
value: function onModifyCopyableRange(ranges) {
var _this4 = this;
var newRanges = [];
var pushRange = function pushRange(startRow, endRow, startCol, endCol) {
newRanges.push({
startRow: startRow,
endRow: endRow,
startCol: startCol,
endCol: endCol
});
};
(0, _array.arrayEach)(ranges, function (range) {
var isHidden = true;
var rangeStart = 0;
(0, _number.rangeEach)(range.startCol, range.endCol, function (col) {
if (_this4.isHidden(col)) {
if (!isHidden) {
pushRange(range.startRow, range.endRow, rangeStart, col - 1);
}
isHidden = true;
} else {
if (isHidden) {
rangeStart = col;
}
if (col === range.endCol) {
pushRange(range.startRow, range.endRow, rangeStart, col);
}
isHidden = false;
}
});
});
return newRanges;
}
/**
* Adds the needed classes to the headers.
*
* @private
* @param {Number} column
* @param {HTMLElement} TH
*/
}, {
key: "onAfterGetColHeader",
value: function onAfterGetColHeader(column, TH) {
if (this.isHidden(column)) {
return;
}
var firstSectionHidden = true;
var i = column - 1;
do {
if (!this.isHidden(i)) {
firstSectionHidden = false;
break;
}
i -= 1;
} while (i >= 0);
if (firstSectionHidden) {
(0, _element.addClass)(TH, 'firstVisibleColumn');
}
if (!this.settings.indicators) {
return;
}
if (this.isHidden(column - 1)) {
(0, _element.addClass)(TH, 'afterHiddenColumn');
}
if (this.isHidden(column + 1) && column > -1) {
(0, _element.addClass)(TH, 'beforeHiddenColumn');
}
}
/**
* On before set range start listener.
*
* @private
* @param {Object} coords Object with `row` and `col` properties.
*/
}, {
key: "onBeforeSetRangeStart",
value: function onBeforeSetRangeStart(coords) {
var _this5 = this;
if (coords.col > 0) {
return;
}
coords.col = 0;
var getNextColumn = function getNextColumn(col) {
var visualColumn = col;
var physicalColumn = _this5.hot.toPhysicalColumn(visualColumn);
if (_this5.isHidden(physicalColumn, true)) {
visualColumn += 1;
visualColumn = getNextColumn(visualColumn);
}
return visualColumn;
};
coords.col = getNextColumn(coords.col);
}
/**
* On before set range end listener.
*
* @private
* @param {Object} coords Object with `row` and `col` properties.
*/
}, {
key: "onBeforeSetRangeEnd",
value: function onBeforeSetRangeEnd(coords) {
var _this6 = this;
var columnCount = this.hot.countCols();
var getNextColumn = function getNextColumn(col) {
var visualColumn = col;
var physicalColumn = _this6.hot.toPhysicalColumn(visualColumn);
if (_this6.isHidden(physicalColumn, true)) {
if (_this6.lastSelectedColumn > visualColumn || coords.col === columnCount - 1) {
if (visualColumn > 0) {
visualColumn -= 1;
visualColumn = getNextColumn(visualColumn);
} else {
(0, _number.rangeEach)(0, _this6.lastSelectedColumn, function (i) {
if (!_this6.isHidden(i)) {
visualColumn = i;
return false;
}
});
}
} else {
visualColumn += 1;
visualColumn = getNextColumn(visualColumn);
}
}
return visualColumn;
};
coords.col = getNextColumn(coords.col);
this.lastSelectedColumn = coords.col;
}
/**
* Add Show-hide columns to context menu.
*
* @private
* @param {Object} options
*/
}, {
key: "onAfterContextMenuDefaultOptions",
value: function onAfterContextMenuDefaultOptions(options) {
options.items.push({
name: _predefinedItems.SEPARATOR
}, (0, _hideColumn.default)(this), (0, _showColumn.default)(this));
}
/**
* `onAfterCreateCol` hook callback.
*
* @private
*/
}, {
key: "onAfterCreateCol",
value: function onAfterCreateCol(index, amount) {
var tempHidden = [];
(0, _array.arrayEach)(this.hiddenColumns, function (col) {
var visualColumn = col;
if (visualColumn >= index) {
visualColumn += amount;
}
tempHidden.push(visualColumn);
});
this.hiddenColumns = tempHidden;
}
/**
* `onAfterRemoveCol` hook callback.
*
* @private
*/
}, {
key: "onAfterRemoveCol",
value: function onAfterRemoveCol(index, amount) {
var tempHidden = [];
(0, _array.arrayEach)(this.hiddenColumns, function (col) {
var visualColumn = col;
if (visualColumn >= index) {
visualColumn -= amount;
}
tempHidden.push(visualColumn);
});
this.hiddenColumns = tempHidden;
}
/**
* `afterPluginsInitialized` hook callback.
*
* @private
*/
}, {
key: "onInit",
value: function onInit() {
var _this7 = this;
var settings = this.hot.getSettings().hiddenColumns;
if ((0, _typeof2.default)(settings) === 'object') {
this.settings = settings;
if (settings.copyPasteEnabled === void 0) {
settings.copyPasteEnabled = true;
}
if (Array.isArray(settings.columns)) {
this.hideColumns(settings.columns);
}
if (!settings.copyPasteEnabled) {
this.addHook('modifyCopyableRange', function (ranges) {
return _this7.onModifyCopyableRange(ranges);
});
}
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenColumns.prototype), "destroy", this).call(this);
}
}]);
return HiddenColumns;
}(_base.default);
function hiddenRenderer(hotInstance, td) {
td.textContent = '';
}
(0, _plugins.registerPlugin)('hiddenColumns', HiddenColumns);
var _default = HiddenColumns;
exports.default = _default;
/***/ }),
/* 514 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = hideColumnItem;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _number = __webpack_require__(15);
var C = _interopRequireWildcard(__webpack_require__(11));
function hideColumnItem(hiddenColumnsPlugin) {
return {
key: 'hidden_columns_hide',
name: function name() {
var selection = this.getSelectedLast();
var pluralForm = 0;
if (Array.isArray(selection)) {
var _selection = (0, _slicedToArray2.default)(selection, 4),
fromColumn = _selection[1],
toColumn = _selection[3];
if (fromColumn - toColumn !== 0) {
pluralForm = 1;
}
}
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_HIDE_COLUMN, pluralForm);
},
callback: function callback() {
var _this$getSelectedRang = this.getSelectedRangeLast(),
from = _this$getSelectedRang.from,
to = _this$getSelectedRang.to;
var start = Math.min(from.col, to.col);
var end = Math.max(from.col, to.col);
(0, _number.rangeEach)(start, end, function (column) {
return hiddenColumnsPlugin.hideColumn(column);
});
this.render();
this.view.wt.wtOverlays.adjustElementsSize(true);
},
disabled: false,
hidden: function hidden() {
return !this.selection.isSelectedByColumnHeader();
}
};
}
/***/ }),
/* 515 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = showColumnItem;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _number = __webpack_require__(15);
var C = _interopRequireWildcard(__webpack_require__(11));
function showColumnItem(hiddenColumnsPlugin) {
var beforeHiddenColumns = [];
var afterHiddenColumns = [];
return {
key: 'hidden_columns_show',
name: function name() {
var selection = this.getSelectedLast();
var pluralForm = 0;
if (Array.isArray(selection)) {
var _selection = (0, _slicedToArray2.default)(selection, 4),
fromColumn = _selection[1],
toColumn = _selection[3];
if (fromColumn > toColumn) {
var _ref = [toColumn, fromColumn];
fromColumn = _ref[0];
toColumn = _ref[1];
}
var hiddenColumns = 0;
if (fromColumn === toColumn) {
hiddenColumns = beforeHiddenColumns.length + afterHiddenColumns.length;
} else {
(0, _number.rangeEach)(fromColumn, toColumn, function (column) {
if (hiddenColumnsPlugin.isHidden(column)) {
hiddenColumns += 1;
}
});
}
pluralForm = hiddenColumns <= 1 ? 0 : 1;
}
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_SHOW_COLUMN, pluralForm);
},
callback: function callback() {
var _this$getSelectedRang = this.getSelectedRangeLast(),
from = _this$getSelectedRang.from,
to = _this$getSelectedRang.to;
var start = Math.min(from.col, to.col);
var end = Math.max(from.col, to.col);
if (start === end) {
if (beforeHiddenColumns.length === start) {
hiddenColumnsPlugin.showColumns(beforeHiddenColumns);
beforeHiddenColumns.length = 0;
}
if (afterHiddenColumns.length === this.countSourceCols() - (start + 1)) {
hiddenColumnsPlugin.showColumns(afterHiddenColumns);
afterHiddenColumns.length = 0;
}
} else {
(0, _number.rangeEach)(start, end, function (column) {
return hiddenColumnsPlugin.showColumn(column);
});
}
this.render();
this.view.wt.wtOverlays.adjustElementsSize(true);
},
disabled: false,
hidden: function hidden() {
if (!hiddenColumnsPlugin.hiddenColumns.length || !this.selection.isSelectedByColumnHeader()) {
return true;
}
beforeHiddenColumns.length = 0;
afterHiddenColumns.length = 0;
var _this$getSelectedRang2 = this.getSelectedRangeLast(),
from = _this$getSelectedRang2.from,
to = _this$getSelectedRang2.to;
var start = Math.min(from.col, to.col);
var end = Math.max(from.col, to.col);
var hiddenInSelection = false;
if (start === end) {
var totalColumnLength = this.countSourceCols();
(0, _number.rangeEach)(0, totalColumnLength, function (column) {
var partedHiddenLength = beforeHiddenColumns.length + afterHiddenColumns.length;
if (partedHiddenLength === hiddenColumnsPlugin.hiddenColumns.length) {
return false;
}
if (column < start && hiddenColumnsPlugin.isHidden(column)) {
beforeHiddenColumns.push(column);
} else if (hiddenColumnsPlugin.isHidden(column)) {
afterHiddenColumns.push(column);
}
});
totalColumnLength -= 1;
if (beforeHiddenColumns.length === start && start > 0 || afterHiddenColumns.length === totalColumnLength - start && start < totalColumnLength) {
hiddenInSelection = true;
}
} else {
(0, _number.rangeEach)(start, end, function (column) {
if (hiddenColumnsPlugin.isHidden(column)) {
hiddenInSelection = true;
return false;
}
});
}
return !hiddenInSelection;
}
};
}
/***/ }),
/* 516 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 517 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(56);
__webpack_require__(59);
__webpack_require__(34);
__webpack_require__(12);
__webpack_require__(16);
__webpack_require__(54);
__webpack_require__(33);
__webpack_require__(80);
__webpack_require__(81);
__webpack_require__(10);
__webpack_require__(82);
__webpack_require__(39);
__webpack_require__(14);
__webpack_require__(46);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _typeof2 = _interopRequireDefault(__webpack_require__(44));
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _element = __webpack_require__(5);
var _number = __webpack_require__(15);
var _array = __webpack_require__(3);
var _plugins = __webpack_require__(20);
var _pluginHooks = _interopRequireDefault(__webpack_require__(43));
var _hideRow = _interopRequireDefault(__webpack_require__(518));
var _showRow = _interopRequireDefault(__webpack_require__(519));
__webpack_require__(520);
_pluginHooks.default.getSingleton().register('beforeHideRows');
_pluginHooks.default.getSingleton().register('afterHideRows');
_pluginHooks.default.getSingleton().register('beforeUnhideRows');
_pluginHooks.default.getSingleton().register('afterUnhideRows');
/**
* @plugin HiddenRows
*
* @description
* Plugin allows to hide certain rows. The hiding is achieved by rendering the rows with height set as 0px.
* The plugin not modifies the source data and do not participate in data transformation (the shape of data returned
* by `getData*` methods stays intact).
*
* Possible plugin settings:
* * `copyPasteEnabled` as `Boolean` (default `true`)
* * `rows` as `Array`
* * `indicators` as `Boolean` (default `false`)
*
* @example
*
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* date: getData(),
* hiddenRows: {
* copyPasteEnabled: true,
* indicators: true,
* rows: [1, 2, 5]
* }
* });
*
* // access to hiddenRows plugin instance
* const hiddenRowsPlugin = hot.getPlugin('hiddenRows');
*
* // show single row
* hiddenRowsPlugin.showRow(1);
*
* // show multiple rows
* hiddenRowsPlugin.showRow(1, 2, 9);
*
* // or as an array
* hiddenRowsPlugin.showRows([1, 2, 9]);
*
* // hide single row
* hiddenRowsPlugin.hideRow(1);
*
* // hide multiple rows
* hiddenRowsPlugin.hideRow(1, 2, 9);
*
* // or as an array
* hiddenRowsPlugin.hideRows([1, 2, 9]);
*
* // rerender the table to see all changes
* hot.render();
* ```
*/
var HiddenRows =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(HiddenRows, _BasePlugin);
function HiddenRows(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, HiddenRows);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(HiddenRows).call(this, hotInstance));
/**
* Cached settings from Handsontable settings.
*
* @private
* @type {Object}
*/
_this.settings = {};
/**
* List of hidden rows indexes.
*
* @private
* @type {Number[]}
*/
_this.hiddenRows = [];
/**
* Last selected row index.
*
* @private
* @type {Number}
* @default -1
*/
_this.lastSelectedRow = -1;
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link HiddenRows#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(HiddenRows, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().hiddenRows;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
if (this.hot.hasRowHeaders()) {
this.addHook('afterGetRowHeader', function (row, TH) {
return _this2.onAfterGetRowHeader(row, TH);
});
} else {
this.addHook('afterRenderer', function (TD, row) {
return _this2.onAfterGetRowHeader(row, TD);
});
}
this.addHook('afterContextMenuDefaultOptions', function (options) {
return _this2.onAfterContextMenuDefaultOptions(options);
});
this.addHook('afterGetCellMeta', function (row, col, cellProperties) {
return _this2.onAfterGetCellMeta(row, col, cellProperties);
});
this.addHook('modifyRowHeight', function (height, row) {
return _this2.onModifyRowHeight(height, row);
});
this.addHook('beforeSetRangeStartOnly', function (coords) {
return _this2.onBeforeSetRangeStartOnly(coords);
});
this.addHook('beforeSetRangeStart', function (coords) {
return _this2.onBeforeSetRangeStart(coords);
});
this.addHook('beforeSetRangeEnd', function (coords) {
return _this2.onBeforeSetRangeEnd(coords);
});
this.addHook('hiddenRow', function (row) {
return _this2.isHidden(row);
});
this.addHook('afterCreateRow', function (index, amount) {
return _this2.onAfterCreateRow(index, amount);
});
this.addHook('afterRemoveRow', function (index, amount) {
return _this2.onAfterRemoveRow(index, amount);
});
this.addHook('init', function () {
return _this2.onInit();
}); // Dirty workaround - the section below runs only if the HOT instance is already prepared.
if (this.hot.view) {
this.onInit();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
this.disablePlugin();
this.enablePlugin();
this.onInit();
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.settings = {};
this.hiddenRows = [];
this.lastSelectedRow = -1;
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "disablePlugin", this).call(this);
this.resetCellsMeta();
}
/**
* Shows the rows provided in the array.
*
* @param {Number[]} rows Array of visual row indexes.
*/
}, {
key: "showRows",
value: function showRows(rows) {
var _this3 = this;
var currentHideConfig = this.hiddenRows;
var validRows = this.isRowDataValid(rows);
var physicalRows = (0, _array.arrayMap)(rows, function (visualRowIndex) {
return _this3.hot.toPhysicalRow(visualRowIndex);
});
var destinationHideConfig = currentHideConfig;
if (validRows) {
destinationHideConfig = this.hiddenRows.filter(function (hiddenRow) {
return physicalRows.includes(hiddenRow) === false;
});
}
var continueHiding = this.hot.runHooks('beforeUnhideRows', currentHideConfig, destinationHideConfig, validRows);
if (continueHiding === false) {
return;
}
if (validRows) {
this.hiddenRows = destinationHideConfig;
}
this.hot.runHooks('afterUnhideRows', currentHideConfig, destinationHideConfig, validRows, validRows && destinationHideConfig.length < currentHideConfig.length);
}
/**
* Shows the row provided as row index (counting from 0).
*
* @param {...Number} row Visual row index.
*/
}, {
key: "showRow",
value: function showRow() {
for (var _len = arguments.length, row = new Array(_len), _key = 0; _key < _len; _key++) {
row[_key] = arguments[_key];
}
this.showRows(row);
}
/**
* Hides the rows provided in the array.
*
* @param {Number[]} rows Array of visual row indexes.
*/
}, {
key: "hideRows",
value: function hideRows(rows) {
var _this4 = this;
var currentHideConfig = this.hiddenRows;
var validRows = this.isRowDataValid(rows);
var physicalRows = (0, _array.arrayMap)(rows, function (visualRowIndex) {
return _this4.hot.toPhysicalRow(visualRowIndex);
});
var destinationHideConfig = currentHideConfig;
if (validRows) {
// Creating unique list of indexes.
destinationHideConfig = Array.from(new Set(currentHideConfig.concat(physicalRows)));
}
var continueHiding = this.hot.runHooks('beforeHideRows', currentHideConfig, destinationHideConfig, validRows);
if (continueHiding === false) {
return;
}
if (validRows) {
this.hiddenRows = destinationHideConfig;
}
this.hot.runHooks('afterHideRows', currentHideConfig, destinationHideConfig, validRows, validRows && destinationHideConfig.length > currentHideConfig.length);
}
/**
* Hides the row provided as row index (counting from 0).
*
* @param {...Number} row Visual row index.
*/
}, {
key: "hideRow",
value: function hideRow() {
for (var _len2 = arguments.length, row = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
row[_key2] = arguments[_key2];
}
this.hideRows(row);
}
/**
* Checks if given row is hidden.
*
* @param {Number} row Row index.
* @param {Boolean} isPhysicalIndex flag which determines type of index.
* @returns {Boolean}
*/
}, {
key: "isHidden",
value: function isHidden(row) {
var isPhysicalIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var physicalRow = row;
if (!isPhysicalIndex) {
physicalRow = this.hot.toPhysicalRow(row);
}
return this.hiddenRows.includes(physicalRow);
}
/**
* Check whether all of the provided row indexes are within the bounds of the table.
*
* @param {Array} rows Array of visual row indexes.
*/
}, {
key: "isRowDataValid",
value: function isRowDataValid(rows) {
var _this5 = this;
return rows.every(function (row) {
return Number.isInteger(row) && row >= 0 && row < _this5.hot.countRows();
});
}
/**
* Resets all rendered cells meta.
*
* @private
*/
}, {
key: "resetCellsMeta",
value: function resetCellsMeta() {
(0, _array.arrayEach)(this.hot.getCellsMeta(), function (meta) {
if (meta) {
meta.skipRowOnPaste = false;
}
});
}
/**
* Sets the copy-related cell meta.
*
* @private
* @param {Number} row Row index.
* @param {Number} col Column index.
* @param {Object} cellProperties Cell meta object properties.
*
* @fires Hooks#unmodifyRow
*/
}, {
key: "onAfterGetCellMeta",
value: function onAfterGetCellMeta(row, col, cellProperties) {
var visualRow = this.hot.runHooks('unmodifyRow', row);
if (this.settings.copyPasteEnabled === false && this.isHidden(visualRow)) {
cellProperties.skipRowOnPaste = true;
} else {
cellProperties.skipRowOnPaste = false;
}
if (this.isHidden(visualRow - 1)) {
var firstSectionHidden = true;
var i = visualRow - 1;
cellProperties.className = cellProperties.className || '';
if (cellProperties.className.indexOf('afterHiddenRow') === -1) {
cellProperties.className += ' afterHiddenRow';
}
do {
if (!this.isHidden(i)) {
firstSectionHidden = false;
break;
}
i -= 1;
} while (i >= 0);
if (firstSectionHidden && cellProperties.className.indexOf('firstVisibleRow') === -1) {
cellProperties.className += ' firstVisibleRow';
}
} else if (cellProperties.className) {
var classArr = cellProperties.className.split(' ');
if (classArr.length) {
var containAfterHiddenColumn = classArr.indexOf('afterHiddenRow');
if (containAfterHiddenColumn > -1) {
classArr.splice(containAfterHiddenColumn, 1);
}
var containFirstVisible = classArr.indexOf('firstVisibleRow');
if (containFirstVisible > -1) {
classArr.splice(containFirstVisible, 1);
}
cellProperties.className = classArr.join(' ');
}
}
}
/**
* Adds the needed classes to the headers.
*
* @private
* @param {Number} row Row index.
* @param {HTMLElement} th Table header element.
*/
}, {
key: "onAfterGetRowHeader",
value: function onAfterGetRowHeader(row, th) {
var tr = th.parentNode;
if (tr) {
if (this.isHidden(row)) {
(0, _element.addClass)(tr, 'hide');
} else {
(0, _element.removeClass)(tr, 'hide');
}
}
var firstSectionHidden = true;
var i = row - 1;
do {
if (!this.isHidden(i)) {
firstSectionHidden = false;
break;
}
i -= 1;
} while (i >= 0);
if (firstSectionHidden) {
(0, _element.addClass)(th, 'firstVisibleRow');
}
if (this.settings.indicators && this.hot.hasRowHeaders()) {
if (this.isHidden(row - 1)) {
(0, _element.addClass)(th, 'afterHiddenRow');
}
if (this.isHidden(row + 1)) {
(0, _element.addClass)(th, 'beforeHiddenRow');
}
}
}
/**
* Adds the additional row height for the hidden row indicators.
*
* @private
* @param {Number} height Row height.
* @param {Number} row Row index.
* @returns {Number}
*/
}, {
key: "onModifyRowHeight",
value: function onModifyRowHeight(height, row) {
if (this.isHidden(row)) {
return 0.1;
}
return height;
}
/**
* On modify copyable range listener.
*
* @private
* @param {Array} ranges Array of selected copyable text.
* @returns {Array} Returns modyfied range.
*/
}, {
key: "onModifyCopyableRange",
value: function onModifyCopyableRange(ranges) {
var _this6 = this;
var newRanges = [];
var pushRange = function pushRange(startRow, endRow, startCol, endCol) {
newRanges.push({
startRow: startRow,
endRow: endRow,
startCol: startCol,
endCol: endCol
});
};
(0, _array.arrayEach)(ranges, function (range) {
var isHidden = true;
var rangeStart = 0;
(0, _number.rangeEach)(range.startRow, range.endRow, function (row) {
if (_this6.isHidden(row)) {
if (!isHidden) {
pushRange(rangeStart, row - 1, range.startCol, range.endCol);
}
isHidden = true;
} else {
if (isHidden) {
rangeStart = row;
}
if (row === range.endRow) {
pushRange(rangeStart, row, range.startCol, range.endCol);
}
isHidden = false;
}
});
});
return newRanges;
}
/**
* On before set range start listener, when selection was triggered by the cell.
*
* @private
* @param {Object} coords Object with `row` and `col` properties.
*/
}, {
key: "onBeforeSetRangeStart",
value: function onBeforeSetRangeStart(coords) {
var _this7 = this;
var actualSelection = this.hot.getSelectedLast() || false;
var lastPossibleIndex = this.hot.countRows() - 1;
var getNextRow = function getNextRow(row) {
var direction = 0;
var visualRow = row;
if (actualSelection) {
direction = visualRow > actualSelection[0] ? 1 : -1;
_this7.lastSelectedRow = actualSelection[0];
}
if (lastPossibleIndex < visualRow || visualRow < 0) {
return _this7.lastSelectedRow;
}
if (_this7.isHidden(visualRow)) {
visualRow = getNextRow(visualRow + direction);
}
return visualRow;
};
coords.row = getNextRow(coords.row);
}
/**
* On before set range start listener, when selection was triggered by the headers.
*
* @private
* @param {Object} coords Object with `row` and `col` properties.
*/
}, {
key: "onBeforeSetRangeStartOnly",
value: function onBeforeSetRangeStartOnly(coords) {
var _this8 = this;
if (coords.row > 0) {
return;
}
coords.row = 0;
var getNextRow = function getNextRow(row) {
var visualRow = row;
if (_this8.isHidden(visualRow)) {
visualRow += 1;
visualRow = getNextRow(visualRow);
}
return visualRow;
};
coords.row = getNextRow(coords.row);
}
/**
* On before set range end listener.
*
* @private
* @param {Object} coords Object with `row` and `col` properties.
*/
}, {
key: "onBeforeSetRangeEnd",
value: function onBeforeSetRangeEnd(coords) {
var _this9 = this;
var rowCount = this.hot.countRows();
var getNextRow = function getNextRow(row) {
var visualRow = row;
if (_this9.isHidden(visualRow)) {
if (_this9.lastSelectedRow > visualRow || coords.row === rowCount - 1) {
if (visualRow > 0) {
visualRow -= 1;
visualRow = getNextRow(visualRow);
} else {
(0, _number.rangeEach)(0, _this9.lastSelectedRow, function (i) {
if (!_this9.isHidden(i)) {
visualRow = i;
return false;
}
});
}
} else {
visualRow += 1;
visualRow = getNextRow(visualRow);
}
}
return visualRow;
};
coords.row = getNextRow(coords.row);
this.lastSelectedRow = coords.row;
}
/**
* Adds Show-hide columns to context menu.
*
* @private
* @param {Object} options
*/
}, {
key: "onAfterContextMenuDefaultOptions",
value: function onAfterContextMenuDefaultOptions(options) {
options.items.push({
name: '---------'
}, (0, _hideRow.default)(this), (0, _showRow.default)(this));
}
/**
* Recalculates index of hidden rows after add row action
*
* @private
* @param {Number} index
* @param {Number} amount
*/
}, {
key: "onAfterCreateRow",
value: function onAfterCreateRow(index, amount) {
var tempHidden = [];
(0, _array.arrayEach)(this.hiddenRows, function (row) {
var visualRow = row;
if (visualRow >= index) {
visualRow += amount;
}
tempHidden.push(visualRow);
});
this.hiddenRows = tempHidden;
}
/**
* Recalculates index of hidden rows after remove row action
*
* @private
* @param {Number} index
* @param {Number} amount
*/
}, {
key: "onAfterRemoveRow",
value: function onAfterRemoveRow(index, amount) {
var tempHidden = [];
(0, _array.arrayEach)(this.hiddenRows, function (row) {
var visualRow = row;
if (visualRow >= index) {
visualRow -= amount;
}
tempHidden.push(visualRow);
});
this.hiddenRows = tempHidden;
}
/**
* `afterPluginsInitialized` hook callback.
*
* @private
*/
}, {
key: "onInit",
value: function onInit() {
var _this10 = this;
var settings = this.hot.getSettings().hiddenRows;
if ((0, _typeof2.default)(settings) === 'object') {
this.settings = settings;
if (settings.copyPasteEnabled === void 0) {
settings.copyPasteEnabled = true;
}
if (Array.isArray(settings.rows)) {
this.hideRows(settings.rows);
}
if (!settings.copyPasteEnabled) {
this.addHook('modifyCopyableRange', function (ranges) {
return _this10.onModifyCopyableRange(ranges);
});
}
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
(0, _get2.default)((0, _getPrototypeOf2.default)(HiddenRows.prototype), "destroy", this).call(this);
}
}]);
return HiddenRows;
}(_base.default);
(0, _plugins.registerPlugin)('hiddenRows', HiddenRows);
var _default = HiddenRows;
exports.default = _default;
/***/ }),
/* 518 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = hideRowItem;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _number = __webpack_require__(15);
var C = _interopRequireWildcard(__webpack_require__(11));
function hideRowItem(hiddenRowsPlugin) {
return {
key: 'hidden_rows_hide',
name: function name() {
var selection = this.getSelectedLast();
var pluralForm = 0;
if (Array.isArray(selection)) {
var _selection = (0, _slicedToArray2.default)(selection, 3),
fromRow = _selection[0],
toRow = _selection[2];
if (fromRow - toRow !== 0) {
pluralForm = 1;
}
}
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_HIDE_ROW, pluralForm);
},
callback: function callback() {
var _this$getSelectedRang = this.getSelectedRangeLast(),
from = _this$getSelectedRang.from,
to = _this$getSelectedRang.to;
var start = Math.min(from.row, to.row);
var end = Math.max(from.row, to.row);
(0, _number.rangeEach)(start, end, function (row) {
return hiddenRowsPlugin.hideRow(row);
});
this.render();
this.view.wt.wtOverlays.adjustElementsSize(true);
},
disabled: false,
hidden: function hidden() {
return !this.selection.isSelectedByRowHeader();
}
};
}
/***/ }),
/* 519 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireWildcard = __webpack_require__(9);
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = showRowItem;
var _slicedToArray2 = _interopRequireDefault(__webpack_require__(19));
var _number = __webpack_require__(15);
var C = _interopRequireWildcard(__webpack_require__(11));
function showRowItem(hiddenRowsPlugin) {
var beforeHiddenRows = [];
var afterHiddenRows = [];
return {
key: 'hidden_rows_show',
name: function name() {
var selection = this.getSelectedLast();
var pluralForm = 0;
if (Array.isArray(selection)) {
var _selection = (0, _slicedToArray2.default)(selection, 3),
fromRow = _selection[0],
toRow = _selection[2];
if (fromRow > toRow) {
var _ref = [toRow, fromRow];
fromRow = _ref[0];
toRow = _ref[1];
}
var hiddenRows = 0;
if (fromRow === toRow) {
hiddenRows = beforeHiddenRows.length + afterHiddenRows.length;
} else {
(0, _number.rangeEach)(fromRow, toRow, function (column) {
if (hiddenRowsPlugin.isHidden(column)) {
hiddenRows += 1;
}
});
}
pluralForm = hiddenRows <= 1 ? 0 : 1;
}
return this.getTranslatedPhrase(C.CONTEXTMENU_ITEMS_SHOW_ROW, pluralForm);
},
callback: function callback() {
var _this$getSelectedRang = this.getSelectedRangeLast(),
from = _this$getSelectedRang.from,
to = _this$getSelectedRang.to;
var start = Math.min(from.row, to.row);
var end = Math.max(from.row, to.row);
if (start === end) {
if (beforeHiddenRows.length === start) {
hiddenRowsPlugin.showRows(beforeHiddenRows);
beforeHiddenRows.length = 0;
}
if (afterHiddenRows.length === this.countSourceRows() - (start + 1)) {
hiddenRowsPlugin.showRows(afterHiddenRows);
afterHiddenRows.length = 0;
}
} else {
(0, _number.rangeEach)(start, end, function (row) {
return hiddenRowsPlugin.showRow(row);
});
}
this.render();
this.view.wt.wtOverlays.adjustElementsSize(true);
},
disabled: false,
hidden: function hidden() {
if (!hiddenRowsPlugin.hiddenRows.length || !this.selection.isSelectedByRowHeader()) {
return true;
}
beforeHiddenRows.length = 0;
afterHiddenRows.length = 0;
var _this$getSelectedRang2 = this.getSelectedRangeLast(),
from = _this$getSelectedRang2.from,
to = _this$getSelectedRang2.to;
var start = Math.min(from.row, to.row);
var end = Math.max(from.row, to.row);
var hiddenInSelection = false;
if (start === end) {
var totalRowsLength = this.countSourceRows();
(0, _number.rangeEach)(0, totalRowsLength, function (i) {
var partedHiddenLength = beforeHiddenRows.length + afterHiddenRows.length;
if (partedHiddenLength === hiddenRowsPlugin.hiddenRows.length) {
return false;
}
if (i < start) {
if (hiddenRowsPlugin.isHidden(i)) {
beforeHiddenRows.push(i);
}
} else if (hiddenRowsPlugin.isHidden(i)) {
afterHiddenRows.push(i);
}
});
totalRowsLength -= 1;
if (beforeHiddenRows.length === start && start > 0 || afterHiddenRows.length === totalRowsLength - start && start < totalRowsLength) {
hiddenInSelection = true;
}
} else {
(0, _number.rangeEach)(start, end, function (i) {
if (hiddenRowsPlugin.isHidden(i)) {
hiddenInSelection = true;
return false;
}
});
}
return !hiddenInSelection;
}
};
}
/***/ }),
/* 520 */
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/* 521 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
__webpack_require__(18);
__webpack_require__(56);
__webpack_require__(59);
__webpack_require__(34);
__webpack_require__(16);
__webpack_require__(80);
__webpack_require__(81);
__webpack_require__(10);
__webpack_require__(82);
__webpack_require__(39);
__webpack_require__(14);
__webpack_require__(17);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(7));
var _assertThisInitialized2 = _interopRequireDefault(__webpack_require__(26));
var _getPrototypeOf2 = _interopRequireDefault(__webpack_require__(6));
var _get2 = _interopRequireDefault(__webpack_require__(13));
var _inherits2 = _interopRequireDefault(__webpack_require__(8));
var _base = _interopRequireDefault(__webpack_require__(21));
var _number = __webpack_require__(15);
var _plugins = __webpack_require__(20);
var _rowsMapper = _interopRequireDefault(__webpack_require__(522));
var _array = __webpack_require__(3);
/**
* @plugin TrimRows
*
* @description
* The plugin allows to trim certain rows. The trimming is achieved by applying the transformation algorithm to the data
* transformation. In this case, when the row is trimmed it is not accessible using `getData*` methods thus the trimmed
* data is not visible to other plugins.
*
* @example
* ```js
* const container = document.getElementById('example');
* const hot = new Handsontable(container, {
* date: getData(),
* // hide selected rows on table initialization
* trimRows: [1, 2, 5]
* });
*
* // access the trimRows plugin instance
* const trimRowsPlugin = hot.getPlugin('trimRows');
*
* // hide single row
* trimRowsPlugin.trimRow(1);
*
* // hide multiple rows
* trimRowsPlugin.trimRow(1, 2, 9);
*
* // or as an array
* trimRowsPlugin.trimRows([1, 2, 9]);
*
* // show single row
* trimRowsPlugin.untrimRow(1);
*
* // show multiple rows
* trimRowsPlugin.untrimRow(1, 2, 9);
*
* // or as an array
* trimRowsPlugin.untrimRows([1, 2, 9]);
*
* // rerender table to see the changes
* hot.render();
* ```
*/
var TrimRows =
/*#__PURE__*/
function (_BasePlugin) {
(0, _inherits2.default)(TrimRows, _BasePlugin);
function TrimRows(hotInstance) {
var _this;
(0, _classCallCheck2.default)(this, TrimRows);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(TrimRows).call(this, hotInstance));
/**
* List of trimmed row indexes.
*
* @private
* @type {Array}
*/
_this.trimmedRows = [];
/**
* List of last removed row indexes.
*
* @private
* @type {Array}
*/
_this.removedRows = [];
/**
* Object containing visual row indexes mapped to data source indexes.
*
* @private
* @type {RowsMapper}
*/
_this.rowsMapper = new _rowsMapper.default((0, _assertThisInitialized2.default)(_this));
return _this;
}
/**
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
* hook and if it returns `true` than the {@link AutoRowSize#enablePlugin} method is called.
*
* @returns {Boolean}
*/
(0, _createClass2.default)(TrimRows, [{
key: "isEnabled",
value: function isEnabled() {
return !!this.hot.getSettings().trimRows;
}
/**
* Enables the plugin functionality for this Handsontable instance.
*/
}, {
key: "enablePlugin",
value: function enablePlugin() {
var _this2 = this;
if (this.enabled) {
return;
}
var settings = this.hot.getSettings().trimRows;
if (Array.isArray(settings)) {
this.trimmedRows = settings;
}
this.rowsMapper.createMap(this.hot.countSourceRows());
this.addHook('modifyRow', function (row, source) {
return _this2.onModifyRow(row, source);
});
this.addHook('unmodifyRow', function (row, source) {
return _this2.onUnmodifyRow(row, source);
});
this.addHook('beforeCreateRow', function (index, amount, source) {
return _this2.onBeforeCreateRow(index, amount, source);
});
this.addHook('afterCreateRow', function (index, amount) {
return _this2.onAfterCreateRow(index, amount);
});
this.addHook('beforeRemoveRow', function (index, amount) {
return _this2.onBeforeRemoveRow(index, amount);
});
this.addHook('afterRemoveRow', function () {
return _this2.onAfterRemoveRow();
});
this.addHook('afterLoadData', function (firstRun) {
return _this2.onAfterLoadData(firstRun);
});
(0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "enablePlugin", this).call(this);
}
/**
* Updates the plugin state. This method is executed when {@link Core#updateSettings} is invoked.
*/
}, {
key: "updatePlugin",
value: function updatePlugin() {
var settings = this.hot.getSettings().trimRows;
if (Array.isArray(settings)) {
this.disablePlugin();
this.enablePlugin();
}
(0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "updatePlugin", this).call(this);
}
/**
* Disables the plugin functionality for this Handsontable instance.
*/
}, {
key: "disablePlugin",
value: function disablePlugin() {
this.trimmedRows = [];
this.removedRows.length = 0;
this.rowsMapper.clearMap();
(0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "disablePlugin", this).call(this);
}
/**
* Trims the rows provided in the array.
*
* @param {Number[]} rows Array of physical row indexes.
* @fires Hooks#skipLengthCache
* @fires Hooks#beforeTrimRow
* @fires Hooks#afterTrimRow
*/
}, {
key: "trimRows",
value: function trimRows(rows) {
var currentTrimConfig = this.trimmedRows;
var isValidConfig = this.isValidConfig(rows);
var destinationTrimConfig = currentTrimConfig;
if (isValidConfig) {
destinationTrimConfig = Array.from(new Set(currentTrimConfig.concat(rows)));
}
var allowTrimRow = this.hot.runHooks('beforeTrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig);
if (allowTrimRow === false) {
return;
}
if (isValidConfig) {
this.trimmedRows = destinationTrimConfig;
this.hot.runHooks('skipLengthCache', 100);
this.rowsMapper.createMap(this.hot.countSourceRows());
}
this.hot.runHooks('afterTrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig, isValidConfig && destinationTrimConfig.length > currentTrimConfig.length);
}
/**
* Trims the row provided as physical row index (counting from 0).
*
* @param {...Number} row Physical row index.
*/
}, {
key: "trimRow",
value: function trimRow() {
for (var _len = arguments.length, row = new Array(_len), _key = 0; _key < _len; _key++) {
row[_key] = arguments[_key];
}
this.trimRows(row);
}
/**
* Untrims the rows provided in the array.
*
* @param {Number[]} rows Array of physical row indexes.
* @fires Hooks#skipLengthCache
* @fires Hooks#beforeUntrimRow
* @fires Hooks#afterUntrimRow
*/
}, {
key: "untrimRows",
value: function untrimRows(rows) {
var currentTrimConfig = this.trimmedRows;
var isValidConfig = this.isValidConfig(rows);
var destinationTrimConfig = currentTrimConfig;
if (isValidConfig) {
destinationTrimConfig = this.trimmedRows.filter(function (trimmedRow) {
return rows.includes(trimmedRow) === false;
});
}
var allowUntrimRow = this.hot.runHooks('beforeUntrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig);
if (allowUntrimRow === false) {
return;
}
if (isValidConfig) {
this.trimmedRows = destinationTrimConfig;
this.hot.runHooks('skipLengthCache', 100);
this.rowsMapper.createMap(this.hot.countSourceRows());
}
this.hot.runHooks('afterUntrimRow', currentTrimConfig, destinationTrimConfig, isValidConfig, isValidConfig && destinationTrimConfig.length < currentTrimConfig.length);
}
/**
* Untrims the row provided as row index (counting from 0).
*
* @param {...Number} row Physical row index.
*/
}, {
key: "untrimRow",
value: function untrimRow() {
for (var _len2 = arguments.length, row = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
row[_key2] = arguments[_key2];
}
this.untrimRows(row);
}
/**
* Checks if given physical row is hidden.
*
* @returns {Boolean}
*/
}, {
key: "isTrimmed",
value: function isTrimmed(row) {
return this.trimmedRows.includes(row);
}
/**
* Untrims all trimmed rows.
*/
}, {
key: "untrimAll",
value: function untrimAll() {
this.untrimRows([].concat(this.trimmedRows));
}
/**
* Get if trim config is valid.
*
* @param {Array} trimmedRows List of physical row indexes.
* @returns {Boolean}
*/
}, {
key: "isValidConfig",
value: function isValidConfig(trimmedRows) {
var _this3 = this;
return trimmedRows.every(function (trimmedRow) {
return Number.isInteger(trimmedRow) && trimmedRow >= 0 && trimmedRow < _this3.hot.countSourceRows();
});
}
/**
* On modify row listener.
*
* @private
* @param {Number} row Visual row index.
* @param {String} source Source name.
* @returns {Number|null}
*/
}, {
key: "onModifyRow",
value: function onModifyRow(row, source) {
var physicalRow = row;
if (source !== this.pluginName) {
physicalRow = this.rowsMapper.getValueByIndex(physicalRow);
}
return physicalRow;
}
/**
* On unmodifyRow listener.
*
* @private
* @param {Number} row Physical row index.
* @param {String} source Source name.
* @returns {Number|null}
*/
}, {
key: "onUnmodifyRow",
value: function onUnmodifyRow(row, source) {
var visualRow = row;
if (source !== this.pluginName) {
visualRow = this.rowsMapper.getIndexByValue(visualRow);
}
return visualRow;
}
/**
* `beforeCreateRow` hook callback.
*
* @private
* @param {Number} index Index of the newly created row.
* @param {Number} amount Amount of created rows.
* @param {String} source Source of the change.
*/
}, {
key: "onBeforeCreateRow",
value: function onBeforeCreateRow(index, amount, source) {
if (this.isEnabled() && this.trimmedRows.length > 0 && source === 'auto') {
return false;
}
}
/**
* On after create row listener.
*
* @private
* @param {Number} index Visual row index.
* @param {Number} amount Defines how many rows removed.
*/
}, {
key: "onAfterCreateRow",
value: function onAfterCreateRow(index, amount) {
var _this4 = this;
this.rowsMapper.shiftItems(index, amount);
this.trimmedRows = (0, _array.arrayMap)(this.trimmedRows, function (trimmedRow) {
if (trimmedRow >= _this4.rowsMapper.getValueByIndex(index)) {
return trimmedRow + amount;
}
return trimmedRow;
});
}
/**
* On before remove row listener.
*
* @private
* @param {Number} index Visual row index.
* @param {Number} amount Defines how many rows removed.
*
* @fires Hooks#modifyRow
*/
}, {
key: "onBeforeRemoveRow",
value: function onBeforeRemoveRow(index, amount) {
var _this5 = this;
this.removedRows.length = 0;
if (index !== false) {
// Collect physical row index.
(0, _number.rangeEach)(index, index + amount - 1, function (removedIndex) {
_this5.removedRows.push(_this5.hot.runHooks('modifyRow', removedIndex, _this5.pluginName));
});
}
}
/**
* On after remove row listener.
*
* @private
*/
}, {
key: "onAfterRemoveRow",
value: function onAfterRemoveRow() {
var _this6 = this;
this.rowsMapper.unshiftItems(this.removedRows); // TODO: Maybe it can be optimized? N x M checks, where N is number of already trimmed rows and M is number of removed rows.
// Decreasing physical indexes (some of them should be updated, because few indexes are missing in new list of indexes after removal).
this.trimmedRows = (0, _array.arrayMap)(this.trimmedRows, function (trimmedRow) {
return trimmedRow - _this6.removedRows.filter(function (removedRow) {
return removedRow < trimmedRow;
}).length;
});
}
/**
* On after load data listener.
*
* @private
* @param {Boolean} firstRun Indicates if hook was fired while Handsontable initialization.
*/
}, {
key: "onAfterLoadData",
value: function onAfterLoadData(firstRun) {
if (!firstRun) {
this.rowsMapper.createMap(this.hot.countSourceRows());
}
}
/**
* Destroys the plugin instance.
*/
}, {
key: "destroy",
value: function destroy() {
this.rowsMapper.destroy();
(0, _get2.default)((0, _getPrototypeOf2.default)(TrimRows.prototype), "destroy", this).call(this);
}
}]);
return TrimRows;
}(_base.default);
(0, _plugins.registerPlugin)('trimRows', TrimRows);
var _default = TrimRows;
exports.default = _default;
/***/ }),
/* 522 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _interopRequireDefault = __webpack_require__(0);
exports.__esModule = true;
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(__webpack_require__(1));
var _createClass2 = _interopRequireDefault(__webpack_require__(2));
var _arrayMapper = _interopRequireDefault(__webpack_require__(91));
var _object = __webpack_require__(4);
var _number = __webpack_require__(15);
/**
* @class RowsMapper
* @plugin TrimRows
*/
var RowsMapper =
/*#__PURE__*/
function () {
function RowsMapper(trimRows) {
(0, _classCallCheck2.default)(this, RowsMapper);
/**
* Instance of TrimRows plugin.
*
* @type {TrimRows}
*/
this.trimRows = trimRows;
}
/**
* Reset current map array and create new one.
*
* @param {Number} [length] Custom generated map length.
*/
(0, _createClass2.default)(RowsMapper, [{
key: "createMap",
value: function createMap(length) {
var _this = this;
var rowOffset = 0;
var originLength = length === void 0 ? this._arrayMap.length : length;
this._arrayMap.length = 0;
(0, _number.rangeEach)(originLength - 1, function (itemIndex) {
if (_this.trimRows.isTrimmed(itemIndex)) {
rowOffset += 1;
} else {
_this._arrayMap[itemIndex - rowOffset] = itemIndex;
}
});
}
/**
* Destroy class.
*/
}, {
key: "destroy",
value: function destroy() {
this._arrayMap = null;
}
}]);
return RowsMapper;
}();
(0, _object.mixin)(RowsMapper, _arrayMapper.default);
var _default = RowsMapper;
exports.default = _default;
/***/ })
/******/ ])["default"];
});
//# sourceMappingURL=handsontable.js.map