You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55988 lines
1.6 MiB
55988 lines
1.6 MiB
/*!
|
|
* (The MIT License)
|
|
*
|
|
* Copyright (c) 2012-2014 Marcin Warpechowski
|
|
* Copyright (c) 2015 Handsoncode sp. z o.o. <hello@handsoncode.net>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* 'Software'), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* Version: 0.33.0
|
|
* Date: Mon Jul 10 2017 10:08:33 GMT+0200 (CEST)
|
|
*/
|
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
module.exports = factory();
|
|
else if(typeof define === 'function' && define.amd)
|
|
define("Handsontable", [], factory);
|
|
else if(typeof exports === 'object')
|
|
exports["Handsontable"] = factory();
|
|
else
|
|
root["Handsontable"] = factory();
|
|
})(this, function() {
|
|
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;
|
|
/******/
|
|
/******/ // identity function for calling harmony imports with the correct context
|
|
/******/ __webpack_require__.i = function(value) { return value; };
|
|
/******/
|
|
/******/ // define getter function for harmony exports
|
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
|
/******/ Object.defineProperty(exports, name, {
|
|
/******/ configurable: false,
|
|
/******/ enumerable: true,
|
|
/******/ get: getter
|
|
/******/ });
|
|
/******/ }
|
|
/******/ };
|
|
/******/
|
|
/******/ // 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 = 323);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.HTML_CHARACTERS = undefined;
|
|
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.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;
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _feature = __webpack_require__(34);
|
|
|
|
/**
|
|
* 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;
|
|
|
|
while (element != null) {
|
|
if (iteration === level) {
|
|
parent = element;
|
|
break;
|
|
}
|
|
|
|
if (element.host && element.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
element = element.host;
|
|
} else {
|
|
iteration++;
|
|
element = element.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) {
|
|
while (element != null && element !== until) {
|
|
if (element.nodeType === Node.ELEMENT_NODE && (nodes.indexOf(element.nodeName) > -1 || nodes.indexOf(element) > -1)) {
|
|
return element;
|
|
}
|
|
if (element.host && element.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
element = element.host;
|
|
} else {
|
|
element = element.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 = [];
|
|
|
|
while (element) {
|
|
element = closest(element, nodes, until);
|
|
|
|
if (!element || until && !until.contains(element)) {
|
|
break;
|
|
}
|
|
matched.push(element);
|
|
|
|
if (element.host && element.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
element = element.host;
|
|
} else {
|
|
element = element.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(document.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',
|
|
result = false,
|
|
parentNode;
|
|
|
|
parentNode = polymerWrap(element);
|
|
|
|
function isHotTable(element) {
|
|
return element.nodeType === Node.ELEMENT_NODE && element.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;
|
|
}
|
|
|
|
/**
|
|
* Wrap element into polymer/webcomponent container if exists
|
|
*
|
|
* @param element
|
|
* @returns {*}
|
|
*/
|
|
function polymerWrap(element) {
|
|
/* global Polymer */
|
|
return typeof Polymer !== 'undefined' && typeof wrap === 'function' ? wrap(element) : element;
|
|
}
|
|
|
|
/**
|
|
* Unwrap element from polymer/webcomponent container if exists
|
|
*
|
|
* @param element
|
|
* @returns {*}
|
|
*/
|
|
function polymerUnwrap(element) {
|
|
/* global Polymer */
|
|
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;
|
|
|
|
if (element.previousSibling) {
|
|
/* eslint-disable no-cond-assign */
|
|
while (element = element.previousSibling) {
|
|
++i;
|
|
}
|
|
}
|
|
|
|
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 = document.querySelector('.ht_clone_' + overlayType);
|
|
return overlayElement ? overlayElement.contains(element) : null;
|
|
}
|
|
|
|
var classListSupport = !!document.documentElement.classList;
|
|
var _hasClass, _addClass, _removeClass;
|
|
|
|
function filterEmptyClassNames(classNames) {
|
|
var len = 0,
|
|
result = [];
|
|
|
|
if (!classNames || !classNames.length) {
|
|
return result;
|
|
}
|
|
while (classNames[len]) {
|
|
result.push(classNames[len]);
|
|
len++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
if (classListSupport) {
|
|
var isSupportMultipleClassesArg = function () {
|
|
var element = document.createElement('div');
|
|
|
|
element.classList.add('test', 'test2');
|
|
|
|
return element.classList.contains('test2');
|
|
}();
|
|
|
|
_hasClass = function _hasClass(element, className) {
|
|
if (className === '') {
|
|
return false;
|
|
}
|
|
|
|
return element.classList.contains(className);
|
|
};
|
|
|
|
_addClass = function _addClass(element, className) {
|
|
var len = 0;
|
|
|
|
if (typeof className === 'string') {
|
|
className = className.split(' ');
|
|
}
|
|
className = filterEmptyClassNames(className);
|
|
|
|
if (isSupportMultipleClassesArg) {
|
|
element.classList.add.apply(element.classList, className);
|
|
} else {
|
|
while (className && className[len]) {
|
|
element.classList.add(className[len]);
|
|
len++;
|
|
}
|
|
}
|
|
};
|
|
|
|
_removeClass = function _removeClass(element, className) {
|
|
var len = 0;
|
|
|
|
if (typeof className === 'string') {
|
|
className = className.split(' ');
|
|
}
|
|
className = filterEmptyClassNames(className);
|
|
|
|
if (isSupportMultipleClassesArg) {
|
|
element.classList.remove.apply(element.classList, className);
|
|
} else {
|
|
while (className && className[len]) {
|
|
element.classList.remove(className[len]);
|
|
len++;
|
|
}
|
|
}
|
|
};
|
|
} else {
|
|
var createClassNameRegExp = function createClassNameRegExp(className) {
|
|
return new RegExp('(\\s|^)' + className + '(\\s|$)');
|
|
};
|
|
|
|
_hasClass = function _hasClass(element, className) {
|
|
// http://snipplr.com/view/3561/addclass-removeclass-hasclass/
|
|
return !!element.className.match(createClassNameRegExp(className));
|
|
};
|
|
|
|
_addClass = function _addClass(element, className) {
|
|
var len = 0,
|
|
_className = element.className;
|
|
|
|
if (typeof className === 'string') {
|
|
className = className.split(' ');
|
|
}
|
|
if (_className === '') {
|
|
_className = className.join(' ');
|
|
} else {
|
|
while (className && className[len]) {
|
|
if (!createClassNameRegExp(className[len]).test(_className)) {
|
|
_className += ' ' + className[len];
|
|
}
|
|
len++;
|
|
}
|
|
}
|
|
element.className = _className;
|
|
};
|
|
|
|
_removeClass = function _removeClass(element, className) {
|
|
var len = 0,
|
|
_className = element.className;
|
|
|
|
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++;
|
|
}
|
|
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 = exports.HTML_CHARACTERS = /(<(.*)>|&(.*);)/;
|
|
|
|
/**
|
|
* Insert content into element trying avoid innerHTML method.
|
|
* @return {void}
|
|
*/
|
|
function fastInnerHTML(element, content) {
|
|
if (HTML_CHARACTERS.test(content)) {
|
|
element.innerHTML = content;
|
|
} else {
|
|
fastInnerText(element, content);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Insert text content into element
|
|
* @return {void}
|
|
*/
|
|
|
|
var textContextSupport = !!document.createTextNode('test').textContent;
|
|
|
|
function fastInnerText(element, content) {
|
|
var child = element.firstChild;
|
|
|
|
if (child && child.nodeType === 3 && child.nextSibling === null) {
|
|
// fast lane - replace existing text node
|
|
|
|
if (textContextSupport) {
|
|
// 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(document.createTextNode(content));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns true if element is attached to the DOM and visible, false otherwise
|
|
* @param elem
|
|
* @returns {boolean}
|
|
*/
|
|
function isVisible(elem) {
|
|
var next = elem;
|
|
|
|
while (polymerUnwrap(next) !== document.documentElement) {
|
|
// until <html> 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.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 offsetLeft, offsetTop, lastElem, docElem, box;
|
|
|
|
docElem = document.documentElement;
|
|
|
|
if ((0, _feature.hasCaptionProblem)() && elem.firstChild && elem.firstChild.nodeName === 'CAPTION') {
|
|
// fixes problem with Firefox ignoring <caption> in TABLE offset (see also export outerHeight)
|
|
// http://jsperf.com/offset-vs-getboundingclientrect/8
|
|
box = elem.getBoundingClientRect();
|
|
|
|
return {
|
|
top: box.top + (window.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
|
|
left: box.left + (window.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
|
|
};
|
|
}
|
|
offsetLeft = elem.offsetLeft;
|
|
offsetTop = elem.offsetTop;
|
|
lastElem = elem;
|
|
|
|
/* eslint-disable no-cond-assign */
|
|
while (elem = elem.offsetParent) {
|
|
// from my observation, document.body always has scrollLeft/scrollTop == 0
|
|
if (elem === document.body) {
|
|
break;
|
|
}
|
|
offsetLeft += elem.offsetLeft;
|
|
offsetTop += elem.offsetTop;
|
|
lastElem = elem;
|
|
}
|
|
|
|
// 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 += window.pageXOffset || docElem.scrollLeft;
|
|
offsetTop += window.pageYOffset || docElem.scrollTop;
|
|
}
|
|
|
|
return {
|
|
left: offsetLeft,
|
|
top: offsetTop
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns the document's scrollTop property.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
function getWindowScrollTop() {
|
|
var res = window.scrollY;
|
|
|
|
if (res === void 0) {
|
|
// IE8-11
|
|
res = document.documentElement.scrollTop;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* Returns the document's scrollLeft property.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
function getWindowScrollLeft() {
|
|
var res = window.scrollX;
|
|
|
|
if (res === void 0) {
|
|
// IE8-11
|
|
res = document.documentElement.scrollLeft;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* Returns the provided element's scrollTop property.
|
|
*
|
|
* @param element
|
|
* @returns {Number}
|
|
*/
|
|
function getScrollTop(element) {
|
|
if (element === window) {
|
|
return getWindowScrollTop();
|
|
}
|
|
return element.scrollTop;
|
|
}
|
|
|
|
/**
|
|
* Returns the provided element's scrollLeft property.
|
|
*
|
|
* @param element
|
|
* @returns {Number}
|
|
*/
|
|
function getScrollLeft(element) {
|
|
if (element === window) {
|
|
return getWindowScrollLeft();
|
|
}
|
|
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 el = element.parentNode,
|
|
props = ['auto', 'scroll'],
|
|
overflow,
|
|
overflowX,
|
|
overflowY,
|
|
computedStyle = '',
|
|
computedOverflow = '',
|
|
computedOverflowY = '',
|
|
computedOverflowX = '';
|
|
|
|
while (el && el.style && document.body !== el) {
|
|
overflow = el.style.overflow;
|
|
overflowX = el.style.overflowX;
|
|
overflowY = el.style.overflowY;
|
|
|
|
if (overflow == 'scroll' || overflowX == 'scroll' || overflowY == 'scroll') {
|
|
return el;
|
|
} else if (window.getComputedStyle) {
|
|
computedStyle = window.getComputedStyle(el);
|
|
computedOverflow = computedStyle.getPropertyValue('overflow');
|
|
computedOverflowY = computedStyle.getPropertyValue('overflow-y');
|
|
computedOverflowX = computedStyle.getPropertyValue('overflow-x');
|
|
|
|
if (computedOverflow === 'scroll' || computedOverflowX === 'scroll' || computedOverflowY === 'scroll') {
|
|
return el;
|
|
}
|
|
}
|
|
|
|
if (el.clientHeight <= el.scrollHeight && (props.indexOf(overflowY) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowY) !== -1)) {
|
|
return el;
|
|
}
|
|
if (el.clientWidth <= el.scrollWidth && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowX) !== -1)) {
|
|
return el;
|
|
}
|
|
el = el.parentNode;
|
|
}
|
|
|
|
return window;
|
|
}
|
|
|
|
/**
|
|
* 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 el = base.parentNode;
|
|
|
|
while (el && el.style && document.body !== el) {
|
|
if (el.style.overflow !== 'visible' && el.style.overflow !== '') {
|
|
return el;
|
|
} else if (window.getComputedStyle) {
|
|
var computedStyle = window.getComputedStyle(el);
|
|
|
|
if (computedStyle.getPropertyValue('overflow') !== 'visible' && computedStyle.getPropertyValue('overflow') !== '') {
|
|
return el;
|
|
}
|
|
}
|
|
|
|
el = el.parentNode;
|
|
}
|
|
|
|
return window;
|
|
}
|
|
|
|
/**
|
|
* Returns a style property for the provided element. (Be it an inline or external style).
|
|
*
|
|
* @param {HTMLElement} element
|
|
* @param {String} prop Wanted property
|
|
* @returns {String|undefined} Element's style property
|
|
*/
|
|
function getStyle(element, prop) {
|
|
/* eslint-disable */
|
|
if (!element) {
|
|
return;
|
|
} else if (element === window) {
|
|
if (prop === 'width') {
|
|
return window.innerWidth + 'px';
|
|
} else if (prop === 'height') {
|
|
return window.innerHeight + 'px';
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
var styleProp = element.style[prop],
|
|
computedStyle;
|
|
|
|
if (styleProp !== '' && styleProp !== void 0) {
|
|
return styleProp;
|
|
} else {
|
|
computedStyle = getComputedStyle(element);
|
|
|
|
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
|
|
* @returns {IEElementStyle|CssStyle} Elements computed style object
|
|
*/
|
|
function getComputedStyle(element) {
|
|
return element.currentStyle || document.defaultView.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 <caption> 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) {
|
|
if (window.addEventListener) {
|
|
element.addEventListener(event, callback, false);
|
|
} else {
|
|
element.attachEvent('on' + event, callback);
|
|
}
|
|
}
|
|
|
|
function removeEvent(element, event, callback) {
|
|
if (window.removeEventListener) {
|
|
element.removeEventListener(event, callback, false);
|
|
} else {
|
|
element.detachEvent('on' + event, callback);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns caret position in text input
|
|
*
|
|
* @author http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
|
|
* @return {Number}
|
|
*/
|
|
function getCaretPosition(el) {
|
|
if (el.selectionStart) {
|
|
return el.selectionStart;
|
|
} else if (document.selection) {
|
|
// IE8
|
|
el.focus();
|
|
|
|
var r = document.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) {
|
|
if (el.selectionEnd) {
|
|
return el.selectionEnd;
|
|
} else if (document.selection) {
|
|
// IE8
|
|
var r = document.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.
|
|
*
|
|
* @returns {String}
|
|
*/
|
|
function getSelectionText() {
|
|
var text = '';
|
|
|
|
if (window.getSelection) {
|
|
text = window.getSelection().toString();
|
|
} else if (document.selection && document.selection.type !== 'Control') {
|
|
text = document.selection.createRange().text;
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
|
|
// http://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes
|
|
function walkontableCalculateScrollbarWidth() {
|
|
var inner = document.createElement('div');
|
|
inner.style.height = '200px';
|
|
inner.style.width = '100%';
|
|
|
|
var outer = document.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);
|
|
|
|
(document.body || document.documentElement).appendChild(outer);
|
|
var w1 = inner.offsetWidth;
|
|
outer.style.overflow = 'scroll';
|
|
var w2 = inner.offsetWidth;
|
|
if (w1 == w2) {
|
|
w2 = outer.clientWidth;
|
|
}
|
|
|
|
(document.body || document.documentElement).removeChild(outer);
|
|
|
|
return w1 - w2;
|
|
}
|
|
|
|
/**
|
|
* Returns the computed width of the native browser scroll bar.
|
|
*
|
|
* @return {Number} width
|
|
*/
|
|
function getScrollbarWidth() {
|
|
if (cachedScrollbarWidth === void 0) {
|
|
cachedScrollbarWidth = walkontableCalculateScrollbarWidth();
|
|
}
|
|
|
|
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(' + left + ',' + top + ',0)';
|
|
} else {
|
|
overlayElem.style.transform = 'translate3d(' + left + ',' + 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;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 1 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
exports.duckSchema = duckSchema;
|
|
exports.inherit = inherit;
|
|
exports.extend = extend;
|
|
exports.deepExtend = deepExtend;
|
|
exports.deepClone = deepClone;
|
|
exports.clone = clone;
|
|
exports.mixin = mixin;
|
|
exports.isObjectEquals = isObjectEquals;
|
|
exports.isObject = isObject;
|
|
exports.defineGetter = defineGetter;
|
|
exports.objectEach = objectEach;
|
|
exports.getProperty = getProperty;
|
|
exports.deepObjectSize = deepObjectSize;
|
|
exports.createObjectPropListener = createObjectPropListener;
|
|
exports.hasOwnProperty = hasOwnProperty;
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
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; }
|
|
|
|
/**
|
|
* 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 && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && !Array.isArray(value)) {
|
|
schema[key] = duckSchema(value);
|
|
} else if (Array.isArray(value)) {
|
|
if (value.length && _typeof(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] && _typeof(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 ((typeof obj === 'undefined' ? 'undefined' : _typeof(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 = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
mixins[_key - 1] = arguments[_key];
|
|
}
|
|
|
|
(0, _array.arrayEach)(mixins, function (mixin) {
|
|
Base.MIXINS.push(mixin.MIXIN_NAME);
|
|
|
|
objectEach(mixin, function (value, key) {
|
|
if (Base.prototype[key] !== void 0) {
|
|
throw new Error('Mixin conflict. Property \'' + key + '\' already exist and cannot be overwritten.');
|
|
}
|
|
if (typeof value === 'function') {
|
|
Base.prototype[key] = value;
|
|
} else {
|
|
var getter = function _getter(propertyName, initialValue) {
|
|
propertyName = '_' + propertyName;
|
|
|
|
var initValue = function initValue(value) {
|
|
if (Array.isArray(value) || isObject(value)) {
|
|
value = deepClone(value);
|
|
}
|
|
|
|
return value;
|
|
};
|
|
|
|
return function () {
|
|
if (this[propertyName] === void 0) {
|
|
this[propertyName] = initValue(initialValue);
|
|
}
|
|
|
|
return this[propertyName];
|
|
};
|
|
};
|
|
var setter = function _setter(propertyName) {
|
|
propertyName = '_' + propertyName;
|
|
|
|
return function (value) {
|
|
this[propertyName] = value;
|
|
};
|
|
};
|
|
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 isObjectEquals(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) {
|
|
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 (name) {
|
|
result = result[name];
|
|
|
|
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++;
|
|
}
|
|
|
|
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 = '_' + propertyToListen;
|
|
var holder = (_holder = {
|
|
_touched: false
|
|
}, _defineProperty(_holder, privateProperty, defaultValue), _defineProperty(_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);
|
|
}
|
|
|
|
/***/ }),
|
|
/* 2 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
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 i = 0,
|
|
ilen = arr.length;
|
|
|
|
while (i < ilen) {
|
|
arr[i] = [arr[i]];
|
|
i++;
|
|
}
|
|
}
|
|
|
|
function extendArray(arr, extension) {
|
|
var i = 0,
|
|
ilen = extension.length;
|
|
|
|
while (i < ilen) {
|
|
arr.push(extension[i]);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
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,
|
|
length = array.length;
|
|
|
|
if (initFromArray && length) {
|
|
accumulator = array[++index];
|
|
}
|
|
while (++index < length) {
|
|
accumulator = iteratee(accumulator, array[index], index, array);
|
|
}
|
|
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* 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 = -1,
|
|
length = array.length,
|
|
resIndex = -1,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
|
|
if (predicate(value, index, array)) {
|
|
result[++resIndex] = value;
|
|
}
|
|
}
|
|
|
|
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 = -1,
|
|
length = array.length,
|
|
resIndex = -1,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
|
|
result[++resIndex] = iteratee(value, index, array);
|
|
}
|
|
|
|
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.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEach(array, iteratee) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (iteratee(array[index], index, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 3 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var global = __webpack_require__(13)
|
|
, core = __webpack_require__(45)
|
|
, hide = __webpack_require__(32)
|
|
, redefine = __webpack_require__(33)
|
|
, ctx = __webpack_require__(29)
|
|
, PROTOTYPE = 'prototype';
|
|
|
|
var $export = function(type, name, source){
|
|
var IS_FORCED = type & $export.F
|
|
, IS_GLOBAL = type & $export.G
|
|
, IS_STATIC = type & $export.S
|
|
, IS_PROTO = type & $export.P
|
|
, IS_BIND = type & $export.B
|
|
, target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]
|
|
, exports = IS_GLOBAL ? core : core[name] || (core[name] = {})
|
|
, expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {})
|
|
, key, own, out, exp;
|
|
if(IS_GLOBAL)source = name;
|
|
for(key in source){
|
|
// contains in native
|
|
own = !IS_FORCED && target && target[key] !== undefined;
|
|
// export native or passed
|
|
out = (own ? target : source)[key];
|
|
// bind timers to global for call from export context
|
|
exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
|
|
// extend global
|
|
if(target)redefine(target, key, out, type & $export.U);
|
|
// export
|
|
if(exports[key] != out)hide(exports, key, exp);
|
|
if(IS_PROTO && expProto[key] != out)expProto[key] = out;
|
|
}
|
|
};
|
|
global.core = core;
|
|
// type bitmap
|
|
$export.F = 1; // forced
|
|
$export.G = 2; // global
|
|
$export.S = 4; // static
|
|
$export.P = 8; // proto
|
|
$export.B = 16; // bind
|
|
$export.W = 32; // wrap
|
|
$export.U = 64; // safe
|
|
$export.R = 128; // real proto method for `library`
|
|
module.exports = $export;
|
|
|
|
/***/ }),
|
|
/* 4 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // import Core from './core';
|
|
|
|
|
|
exports.getListenersCounter = getListenersCounter;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _feature = __webpack_require__(34);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* 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 = function () {
|
|
/**
|
|
* @param {Object} [context=null]
|
|
* @private
|
|
*/
|
|
function EventManager() {
|
|
var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
|
|
_classCallCheck(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.
|
|
* @returns {Function} Returns function which you can easily call to remove that event
|
|
*/
|
|
|
|
|
|
_createClass(EventManager, [{
|
|
key: 'addEventListener',
|
|
value: function addEventListener(element, eventName, callback) {
|
|
var _this = this;
|
|
|
|
var context = this.context;
|
|
|
|
function callbackProxy(event) {
|
|
event = extendEvent(context, event);
|
|
|
|
callback.call(this, event);
|
|
}
|
|
this.context.eventListeners.push({
|
|
element: element,
|
|
event: eventName,
|
|
callback: callback,
|
|
callbackProxy: callbackProxy
|
|
});
|
|
|
|
if (window.addEventListener) {
|
|
element.addEventListener(eventName, callbackProxy, false);
|
|
} else {
|
|
element.attachEvent('on' + eventName, callbackProxy);
|
|
}
|
|
listenersCounter++;
|
|
|
|
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 = void 0;
|
|
|
|
while (len--) {
|
|
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);
|
|
|
|
if (tmpEvent.element.removeEventListener) {
|
|
tmpEvent.element.removeEventListener(tmpEvent.event, tmpEvent.callbackProxy, false);
|
|
} else {
|
|
tmpEvent.element.detachEvent('on' + tmpEvent.event, tmpEvent.callbackProxy);
|
|
}
|
|
listenersCounter--;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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--) {
|
|
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 options = {
|
|
bubbles: true,
|
|
cancelable: eventName !== 'mousemove',
|
|
view: window,
|
|
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 (document.createEvent) {
|
|
event = document.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 || document.body.parentNode);
|
|
} else {
|
|
event = document.createEventObject();
|
|
}
|
|
|
|
if (element.dispatchEvent) {
|
|
element.dispatchEvent(event);
|
|
} else {
|
|
element.fireEvent('on' + eventName, event);
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return EventManager;
|
|
}();
|
|
|
|
/**
|
|
* @param {Object} context
|
|
* @param {Event} event
|
|
* @private
|
|
* @returns {*}
|
|
*/
|
|
|
|
|
|
function extendEvent(context, event) {
|
|
var componentName = 'HOT-TABLE';
|
|
var isHotTableSpotted = void 0;
|
|
var fromElement = void 0;
|
|
var realTarget = void 0;
|
|
var target = void 0;
|
|
var len = void 0;
|
|
var nativeStopImmediatePropagation = void 0;
|
|
|
|
event.isTargetWebComponent = false;
|
|
event.realTarget = event.target;
|
|
|
|
nativeStopImmediatePropagation = event.stopImmediatePropagation;
|
|
event.stopImmediatePropagation = function () {
|
|
nativeStopImmediatePropagation.apply(this);
|
|
(0, _event.stopImmediatePropagation)(this);
|
|
};
|
|
|
|
if (!EventManager.isHotTableEnv) {
|
|
return event;
|
|
}
|
|
event = (0, _element.polymerWrap)(event);
|
|
len = event.path ? event.path.length : 0;
|
|
|
|
while (len--) {
|
|
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 (context instanceof Core || context instanceof Walkontable) {
|
|
// Polymer doesn't support `event.target` property properly we must emulate it ourselves
|
|
if (context instanceof Core) {
|
|
fromElement = context.view ? context.view.wt.wtTable.TABLE : null;
|
|
} else if (context instanceof Walkontable) {
|
|
// .wtHider
|
|
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;
|
|
}
|
|
|
|
exports.default = EventManager;
|
|
function getListenersCounter() {
|
|
return listenersCounter;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 5 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.getPluginName = exports.getRegistredPluginNames = exports.getPlugin = exports.registerPlugin = undefined;
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var registeredPlugins = new WeakMap();
|
|
|
|
/**
|
|
* Registers plugin under given name
|
|
*
|
|
* @param {String} pluginName
|
|
* @param {Function} PluginClass
|
|
*/
|
|
/**
|
|
* Utility to register plugins and common namespace for keeping reference to all plugins classes
|
|
*/
|
|
function registerPlugin(pluginName, PluginClass) {
|
|
pluginName = (0, _string.toUpperCaseFirst)(pluginName);
|
|
|
|
_pluginHooks2.default.getSingleton().add('construct', function () {
|
|
var holder = void 0;
|
|
|
|
if (!registeredPlugins.has(this)) {
|
|
registeredPlugins.set(this, {});
|
|
}
|
|
holder = registeredPlugins.get(this);
|
|
|
|
if (!holder[pluginName]) {
|
|
holder[pluginName] = new PluginClass(this);
|
|
}
|
|
});
|
|
_pluginHooks2.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;
|
|
}
|
|
|
|
exports.registerPlugin = registerPlugin;
|
|
exports.getPlugin = getPlugin;
|
|
exports.getRegistredPluginNames = getRegistredPluginNames;
|
|
exports.getPluginName = getPluginName;
|
|
|
|
/***/ }),
|
|
/* 6 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
exports.isNumeric = isNumeric;
|
|
exports.rangeEach = rangeEach;
|
|
exports.rangeEachReverse = rangeEachReverse;
|
|
exports.valueAccordingPercent = valueAccordingPercent;
|
|
/**
|
|
* 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 = typeof n === 'undefined' ? 'undefined' : _typeof(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} rangeTo The number where finish iterate.
|
|
* @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;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 7 */
|
|
/***/ (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__(0);
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
return event.clientX + (0, _element.getWindowScrollLeft)();
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
return event.clientY + (0, _element.getWindowScrollTop)();
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 8 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @description
|
|
* Handsontable events are the common interface that function in 2 ways: as __callbacks__ and as __hooks__.
|
|
*
|
|
* @example
|
|
*
|
|
* ```js
|
|
* // Using events as callbacks:
|
|
* ...
|
|
* var hot1 = new Handsontable(document.getElementById('example1'), {
|
|
* afterChange: function(changes, source) {
|
|
* $.ajax({
|
|
* url: "save.php',
|
|
* data: change
|
|
* });
|
|
* }
|
|
* });
|
|
* ...
|
|
* ```
|
|
*
|
|
* ```js
|
|
* // Using events as plugin hooks:
|
|
* ...
|
|
* var hot1 = new Handsontable(document.getElementById('example1'), {
|
|
* myPlugin: true
|
|
* });
|
|
*
|
|
* var 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 = [
|
|
/**
|
|
* Callback fired after resetting a cell's meta.
|
|
*
|
|
* @event Hooks#afterCellMetaReset
|
|
* @since 0.11
|
|
*/
|
|
'afterCellMetaReset',
|
|
|
|
/**
|
|
* @description
|
|
* Callback fired after one or more cells has been changed. Its main use case is to save the input.
|
|
*
|
|
* __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 http://docs.handsontable.com/tutorial-using-callbacks.html#page-source-definition}).
|
|
*/
|
|
'afterChange',
|
|
|
|
/**
|
|
* @description
|
|
* Fired after observing changes.
|
|
*
|
|
* @event Hooks#afterChangesObserved
|
|
*/
|
|
'afterChangesObserved',
|
|
|
|
/**
|
|
* @description
|
|
* Fired 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 `contextMenu` option.
|
|
*
|
|
* @event Hooks#afterContextMenuDefaultOptions
|
|
* @param {Array} predefinedItems Array of objects containing information about the pre-defined Context Menu items.
|
|
*/
|
|
'afterContextMenuDefaultOptions',
|
|
|
|
/**
|
|
* @description
|
|
* Fired 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 {Array} menuItems Array of objects containing information about to generated Context Menu items.
|
|
*/
|
|
'beforeContextMenuSetItems',
|
|
|
|
/**
|
|
* @description
|
|
* Fired 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 `contextMenu` option.
|
|
*
|
|
* @pro
|
|
* @event Hooks#afterDropdownMenuDefaultOptions
|
|
* @param {Array} predefinedItems Array of objects containing information about the pre-defined Context Menu items.
|
|
*/
|
|
'afterDropdownMenuDefaultOptions',
|
|
|
|
/**
|
|
* @description
|
|
* Fired 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.
|
|
*
|
|
* @pro
|
|
* @event Hooks#beforeDropdownMenuSetItems
|
|
* @param {Array} menuItems Array of objects containing information about to generated Dropdown Menu items.
|
|
*/
|
|
'beforeDropdownMenuSetItems',
|
|
|
|
/**
|
|
* @description
|
|
* Fired after hiding the Context Menu.
|
|
*
|
|
* @event Hooks#afterContextMenuHide
|
|
* @param {Object} context The Context menu instance.
|
|
*/
|
|
'afterContextMenuHide',
|
|
|
|
/**
|
|
* @description
|
|
* Fired after opening the Context Menu.
|
|
*
|
|
* @event Hooks#afterContextMenuShow
|
|
* @param {Object} context The Context Menu instance.
|
|
*/
|
|
'afterContextMenuShow',
|
|
|
|
/**
|
|
* @description
|
|
* Fired after reaching the copy limit while copying data.
|
|
*
|
|
* @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',
|
|
|
|
/**
|
|
* Callback is fired before a new column was created.
|
|
*
|
|
* @since 0.28.0
|
|
* @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',
|
|
|
|
/**
|
|
* Callback is fired after a new column was created.
|
|
*
|
|
* @event Hooks#afterCreateCol
|
|
* @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}).
|
|
*/
|
|
'afterCreateCol',
|
|
|
|
/**
|
|
* Callback is fired before a new row was created.
|
|
*
|
|
* @since 0.28.0
|
|
* @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',
|
|
|
|
/**
|
|
* Callback is fired after a new row was created.
|
|
*
|
|
* @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',
|
|
|
|
/**
|
|
* Fired on a `keydown` event on the document body.
|
|
*
|
|
* @event Hooks#afterDocumentKeyDown
|
|
* @param {Event} event A `keydown` event.
|
|
*/
|
|
'afterDocumentKeyDown',
|
|
|
|
/**
|
|
* Callback fired after getting the cell settings.
|
|
*
|
|
* @event Hooks#afterGetCellMeta
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {Object} cellProperties Object containing the cell properties.
|
|
*/
|
|
'afterGetCellMeta',
|
|
|
|
/**
|
|
* Callback fired after retrieving information about a column header and appending it to the table header.
|
|
*
|
|
* @event Hooks#afterGetColHeader
|
|
* @param {Number} col Visual column index.
|
|
* @param {Element} TH Header's TH element.
|
|
*/
|
|
'afterGetColHeader',
|
|
|
|
/**
|
|
* Callback fired after retrieving information about a column header and appending it to the table header.
|
|
*
|
|
* @event Hooks#afterGetRowHeader
|
|
* @param {Number} row Visual row index.
|
|
* @param {Element} TH Header's TH element.
|
|
*/
|
|
'afterGetRowHeader',
|
|
|
|
/**
|
|
* Callback fired after Handsontable instance is initiated.
|
|
*
|
|
* @event Hooks#afterInit
|
|
*/
|
|
'afterInit',
|
|
|
|
/**
|
|
* Callback fired after new data is loaded (by `loadData` method) into the data source array.
|
|
*
|
|
* @event Hooks#afterLoadData
|
|
* @param {Boolean} firstTime 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
|
|
* @since 0.11
|
|
* @param {Object} event `mousedown` event object.
|
|
*/
|
|
'afterOnCellCornerMouseDown',
|
|
|
|
/**
|
|
* Fired after a `dblclick` event is triggered on the cell corner (the drag handle).
|
|
*
|
|
* @event Hooks#afterOnCellCornerDblClick
|
|
* @since 0.30.0
|
|
* @param {Object} event `dblclick` event object.
|
|
*/
|
|
'afterOnCellCornerDblClick',
|
|
|
|
/**
|
|
* Callback fired after clicking on a cell or row/column header.
|
|
* In case the row/column header was clicked, the index is negative.
|
|
* For example clicking on the row header of cell (0, 0) results with `afterOnCellMouseDown` called
|
|
* with coords `{row: 0, col: -1}`.
|
|
*
|
|
* @event Hooks#afterOnCellMouseDown
|
|
* @since 0.11
|
|
* @param {Object} event `mousedown` event object.
|
|
* @param {Object} coords Coordinates object containing the visual row and visual column indexes of the clicked cell.
|
|
* @param {Element} TD Cell's TD (or TH) element.
|
|
*/
|
|
'afterOnCellMouseDown',
|
|
|
|
/**
|
|
* Callback 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
|
|
* @since 0.11
|
|
* @param {Object} event `mouseover` event object.
|
|
* @param {Object} coords Hovered cell's visual coordinate object.
|
|
* @param {Element} TD Cell's TD (or TH) element.
|
|
*/
|
|
'afterOnCellMouseOver',
|
|
|
|
/**
|
|
* Callback fired after leaving a cell or row/column header with the mouse cursor.
|
|
*
|
|
* @event Hooks#afterOnCellMouseOut
|
|
* @since 0.31.1
|
|
* @param {Object} event `mouseout` event object.
|
|
* @param {Object} coords Leaved cell's visual coordinate object.
|
|
* @param {Element} TD Cell's TD (or TH) element.
|
|
*/
|
|
'afterOnCellMouseOut',
|
|
|
|
/**
|
|
* Callback is fired when one or more columns are removed.
|
|
*
|
|
* @event Hooks#afterRemoveCol
|
|
* @param {Number} index Is an visual index of starter column.
|
|
* @param {Number} amount Is an amount of removed columns.
|
|
*/
|
|
'afterRemoveCol',
|
|
|
|
/**
|
|
* Callback is fired when one or more rows are removed.
|
|
*
|
|
* @event Hooks#afterRemoveRow
|
|
* @param {Number} index Is an visual index of starter row.
|
|
* @param {Number} amount Is an amount of removed rows.
|
|
*/
|
|
'afterRemoveRow',
|
|
|
|
/**
|
|
* Callback 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
|
|
* @since 0.24.2
|
|
* @param {Element} TD Currently rendered cell's 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.
|
|
*/
|
|
'beforeRenderer',
|
|
|
|
/**
|
|
* Fired after finishing rendering the cell (after the renderer finishes).
|
|
*
|
|
* @event Hooks#afterRenderer
|
|
* @since 0.11.0
|
|
* @param {Element} TD Currently rendered cell's 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.
|
|
*/
|
|
'afterRenderer',
|
|
|
|
/**
|
|
* Fired after the horizontal scroll event.
|
|
*
|
|
* @event Hooks#afterScrollHorizontally
|
|
* @since 0.11
|
|
*/
|
|
'afterScrollHorizontally',
|
|
|
|
/**
|
|
* Fired after the vertical scroll event.
|
|
*
|
|
* @event Hooks#afterScrollVertically
|
|
* @since 0.11
|
|
*/
|
|
'afterScrollVertically',
|
|
|
|
/**
|
|
* Callback fired after one or more cells are selected (e.g. during mouse move).
|
|
*
|
|
* @event Hooks#afterSelection
|
|
* @param {Number} r Selection start visual row index.
|
|
* @param {Number} c Selection start visual column index.
|
|
* @param {Number} r2 Selection end visual row index.
|
|
* @param {Number} c2 Selection end visual column index.
|
|
* @param {Object} preventScrolling Object with `value` property where its value change will be observed.
|
|
* * @example
|
|
* ```js
|
|
* handsontable({
|
|
* afterSelection: function (r, c, r2, c2, preventScrolling) {
|
|
* // setting if prevent scrolling after selection
|
|
*
|
|
* preventScrolling.value = true;
|
|
* }
|
|
* })
|
|
* ```
|
|
*/
|
|
'afterSelection',
|
|
|
|
/**
|
|
* Callback fired after one or more cells are selected. The `p` argument represents the source object property name instead of the column number.
|
|
*
|
|
* @event Hooks#afterSelectionByProp
|
|
* @param {Number} r Selection start visual row index.
|
|
* @param {String} p Selection start data source object property name.
|
|
* @param {Number} r2 Selection end visual row index.
|
|
* @param {String} p2 Selection end data source object property name.
|
|
* @param {Object} preventScrolling Object with `value` property where its value change will be observed.
|
|
* * @example
|
|
* ```js
|
|
* handsontable({
|
|
* afterSelectionByProp: function (r, c, r2, c2, preventScrolling) {
|
|
* // setting if prevent scrolling after selection
|
|
*
|
|
* preventScrolling.value = true;
|
|
* }
|
|
* })
|
|
* ```
|
|
*/
|
|
'afterSelectionByProp',
|
|
|
|
/**
|
|
* Callback fired after one or more cells are selected (e.g. on mouse up).
|
|
*
|
|
* @event Hooks#afterSelectionEnd
|
|
* @param {Number} r Selection start visual row index.
|
|
* @param {Number} c Selection start visual column index.
|
|
* @param {Number} r2 Selection end visual row index.
|
|
* @param {Number} c2 Selection end visual column index.
|
|
*/
|
|
'afterSelectionEnd',
|
|
|
|
/**
|
|
* Callback fired after one or more cells are selected (e.g. on mouse up). The `p` argument represents the data source object
|
|
* property name instead of the column number.
|
|
*
|
|
* @event Hooks#afterSelectionEndByProp
|
|
* @param {Number} r Selection start visual row index.
|
|
* @param {String} p Selection start data source object property index.
|
|
* @param {Number} r2 Selection end visual row index.
|
|
* @param {String} p2 Selection end data source object property index.
|
|
*/
|
|
'afterSelectionEndByProp',
|
|
|
|
/**
|
|
* Called after cell meta is changed.
|
|
*
|
|
* @event Hooks#afterSetCellMeta
|
|
* @since 0.11.0
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {String} key The updated meta key.
|
|
* @param {*} value The updated meta value.
|
|
*/
|
|
'afterSetCellMeta',
|
|
|
|
/**
|
|
* Called after cell data was changed.
|
|
*
|
|
* @event Hooks#afterSetDataAtCell
|
|
* @since 0.28.0
|
|
* @param {Array} changes An array of changes in format `[[row, col, 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',
|
|
|
|
/**
|
|
* Called after cell data was changed.
|
|
*
|
|
* @event Hooks#afterSetDataAtRowProp
|
|
* @since 0.28.0
|
|
* @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
|
|
*/
|
|
'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
|
|
* @since 0.9.5
|
|
* @param {Boolean} isValid `true` if valid, `false` if not.
|
|
* @param {*} value The value in question.
|
|
* @param {Number} row 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}).
|
|
*/
|
|
'afterValidate',
|
|
|
|
/**
|
|
* Fired before populating the data in the autofill feature.
|
|
*
|
|
* @event Hooks#beforeAutofill
|
|
* @param {Object} start Object containing information about first filled cell: `{row: 2, col: 0}`.
|
|
* @param {Object} 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 stateBefore
|
|
* @param range
|
|
* @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`
|
|
* for horizontal alignment,
|
|
*
|
|
*
|
|
* * `htTop`,
|
|
* * `htMiddle`,
|
|
* * `htBottom`
|
|
* for vertical alignment.
|
|
*/
|
|
'beforeCellAlignment',
|
|
|
|
/**
|
|
* Callback fired before one or more cells is changed. Its main purpose is to alter changes silently before input.
|
|
*
|
|
* @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(document.getElementById('example'), {
|
|
* beforeChange: function(changes, source) {
|
|
* // [[row, prop, oldVal, newVal], ...]
|
|
* changes[0] = null;
|
|
* }
|
|
* });
|
|
* ...
|
|
*
|
|
* // To alter a single change, overwrite the desired value to changes[i][3].
|
|
* ...
|
|
* new Handsontable(document.getElementById('example'), {
|
|
* beforeChange: function(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(document.getElementById('example'), {
|
|
* beforeChange: function(changes, source) {
|
|
* // [[row, prop, oldVal, newVal], ...]
|
|
* return false;
|
|
* }
|
|
* });
|
|
* ...
|
|
* ```
|
|
*/
|
|
'beforeChange',
|
|
|
|
/**
|
|
* Fired right before rendering the changes.
|
|
*
|
|
* @event Hooks#beforeChangeRender
|
|
* @since 0.11
|
|
* @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',
|
|
|
|
/**
|
|
* Callback fired before getting cell settings.
|
|
*
|
|
* @event Hooks#beforeGetCellMeta
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {Object} cellProperties Object containing the cell's properties.
|
|
*/
|
|
'beforeGetCellMeta',
|
|
|
|
/**
|
|
* @description
|
|
* Callback fired before Handsontable instance is initiated.
|
|
*
|
|
* @event Hooks#beforeInit
|
|
*/
|
|
'beforeInit',
|
|
|
|
/**
|
|
* Callback fired before Walkontable instance is initiated.
|
|
*
|
|
* @since 0.11
|
|
* @event Hooks#beforeInitWalkontable
|
|
* @param {Object} walkontableConfig Walkontable configuration object.
|
|
*/
|
|
'beforeInitWalkontable',
|
|
|
|
/**
|
|
* Callback fired before keydown event is handled. It can be used to overwrite default key bindings.
|
|
* Caution - in your `beforeKeyDown` handler you need to call `event.stopImmediatePropagation()` to prevent default key behavior.
|
|
*
|
|
* @event Hooks#beforeKeyDown
|
|
* @since 0.9.0
|
|
* @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 {Element} TD TD element.
|
|
*/
|
|
'beforeOnCellMouseDown',
|
|
|
|
/**
|
|
* 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 {Element} TD TD element.
|
|
* @param {Object} blockCalculations Contain keys 'row' and 'column' with boolean value.
|
|
*/
|
|
'beforeOnCellMouseOver',
|
|
|
|
/**
|
|
* Fired after the user moved cursor out from a cell, but before all the calculations related with it.
|
|
*
|
|
* @event Hooks#beforeOnCellMouseOut
|
|
* @since 0.31.1
|
|
* @param {Event} event The `mouseout` event object.
|
|
* @param {WalkontableCellCoords} coords WalkontableCellCoords object containing the visual coordinates of the leaved cell.
|
|
* @param {Element} TD TD element.
|
|
*/
|
|
'beforeOnCellMouseOut',
|
|
|
|
/**
|
|
* Callback is fired when 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 {Array} [visualCols] Consists of visual indexes of processed columns.
|
|
*/
|
|
'beforeRemoveCol',
|
|
|
|
/**
|
|
* Callback is 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 {Array} [visualRows] Consists of visual indexes of processed rows.
|
|
*/
|
|
'beforeRemoveRow',
|
|
|
|
/**
|
|
* Callback fired before 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',
|
|
|
|
/**
|
|
* Callback fired before setting range is started.
|
|
*
|
|
* @event Hooks#beforeSetRangeStart
|
|
* @param {Array} coords CellCoords array.
|
|
*/
|
|
'beforeSetRangeStart',
|
|
|
|
/**
|
|
* Callback fired before setting range is ended.
|
|
*
|
|
* @event Hooks#beforeSetRangeEnd
|
|
* @param {Array} coords CellCoords array.
|
|
*/
|
|
'beforeSetRangeEnd',
|
|
|
|
/**
|
|
* Fired before the logic of handling a touch scroll, when user started scrolling on a touch-enabled device.
|
|
*
|
|
* @event Hooks#beforeTouchScroll
|
|
*/
|
|
'beforeTouchScroll',
|
|
|
|
/**
|
|
* @description
|
|
* A plugin hook executed before validator function, 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.
|
|
*
|
|
* __Notice:__ this will not affect values of changes. This will change value ONLY for validation!
|
|
*
|
|
* @event Hooks#beforeValidate
|
|
* @since 0.9.5
|
|
* @param {*} value Value of the cell.
|
|
* @param {Number} row 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',
|
|
|
|
/**
|
|
* Callback fired before cell value is rendered into the DOM (through renderer function).
|
|
*
|
|
* @event Hooks#beforeValueRender
|
|
* @since 0.29.0
|
|
* @param {*} value Cell value to render.
|
|
*/
|
|
'beforeValueRender',
|
|
|
|
/**
|
|
* Callback fired after Handsontable instance is constructed (via `new` operator).
|
|
*
|
|
* @event Hooks#construct
|
|
* @since 0.16.1
|
|
*/
|
|
'construct',
|
|
|
|
/**
|
|
* Callback fired after Handsontable instance is initiated but before table is rendered.
|
|
*
|
|
* @event Hooks#init
|
|
* @since 0.16.1
|
|
*/
|
|
'init',
|
|
|
|
/**
|
|
* Fired when a column index is about to be modified by a callback function.
|
|
*
|
|
* @event Hooks#modifyCol
|
|
* @since 0.11
|
|
* @param {Number} col Visual column index.
|
|
*/
|
|
'modifyCol',
|
|
|
|
/**
|
|
* Fired when a column index is about to be de-modified by a callback function.
|
|
*
|
|
* @event Hooks#unmodifyCol
|
|
* @since 0.23.0
|
|
* @param {Number} col Physical column index.
|
|
*/
|
|
'unmodifyCol',
|
|
|
|
/**
|
|
* Fired when a physical row index is about to be de-modified by a callback function.
|
|
*
|
|
* @event Hooks#unmodifyRow
|
|
* @since 0.26.2
|
|
* @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
|
|
* @since 0.20.0
|
|
* @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
|
|
* @since 0.11
|
|
* @param {Number} width Current column width.
|
|
* @param {Number} col Column index.
|
|
*/
|
|
'modifyColWidth',
|
|
|
|
/**
|
|
* Fired when a row index is about to be modified by a callback function.
|
|
*
|
|
* @event Hooks#modifyRow
|
|
* @since 0.11
|
|
* @param {Number} row Row index.
|
|
*/
|
|
'modifyRow',
|
|
|
|
/**
|
|
* Fired when a row header index is about to be modified by a callback function.
|
|
*
|
|
* @event Hooks#modifyRowHeader
|
|
* @since 0.20.0
|
|
* @param {Number} row Row header index.
|
|
*/
|
|
'modifyRowHeader',
|
|
|
|
/**
|
|
* Fired when a row height is about to be modified by a callback function.
|
|
*
|
|
* @event Hooks#modifyRowHeight
|
|
* @since 0.11.0
|
|
* @param {Number} height Row height.
|
|
* @param {Number} row Row index.
|
|
*/
|
|
'modifyRowHeight',
|
|
|
|
/**
|
|
* Fired when a data was retrieved or modified.
|
|
*
|
|
* @event Hooks#modifyData
|
|
* @since 0.28.0
|
|
* @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
|
|
* @since 0.28.0
|
|
* @param {Number} row Physical row index.
|
|
*/
|
|
'modifyRowData',
|
|
|
|
/**
|
|
* Fired after loading data using the Persistent State plugin.
|
|
*
|
|
* @event Hooks#persistentStateLoad
|
|
* @param {String} key Key string.
|
|
* @param {Object} valuePlaceholder Object containing the loaded data.
|
|
*/
|
|
'persistentStateLoad',
|
|
|
|
/**
|
|
* Fired after resetting data using the Persistent State plugin.
|
|
*
|
|
* @event Hooks#persistentStateReset
|
|
* @param {String} key Key string.
|
|
*/
|
|
'persistentStateReset',
|
|
|
|
/**
|
|
* Fired after resetting data using the Persistent State plugin.
|
|
*
|
|
* @event Hooks#persistentStateSave
|
|
* @param {String} key Key string.
|
|
* @param {Mixed} value Value to save.
|
|
*/
|
|
'persistentStateSave',
|
|
|
|
/**
|
|
* Fired before sorting the column. If you return `false` value then sorting will be not applied by
|
|
* Handsontable (useful for server-side sorting).
|
|
*
|
|
* @event Hooks#beforeColumnSort
|
|
* @param {Number} column Sorted visual column index.
|
|
* @param {Boolean} order Soring order where:
|
|
* * `true` means ascending order,
|
|
* * `false` means descending order,
|
|
* * `undefined` means original order.
|
|
*/
|
|
'beforeColumnSort',
|
|
|
|
/**
|
|
* Fired after sorting the column.
|
|
*
|
|
* @event Hooks#afterColumnSort
|
|
* @param {Number} column Sorted visual column index.
|
|
* @param {Boolean} order Soring order where:
|
|
* * `true` means ascending order
|
|
* * `false` means descending order
|
|
* * `undefined` means original order
|
|
*/
|
|
'afterColumnSort',
|
|
|
|
/**
|
|
* @description
|
|
* Fired after setting range of autofill.
|
|
* Both arguments are provided in the following format:
|
|
* ```js
|
|
* [startRow, startColumn, endRow, endColumn]
|
|
* ```
|
|
*
|
|
* @event Hooks#modifyAutofillRange
|
|
* @param {Array} startArea Array of visual coordinates of the starting point for the drag-down operation.
|
|
* @param {Array} entireArea Array of visual coordinates of the entire area of the drag-down operation.
|
|
*/
|
|
'modifyAutofillRange',
|
|
|
|
/**
|
|
* Fired to allow modifying the copyable range with a callback function.
|
|
*
|
|
* @since 0.19.0
|
|
* @event Hooks#modifyCopyableRange
|
|
* @param {Array} copyableRanges Array of objects defining copyable cells.
|
|
*/
|
|
'modifyCopyableRange',
|
|
|
|
/**
|
|
* Called before copying the values into clipboard and before clearing values of the selected cells.
|
|
*
|
|
* @event Hooks#beforeCut
|
|
* @since 0.31.1
|
|
* @param {Array} data An array of arrays which contains data to cut.
|
|
* @param {Array} 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 cancelled.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* // To disregard a single row, remove it from array using data.splice(i, 1).
|
|
* ...
|
|
* new Handsontable(document.getElementById('example'), {
|
|
* 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 cutting out, return false from the callback.
|
|
* ...
|
|
* new Handsontable(document.getElementById('example'), {
|
|
* beforeCut: function(data, coords) {
|
|
* return false;
|
|
* }
|
|
* });
|
|
* ...
|
|
* ```
|
|
*/
|
|
'beforeCut',
|
|
|
|
/**
|
|
* Fired after data are cutted out from the table.
|
|
*
|
|
* @event Hooks#afterCut
|
|
* @since 0.31.1
|
|
* @param {Array} data An array of arrays which contains the cutted out data.
|
|
* @param {Array} 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
|
|
* @since 0.31.1
|
|
* @param {Array} data An array of arrays which contains data to copied.
|
|
* @param {Array} 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 cancelled.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* // To disregard a single row, remove it from array using data.splice(i, 1).
|
|
* ...
|
|
* new Handsontable(document.getElementById('example'), {
|
|
* beforeCopy: 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 copying, return false from the callback.
|
|
* ...
|
|
* new Handsontable(document.getElementById('example'), {
|
|
* beforeCopy: function(data, coords) {
|
|
* return false;
|
|
* }
|
|
* });
|
|
* ...
|
|
* ```
|
|
*/
|
|
'beforeCopy',
|
|
|
|
/**
|
|
* Fired after data are pasted into table.
|
|
*
|
|
* @event Hooks#afterCopy
|
|
* @since 0.31.1
|
|
* @param {Array} data An array of arrays which contains the copied data.
|
|
* @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
|
|
* which was copied.
|
|
*/
|
|
'afterCopy',
|
|
|
|
/**
|
|
* Fired before values are pasted into table.
|
|
*
|
|
* @event Hooks#beforePaste
|
|
* @since 0.31.1
|
|
* @param {Array} data An array of arrays which contains data to paste.
|
|
* @param {Array} 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 cancelled.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* // To disregard a single row, remove it from array using data.splice(i, 1).
|
|
* ...
|
|
* new Handsontable(document.getElementById('example'), {
|
|
* beforePaste: 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 pasting, return false from the callback.
|
|
* ...
|
|
* new Handsontable(document.getElementById('example'), {
|
|
* beforePaste: function(data, coords) {
|
|
* return false;
|
|
* }
|
|
* });
|
|
* ...
|
|
* ```
|
|
*/
|
|
'beforePaste',
|
|
|
|
/**
|
|
* Fired after values are pasted into table.
|
|
*
|
|
* @event Hooks#afterePaste
|
|
* @since 0.31.1
|
|
* @param {Array} data An array of arrays which contains the pasted data.
|
|
* @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
|
|
* that correspond to the previously selected area.
|
|
*/
|
|
'afterPaste',
|
|
|
|
/**
|
|
* Fired before change order of the visual indexes.
|
|
*
|
|
* @event Hooks#beforeColumnMove
|
|
* @param {Array} columns Array of visual column indexes to be moved.
|
|
* @param {Number} target Visual column index being a target for moved columns.
|
|
*/
|
|
'beforeColumnMove',
|
|
|
|
/**
|
|
* Fired after change order of the visual indexes.
|
|
*
|
|
* @event Hooks#afterColumnMove
|
|
* @param {Array} columns Array of visual column indexes that were moved.
|
|
* @param {Number} target Visual column index being a target for moved columns.
|
|
*/
|
|
'afterColumnMove',
|
|
|
|
/**
|
|
* Fired before change order of the visual indexes.
|
|
*
|
|
* @event Hooks#beforeRowMove
|
|
* @param {Array} rows Array of visual row indexes to be moved.
|
|
* @param {Number} target Visual row index being a target for moved rows.
|
|
*/
|
|
'beforeRowMove',
|
|
|
|
/**
|
|
* Fired after change order of the visual indexes.
|
|
*
|
|
* @event Hooks#afterRowMove
|
|
* @param {Array} rows Array of visual row indexes that were moved.
|
|
* @param {Number} target Visual row index being a target for moved rows.
|
|
*/
|
|
'afterRowMove',
|
|
|
|
/**
|
|
* Fired before rendering the table with modified column sizes.
|
|
*
|
|
* @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 after rendering the table with modified column sizes.
|
|
*
|
|
* @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 before rendering the table with modified row sizes.
|
|
*
|
|
* @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 after rendering the table with modified row sizes.
|
|
*
|
|
* @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 {Array} array Array of the column header renderers.
|
|
*/
|
|
'afterGetColumnHeaderRenderers',
|
|
|
|
/**
|
|
* Fired after getting the row header renderers.
|
|
*
|
|
* @event Hooks#afterGetRowHeaderRenderers
|
|
* @param {Array} array 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 before applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}.
|
|
*
|
|
* @pro
|
|
* @event Hooks#beforeFilter
|
|
* @param {Array} conditionsStack An array of objects with added formulas.
|
|
* @returns {Boolean} If hook returns `false` value then filtering won't be applied on the UI side (server-side filtering).
|
|
*/
|
|
'beforeFilter',
|
|
|
|
/**
|
|
* Fired after applying [filtering]{@link http://docs.handsontable.com/pro/demo-filtering.html}.
|
|
*
|
|
* @pro
|
|
* @event Hooks#afterFilter
|
|
* @param {Array} conditionsStack An array of objects with added formulas.
|
|
*/
|
|
'afterFilter',
|
|
|
|
/**
|
|
* Used to modify the column header height.
|
|
*
|
|
* @event Hooks#modifyColumnHeaderHeight
|
|
* @since 0.25.0
|
|
* @param {Number} col Visual column index.
|
|
*/
|
|
'modifyColumnHeaderHeight',
|
|
|
|
/**
|
|
* Fired before the undo action. Contains information about the action that is being undone.
|
|
*
|
|
* @event Hooks#beforeUndo
|
|
* @since 0.26.2
|
|
* @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 after the undo action. Contains information about the action that is being undone.
|
|
*
|
|
* @event Hooks#afterUndo
|
|
* @since 0.26.2
|
|
* @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 before the redo action. Contains information about the action that is being redone.
|
|
*
|
|
* @event Hooks#beforeRedo
|
|
* @since 0.26.2
|
|
* @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 after the redo action. Contains information about the action that is being redone.
|
|
*
|
|
* @event Hooks#afterRedo
|
|
* @since 0.26.2
|
|
* @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',
|
|
|
|
/**
|
|
* Used to modify 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 Array of arrays. 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 when saving/loading the manual row heights state.
|
|
*
|
|
* @event Hooks#manualRowHeights
|
|
* @param {Array} state The current manual row heights state.
|
|
*/
|
|
'manualRowHeights',
|
|
|
|
/**
|
|
* 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 after trimming rows in the TrimRows plugin.
|
|
*
|
|
* @pro
|
|
* @event Hooks#afterTrimRow
|
|
* @param {Array} rows Physical indexes of trimmed rows.
|
|
*/
|
|
'afterTrimRow',
|
|
|
|
/**
|
|
* Fired after untrimming rows in the TrimRows plugin.
|
|
*
|
|
* @pro
|
|
* @event Hooks#afterUntrimRow
|
|
* @param {Array} rows Physical indexes of untrimmed rows.
|
|
*/
|
|
'afterUntrimRow',
|
|
|
|
/**
|
|
* Fired after opening the dropdown menu.
|
|
*
|
|
* @pro
|
|
* @event Hooks#afterDropdownMenuShow
|
|
* @param {DropdownMenu} instance The DropdownMenu instance.
|
|
*/
|
|
'afterDropdownMenuShow',
|
|
|
|
/**
|
|
* Fired after hiding the dropdown menu.
|
|
*
|
|
* @pro
|
|
* @event Hooks#afterDropdownMenuHide
|
|
* @param {DropdownMenu} instance The DropdownMenu instance.
|
|
*/
|
|
'afterDropdownMenuHide',
|
|
|
|
/**
|
|
* Used to check whether the provided row index is hidden.
|
|
*
|
|
* @pro
|
|
* @event Hooks#hiddenRow
|
|
* @param {Number} row The visual row index in question.
|
|
*/
|
|
'hiddenRow',
|
|
|
|
/**
|
|
* Used to check whether the provided column index is hidden.
|
|
*
|
|
* @pro
|
|
* @event Hooks#hiddenColumn
|
|
* @param {Number} column The visual column index in question.
|
|
*/
|
|
'hiddenColumn',
|
|
|
|
/**
|
|
* Fired before adding a children to the NestedRows structure.
|
|
*
|
|
* @pro
|
|
* @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 after adding a children to the NestedRows structure.
|
|
*
|
|
* @pro
|
|
* @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 before detaching a child from its parent in the NestedRows plugin.
|
|
*
|
|
* @pro
|
|
* @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 after detaching a child from its parent in the NestedRows plugin.
|
|
*
|
|
* @pro
|
|
* @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 Row index of the edited cell.
|
|
* @param {Number} column Column index of the edited cell.
|
|
*/
|
|
'afterBeginEditing'];
|
|
|
|
var Hooks = function () {
|
|
_createClass(Hooks, null, [{
|
|
key: 'getSingleton',
|
|
value: function getSingleton() {
|
|
return globalSingleton;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
}]);
|
|
|
|
function Hooks() {
|
|
_classCallCheck(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: [],
|
|
* ...
|
|
* }
|
|
* ```
|
|
*/
|
|
|
|
|
|
_createClass(Hooks, [{
|
|
key: 'createEmptyBucket',
|
|
value: function createEmptyBucket() {
|
|
var bucket = Object.create(null);
|
|
|
|
(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 index = -1;
|
|
var length = globalHandlers ? globalHandlers.length : 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) {
|
|
/* 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) {
|
|
p1 = res;
|
|
}
|
|
if (globalHandlers[index] && globalHandlers[index].runOnce) {
|
|
this.remove(key, globalHandlers[index]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
{
|
|
var localHandlers = this.getBucket(context)[key];
|
|
var _index = -1;
|
|
var _length = localHandlers ? localHandlers.length : 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) {
|
|
/* 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) {
|
|
p1 = _res;
|
|
}
|
|
if (localHandlers[_index] && localHandlers[_index].runOnce) {
|
|
this.remove(key, localHandlers[_index], context);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
(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();
|
|
|
|
exports.default = Hooks;
|
|
|
|
/***/ }),
|
|
/* 9 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.getRegisteredRenderers = exports.getRegisteredRendererNames = exports.hasRenderer = exports.getRenderer = exports.registerRenderer = undefined;
|
|
|
|
var _staticRegister2 = __webpack_require__(52);
|
|
|
|
var _staticRegister3 = _interopRequireDefault(_staticRegister2);
|
|
|
|
var _cellDecorator = __webpack_require__(377);
|
|
|
|
var _cellDecorator2 = _interopRequireDefault(_cellDecorator);
|
|
|
|
var _autocompleteRenderer = __webpack_require__(378);
|
|
|
|
var _autocompleteRenderer2 = _interopRequireDefault(_autocompleteRenderer);
|
|
|
|
var _checkboxRenderer = __webpack_require__(379);
|
|
|
|
var _checkboxRenderer2 = _interopRequireDefault(_checkboxRenderer);
|
|
|
|
var _htmlRenderer = __webpack_require__(380);
|
|
|
|
var _htmlRenderer2 = _interopRequireDefault(_htmlRenderer);
|
|
|
|
var _numericRenderer = __webpack_require__(381);
|
|
|
|
var _numericRenderer2 = _interopRequireDefault(_numericRenderer);
|
|
|
|
var _passwordRenderer = __webpack_require__(382);
|
|
|
|
var _passwordRenderer2 = _interopRequireDefault(_passwordRenderer);
|
|
|
|
var _textRenderer = __webpack_require__(383);
|
|
|
|
var _textRenderer2 = _interopRequireDefault(_textRenderer);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var _staticRegister = (0, _staticRegister3.default)('renderers'),
|
|
register = _staticRegister.register,
|
|
getItem = _staticRegister.getItem,
|
|
hasItem = _staticRegister.hasItem,
|
|
getNames = _staticRegister.getNames,
|
|
getValues = _staticRegister.getValues;
|
|
|
|
register('base', _cellDecorator2.default);
|
|
register('autocomplete', _autocompleteRenderer2.default);
|
|
register('checkbox', _checkboxRenderer2.default);
|
|
register('html', _htmlRenderer2.default);
|
|
register('numeric', _numericRenderer2.default);
|
|
register('password', _passwordRenderer2.default);
|
|
register('text', _textRenderer2.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 "' + name + '" name');
|
|
}
|
|
|
|
return getItem(name);
|
|
}
|
|
|
|
exports.registerRenderer = register;
|
|
exports.getRenderer = _getItem;
|
|
exports.hasRenderer = hasItem;
|
|
exports.getRegisteredRendererNames = getNames;
|
|
exports.getRegisteredRenderers = getValues;
|
|
|
|
/***/ }),
|
|
/* 10 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var store = __webpack_require__(84)('wks')
|
|
, uid = __webpack_require__(50)
|
|
, Symbol = __webpack_require__(13).Symbol
|
|
, USE_SYMBOL = typeof Symbol == 'function';
|
|
|
|
var $exports = module.exports = function(name){
|
|
return store[name] || (store[name] =
|
|
USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
|
|
};
|
|
|
|
$exports.store = store;
|
|
|
|
/***/ }),
|
|
/* 11 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.Viewport = exports.TableRenderer = exports.Table = exports.Settings = exports.Selection = exports.Scroll = exports.Overlays = exports.Event = exports.Core = exports.default = exports.Border = exports.TopLeftCornerOverlay = exports.TopOverlay = exports.LeftOverlay = exports.DebugOverlay = exports.RowFilter = exports.ColumnFilter = exports.CellRange = exports.CellCoords = exports.ViewportRowsCalculator = exports.ViewportColumnsCalculator = undefined;
|
|
|
|
__webpack_require__(97);
|
|
|
|
__webpack_require__(114);
|
|
|
|
__webpack_require__(123);
|
|
|
|
__webpack_require__(124);
|
|
|
|
__webpack_require__(108);
|
|
|
|
__webpack_require__(122);
|
|
|
|
__webpack_require__(105);
|
|
|
|
__webpack_require__(106);
|
|
|
|
__webpack_require__(107);
|
|
|
|
__webpack_require__(96);
|
|
|
|
__webpack_require__(119);
|
|
|
|
__webpack_require__(117);
|
|
|
|
__webpack_require__(115);
|
|
|
|
__webpack_require__(120);
|
|
|
|
__webpack_require__(121);
|
|
|
|
__webpack_require__(116);
|
|
|
|
__webpack_require__(118);
|
|
|
|
__webpack_require__(109);
|
|
|
|
__webpack_require__(110);
|
|
|
|
__webpack_require__(111);
|
|
|
|
__webpack_require__(113);
|
|
|
|
__webpack_require__(112);
|
|
|
|
__webpack_require__(94);
|
|
|
|
__webpack_require__(95);
|
|
|
|
__webpack_require__(90);
|
|
|
|
__webpack_require__(93);
|
|
|
|
__webpack_require__(92);
|
|
|
|
__webpack_require__(91);
|
|
|
|
__webpack_require__(68);
|
|
|
|
__webpack_require__(99);
|
|
|
|
__webpack_require__(100);
|
|
|
|
__webpack_require__(102);
|
|
|
|
__webpack_require__(101);
|
|
|
|
__webpack_require__(98);
|
|
|
|
__webpack_require__(104);
|
|
|
|
__webpack_require__(103);
|
|
|
|
__webpack_require__(125);
|
|
|
|
__webpack_require__(128);
|
|
|
|
__webpack_require__(126);
|
|
|
|
__webpack_require__(127);
|
|
|
|
__webpack_require__(130);
|
|
|
|
__webpack_require__(129);
|
|
|
|
__webpack_require__(132);
|
|
|
|
__webpack_require__(131);
|
|
|
|
var _viewportColumns = __webpack_require__(251);
|
|
|
|
var _viewportColumns2 = _interopRequireDefault(_viewportColumns);
|
|
|
|
var _viewportRows = __webpack_require__(252);
|
|
|
|
var _viewportRows2 = _interopRequireDefault(_viewportRows);
|
|
|
|
var _coords = __webpack_require__(43);
|
|
|
|
var _coords2 = _interopRequireDefault(_coords);
|
|
|
|
var _range = __webpack_require__(69);
|
|
|
|
var _range2 = _interopRequireDefault(_range);
|
|
|
|
var _column = __webpack_require__(255);
|
|
|
|
var _column2 = _interopRequireDefault(_column);
|
|
|
|
var _row = __webpack_require__(256);
|
|
|
|
var _row2 = _interopRequireDefault(_row);
|
|
|
|
var _debug = __webpack_require__(299);
|
|
|
|
var _debug2 = _interopRequireDefault(_debug);
|
|
|
|
var _left = __webpack_require__(300);
|
|
|
|
var _left2 = _interopRequireDefault(_left);
|
|
|
|
var _top = __webpack_require__(301);
|
|
|
|
var _top2 = _interopRequireDefault(_top);
|
|
|
|
var _topLeftCorner = __webpack_require__(302);
|
|
|
|
var _topLeftCorner2 = _interopRequireDefault(_topLeftCorner);
|
|
|
|
var _border = __webpack_require__(250);
|
|
|
|
var _border2 = _interopRequireDefault(_border);
|
|
|
|
var _core = __webpack_require__(253);
|
|
|
|
var _core2 = _interopRequireDefault(_core);
|
|
|
|
var _event = __webpack_require__(254);
|
|
|
|
var _event2 = _interopRequireDefault(_event);
|
|
|
|
var _overlays = __webpack_require__(257);
|
|
|
|
var _overlays2 = _interopRequireDefault(_overlays);
|
|
|
|
var _scroll = __webpack_require__(258);
|
|
|
|
var _scroll2 = _interopRequireDefault(_scroll);
|
|
|
|
var _selection = __webpack_require__(303);
|
|
|
|
var _selection2 = _interopRequireDefault(_selection);
|
|
|
|
var _settings = __webpack_require__(259);
|
|
|
|
var _settings2 = _interopRequireDefault(_settings);
|
|
|
|
var _table = __webpack_require__(260);
|
|
|
|
var _table2 = _interopRequireDefault(_table);
|
|
|
|
var _tableRenderer = __webpack_require__(261);
|
|
|
|
var _tableRenderer2 = _interopRequireDefault(_tableRenderer);
|
|
|
|
var _viewport = __webpack_require__(262);
|
|
|
|
var _viewport2 = _interopRequireDefault(_viewport);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
exports.ViewportColumnsCalculator = _viewportColumns2.default;
|
|
exports.ViewportRowsCalculator = _viewportRows2.default;
|
|
exports.CellCoords = _coords2.default;
|
|
exports.CellRange = _range2.default;
|
|
exports.ColumnFilter = _column2.default;
|
|
exports.RowFilter = _row2.default;
|
|
exports.DebugOverlay = _debug2.default;
|
|
exports.LeftOverlay = _left2.default;
|
|
exports.TopOverlay = _top2.default;
|
|
exports.TopLeftCornerOverlay = _topLeftCorner2.default;
|
|
exports.Border = _border2.default;
|
|
exports.default = _core2.default;
|
|
exports.Core = _core2.default;
|
|
exports.Event = _event2.default;
|
|
exports.Overlays = _overlays2.default;
|
|
exports.Scroll = _scroll2.default;
|
|
exports.Selection = _selection2.default;
|
|
exports.Settings = _settings2.default;
|
|
exports.Table = _table2.default;
|
|
exports.TableRenderer = _tableRenderer2.default;
|
|
exports.Viewport = _viewport2.default;
|
|
|
|
/***/ }),
|
|
/* 12 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _recordTranslator = __webpack_require__(268);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var privatePool = new WeakMap();
|
|
var initializedPlugins = null;
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
|
|
var BasePlugin = function () {
|
|
/**
|
|
* @param {Object} hotInstance Handsontable instance.
|
|
*/
|
|
function BasePlugin(hotInstance) {
|
|
var _this = this;
|
|
|
|
_classCallCheck(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 () {
|
|
return _this.onUpdateSettings();
|
|
});
|
|
this.hot.addHook('beforeInit', function () {
|
|
return _this.init();
|
|
});
|
|
}
|
|
|
|
_createClass(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;
|
|
}();
|
|
|
|
exports.default = BasePlugin;
|
|
|
|
/***/ }),
|
|
/* 13 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
|
|
var global = module.exports = typeof window != 'undefined' && window.Math == Math
|
|
? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
|
|
if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
|
|
|
|
/***/ }),
|
|
/* 14 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.getRegisteredEditors = exports.getRegisteredEditorNames = exports.hasEditor = exports.getEditorInstance = exports.getEditor = exports.registerEditor = undefined;
|
|
exports.RegisteredEditor = RegisteredEditor;
|
|
exports._getEditorInstance = _getEditorInstance;
|
|
|
|
var _staticRegister2 = __webpack_require__(52);
|
|
|
|
var _staticRegister3 = _interopRequireDefault(_staticRegister2);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _baseEditor = __webpack_require__(37);
|
|
|
|
var _baseEditor2 = _interopRequireDefault(_baseEditor);
|
|
|
|
var _autocompleteEditor = __webpack_require__(263);
|
|
|
|
var _autocompleteEditor2 = _interopRequireDefault(_autocompleteEditor);
|
|
|
|
var _checkboxEditor = __webpack_require__(316);
|
|
|
|
var _checkboxEditor2 = _interopRequireDefault(_checkboxEditor);
|
|
|
|
var _dateEditor = __webpack_require__(317);
|
|
|
|
var _dateEditor2 = _interopRequireDefault(_dateEditor);
|
|
|
|
var _dropdownEditor = __webpack_require__(318);
|
|
|
|
var _dropdownEditor2 = _interopRequireDefault(_dropdownEditor);
|
|
|
|
var _handsontableEditor = __webpack_require__(264);
|
|
|
|
var _handsontableEditor2 = _interopRequireDefault(_handsontableEditor);
|
|
|
|
var _mobileTextEditor = __webpack_require__(319);
|
|
|
|
var _mobileTextEditor2 = _interopRequireDefault(_mobileTextEditor);
|
|
|
|
var _numericEditor = __webpack_require__(320);
|
|
|
|
var _numericEditor2 = _interopRequireDefault(_numericEditor);
|
|
|
|
var _passwordEditor = __webpack_require__(321);
|
|
|
|
var _passwordEditor2 = _interopRequireDefault(_passwordEditor);
|
|
|
|
var _selectEditor = __webpack_require__(322);
|
|
|
|
var _selectEditor2 = _interopRequireDefault(_selectEditor);
|
|
|
|
var _textEditor = __webpack_require__(44);
|
|
|
|
var _textEditor2 = _interopRequireDefault(_textEditor);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var registeredEditorClasses = new WeakMap(); /**
|
|
* Utility to register editors and common namespace for keeping reference to all editor classes
|
|
*/
|
|
|
|
var _staticRegister = (0, _staticRegister3.default)('editors'),
|
|
register = _staticRegister.register,
|
|
getItem = _staticRegister.getItem,
|
|
hasItem = _staticRegister.hasItem,
|
|
getNames = _staticRegister.getNames,
|
|
getValues = _staticRegister.getValues;
|
|
|
|
_register('base', _baseEditor2.default);
|
|
_register('autocomplete', _autocompleteEditor2.default);
|
|
_register('checkbox', _checkboxEditor2.default);
|
|
_register('date', _dateEditor2.default);
|
|
_register('dropdown', _dropdownEditor2.default);
|
|
_register('handsontable', _handsontableEditor2.default);
|
|
_register('mobile', _mobileTextEditor2.default);
|
|
_register('numeric', _numericEditor2.default);
|
|
_register('password', _passwordEditor2.default);
|
|
_register('select', _selectEditor2.default);
|
|
_register('text', _textEditor2.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];
|
|
};
|
|
|
|
_pluginHooks2.default.getSingleton().add('afterDestroy', function () {
|
|
instances = {};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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 = void 0;
|
|
|
|
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 "' + 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 "' + 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);
|
|
}
|
|
|
|
exports.registerEditor = _register;
|
|
exports.getEditor = _getItem;
|
|
exports.getEditorInstance = _getEditorInstance;
|
|
exports.hasEditor = hasItem;
|
|
exports.getRegisteredEditorNames = getNames;
|
|
exports.getRegisteredEditors = getValues;
|
|
|
|
/***/ }),
|
|
/* 15 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function(it){
|
|
return typeof it === 'object' ? it !== null : typeof it === 'function';
|
|
};
|
|
|
|
/***/ }),
|
|
/* 16 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY_CODES = undefined;
|
|
exports.isPrintableChar = isPrintableChar;
|
|
exports.isMetaKey = isMetaKey;
|
|
exports.isCtrlKey = isCtrlKey;
|
|
exports.isKey = isKey;
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var KEY_CODES = exports.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_LEFT: 91,
|
|
COMMAND_LEFT: 17,
|
|
COMMAND_RIGHT: 93,
|
|
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,
|
|
X: 88,
|
|
C: 67,
|
|
V: 86
|
|
};
|
|
|
|
/**
|
|
* Returns true if keyCode represents a printable character.
|
|
*
|
|
* @param {Number} keyCode
|
|
* @returns {Boolean}
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} keyCode
|
|
* @returns {Boolean}
|
|
*/
|
|
function isCtrlKey(keyCode) {
|
|
return [KEY_CODES.CONTROL_LEFT, 224, KEY_CODES.COMMAND_LEFT, KEY_CODES.COMMAND_RIGHT].indexOf(keyCode) !== -1;
|
|
}
|
|
|
|
/**
|
|
* @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;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 17 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
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__(2);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _separator = __webpack_require__(72);
|
|
|
|
function normalizeSelection(selRange) {
|
|
return {
|
|
start: selRange.getTopLeftCorner(),
|
|
end: selRange.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;
|
|
}
|
|
className = className.replace('htTop', '').replace('htMiddle', '').replace('htBottom', '').replace(' ', '');
|
|
|
|
className += ' ' + alignment;
|
|
|
|
return className;
|
|
}
|
|
|
|
function prepareHorizontalAlignClass(className, alignment) {
|
|
if (className.indexOf(alignment) != -1) {
|
|
return className;
|
|
}
|
|
className = className.replace('htLeft', '').replace('htCenter', '').replace('htRight', '').replace('htJustify', '').replace(' ', '');
|
|
|
|
className += ' ' + alignment;
|
|
|
|
return className;
|
|
}
|
|
|
|
function getAlignmentClasses(range, callback) {
|
|
var classes = {};
|
|
|
|
for (var row = range.from.row; row <= range.to.row; row++) {
|
|
for (var col = range.from.col; col <= range.to.col; col++) {
|
|
if (!classes[row]) {
|
|
classes[row] = [];
|
|
}
|
|
classes[row][col] = callback(row, col);
|
|
}
|
|
}
|
|
|
|
return classes;
|
|
}
|
|
|
|
function align(range, type, alignment, cellDescriptor, propertySetter) {
|
|
if (range.from.row == range.to.row && range.from.col == range.to.col) {
|
|
applyAlignClassName(range.from.row, range.from.col, type, alignment, cellDescriptor, propertySetter);
|
|
} else {
|
|
for (var row = range.from.row; row <= range.to.row; row++) {
|
|
for (var col = range.from.col; col <= range.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(range, comparator) {
|
|
var result = false;
|
|
|
|
if (range) {
|
|
range.forAll(function (row, col) {
|
|
if (comparator(row, col)) {
|
|
result = true;
|
|
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function markLabelAsSelected(label) {
|
|
// workaround for https://github.com/handsontable/handsontable/issues/1946
|
|
return '<span class="selected">' + String.fromCharCode(10003) + '</span>' + 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;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 18 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(15);
|
|
module.exports = function(it){
|
|
if(!isObject(it))throw TypeError(it + ' is not an object!');
|
|
return it;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 19 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var anObject = __webpack_require__(18)
|
|
, IE8_DOM_DEFINE = __webpack_require__(275)
|
|
, toPrimitive = __webpack_require__(87)
|
|
, dP = Object.defineProperty;
|
|
|
|
exports.f = __webpack_require__(21) ? Object.defineProperty : function defineProperty(O, P, Attributes){
|
|
anObject(O);
|
|
P = toPrimitive(P, true);
|
|
anObject(Attributes);
|
|
if(IE8_DOM_DEFINE)try {
|
|
return dP(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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 20 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
exports.stringify = stringify;
|
|
exports.isDefined = isDefined;
|
|
exports.isUndefined = isUndefined;
|
|
exports.isEmpty = isEmpty;
|
|
exports.isRegExp = isRegExp;
|
|
|
|
/**
|
|
* Converts any value to string.
|
|
*
|
|
* @param {*} value
|
|
* @returns {String}
|
|
*/
|
|
function stringify(value) {
|
|
var result = void 0;
|
|
|
|
switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) {
|
|
case 'string':
|
|
case 'number':
|
|
result = '' + 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]';
|
|
}
|
|
|
|
/***/ }),
|
|
/* 21 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// Thank's IE8 for his funny defineProperty
|
|
module.exports = !__webpack_require__(31)(function(){
|
|
return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
|
|
});
|
|
|
|
/***/ }),
|
|
/* 22 */
|
|
/***/ (function(module, exports) {
|
|
|
|
var hasOwnProperty = {}.hasOwnProperty;
|
|
module.exports = function(it, key){
|
|
return hasOwnProperty.call(it, key);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 23 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// to indexed object, toObject with fallback for non-array-like ES3 strings
|
|
var IObject = __webpack_require__(78)
|
|
, defined = __webpack_require__(30);
|
|
module.exports = function(it){
|
|
return IObject(defined(it));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 24 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 7.1.15 ToLength
|
|
var toInteger = __webpack_require__(62)
|
|
, min = Math.min;
|
|
module.exports = function(it){
|
|
return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
|
|
};
|
|
|
|
/***/ }),
|
|
/* 25 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.isIE8 = isIE8;
|
|
exports.isIE9 = isIE9;
|
|
exports.isSafari = isSafari;
|
|
exports.isChrome = isChrome;
|
|
exports.isMobileBrowser = isMobileBrowser;
|
|
|
|
var _isIE8 = !document.createTextNode('test').textContent;
|
|
|
|
function isIE8() {
|
|
return _isIE8;
|
|
}
|
|
|
|
var _isIE9 = !!document.documentMode;
|
|
|
|
function isIE9() {
|
|
return _isIE9;
|
|
}
|
|
|
|
var _isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
|
|
|
|
function isSafari() {
|
|
return _isSafari;
|
|
}
|
|
|
|
var _isChrome = /Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor);
|
|
|
|
function isChrome() {
|
|
return _isChrome;
|
|
}
|
|
|
|
function isMobileBrowser(userAgent) {
|
|
if (!userAgent) {
|
|
userAgent = navigator.userAgent;
|
|
}
|
|
|
|
return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)
|
|
);
|
|
}
|
|
|
|
/***/ }),
|
|
/* 26 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.getRegisteredValidators = exports.getRegisteredValidatorNames = exports.hasValidator = exports.getValidator = exports.registerValidator = undefined;
|
|
|
|
var _staticRegister2 = __webpack_require__(52);
|
|
|
|
var _staticRegister3 = _interopRequireDefault(_staticRegister2);
|
|
|
|
var _autocompleteValidator = __webpack_require__(388);
|
|
|
|
var _autocompleteValidator2 = _interopRequireDefault(_autocompleteValidator);
|
|
|
|
var _dateValidator = __webpack_require__(389);
|
|
|
|
var _dateValidator2 = _interopRequireDefault(_dateValidator);
|
|
|
|
var _numericValidator = __webpack_require__(390);
|
|
|
|
var _numericValidator2 = _interopRequireDefault(_numericValidator);
|
|
|
|
var _timeValidator = __webpack_require__(391);
|
|
|
|
var _timeValidator2 = _interopRequireDefault(_timeValidator);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var _staticRegister = (0, _staticRegister3.default)('validators'),
|
|
register = _staticRegister.register,
|
|
getItem = _staticRegister.getItem,
|
|
hasItem = _staticRegister.hasItem,
|
|
getNames = _staticRegister.getNames,
|
|
getValues = _staticRegister.getValues;
|
|
|
|
register('autocomplete', _autocompleteValidator2.default);
|
|
register('date', _dateValidator2.default);
|
|
register('numeric', _numericValidator2.default);
|
|
register('time', _timeValidator2.default);
|
|
|
|
/**
|
|
* Retrieve validator function.
|
|
*
|
|
* @param {String} name Validator identification.
|
|
* @returns {Function} Returns validator function.
|
|
*/
|
|
function _getItem(name) {
|
|
if (typeof name === 'function') {
|
|
return name;
|
|
}
|
|
if (!hasItem(name)) {
|
|
throw Error('No registered validator found under "' + name + '" name');
|
|
}
|
|
|
|
return getItem(name);
|
|
}
|
|
|
|
exports.registerValidator = register;
|
|
exports.getValidator = _getItem;
|
|
exports.hasValidator = hasItem;
|
|
exports.getRegisteredValidatorNames = getNames;
|
|
exports.getRegisteredValidators = getValues;
|
|
|
|
/***/ }),
|
|
/* 27 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
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__(20);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
/**
|
|
* 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 = Array(_len), _key = 0; _key < _len; _key++) {
|
|
strings[_key] = arguments[_key];
|
|
}
|
|
|
|
var length = strings.length;
|
|
|
|
while (length--) {
|
|
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 ('' + 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) {
|
|
string += '';
|
|
|
|
return string.replace(STRIP_TAGS_REGEX, '');
|
|
}
|
|
|
|
/***/ }),
|
|
/* 28 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _core = __webpack_require__(253);
|
|
|
|
var _core2 = _interopRequireDefault(_core);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var registeredOverlays = {};
|
|
|
|
/**
|
|
* Creates an overlay over the original Walkontable instance. The overlay renders the clone of the original Walkontable
|
|
* and (optionally) implements behavior needed for native horizontal and vertical scrolling.
|
|
*
|
|
* @class Overlay
|
|
*/
|
|
|
|
var Overlay = function () {
|
|
_createClass(Overlay, null, [{
|
|
key: 'registerOverlay',
|
|
|
|
|
|
/**
|
|
* Register overlay class.
|
|
*
|
|
* @param {String} type Overlay type, one of the CLONE_TYPES value
|
|
* @param {Overlay} overlayClass Overlay class extended from base overlay class {@link Overlay}
|
|
*/
|
|
value: function registerOverlay(type, overlayClass) {
|
|
if (Overlay.CLONE_TYPES.indexOf(type) === -1) {
|
|
throw new Error('Unsupported overlay (' + type + ').');
|
|
}
|
|
registeredOverlays[type] = overlayClass;
|
|
}
|
|
|
|
/**
|
|
* Create new instance of overlay type.
|
|
*
|
|
* @param {String} type Overlay type, one of the CLONE_TYPES value
|
|
* @param {Walkontable} wot Walkontable instance
|
|
*/
|
|
|
|
}, {
|
|
key: 'createOverlay',
|
|
value: function createOverlay(type, wot) {
|
|
return new registeredOverlays[type](wot);
|
|
}
|
|
|
|
/**
|
|
* Check if specified overlay was registered.
|
|
*
|
|
* @param {String} type Overlay type, one of the CLONE_TYPES value
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'hasOverlay',
|
|
value: function hasOverlay(type) {
|
|
return registeredOverlays[type] !== void 0;
|
|
}
|
|
|
|
/**
|
|
* Checks if overlay object (`overlay`) is instance of overlay type (`type`).
|
|
*
|
|
* @param {Overlay} overlay Overlay object
|
|
* @param {String} type Overlay type, one of the CLONE_TYPES value
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isOverlayTypeOf',
|
|
value: function isOverlayTypeOf(overlay, type) {
|
|
if (!overlay || !registeredOverlays[type]) {
|
|
return false;
|
|
}
|
|
|
|
return overlay instanceof registeredOverlays[type];
|
|
}
|
|
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
*/
|
|
|
|
}, {
|
|
key: 'CLONE_TOP',
|
|
|
|
/**
|
|
* @type {String}
|
|
*/
|
|
get: function get() {
|
|
return 'top';
|
|
}
|
|
|
|
/**
|
|
* @type {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'CLONE_BOTTOM',
|
|
get: function get() {
|
|
return 'bottom';
|
|
}
|
|
|
|
/**
|
|
* @type {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'CLONE_LEFT',
|
|
get: function get() {
|
|
return 'left';
|
|
}
|
|
|
|
/**
|
|
* @type {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'CLONE_TOP_LEFT_CORNER',
|
|
get: function get() {
|
|
return 'top_left_corner';
|
|
}
|
|
|
|
/**
|
|
* @type {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'CLONE_BOTTOM_LEFT_CORNER',
|
|
get: function get() {
|
|
return 'bottom_left_corner';
|
|
}
|
|
|
|
/**
|
|
* @type {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'CLONE_DEBUG',
|
|
get: function get() {
|
|
return 'debug';
|
|
}
|
|
|
|
/**
|
|
* List of all availables clone types
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'CLONE_TYPES',
|
|
get: function get() {
|
|
return [Overlay.CLONE_TOP, Overlay.CLONE_BOTTOM, Overlay.CLONE_LEFT, Overlay.CLONE_TOP_LEFT_CORNER, Overlay.CLONE_BOTTOM_LEFT_CORNER, Overlay.CLONE_DEBUG];
|
|
}
|
|
}]);
|
|
|
|
function Overlay(wotInstance) {
|
|
_classCallCheck(this, Overlay);
|
|
|
|
(0, _object.defineGetter)(this, 'wot', wotInstance, {
|
|
writable: false
|
|
});
|
|
|
|
// legacy support, deprecated in the future
|
|
this.instance = this.wot;
|
|
|
|
this.type = '';
|
|
this.mainTableScrollableElement = null;
|
|
this.TABLE = this.wot.wtTable.TABLE;
|
|
this.hider = this.wot.wtTable.hider;
|
|
this.spreader = this.wot.wtTable.spreader;
|
|
this.holder = this.wot.wtTable.holder;
|
|
this.wtRootElement = this.wot.wtTable.wtRootElement;
|
|
this.trimmingContainer = (0, _element.getTrimmingContainer)(this.hider.parentNode.parentNode);
|
|
this.areElementSizesAdjusted = false;
|
|
this.updateStateOfRendering();
|
|
}
|
|
|
|
/**
|
|
* Update internal state of object with an information about the need of full rendering of the overlay.
|
|
*
|
|
* @returns {Boolean} Returns `true` if the state has changed since the last check.
|
|
*/
|
|
|
|
|
|
_createClass(Overlay, [{
|
|
key: 'updateStateOfRendering',
|
|
value: function updateStateOfRendering() {
|
|
var previousState = this.needFullRender;
|
|
|
|
this.needFullRender = this.shouldBeRendered();
|
|
|
|
var changed = previousState !== this.needFullRender;
|
|
|
|
if (changed && !this.needFullRender) {
|
|
this.reset();
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
/**
|
|
* Checks if overlay should be fully rendered
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'shouldBeRendered',
|
|
value: function shouldBeRendered() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Update the trimming container.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updateTrimmingContainer',
|
|
value: function updateTrimmingContainer() {
|
|
this.trimmingContainer = (0, _element.getTrimmingContainer)(this.hider.parentNode.parentNode);
|
|
}
|
|
|
|
/**
|
|
* Update the main scrollable element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updateMainScrollableElement',
|
|
value: function updateMainScrollableElement() {
|
|
this.mainTableScrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE);
|
|
}
|
|
|
|
/**
|
|
* Make a clone of table for overlay
|
|
*
|
|
* @param {String} direction Can be `Overlay.CLONE_TOP`, `Overlay.CLONE_LEFT`,
|
|
* `Overlay.CLONE_TOP_LEFT_CORNER`, `Overlay.CLONE_DEBUG`
|
|
* @returns {Walkontable}
|
|
*/
|
|
|
|
}, {
|
|
key: 'makeClone',
|
|
value: function makeClone(direction) {
|
|
if (Overlay.CLONE_TYPES.indexOf(direction) === -1) {
|
|
throw new Error('Clone type "' + direction + '" is not supported.');
|
|
}
|
|
var clone = document.createElement('DIV');
|
|
var clonedTable = document.createElement('TABLE');
|
|
|
|
clone.className = 'ht_clone_' + direction + ' handsontable';
|
|
clone.style.position = 'absolute';
|
|
clone.style.top = 0;
|
|
clone.style.left = 0;
|
|
clone.style.overflow = 'hidden';
|
|
|
|
clonedTable.className = this.wot.wtTable.TABLE.className;
|
|
clone.appendChild(clonedTable);
|
|
|
|
this.type = direction;
|
|
this.wot.wtTable.wtRootElement.parentNode.appendChild(clone);
|
|
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
|
|
if (preventOverflow === true || preventOverflow === 'horizontal' && this.type === Overlay.CLONE_TOP || preventOverflow === 'vertical' && this.type === Overlay.CLONE_LEFT) {
|
|
this.mainTableScrollableElement = window;
|
|
} else {
|
|
this.mainTableScrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE);
|
|
}
|
|
|
|
return new _core2.default({
|
|
cloneSource: this.wot,
|
|
cloneOverlay: this,
|
|
table: clonedTable
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Refresh/Redraw overlay
|
|
*
|
|
* @param {Boolean} [fastDraw=false]
|
|
*/
|
|
|
|
}, {
|
|
key: 'refresh',
|
|
value: function refresh() {
|
|
var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
// When hot settings are changed we allow to refresh overlay once before blocking
|
|
var nextCycleRenderFlag = this.shouldBeRendered();
|
|
|
|
if (this.clone && (this.needFullRender || nextCycleRenderFlag)) {
|
|
this.clone.draw(fastDraw);
|
|
}
|
|
this.needFullRender = nextCycleRenderFlag;
|
|
}
|
|
|
|
/**
|
|
* Reset overlay styles to initial values.
|
|
*/
|
|
|
|
}, {
|
|
key: 'reset',
|
|
value: function reset() {
|
|
if (!this.clone) {
|
|
return;
|
|
}
|
|
var holder = this.clone.wtTable.holder;
|
|
var hider = this.clone.wtTable.hider;
|
|
var holderStyle = holder.style;
|
|
var hidderStyle = hider.style;
|
|
var rootStyle = holder.parentNode.style;
|
|
|
|
(0, _array.arrayEach)([holderStyle, hidderStyle, rootStyle], function (style) {
|
|
style.width = '';
|
|
style.height = '';
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Destroy overlay instance
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
new _eventManager2.default(this.clone).destroy();
|
|
}
|
|
}]);
|
|
|
|
return Overlay;
|
|
}();
|
|
|
|
exports.default = Overlay;
|
|
|
|
/***/ }),
|
|
/* 29 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// optional / simple context binding
|
|
var aFunction = __webpack_require__(73);
|
|
module.exports = function(fn, that, length){
|
|
aFunction(fn);
|
|
if(that === undefined)return fn;
|
|
switch(length){
|
|
case 1: return function(a){
|
|
return fn.call(that, a);
|
|
};
|
|
case 2: return function(a, b){
|
|
return fn.call(that, a, b);
|
|
};
|
|
case 3: return function(a, b, c){
|
|
return fn.call(that, a, b, c);
|
|
};
|
|
}
|
|
return function(/* ...args */){
|
|
return fn.apply(that, arguments);
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 30 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// 7.2.1 RequireObjectCoercible(argument)
|
|
module.exports = function(it){
|
|
if(it == undefined)throw TypeError("Can't call method on " + it);
|
|
return it;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 31 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function(exec){
|
|
try {
|
|
return !!exec();
|
|
} catch(e){
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 32 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var dP = __webpack_require__(19)
|
|
, createDesc = __webpack_require__(41);
|
|
module.exports = __webpack_require__(21) ? function(object, key, value){
|
|
return dP.f(object, key, createDesc(1, value));
|
|
} : function(object, key, value){
|
|
object[key] = value;
|
|
return object;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 33 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var global = __webpack_require__(13)
|
|
, hide = __webpack_require__(32)
|
|
, has = __webpack_require__(22)
|
|
, SRC = __webpack_require__(50)('src')
|
|
, TO_STRING = 'toString'
|
|
, $toString = Function[TO_STRING]
|
|
, TPL = ('' + $toString).split(TO_STRING);
|
|
|
|
__webpack_require__(45).inspectSource = function(it){
|
|
return $toString.call(it);
|
|
};
|
|
|
|
(module.exports = function(O, key, val, safe){
|
|
var isFunction = typeof val == 'function';
|
|
if(isFunction)has(val, 'name') || hide(val, 'name', key);
|
|
if(O[key] === val)return;
|
|
if(isFunction)has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
|
|
if(O === global){
|
|
O[key] = val;
|
|
} else {
|
|
if(!safe){
|
|
delete O[key];
|
|
hide(O, key, val);
|
|
} else {
|
|
if(O[key])O[key] = val;
|
|
else hide(O, key, val);
|
|
}
|
|
}
|
|
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
|
|
})(Function.prototype, TO_STRING, function toString(){
|
|
return typeof this == 'function' && this[SRC] || $toString.call(this);
|
|
});
|
|
|
|
/***/ }),
|
|
/* 34 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
exports.requestAnimationFrame = requestAnimationFrame;
|
|
exports.cancelAnimationFrame = cancelAnimationFrame;
|
|
exports.isTouchSupported = isTouchSupported;
|
|
exports.isWebComponentSupportedNatively = isWebComponentSupportedNatively;
|
|
exports.hasCaptionProblem = hasCaptionProblem;
|
|
exports.getComparisonFunction = getComparisonFunction;
|
|
// https://gist.github.com/paulirish/1579671
|
|
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[vendors[x] + 'RequestAnimationFrame'];
|
|
_cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[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);
|
|
}
|
|
|
|
/**
|
|
* 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 = '<tr><td>t<br>t</td></tr>';
|
|
|
|
var CAPTION = document.createElement('CAPTION');
|
|
CAPTION.innerHTML = 'c<br>c<br>c<br>c';
|
|
CAPTION.style.padding = 0;
|
|
CAPTION.style.margin = 0;
|
|
TABLE.insertBefore(CAPTION, TBODY);
|
|
|
|
document.body.appendChild(TABLE);
|
|
_hasCaptionProblem = TABLE.offsetHeight < 2 * TABLE.lastChild.offsetHeight; // boolean
|
|
document.body.removeChild(TABLE);
|
|
}
|
|
|
|
function hasCaptionProblem() {
|
|
if (_hasCaptionProblem === void 0) {
|
|
detectCaptionProblem();
|
|
}
|
|
|
|
return _hasCaptionProblem;
|
|
}
|
|
|
|
var comparisonFunction = void 0;
|
|
|
|
/**
|
|
* Get string comparison function for sorting purposes. It supports multilingual string comparison base on Internationalization API.
|
|
*
|
|
* @param {String} [language]
|
|
* @param {Object} [options]
|
|
* @returns {*}
|
|
*/
|
|
function getComparisonFunction(language) {
|
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
|
|
if (comparisonFunction) {
|
|
return comparisonFunction;
|
|
}
|
|
|
|
if ((typeof Intl === 'undefined' ? 'undefined' : _typeof(Intl)) === 'object') {
|
|
comparisonFunction = new Intl.Collator(language, options).compare;
|
|
} else if (typeof String.prototype.localeCompare === 'function') {
|
|
comparisonFunction = function comparisonFunction(a, b) {
|
|
return ('' + a).localeCompare(b);
|
|
};
|
|
} else {
|
|
comparisonFunction = function comparisonFunction(a, b) {
|
|
if (a === b) {
|
|
return 0;
|
|
}
|
|
|
|
return a > b ? -1 : 1;
|
|
};
|
|
}
|
|
|
|
return comparisonFunction;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 35 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.isFunction = isFunction;
|
|
exports.throttle = throttle;
|
|
exports.throttleAfterHits = throttleAfterHits;
|
|
exports.debounce = debounce;
|
|
exports.pipe = pipe;
|
|
exports.partial = partial;
|
|
exports.curry = curry;
|
|
exports.curryRight = curryRight;
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
/**
|
|
* Checks if given variable is function.
|
|
*
|
|
* @param {*} func Variable to check.
|
|
* @returns {Boolean}
|
|
*/
|
|
function isFunction(func) {
|
|
return typeof func === 'function';
|
|
}
|
|
|
|
/**
|
|
* Creates throttle function that enforces a maximum number of times a function (`func`) can be called over time (`wait`).
|
|
*
|
|
* @param {Function} func Function to invoke.
|
|
* @param {Number} wait Delay in miliseconds.
|
|
* @returns {Function}
|
|
*/
|
|
function throttle(func) {
|
|
var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
|
|
|
|
var lastCalled = 0;
|
|
var result = {
|
|
lastCallThrottled: true
|
|
};
|
|
var lastTimer = null;
|
|
|
|
function _throttle() {
|
|
var _this = this;
|
|
|
|
var args = arguments;
|
|
var stamp = Date.now();
|
|
var needCall = false;
|
|
|
|
result.lastCallThrottled = true;
|
|
|
|
if (!lastCalled) {
|
|
lastCalled = stamp;
|
|
needCall = true;
|
|
}
|
|
var remaining = wait - (stamp - lastCalled);
|
|
|
|
if (needCall) {
|
|
result.lastCallThrottled = false;
|
|
func.apply(this, args);
|
|
} else {
|
|
if (lastTimer) {
|
|
clearTimeout(lastTimer);
|
|
}
|
|
lastTimer = setTimeout(function () {
|
|
result.lastCallThrottled = false;
|
|
func.apply(_this, args);
|
|
lastCalled = 0;
|
|
lastTimer = void 0;
|
|
}, remaining);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
return _throttle;
|
|
}
|
|
|
|
/**
|
|
* Creates throttle function that enforces a maximum number of times a function (`func`) can be called over
|
|
* time (`wait`) after specified hits.
|
|
*
|
|
* @param {Function} func Function to invoke.
|
|
* @param {Number} wait Delay in miliseconds.
|
|
* @param {Number} hits Number of hits after throttling will be applied.
|
|
* @returns {Function}
|
|
*/
|
|
function throttleAfterHits(func) {
|
|
var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
|
|
var hits = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10;
|
|
|
|
var funcThrottle = throttle(func, wait);
|
|
var remainHits = hits;
|
|
|
|
function _clearHits() {
|
|
remainHits = hits;
|
|
}
|
|
function _throttleAfterHits() {
|
|
if (remainHits) {
|
|
remainHits--;
|
|
|
|
return func.apply(this, arguments);
|
|
}
|
|
|
|
return funcThrottle.apply(this, arguments);
|
|
}
|
|
_throttleAfterHits.clearHits = _clearHits;
|
|
|
|
return _throttleAfterHits;
|
|
}
|
|
|
|
/**
|
|
* Creates debounce function that enforces a function (`func`) not be called again until a certain amount of time (`wait`)
|
|
* has passed without it being called.
|
|
*
|
|
* @param {Function} func Function to invoke.
|
|
* @param {Number} wait Delay in milliseconds.
|
|
* @returns {Function}
|
|
*/
|
|
function debounce(func) {
|
|
var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
|
|
|
|
var lastTimer = null;
|
|
var result = void 0;
|
|
|
|
function _debounce() {
|
|
var _this2 = this;
|
|
|
|
var args = arguments;
|
|
|
|
if (lastTimer) {
|
|
clearTimeout(lastTimer);
|
|
}
|
|
lastTimer = setTimeout(function () {
|
|
result = func.apply(_this2, args);
|
|
}, wait);
|
|
|
|
return result;
|
|
}
|
|
|
|
return _debounce;
|
|
}
|
|
|
|
/**
|
|
* Creates the function that returns the result of calling the given functions. Result of the first function is passed to
|
|
* the second as an argument and so on. Only first function in the chain can handle multiple arguments.
|
|
*
|
|
* @param {Function} functions Functions to compose.
|
|
* @returns {Function}
|
|
*/
|
|
function pipe() {
|
|
for (var _len = arguments.length, functions = Array(_len), _key = 0; _key < _len; _key++) {
|
|
functions[_key] = arguments[_key];
|
|
}
|
|
|
|
var firstFunc = functions[0],
|
|
restFunc = functions.slice(1);
|
|
|
|
|
|
return function _pipe() {
|
|
return (0, _array.arrayReduce)(restFunc, function (acc, fn) {
|
|
return fn(acc);
|
|
}, firstFunc.apply(this, arguments));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates the function that returns the function with cached arguments.
|
|
*
|
|
* @param {Function} func Function to partialization.
|
|
* @param {Array} params Function arguments to cache.
|
|
* @returns {Function}
|
|
*/
|
|
function partial(func) {
|
|
for (var _len2 = arguments.length, params = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
params[_key2 - 1] = arguments[_key2];
|
|
}
|
|
|
|
return function _partial() {
|
|
for (var _len3 = arguments.length, restParams = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
restParams[_key3] = arguments[_key3];
|
|
}
|
|
|
|
return func.apply(this, params.concat(restParams));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates the functions that returns the function with cached arguments. If count if passed arguments will be matched
|
|
* to the arguments defined in `func` then function will be invoked.
|
|
* Arguments are added to the stack in direction from the left to the right.
|
|
*
|
|
* @example
|
|
* ```
|
|
* var replace = curry(function(find, replace, string) {
|
|
* return string.replace(find, replace);
|
|
* });
|
|
*
|
|
* // returns function with bounded first argument
|
|
* var replace = replace('foo')
|
|
*
|
|
* // returns replaced string - all arguments was passed so function was invoked
|
|
* replace('bar', 'Some test with foo...');
|
|
*
|
|
* ```
|
|
*
|
|
* @param {Function} func Function to currying.
|
|
* @returns {Function}
|
|
*/
|
|
function curry(func) {
|
|
var argsLength = func.length;
|
|
|
|
function given(argsSoFar) {
|
|
return function _curry() {
|
|
for (var _len4 = arguments.length, params = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
params[_key4] = arguments[_key4];
|
|
}
|
|
|
|
var passedArgsSoFar = argsSoFar.concat(params);
|
|
var result = void 0;
|
|
|
|
if (passedArgsSoFar.length >= argsLength) {
|
|
result = func.apply(this, passedArgsSoFar);
|
|
} else {
|
|
result = given(passedArgsSoFar);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
}
|
|
|
|
return given([]);
|
|
}
|
|
|
|
/**
|
|
* Creates the functions that returns the function with cached arguments. If count if passed arguments will be matched
|
|
* to the arguments defined in `func` then function will be invoked.
|
|
* Arguments are added to the stack in direction from the right to the left.
|
|
*
|
|
* @example
|
|
* ```
|
|
* var replace = curry(function(find, replace, string) {
|
|
* return string.replace(find, replace);
|
|
* });
|
|
*
|
|
* // returns function with bounded first argument
|
|
* var replace = replace('Some test with foo...')
|
|
*
|
|
* // returns replaced string - all arguments was passed so function was invoked
|
|
* replace('bar', 'foo');
|
|
*
|
|
* ```
|
|
*
|
|
* @param {Function} func Function to currying.
|
|
* @returns {Function}
|
|
*/
|
|
function curryRight(func) {
|
|
var argsLength = func.length;
|
|
|
|
function given(argsSoFar) {
|
|
return function _curry() {
|
|
for (var _len5 = arguments.length, params = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
|
|
params[_key5] = arguments[_key5];
|
|
}
|
|
|
|
var passedArgsSoFar = argsSoFar.concat(params.reverse());
|
|
var result = void 0;
|
|
|
|
if (passedArgsSoFar.length >= argsLength) {
|
|
result = func.apply(this, passedArgsSoFar);
|
|
} else {
|
|
result = given(passedArgsSoFar);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
}
|
|
|
|
return given([]);
|
|
}
|
|
|
|
/***/ }),
|
|
/* 36 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(module) {//! moment.js
|
|
//! version : 2.18.1
|
|
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
|
|
//! license : MIT
|
|
//! momentjs.com
|
|
|
|
;(function (global, factory) {
|
|
true ? module.exports = factory() :
|
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
global.moment = factory()
|
|
}(this, (function () { 'use strict';
|
|
|
|
var hookCallback;
|
|
|
|
function hooks () {
|
|
return hookCallback.apply(null, arguments);
|
|
}
|
|
|
|
// This is done to register the method called with moment()
|
|
// without creating circular dependencies.
|
|
function setHookCallback (callback) {
|
|
hookCallback = callback;
|
|
}
|
|
|
|
function isArray(input) {
|
|
return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
|
|
}
|
|
|
|
function isObject(input) {
|
|
// IE8 will treat undefined and null as object if it wasn't for
|
|
// input != null
|
|
return input != null && Object.prototype.toString.call(input) === '[object Object]';
|
|
}
|
|
|
|
function isObjectEmpty(obj) {
|
|
var k;
|
|
for (k in obj) {
|
|
// even if its not own property I'd still call it non-empty
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function isUndefined(input) {
|
|
return input === void 0;
|
|
}
|
|
|
|
function isNumber(input) {
|
|
return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
|
|
}
|
|
|
|
function isDate(input) {
|
|
return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
|
|
}
|
|
|
|
function map(arr, fn) {
|
|
var res = [], i;
|
|
for (i = 0; i < arr.length; ++i) {
|
|
res.push(fn(arr[i], i));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function hasOwnProp(a, b) {
|
|
return Object.prototype.hasOwnProperty.call(a, b);
|
|
}
|
|
|
|
function extend(a, b) {
|
|
for (var i in b) {
|
|
if (hasOwnProp(b, i)) {
|
|
a[i] = b[i];
|
|
}
|
|
}
|
|
|
|
if (hasOwnProp(b, 'toString')) {
|
|
a.toString = b.toString;
|
|
}
|
|
|
|
if (hasOwnProp(b, 'valueOf')) {
|
|
a.valueOf = b.valueOf;
|
|
}
|
|
|
|
return a;
|
|
}
|
|
|
|
function createUTC (input, format, locale, strict) {
|
|
return createLocalOrUTC(input, format, locale, strict, true).utc();
|
|
}
|
|
|
|
function defaultParsingFlags() {
|
|
// We need to deep clone this object.
|
|
return {
|
|
empty : false,
|
|
unusedTokens : [],
|
|
unusedInput : [],
|
|
overflow : -2,
|
|
charsLeftOver : 0,
|
|
nullInput : false,
|
|
invalidMonth : null,
|
|
invalidFormat : false,
|
|
userInvalidated : false,
|
|
iso : false,
|
|
parsedDateParts : [],
|
|
meridiem : null,
|
|
rfc2822 : false,
|
|
weekdayMismatch : false
|
|
};
|
|
}
|
|
|
|
function getParsingFlags(m) {
|
|
if (m._pf == null) {
|
|
m._pf = defaultParsingFlags();
|
|
}
|
|
return m._pf;
|
|
}
|
|
|
|
var some;
|
|
if (Array.prototype.some) {
|
|
some = Array.prototype.some;
|
|
} else {
|
|
some = function (fun) {
|
|
var t = Object(this);
|
|
var len = t.length >>> 0;
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
if (i in t && fun.call(this, t[i], i, t)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
}
|
|
|
|
var some$1 = some;
|
|
|
|
function isValid(m) {
|
|
if (m._isValid == null) {
|
|
var flags = getParsingFlags(m);
|
|
var parsedParts = some$1.call(flags.parsedDateParts, function (i) {
|
|
return i != null;
|
|
});
|
|
var isNowValid = !isNaN(m._d.getTime()) &&
|
|
flags.overflow < 0 &&
|
|
!flags.empty &&
|
|
!flags.invalidMonth &&
|
|
!flags.invalidWeekday &&
|
|
!flags.nullInput &&
|
|
!flags.invalidFormat &&
|
|
!flags.userInvalidated &&
|
|
(!flags.meridiem || (flags.meridiem && parsedParts));
|
|
|
|
if (m._strict) {
|
|
isNowValid = isNowValid &&
|
|
flags.charsLeftOver === 0 &&
|
|
flags.unusedTokens.length === 0 &&
|
|
flags.bigHour === undefined;
|
|
}
|
|
|
|
if (Object.isFrozen == null || !Object.isFrozen(m)) {
|
|
m._isValid = isNowValid;
|
|
}
|
|
else {
|
|
return isNowValid;
|
|
}
|
|
}
|
|
return m._isValid;
|
|
}
|
|
|
|
function createInvalid (flags) {
|
|
var m = createUTC(NaN);
|
|
if (flags != null) {
|
|
extend(getParsingFlags(m), flags);
|
|
}
|
|
else {
|
|
getParsingFlags(m).userInvalidated = true;
|
|
}
|
|
|
|
return m;
|
|
}
|
|
|
|
// Plugins that add properties should also add the key here (null value),
|
|
// so we can properly clone ourselves.
|
|
var momentProperties = hooks.momentProperties = [];
|
|
|
|
function copyConfig(to, from) {
|
|
var i, prop, val;
|
|
|
|
if (!isUndefined(from._isAMomentObject)) {
|
|
to._isAMomentObject = from._isAMomentObject;
|
|
}
|
|
if (!isUndefined(from._i)) {
|
|
to._i = from._i;
|
|
}
|
|
if (!isUndefined(from._f)) {
|
|
to._f = from._f;
|
|
}
|
|
if (!isUndefined(from._l)) {
|
|
to._l = from._l;
|
|
}
|
|
if (!isUndefined(from._strict)) {
|
|
to._strict = from._strict;
|
|
}
|
|
if (!isUndefined(from._tzm)) {
|
|
to._tzm = from._tzm;
|
|
}
|
|
if (!isUndefined(from._isUTC)) {
|
|
to._isUTC = from._isUTC;
|
|
}
|
|
if (!isUndefined(from._offset)) {
|
|
to._offset = from._offset;
|
|
}
|
|
if (!isUndefined(from._pf)) {
|
|
to._pf = getParsingFlags(from);
|
|
}
|
|
if (!isUndefined(from._locale)) {
|
|
to._locale = from._locale;
|
|
}
|
|
|
|
if (momentProperties.length > 0) {
|
|
for (i = 0; i < momentProperties.length; i++) {
|
|
prop = momentProperties[i];
|
|
val = from[prop];
|
|
if (!isUndefined(val)) {
|
|
to[prop] = val;
|
|
}
|
|
}
|
|
}
|
|
|
|
return to;
|
|
}
|
|
|
|
var updateInProgress = false;
|
|
|
|
// Moment prototype object
|
|
function Moment(config) {
|
|
copyConfig(this, config);
|
|
this._d = new Date(config._d != null ? config._d.getTime() : NaN);
|
|
if (!this.isValid()) {
|
|
this._d = new Date(NaN);
|
|
}
|
|
// Prevent infinite loop in case updateOffset creates new moment
|
|
// objects.
|
|
if (updateInProgress === false) {
|
|
updateInProgress = true;
|
|
hooks.updateOffset(this);
|
|
updateInProgress = false;
|
|
}
|
|
}
|
|
|
|
function isMoment (obj) {
|
|
return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
|
|
}
|
|
|
|
function absFloor (number) {
|
|
if (number < 0) {
|
|
// -0 -> 0
|
|
return Math.ceil(number) || 0;
|
|
} else {
|
|
return Math.floor(number);
|
|
}
|
|
}
|
|
|
|
function toInt(argumentForCoercion) {
|
|
var coercedNumber = +argumentForCoercion,
|
|
value = 0;
|
|
|
|
if (coercedNumber !== 0 && isFinite(coercedNumber)) {
|
|
value = absFloor(coercedNumber);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
// compare two arrays, return the number of differences
|
|
function compareArrays(array1, array2, dontConvert) {
|
|
var len = Math.min(array1.length, array2.length),
|
|
lengthDiff = Math.abs(array1.length - array2.length),
|
|
diffs = 0,
|
|
i;
|
|
for (i = 0; i < len; i++) {
|
|
if ((dontConvert && array1[i] !== array2[i]) ||
|
|
(!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
|
|
diffs++;
|
|
}
|
|
}
|
|
return diffs + lengthDiff;
|
|
}
|
|
|
|
function warn(msg) {
|
|
if (hooks.suppressDeprecationWarnings === false &&
|
|
(typeof console !== 'undefined') && console.warn) {
|
|
console.warn('Deprecation warning: ' + msg);
|
|
}
|
|
}
|
|
|
|
function deprecate(msg, fn) {
|
|
var firstTime = true;
|
|
|
|
return extend(function () {
|
|
if (hooks.deprecationHandler != null) {
|
|
hooks.deprecationHandler(null, msg);
|
|
}
|
|
if (firstTime) {
|
|
var args = [];
|
|
var arg;
|
|
for (var i = 0; i < arguments.length; i++) {
|
|
arg = '';
|
|
if (typeof arguments[i] === 'object') {
|
|
arg += '\n[' + i + '] ';
|
|
for (var key in arguments[0]) {
|
|
arg += key + ': ' + arguments[0][key] + ', ';
|
|
}
|
|
arg = arg.slice(0, -2); // Remove trailing comma and space
|
|
} else {
|
|
arg = arguments[i];
|
|
}
|
|
args.push(arg);
|
|
}
|
|
warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
|
|
firstTime = false;
|
|
}
|
|
return fn.apply(this, arguments);
|
|
}, fn);
|
|
}
|
|
|
|
var deprecations = {};
|
|
|
|
function deprecateSimple(name, msg) {
|
|
if (hooks.deprecationHandler != null) {
|
|
hooks.deprecationHandler(name, msg);
|
|
}
|
|
if (!deprecations[name]) {
|
|
warn(msg);
|
|
deprecations[name] = true;
|
|
}
|
|
}
|
|
|
|
hooks.suppressDeprecationWarnings = false;
|
|
hooks.deprecationHandler = null;
|
|
|
|
function isFunction(input) {
|
|
return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
|
|
}
|
|
|
|
function set (config) {
|
|
var prop, i;
|
|
for (i in config) {
|
|
prop = config[i];
|
|
if (isFunction(prop)) {
|
|
this[i] = prop;
|
|
} else {
|
|
this['_' + i] = prop;
|
|
}
|
|
}
|
|
this._config = config;
|
|
// Lenient ordinal parsing accepts just a number in addition to
|
|
// number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
|
|
// TODO: Remove "ordinalParse" fallback in next major release.
|
|
this._dayOfMonthOrdinalParseLenient = new RegExp(
|
|
(this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
|
|
'|' + (/\d{1,2}/).source);
|
|
}
|
|
|
|
function mergeConfigs(parentConfig, childConfig) {
|
|
var res = extend({}, parentConfig), prop;
|
|
for (prop in childConfig) {
|
|
if (hasOwnProp(childConfig, prop)) {
|
|
if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
|
|
res[prop] = {};
|
|
extend(res[prop], parentConfig[prop]);
|
|
extend(res[prop], childConfig[prop]);
|
|
} else if (childConfig[prop] != null) {
|
|
res[prop] = childConfig[prop];
|
|
} else {
|
|
delete res[prop];
|
|
}
|
|
}
|
|
}
|
|
for (prop in parentConfig) {
|
|
if (hasOwnProp(parentConfig, prop) &&
|
|
!hasOwnProp(childConfig, prop) &&
|
|
isObject(parentConfig[prop])) {
|
|
// make sure changes to properties don't modify parent config
|
|
res[prop] = extend({}, res[prop]);
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function Locale(config) {
|
|
if (config != null) {
|
|
this.set(config);
|
|
}
|
|
}
|
|
|
|
var keys;
|
|
|
|
if (Object.keys) {
|
|
keys = Object.keys;
|
|
} else {
|
|
keys = function (obj) {
|
|
var i, res = [];
|
|
for (i in obj) {
|
|
if (hasOwnProp(obj, i)) {
|
|
res.push(i);
|
|
}
|
|
}
|
|
return res;
|
|
};
|
|
}
|
|
|
|
var keys$1 = keys;
|
|
|
|
var defaultCalendar = {
|
|
sameDay : '[Today at] LT',
|
|
nextDay : '[Tomorrow at] LT',
|
|
nextWeek : 'dddd [at] LT',
|
|
lastDay : '[Yesterday at] LT',
|
|
lastWeek : '[Last] dddd [at] LT',
|
|
sameElse : 'L'
|
|
};
|
|
|
|
function calendar (key, mom, now) {
|
|
var output = this._calendar[key] || this._calendar['sameElse'];
|
|
return isFunction(output) ? output.call(mom, now) : output;
|
|
}
|
|
|
|
var defaultLongDateFormat = {
|
|
LTS : 'h:mm:ss A',
|
|
LT : 'h:mm A',
|
|
L : 'MM/DD/YYYY',
|
|
LL : 'MMMM D, YYYY',
|
|
LLL : 'MMMM D, YYYY h:mm A',
|
|
LLLL : 'dddd, MMMM D, YYYY h:mm A'
|
|
};
|
|
|
|
function longDateFormat (key) {
|
|
var format = this._longDateFormat[key],
|
|
formatUpper = this._longDateFormat[key.toUpperCase()];
|
|
|
|
if (format || !formatUpper) {
|
|
return format;
|
|
}
|
|
|
|
this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
|
|
return val.slice(1);
|
|
});
|
|
|
|
return this._longDateFormat[key];
|
|
}
|
|
|
|
var defaultInvalidDate = 'Invalid date';
|
|
|
|
function invalidDate () {
|
|
return this._invalidDate;
|
|
}
|
|
|
|
var defaultOrdinal = '%d';
|
|
var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
|
|
|
|
function ordinal (number) {
|
|
return this._ordinal.replace('%d', number);
|
|
}
|
|
|
|
var defaultRelativeTime = {
|
|
future : 'in %s',
|
|
past : '%s ago',
|
|
s : 'a few seconds',
|
|
ss : '%d seconds',
|
|
m : 'a minute',
|
|
mm : '%d minutes',
|
|
h : 'an hour',
|
|
hh : '%d hours',
|
|
d : 'a day',
|
|
dd : '%d days',
|
|
M : 'a month',
|
|
MM : '%d months',
|
|
y : 'a year',
|
|
yy : '%d years'
|
|
};
|
|
|
|
function relativeTime (number, withoutSuffix, string, isFuture) {
|
|
var output = this._relativeTime[string];
|
|
return (isFunction(output)) ?
|
|
output(number, withoutSuffix, string, isFuture) :
|
|
output.replace(/%d/i, number);
|
|
}
|
|
|
|
function pastFuture (diff, output) {
|
|
var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
|
|
return isFunction(format) ? format(output) : format.replace(/%s/i, output);
|
|
}
|
|
|
|
var aliases = {};
|
|
|
|
function addUnitAlias (unit, shorthand) {
|
|
var lowerCase = unit.toLowerCase();
|
|
aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
|
|
}
|
|
|
|
function normalizeUnits(units) {
|
|
return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
|
|
}
|
|
|
|
function normalizeObjectUnits(inputObject) {
|
|
var normalizedInput = {},
|
|
normalizedProp,
|
|
prop;
|
|
|
|
for (prop in inputObject) {
|
|
if (hasOwnProp(inputObject, prop)) {
|
|
normalizedProp = normalizeUnits(prop);
|
|
if (normalizedProp) {
|
|
normalizedInput[normalizedProp] = inputObject[prop];
|
|
}
|
|
}
|
|
}
|
|
|
|
return normalizedInput;
|
|
}
|
|
|
|
var priorities = {};
|
|
|
|
function addUnitPriority(unit, priority) {
|
|
priorities[unit] = priority;
|
|
}
|
|
|
|
function getPrioritizedUnits(unitsObj) {
|
|
var units = [];
|
|
for (var u in unitsObj) {
|
|
units.push({unit: u, priority: priorities[u]});
|
|
}
|
|
units.sort(function (a, b) {
|
|
return a.priority - b.priority;
|
|
});
|
|
return units;
|
|
}
|
|
|
|
function makeGetSet (unit, keepTime) {
|
|
return function (value) {
|
|
if (value != null) {
|
|
set$1(this, unit, value);
|
|
hooks.updateOffset(this, keepTime);
|
|
return this;
|
|
} else {
|
|
return get(this, unit);
|
|
}
|
|
};
|
|
}
|
|
|
|
function get (mom, unit) {
|
|
return mom.isValid() ?
|
|
mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
|
|
}
|
|
|
|
function set$1 (mom, unit, value) {
|
|
if (mom.isValid()) {
|
|
mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
|
|
}
|
|
}
|
|
|
|
// MOMENTS
|
|
|
|
function stringGet (units) {
|
|
units = normalizeUnits(units);
|
|
if (isFunction(this[units])) {
|
|
return this[units]();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
|
|
function stringSet (units, value) {
|
|
if (typeof units === 'object') {
|
|
units = normalizeObjectUnits(units);
|
|
var prioritized = getPrioritizedUnits(units);
|
|
for (var i = 0; i < prioritized.length; i++) {
|
|
this[prioritized[i].unit](units[prioritized[i].unit]);
|
|
}
|
|
} else {
|
|
units = normalizeUnits(units);
|
|
if (isFunction(this[units])) {
|
|
return this[units](value);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
function zeroFill(number, targetLength, forceSign) {
|
|
var absNumber = '' + Math.abs(number),
|
|
zerosToFill = targetLength - absNumber.length,
|
|
sign = number >= 0;
|
|
return (sign ? (forceSign ? '+' : '') : '-') +
|
|
Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
|
|
}
|
|
|
|
var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
|
|
|
|
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
|
|
|
|
var formatFunctions = {};
|
|
|
|
var formatTokenFunctions = {};
|
|
|
|
// token: 'M'
|
|
// padded: ['MM', 2]
|
|
// ordinal: 'Mo'
|
|
// callback: function () { this.month() + 1 }
|
|
function addFormatToken (token, padded, ordinal, callback) {
|
|
var func = callback;
|
|
if (typeof callback === 'string') {
|
|
func = function () {
|
|
return this[callback]();
|
|
};
|
|
}
|
|
if (token) {
|
|
formatTokenFunctions[token] = func;
|
|
}
|
|
if (padded) {
|
|
formatTokenFunctions[padded[0]] = function () {
|
|
return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
|
|
};
|
|
}
|
|
if (ordinal) {
|
|
formatTokenFunctions[ordinal] = function () {
|
|
return this.localeData().ordinal(func.apply(this, arguments), token);
|
|
};
|
|
}
|
|
}
|
|
|
|
function removeFormattingTokens(input) {
|
|
if (input.match(/\[[\s\S]/)) {
|
|
return input.replace(/^\[|\]$/g, '');
|
|
}
|
|
return input.replace(/\\/g, '');
|
|
}
|
|
|
|
function makeFormatFunction(format) {
|
|
var array = format.match(formattingTokens), i, length;
|
|
|
|
for (i = 0, length = array.length; i < length; i++) {
|
|
if (formatTokenFunctions[array[i]]) {
|
|
array[i] = formatTokenFunctions[array[i]];
|
|
} else {
|
|
array[i] = removeFormattingTokens(array[i]);
|
|
}
|
|
}
|
|
|
|
return function (mom) {
|
|
var output = '', i;
|
|
for (i = 0; i < length; i++) {
|
|
output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
|
|
}
|
|
return output;
|
|
};
|
|
}
|
|
|
|
// format date using native date object
|
|
function formatMoment(m, format) {
|
|
if (!m.isValid()) {
|
|
return m.localeData().invalidDate();
|
|
}
|
|
|
|
format = expandFormat(format, m.localeData());
|
|
formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
|
|
|
|
return formatFunctions[format](m);
|
|
}
|
|
|
|
function expandFormat(format, locale) {
|
|
var i = 5;
|
|
|
|
function replaceLongDateFormatTokens(input) {
|
|
return locale.longDateFormat(input) || input;
|
|
}
|
|
|
|
localFormattingTokens.lastIndex = 0;
|
|
while (i >= 0 && localFormattingTokens.test(format)) {
|
|
format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
|
|
localFormattingTokens.lastIndex = 0;
|
|
i -= 1;
|
|
}
|
|
|
|
return format;
|
|
}
|
|
|
|
var match1 = /\d/; // 0 - 9
|
|
var match2 = /\d\d/; // 00 - 99
|
|
var match3 = /\d{3}/; // 000 - 999
|
|
var match4 = /\d{4}/; // 0000 - 9999
|
|
var match6 = /[+-]?\d{6}/; // -999999 - 999999
|
|
var match1to2 = /\d\d?/; // 0 - 99
|
|
var match3to4 = /\d\d\d\d?/; // 999 - 9999
|
|
var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999
|
|
var match1to3 = /\d{1,3}/; // 0 - 999
|
|
var match1to4 = /\d{1,4}/; // 0 - 9999
|
|
var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999
|
|
|
|
var matchUnsigned = /\d+/; // 0 - inf
|
|
var matchSigned = /[+-]?\d+/; // -inf - inf
|
|
|
|
var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
|
|
var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
|
|
|
|
var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
|
|
|
|
// any word (or two) characters or numbers including two/three word month in arabic.
|
|
// includes scottish gaelic two word and hyphenated months
|
|
var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
|
|
|
|
|
|
var regexes = {};
|
|
|
|
function addRegexToken (token, regex, strictRegex) {
|
|
regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
|
|
return (isStrict && strictRegex) ? strictRegex : regex;
|
|
};
|
|
}
|
|
|
|
function getParseRegexForToken (token, config) {
|
|
if (!hasOwnProp(regexes, token)) {
|
|
return new RegExp(unescapeFormat(token));
|
|
}
|
|
|
|
return regexes[token](config._strict, config._locale);
|
|
}
|
|
|
|
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
|
|
function unescapeFormat(s) {
|
|
return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
|
|
return p1 || p2 || p3 || p4;
|
|
}));
|
|
}
|
|
|
|
function regexEscape(s) {
|
|
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
}
|
|
|
|
var tokens = {};
|
|
|
|
function addParseToken (token, callback) {
|
|
var i, func = callback;
|
|
if (typeof token === 'string') {
|
|
token = [token];
|
|
}
|
|
if (isNumber(callback)) {
|
|
func = function (input, array) {
|
|
array[callback] = toInt(input);
|
|
};
|
|
}
|
|
for (i = 0; i < token.length; i++) {
|
|
tokens[token[i]] = func;
|
|
}
|
|
}
|
|
|
|
function addWeekParseToken (token, callback) {
|
|
addParseToken(token, function (input, array, config, token) {
|
|
config._w = config._w || {};
|
|
callback(input, config._w, config, token);
|
|
});
|
|
}
|
|
|
|
function addTimeToArrayFromToken(token, input, config) {
|
|
if (input != null && hasOwnProp(tokens, token)) {
|
|
tokens[token](input, config._a, config, token);
|
|
}
|
|
}
|
|
|
|
var YEAR = 0;
|
|
var MONTH = 1;
|
|
var DATE = 2;
|
|
var HOUR = 3;
|
|
var MINUTE = 4;
|
|
var SECOND = 5;
|
|
var MILLISECOND = 6;
|
|
var WEEK = 7;
|
|
var WEEKDAY = 8;
|
|
|
|
var indexOf;
|
|
|
|
if (Array.prototype.indexOf) {
|
|
indexOf = Array.prototype.indexOf;
|
|
} else {
|
|
indexOf = function (o) {
|
|
// I know
|
|
var i;
|
|
for (i = 0; i < this.length; ++i) {
|
|
if (this[i] === o) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
}
|
|
|
|
var indexOf$1 = indexOf;
|
|
|
|
function daysInMonth(year, month) {
|
|
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('M', ['MM', 2], 'Mo', function () {
|
|
return this.month() + 1;
|
|
});
|
|
|
|
addFormatToken('MMM', 0, 0, function (format) {
|
|
return this.localeData().monthsShort(this, format);
|
|
});
|
|
|
|
addFormatToken('MMMM', 0, 0, function (format) {
|
|
return this.localeData().months(this, format);
|
|
});
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('month', 'M');
|
|
|
|
// PRIORITY
|
|
|
|
addUnitPriority('month', 8);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('M', match1to2);
|
|
addRegexToken('MM', match1to2, match2);
|
|
addRegexToken('MMM', function (isStrict, locale) {
|
|
return locale.monthsShortRegex(isStrict);
|
|
});
|
|
addRegexToken('MMMM', function (isStrict, locale) {
|
|
return locale.monthsRegex(isStrict);
|
|
});
|
|
|
|
addParseToken(['M', 'MM'], function (input, array) {
|
|
array[MONTH] = toInt(input) - 1;
|
|
});
|
|
|
|
addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
|
|
var month = config._locale.monthsParse(input, token, config._strict);
|
|
// if we didn't find a month name, mark the date as invalid.
|
|
if (month != null) {
|
|
array[MONTH] = month;
|
|
} else {
|
|
getParsingFlags(config).invalidMonth = input;
|
|
}
|
|
});
|
|
|
|
// LOCALES
|
|
|
|
var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
|
|
var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
|
|
function localeMonths (m, format) {
|
|
if (!m) {
|
|
return isArray(this._months) ? this._months :
|
|
this._months['standalone'];
|
|
}
|
|
return isArray(this._months) ? this._months[m.month()] :
|
|
this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
|
|
}
|
|
|
|
var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
|
|
function localeMonthsShort (m, format) {
|
|
if (!m) {
|
|
return isArray(this._monthsShort) ? this._monthsShort :
|
|
this._monthsShort['standalone'];
|
|
}
|
|
return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
|
|
this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
|
|
}
|
|
|
|
function handleStrictParse(monthName, format, strict) {
|
|
var i, ii, mom, llc = monthName.toLocaleLowerCase();
|
|
if (!this._monthsParse) {
|
|
// this is not used
|
|
this._monthsParse = [];
|
|
this._longMonthsParse = [];
|
|
this._shortMonthsParse = [];
|
|
for (i = 0; i < 12; ++i) {
|
|
mom = createUTC([2000, i]);
|
|
this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
|
|
this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
|
|
}
|
|
}
|
|
|
|
if (strict) {
|
|
if (format === 'MMM') {
|
|
ii = indexOf$1.call(this._shortMonthsParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
} else {
|
|
ii = indexOf$1.call(this._longMonthsParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
}
|
|
} else {
|
|
if (format === 'MMM') {
|
|
ii = indexOf$1.call(this._shortMonthsParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._longMonthsParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
} else {
|
|
ii = indexOf$1.call(this._longMonthsParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._shortMonthsParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
}
|
|
}
|
|
}
|
|
|
|
function localeMonthsParse (monthName, format, strict) {
|
|
var i, mom, regex;
|
|
|
|
if (this._monthsParseExact) {
|
|
return handleStrictParse.call(this, monthName, format, strict);
|
|
}
|
|
|
|
if (!this._monthsParse) {
|
|
this._monthsParse = [];
|
|
this._longMonthsParse = [];
|
|
this._shortMonthsParse = [];
|
|
}
|
|
|
|
// TODO: add sorting
|
|
// Sorting makes sure if one month (or abbr) is a prefix of another
|
|
// see sorting in computeMonthsParse
|
|
for (i = 0; i < 12; i++) {
|
|
// make the regex if we don't have it already
|
|
mom = createUTC([2000, i]);
|
|
if (strict && !this._longMonthsParse[i]) {
|
|
this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
|
|
this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
|
|
}
|
|
if (!strict && !this._monthsParse[i]) {
|
|
regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
|
|
this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
|
|
}
|
|
// test the regex
|
|
if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
|
|
return i;
|
|
} else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
|
|
return i;
|
|
} else if (!strict && this._monthsParse[i].test(monthName)) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
// MOMENTS
|
|
|
|
function setMonth (mom, value) {
|
|
var dayOfMonth;
|
|
|
|
if (!mom.isValid()) {
|
|
// No op
|
|
return mom;
|
|
}
|
|
|
|
if (typeof value === 'string') {
|
|
if (/^\d+$/.test(value)) {
|
|
value = toInt(value);
|
|
} else {
|
|
value = mom.localeData().monthsParse(value);
|
|
// TODO: Another silent failure?
|
|
if (!isNumber(value)) {
|
|
return mom;
|
|
}
|
|
}
|
|
}
|
|
|
|
dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
|
|
mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
|
|
return mom;
|
|
}
|
|
|
|
function getSetMonth (value) {
|
|
if (value != null) {
|
|
setMonth(this, value);
|
|
hooks.updateOffset(this, true);
|
|
return this;
|
|
} else {
|
|
return get(this, 'Month');
|
|
}
|
|
}
|
|
|
|
function getDaysInMonth () {
|
|
return daysInMonth(this.year(), this.month());
|
|
}
|
|
|
|
var defaultMonthsShortRegex = matchWord;
|
|
function monthsShortRegex (isStrict) {
|
|
if (this._monthsParseExact) {
|
|
if (!hasOwnProp(this, '_monthsRegex')) {
|
|
computeMonthsParse.call(this);
|
|
}
|
|
if (isStrict) {
|
|
return this._monthsShortStrictRegex;
|
|
} else {
|
|
return this._monthsShortRegex;
|
|
}
|
|
} else {
|
|
if (!hasOwnProp(this, '_monthsShortRegex')) {
|
|
this._monthsShortRegex = defaultMonthsShortRegex;
|
|
}
|
|
return this._monthsShortStrictRegex && isStrict ?
|
|
this._monthsShortStrictRegex : this._monthsShortRegex;
|
|
}
|
|
}
|
|
|
|
var defaultMonthsRegex = matchWord;
|
|
function monthsRegex (isStrict) {
|
|
if (this._monthsParseExact) {
|
|
if (!hasOwnProp(this, '_monthsRegex')) {
|
|
computeMonthsParse.call(this);
|
|
}
|
|
if (isStrict) {
|
|
return this._monthsStrictRegex;
|
|
} else {
|
|
return this._monthsRegex;
|
|
}
|
|
} else {
|
|
if (!hasOwnProp(this, '_monthsRegex')) {
|
|
this._monthsRegex = defaultMonthsRegex;
|
|
}
|
|
return this._monthsStrictRegex && isStrict ?
|
|
this._monthsStrictRegex : this._monthsRegex;
|
|
}
|
|
}
|
|
|
|
function computeMonthsParse () {
|
|
function cmpLenRev(a, b) {
|
|
return b.length - a.length;
|
|
}
|
|
|
|
var shortPieces = [], longPieces = [], mixedPieces = [],
|
|
i, mom;
|
|
for (i = 0; i < 12; i++) {
|
|
// make the regex if we don't have it already
|
|
mom = createUTC([2000, i]);
|
|
shortPieces.push(this.monthsShort(mom, ''));
|
|
longPieces.push(this.months(mom, ''));
|
|
mixedPieces.push(this.months(mom, ''));
|
|
mixedPieces.push(this.monthsShort(mom, ''));
|
|
}
|
|
// Sorting makes sure if one month (or abbr) is a prefix of another it
|
|
// will match the longer piece.
|
|
shortPieces.sort(cmpLenRev);
|
|
longPieces.sort(cmpLenRev);
|
|
mixedPieces.sort(cmpLenRev);
|
|
for (i = 0; i < 12; i++) {
|
|
shortPieces[i] = regexEscape(shortPieces[i]);
|
|
longPieces[i] = regexEscape(longPieces[i]);
|
|
}
|
|
for (i = 0; i < 24; i++) {
|
|
mixedPieces[i] = regexEscape(mixedPieces[i]);
|
|
}
|
|
|
|
this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
|
|
this._monthsShortRegex = this._monthsRegex;
|
|
this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
|
|
this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('Y', 0, 0, function () {
|
|
var y = this.year();
|
|
return y <= 9999 ? '' + y : '+' + y;
|
|
});
|
|
|
|
addFormatToken(0, ['YY', 2], 0, function () {
|
|
return this.year() % 100;
|
|
});
|
|
|
|
addFormatToken(0, ['YYYY', 4], 0, 'year');
|
|
addFormatToken(0, ['YYYYY', 5], 0, 'year');
|
|
addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('year', 'y');
|
|
|
|
// PRIORITIES
|
|
|
|
addUnitPriority('year', 1);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('Y', matchSigned);
|
|
addRegexToken('YY', match1to2, match2);
|
|
addRegexToken('YYYY', match1to4, match4);
|
|
addRegexToken('YYYYY', match1to6, match6);
|
|
addRegexToken('YYYYYY', match1to6, match6);
|
|
|
|
addParseToken(['YYYYY', 'YYYYYY'], YEAR);
|
|
addParseToken('YYYY', function (input, array) {
|
|
array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
|
|
});
|
|
addParseToken('YY', function (input, array) {
|
|
array[YEAR] = hooks.parseTwoDigitYear(input);
|
|
});
|
|
addParseToken('Y', function (input, array) {
|
|
array[YEAR] = parseInt(input, 10);
|
|
});
|
|
|
|
// HELPERS
|
|
|
|
function daysInYear(year) {
|
|
return isLeapYear(year) ? 366 : 365;
|
|
}
|
|
|
|
function isLeapYear(year) {
|
|
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
}
|
|
|
|
// HOOKS
|
|
|
|
hooks.parseTwoDigitYear = function (input) {
|
|
return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
|
|
};
|
|
|
|
// MOMENTS
|
|
|
|
var getSetYear = makeGetSet('FullYear', true);
|
|
|
|
function getIsLeapYear () {
|
|
return isLeapYear(this.year());
|
|
}
|
|
|
|
function createDate (y, m, d, h, M, s, ms) {
|
|
// can't just apply() to create a date:
|
|
// https://stackoverflow.com/q/181348
|
|
var date = new Date(y, m, d, h, M, s, ms);
|
|
|
|
// the date constructor remaps years 0-99 to 1900-1999
|
|
if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
|
|
date.setFullYear(y);
|
|
}
|
|
return date;
|
|
}
|
|
|
|
function createUTCDate (y) {
|
|
var date = new Date(Date.UTC.apply(null, arguments));
|
|
|
|
// the Date.UTC function remaps years 0-99 to 1900-1999
|
|
if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
|
|
date.setUTCFullYear(y);
|
|
}
|
|
return date;
|
|
}
|
|
|
|
// start-of-first-week - start-of-year
|
|
function firstWeekOffset(year, dow, doy) {
|
|
var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
|
|
fwd = 7 + dow - doy,
|
|
// first-week day local weekday -- which local weekday is fwd
|
|
fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
|
|
|
|
return -fwdlw + fwd - 1;
|
|
}
|
|
|
|
// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
|
|
function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
|
|
var localWeekday = (7 + weekday - dow) % 7,
|
|
weekOffset = firstWeekOffset(year, dow, doy),
|
|
dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
|
|
resYear, resDayOfYear;
|
|
|
|
if (dayOfYear <= 0) {
|
|
resYear = year - 1;
|
|
resDayOfYear = daysInYear(resYear) + dayOfYear;
|
|
} else if (dayOfYear > daysInYear(year)) {
|
|
resYear = year + 1;
|
|
resDayOfYear = dayOfYear - daysInYear(year);
|
|
} else {
|
|
resYear = year;
|
|
resDayOfYear = dayOfYear;
|
|
}
|
|
|
|
return {
|
|
year: resYear,
|
|
dayOfYear: resDayOfYear
|
|
};
|
|
}
|
|
|
|
function weekOfYear(mom, dow, doy) {
|
|
var weekOffset = firstWeekOffset(mom.year(), dow, doy),
|
|
week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
|
|
resWeek, resYear;
|
|
|
|
if (week < 1) {
|
|
resYear = mom.year() - 1;
|
|
resWeek = week + weeksInYear(resYear, dow, doy);
|
|
} else if (week > weeksInYear(mom.year(), dow, doy)) {
|
|
resWeek = week - weeksInYear(mom.year(), dow, doy);
|
|
resYear = mom.year() + 1;
|
|
} else {
|
|
resYear = mom.year();
|
|
resWeek = week;
|
|
}
|
|
|
|
return {
|
|
week: resWeek,
|
|
year: resYear
|
|
};
|
|
}
|
|
|
|
function weeksInYear(year, dow, doy) {
|
|
var weekOffset = firstWeekOffset(year, dow, doy),
|
|
weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
|
|
return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('w', ['ww', 2], 'wo', 'week');
|
|
addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('week', 'w');
|
|
addUnitAlias('isoWeek', 'W');
|
|
|
|
// PRIORITIES
|
|
|
|
addUnitPriority('week', 5);
|
|
addUnitPriority('isoWeek', 5);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('w', match1to2);
|
|
addRegexToken('ww', match1to2, match2);
|
|
addRegexToken('W', match1to2);
|
|
addRegexToken('WW', match1to2, match2);
|
|
|
|
addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
|
|
week[token.substr(0, 1)] = toInt(input);
|
|
});
|
|
|
|
// HELPERS
|
|
|
|
// LOCALES
|
|
|
|
function localeWeek (mom) {
|
|
return weekOfYear(mom, this._week.dow, this._week.doy).week;
|
|
}
|
|
|
|
var defaultLocaleWeek = {
|
|
dow : 0, // Sunday is the first day of the week.
|
|
doy : 6 // The week that contains Jan 1st is the first week of the year.
|
|
};
|
|
|
|
function localeFirstDayOfWeek () {
|
|
return this._week.dow;
|
|
}
|
|
|
|
function localeFirstDayOfYear () {
|
|
return this._week.doy;
|
|
}
|
|
|
|
// MOMENTS
|
|
|
|
function getSetWeek (input) {
|
|
var week = this.localeData().week(this);
|
|
return input == null ? week : this.add((input - week) * 7, 'd');
|
|
}
|
|
|
|
function getSetISOWeek (input) {
|
|
var week = weekOfYear(this, 1, 4).week;
|
|
return input == null ? week : this.add((input - week) * 7, 'd');
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('d', 0, 'do', 'day');
|
|
|
|
addFormatToken('dd', 0, 0, function (format) {
|
|
return this.localeData().weekdaysMin(this, format);
|
|
});
|
|
|
|
addFormatToken('ddd', 0, 0, function (format) {
|
|
return this.localeData().weekdaysShort(this, format);
|
|
});
|
|
|
|
addFormatToken('dddd', 0, 0, function (format) {
|
|
return this.localeData().weekdays(this, format);
|
|
});
|
|
|
|
addFormatToken('e', 0, 0, 'weekday');
|
|
addFormatToken('E', 0, 0, 'isoWeekday');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('day', 'd');
|
|
addUnitAlias('weekday', 'e');
|
|
addUnitAlias('isoWeekday', 'E');
|
|
|
|
// PRIORITY
|
|
addUnitPriority('day', 11);
|
|
addUnitPriority('weekday', 11);
|
|
addUnitPriority('isoWeekday', 11);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('d', match1to2);
|
|
addRegexToken('e', match1to2);
|
|
addRegexToken('E', match1to2);
|
|
addRegexToken('dd', function (isStrict, locale) {
|
|
return locale.weekdaysMinRegex(isStrict);
|
|
});
|
|
addRegexToken('ddd', function (isStrict, locale) {
|
|
return locale.weekdaysShortRegex(isStrict);
|
|
});
|
|
addRegexToken('dddd', function (isStrict, locale) {
|
|
return locale.weekdaysRegex(isStrict);
|
|
});
|
|
|
|
addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
|
|
var weekday = config._locale.weekdaysParse(input, token, config._strict);
|
|
// if we didn't get a weekday name, mark the date as invalid
|
|
if (weekday != null) {
|
|
week.d = weekday;
|
|
} else {
|
|
getParsingFlags(config).invalidWeekday = input;
|
|
}
|
|
});
|
|
|
|
addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
|
|
week[token] = toInt(input);
|
|
});
|
|
|
|
// HELPERS
|
|
|
|
function parseWeekday(input, locale) {
|
|
if (typeof input !== 'string') {
|
|
return input;
|
|
}
|
|
|
|
if (!isNaN(input)) {
|
|
return parseInt(input, 10);
|
|
}
|
|
|
|
input = locale.weekdaysParse(input);
|
|
if (typeof input === 'number') {
|
|
return input;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function parseIsoWeekday(input, locale) {
|
|
if (typeof input === 'string') {
|
|
return locale.weekdaysParse(input) % 7 || 7;
|
|
}
|
|
return isNaN(input) ? null : input;
|
|
}
|
|
|
|
// LOCALES
|
|
|
|
var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
|
|
function localeWeekdays (m, format) {
|
|
if (!m) {
|
|
return isArray(this._weekdays) ? this._weekdays :
|
|
this._weekdays['standalone'];
|
|
}
|
|
return isArray(this._weekdays) ? this._weekdays[m.day()] :
|
|
this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
|
|
}
|
|
|
|
var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
|
|
function localeWeekdaysShort (m) {
|
|
return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
|
|
}
|
|
|
|
var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
|
|
function localeWeekdaysMin (m) {
|
|
return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
|
|
}
|
|
|
|
function handleStrictParse$1(weekdayName, format, strict) {
|
|
var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
|
|
if (!this._weekdaysParse) {
|
|
this._weekdaysParse = [];
|
|
this._shortWeekdaysParse = [];
|
|
this._minWeekdaysParse = [];
|
|
|
|
for (i = 0; i < 7; ++i) {
|
|
mom = createUTC([2000, 1]).day(i);
|
|
this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
|
|
this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
|
|
this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
|
|
}
|
|
}
|
|
|
|
if (strict) {
|
|
if (format === 'dddd') {
|
|
ii = indexOf$1.call(this._weekdaysParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
} else if (format === 'ddd') {
|
|
ii = indexOf$1.call(this._shortWeekdaysParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
} else {
|
|
ii = indexOf$1.call(this._minWeekdaysParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
}
|
|
} else {
|
|
if (format === 'dddd') {
|
|
ii = indexOf$1.call(this._weekdaysParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._shortWeekdaysParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._minWeekdaysParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
} else if (format === 'ddd') {
|
|
ii = indexOf$1.call(this._shortWeekdaysParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._weekdaysParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._minWeekdaysParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
} else {
|
|
ii = indexOf$1.call(this._minWeekdaysParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._weekdaysParse, llc);
|
|
if (ii !== -1) {
|
|
return ii;
|
|
}
|
|
ii = indexOf$1.call(this._shortWeekdaysParse, llc);
|
|
return ii !== -1 ? ii : null;
|
|
}
|
|
}
|
|
}
|
|
|
|
function localeWeekdaysParse (weekdayName, format, strict) {
|
|
var i, mom, regex;
|
|
|
|
if (this._weekdaysParseExact) {
|
|
return handleStrictParse$1.call(this, weekdayName, format, strict);
|
|
}
|
|
|
|
if (!this._weekdaysParse) {
|
|
this._weekdaysParse = [];
|
|
this._minWeekdaysParse = [];
|
|
this._shortWeekdaysParse = [];
|
|
this._fullWeekdaysParse = [];
|
|
}
|
|
|
|
for (i = 0; i < 7; i++) {
|
|
// make the regex if we don't have it already
|
|
|
|
mom = createUTC([2000, 1]).day(i);
|
|
if (strict && !this._fullWeekdaysParse[i]) {
|
|
this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
|
|
this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
|
|
this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
|
|
}
|
|
if (!this._weekdaysParse[i]) {
|
|
regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
|
|
this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
|
|
}
|
|
// test the regex
|
|
if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
|
|
return i;
|
|
} else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
|
|
return i;
|
|
} else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
|
|
return i;
|
|
} else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
// MOMENTS
|
|
|
|
function getSetDayOfWeek (input) {
|
|
if (!this.isValid()) {
|
|
return input != null ? this : NaN;
|
|
}
|
|
var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
|
|
if (input != null) {
|
|
input = parseWeekday(input, this.localeData());
|
|
return this.add(input - day, 'd');
|
|
} else {
|
|
return day;
|
|
}
|
|
}
|
|
|
|
function getSetLocaleDayOfWeek (input) {
|
|
if (!this.isValid()) {
|
|
return input != null ? this : NaN;
|
|
}
|
|
var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
|
|
return input == null ? weekday : this.add(input - weekday, 'd');
|
|
}
|
|
|
|
function getSetISODayOfWeek (input) {
|
|
if (!this.isValid()) {
|
|
return input != null ? this : NaN;
|
|
}
|
|
|
|
// behaves the same as moment#day except
|
|
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
|
|
// as a setter, sunday should belong to the previous week.
|
|
|
|
if (input != null) {
|
|
var weekday = parseIsoWeekday(input, this.localeData());
|
|
return this.day(this.day() % 7 ? weekday : weekday - 7);
|
|
} else {
|
|
return this.day() || 7;
|
|
}
|
|
}
|
|
|
|
var defaultWeekdaysRegex = matchWord;
|
|
function weekdaysRegex (isStrict) {
|
|
if (this._weekdaysParseExact) {
|
|
if (!hasOwnProp(this, '_weekdaysRegex')) {
|
|
computeWeekdaysParse.call(this);
|
|
}
|
|
if (isStrict) {
|
|
return this._weekdaysStrictRegex;
|
|
} else {
|
|
return this._weekdaysRegex;
|
|
}
|
|
} else {
|
|
if (!hasOwnProp(this, '_weekdaysRegex')) {
|
|
this._weekdaysRegex = defaultWeekdaysRegex;
|
|
}
|
|
return this._weekdaysStrictRegex && isStrict ?
|
|
this._weekdaysStrictRegex : this._weekdaysRegex;
|
|
}
|
|
}
|
|
|
|
var defaultWeekdaysShortRegex = matchWord;
|
|
function weekdaysShortRegex (isStrict) {
|
|
if (this._weekdaysParseExact) {
|
|
if (!hasOwnProp(this, '_weekdaysRegex')) {
|
|
computeWeekdaysParse.call(this);
|
|
}
|
|
if (isStrict) {
|
|
return this._weekdaysShortStrictRegex;
|
|
} else {
|
|
return this._weekdaysShortRegex;
|
|
}
|
|
} else {
|
|
if (!hasOwnProp(this, '_weekdaysShortRegex')) {
|
|
this._weekdaysShortRegex = defaultWeekdaysShortRegex;
|
|
}
|
|
return this._weekdaysShortStrictRegex && isStrict ?
|
|
this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
|
|
}
|
|
}
|
|
|
|
var defaultWeekdaysMinRegex = matchWord;
|
|
function weekdaysMinRegex (isStrict) {
|
|
if (this._weekdaysParseExact) {
|
|
if (!hasOwnProp(this, '_weekdaysRegex')) {
|
|
computeWeekdaysParse.call(this);
|
|
}
|
|
if (isStrict) {
|
|
return this._weekdaysMinStrictRegex;
|
|
} else {
|
|
return this._weekdaysMinRegex;
|
|
}
|
|
} else {
|
|
if (!hasOwnProp(this, '_weekdaysMinRegex')) {
|
|
this._weekdaysMinRegex = defaultWeekdaysMinRegex;
|
|
}
|
|
return this._weekdaysMinStrictRegex && isStrict ?
|
|
this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
|
|
}
|
|
}
|
|
|
|
|
|
function computeWeekdaysParse () {
|
|
function cmpLenRev(a, b) {
|
|
return b.length - a.length;
|
|
}
|
|
|
|
var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
|
|
i, mom, minp, shortp, longp;
|
|
for (i = 0; i < 7; i++) {
|
|
// make the regex if we don't have it already
|
|
mom = createUTC([2000, 1]).day(i);
|
|
minp = this.weekdaysMin(mom, '');
|
|
shortp = this.weekdaysShort(mom, '');
|
|
longp = this.weekdays(mom, '');
|
|
minPieces.push(minp);
|
|
shortPieces.push(shortp);
|
|
longPieces.push(longp);
|
|
mixedPieces.push(minp);
|
|
mixedPieces.push(shortp);
|
|
mixedPieces.push(longp);
|
|
}
|
|
// Sorting makes sure if one weekday (or abbr) is a prefix of another it
|
|
// will match the longer piece.
|
|
minPieces.sort(cmpLenRev);
|
|
shortPieces.sort(cmpLenRev);
|
|
longPieces.sort(cmpLenRev);
|
|
mixedPieces.sort(cmpLenRev);
|
|
for (i = 0; i < 7; i++) {
|
|
shortPieces[i] = regexEscape(shortPieces[i]);
|
|
longPieces[i] = regexEscape(longPieces[i]);
|
|
mixedPieces[i] = regexEscape(mixedPieces[i]);
|
|
}
|
|
|
|
this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
|
|
this._weekdaysShortRegex = this._weekdaysRegex;
|
|
this._weekdaysMinRegex = this._weekdaysRegex;
|
|
|
|
this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
|
|
this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
|
|
this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
function hFormat() {
|
|
return this.hours() % 12 || 12;
|
|
}
|
|
|
|
function kFormat() {
|
|
return this.hours() || 24;
|
|
}
|
|
|
|
addFormatToken('H', ['HH', 2], 0, 'hour');
|
|
addFormatToken('h', ['hh', 2], 0, hFormat);
|
|
addFormatToken('k', ['kk', 2], 0, kFormat);
|
|
|
|
addFormatToken('hmm', 0, 0, function () {
|
|
return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
|
|
});
|
|
|
|
addFormatToken('hmmss', 0, 0, function () {
|
|
return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
|
|
zeroFill(this.seconds(), 2);
|
|
});
|
|
|
|
addFormatToken('Hmm', 0, 0, function () {
|
|
return '' + this.hours() + zeroFill(this.minutes(), 2);
|
|
});
|
|
|
|
addFormatToken('Hmmss', 0, 0, function () {
|
|
return '' + this.hours() + zeroFill(this.minutes(), 2) +
|
|
zeroFill(this.seconds(), 2);
|
|
});
|
|
|
|
function meridiem (token, lowercase) {
|
|
addFormatToken(token, 0, 0, function () {
|
|
return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
|
|
});
|
|
}
|
|
|
|
meridiem('a', true);
|
|
meridiem('A', false);
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('hour', 'h');
|
|
|
|
// PRIORITY
|
|
addUnitPriority('hour', 13);
|
|
|
|
// PARSING
|
|
|
|
function matchMeridiem (isStrict, locale) {
|
|
return locale._meridiemParse;
|
|
}
|
|
|
|
addRegexToken('a', matchMeridiem);
|
|
addRegexToken('A', matchMeridiem);
|
|
addRegexToken('H', match1to2);
|
|
addRegexToken('h', match1to2);
|
|
addRegexToken('k', match1to2);
|
|
addRegexToken('HH', match1to2, match2);
|
|
addRegexToken('hh', match1to2, match2);
|
|
addRegexToken('kk', match1to2, match2);
|
|
|
|
addRegexToken('hmm', match3to4);
|
|
addRegexToken('hmmss', match5to6);
|
|
addRegexToken('Hmm', match3to4);
|
|
addRegexToken('Hmmss', match5to6);
|
|
|
|
addParseToken(['H', 'HH'], HOUR);
|
|
addParseToken(['k', 'kk'], function (input, array, config) {
|
|
var kInput = toInt(input);
|
|
array[HOUR] = kInput === 24 ? 0 : kInput;
|
|
});
|
|
addParseToken(['a', 'A'], function (input, array, config) {
|
|
config._isPm = config._locale.isPM(input);
|
|
config._meridiem = input;
|
|
});
|
|
addParseToken(['h', 'hh'], function (input, array, config) {
|
|
array[HOUR] = toInt(input);
|
|
getParsingFlags(config).bigHour = true;
|
|
});
|
|
addParseToken('hmm', function (input, array, config) {
|
|
var pos = input.length - 2;
|
|
array[HOUR] = toInt(input.substr(0, pos));
|
|
array[MINUTE] = toInt(input.substr(pos));
|
|
getParsingFlags(config).bigHour = true;
|
|
});
|
|
addParseToken('hmmss', function (input, array, config) {
|
|
var pos1 = input.length - 4;
|
|
var pos2 = input.length - 2;
|
|
array[HOUR] = toInt(input.substr(0, pos1));
|
|
array[MINUTE] = toInt(input.substr(pos1, 2));
|
|
array[SECOND] = toInt(input.substr(pos2));
|
|
getParsingFlags(config).bigHour = true;
|
|
});
|
|
addParseToken('Hmm', function (input, array, config) {
|
|
var pos = input.length - 2;
|
|
array[HOUR] = toInt(input.substr(0, pos));
|
|
array[MINUTE] = toInt(input.substr(pos));
|
|
});
|
|
addParseToken('Hmmss', function (input, array, config) {
|
|
var pos1 = input.length - 4;
|
|
var pos2 = input.length - 2;
|
|
array[HOUR] = toInt(input.substr(0, pos1));
|
|
array[MINUTE] = toInt(input.substr(pos1, 2));
|
|
array[SECOND] = toInt(input.substr(pos2));
|
|
});
|
|
|
|
// LOCALES
|
|
|
|
function localeIsPM (input) {
|
|
// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
|
|
// Using charAt should be more compatible.
|
|
return ((input + '').toLowerCase().charAt(0) === 'p');
|
|
}
|
|
|
|
var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
|
|
function localeMeridiem (hours, minutes, isLower) {
|
|
if (hours > 11) {
|
|
return isLower ? 'pm' : 'PM';
|
|
} else {
|
|
return isLower ? 'am' : 'AM';
|
|
}
|
|
}
|
|
|
|
|
|
// MOMENTS
|
|
|
|
// Setting the hour should keep the time, because the user explicitly
|
|
// specified which hour he wants. So trying to maintain the same hour (in
|
|
// a new timezone) makes sense. Adding/subtracting hours does not follow
|
|
// this rule.
|
|
var getSetHour = makeGetSet('Hours', true);
|
|
|
|
// months
|
|
// week
|
|
// weekdays
|
|
// meridiem
|
|
var baseConfig = {
|
|
calendar: defaultCalendar,
|
|
longDateFormat: defaultLongDateFormat,
|
|
invalidDate: defaultInvalidDate,
|
|
ordinal: defaultOrdinal,
|
|
dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
|
|
relativeTime: defaultRelativeTime,
|
|
|
|
months: defaultLocaleMonths,
|
|
monthsShort: defaultLocaleMonthsShort,
|
|
|
|
week: defaultLocaleWeek,
|
|
|
|
weekdays: defaultLocaleWeekdays,
|
|
weekdaysMin: defaultLocaleWeekdaysMin,
|
|
weekdaysShort: defaultLocaleWeekdaysShort,
|
|
|
|
meridiemParse: defaultLocaleMeridiemParse
|
|
};
|
|
|
|
// internal storage for locale config files
|
|
var locales = {};
|
|
var localeFamilies = {};
|
|
var globalLocale;
|
|
|
|
function normalizeLocale(key) {
|
|
return key ? key.toLowerCase().replace('_', '-') : key;
|
|
}
|
|
|
|
// pick the locale from the array
|
|
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
|
|
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
|
|
function chooseLocale(names) {
|
|
var i = 0, j, next, locale, split;
|
|
|
|
while (i < names.length) {
|
|
split = normalizeLocale(names[i]).split('-');
|
|
j = split.length;
|
|
next = normalizeLocale(names[i + 1]);
|
|
next = next ? next.split('-') : null;
|
|
while (j > 0) {
|
|
locale = loadLocale(split.slice(0, j).join('-'));
|
|
if (locale) {
|
|
return locale;
|
|
}
|
|
if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
|
|
//the next array item is better than a shallower substring of this one
|
|
break;
|
|
}
|
|
j--;
|
|
}
|
|
i++;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function loadLocale(name) {
|
|
var oldLocale = null;
|
|
// TODO: Find a better way to register and load all the locales in Node
|
|
if (!locales[name] && (typeof module !== 'undefined') &&
|
|
module && module.exports) {
|
|
try {
|
|
oldLocale = globalLocale._abbr;
|
|
__webpack_require__(418)("./" + name);
|
|
// because defineLocale currently also sets the global locale, we
|
|
// want to undo that for lazy loaded locales
|
|
getSetGlobalLocale(oldLocale);
|
|
} catch (e) { }
|
|
}
|
|
return locales[name];
|
|
}
|
|
|
|
// This function will load locale and then set the global locale. If
|
|
// no arguments are passed in, it will simply return the current global
|
|
// locale key.
|
|
function getSetGlobalLocale (key, values) {
|
|
var data;
|
|
if (key) {
|
|
if (isUndefined(values)) {
|
|
data = getLocale(key);
|
|
}
|
|
else {
|
|
data = defineLocale(key, values);
|
|
}
|
|
|
|
if (data) {
|
|
// moment.duration._locale = moment._locale = data;
|
|
globalLocale = data;
|
|
}
|
|
}
|
|
|
|
return globalLocale._abbr;
|
|
}
|
|
|
|
function defineLocale (name, config) {
|
|
if (config !== null) {
|
|
var parentConfig = baseConfig;
|
|
config.abbr = name;
|
|
if (locales[name] != null) {
|
|
deprecateSimple('defineLocaleOverride',
|
|
'use moment.updateLocale(localeName, config) to change ' +
|
|
'an existing locale. moment.defineLocale(localeName, ' +
|
|
'config) should only be used for creating a new locale ' +
|
|
'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
|
|
parentConfig = locales[name]._config;
|
|
} else if (config.parentLocale != null) {
|
|
if (locales[config.parentLocale] != null) {
|
|
parentConfig = locales[config.parentLocale]._config;
|
|
} else {
|
|
if (!localeFamilies[config.parentLocale]) {
|
|
localeFamilies[config.parentLocale] = [];
|
|
}
|
|
localeFamilies[config.parentLocale].push({
|
|
name: name,
|
|
config: config
|
|
});
|
|
return null;
|
|
}
|
|
}
|
|
locales[name] = new Locale(mergeConfigs(parentConfig, config));
|
|
|
|
if (localeFamilies[name]) {
|
|
localeFamilies[name].forEach(function (x) {
|
|
defineLocale(x.name, x.config);
|
|
});
|
|
}
|
|
|
|
// backwards compat for now: also set the locale
|
|
// make sure we set the locale AFTER all child locales have been
|
|
// created, so we won't end up with the child locale set.
|
|
getSetGlobalLocale(name);
|
|
|
|
|
|
return locales[name];
|
|
} else {
|
|
// useful for testing
|
|
delete locales[name];
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function updateLocale(name, config) {
|
|
if (config != null) {
|
|
var locale, parentConfig = baseConfig;
|
|
// MERGE
|
|
if (locales[name] != null) {
|
|
parentConfig = locales[name]._config;
|
|
}
|
|
config = mergeConfigs(parentConfig, config);
|
|
locale = new Locale(config);
|
|
locale.parentLocale = locales[name];
|
|
locales[name] = locale;
|
|
|
|
// backwards compat for now: also set the locale
|
|
getSetGlobalLocale(name);
|
|
} else {
|
|
// pass null for config to unupdate, useful for tests
|
|
if (locales[name] != null) {
|
|
if (locales[name].parentLocale != null) {
|
|
locales[name] = locales[name].parentLocale;
|
|
} else if (locales[name] != null) {
|
|
delete locales[name];
|
|
}
|
|
}
|
|
}
|
|
return locales[name];
|
|
}
|
|
|
|
// returns locale data
|
|
function getLocale (key) {
|
|
var locale;
|
|
|
|
if (key && key._locale && key._locale._abbr) {
|
|
key = key._locale._abbr;
|
|
}
|
|
|
|
if (!key) {
|
|
return globalLocale;
|
|
}
|
|
|
|
if (!isArray(key)) {
|
|
//short-circuit everything else
|
|
locale = loadLocale(key);
|
|
if (locale) {
|
|
return locale;
|
|
}
|
|
key = [key];
|
|
}
|
|
|
|
return chooseLocale(key);
|
|
}
|
|
|
|
function listLocales() {
|
|
return keys$1(locales);
|
|
}
|
|
|
|
function checkOverflow (m) {
|
|
var overflow;
|
|
var a = m._a;
|
|
|
|
if (a && getParsingFlags(m).overflow === -2) {
|
|
overflow =
|
|
a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :
|
|
a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
|
|
a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
|
|
a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE :
|
|
a[SECOND] < 0 || a[SECOND] > 59 ? SECOND :
|
|
a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
|
|
-1;
|
|
|
|
if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
|
|
overflow = DATE;
|
|
}
|
|
if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
|
|
overflow = WEEK;
|
|
}
|
|
if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
|
|
overflow = WEEKDAY;
|
|
}
|
|
|
|
getParsingFlags(m).overflow = overflow;
|
|
}
|
|
|
|
return m;
|
|
}
|
|
|
|
// iso 8601 regex
|
|
// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
|
|
var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
|
|
var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
|
|
|
|
var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
|
|
|
|
var isoDates = [
|
|
['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
|
|
['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
|
|
['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
|
|
['GGGG-[W]WW', /\d{4}-W\d\d/, false],
|
|
['YYYY-DDD', /\d{4}-\d{3}/],
|
|
['YYYY-MM', /\d{4}-\d\d/, false],
|
|
['YYYYYYMMDD', /[+-]\d{10}/],
|
|
['YYYYMMDD', /\d{8}/],
|
|
// YYYYMM is NOT allowed by the standard
|
|
['GGGG[W]WWE', /\d{4}W\d{3}/],
|
|
['GGGG[W]WW', /\d{4}W\d{2}/, false],
|
|
['YYYYDDD', /\d{7}/]
|
|
];
|
|
|
|
// iso time formats and regexes
|
|
var isoTimes = [
|
|
['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
|
|
['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
|
|
['HH:mm:ss', /\d\d:\d\d:\d\d/],
|
|
['HH:mm', /\d\d:\d\d/],
|
|
['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
|
|
['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
|
|
['HHmmss', /\d\d\d\d\d\d/],
|
|
['HHmm', /\d\d\d\d/],
|
|
['HH', /\d\d/]
|
|
];
|
|
|
|
var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
|
|
|
|
// date from iso format
|
|
function configFromISO(config) {
|
|
var i, l,
|
|
string = config._i,
|
|
match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
|
|
allowTime, dateFormat, timeFormat, tzFormat;
|
|
|
|
if (match) {
|
|
getParsingFlags(config).iso = true;
|
|
|
|
for (i = 0, l = isoDates.length; i < l; i++) {
|
|
if (isoDates[i][1].exec(match[1])) {
|
|
dateFormat = isoDates[i][0];
|
|
allowTime = isoDates[i][2] !== false;
|
|
break;
|
|
}
|
|
}
|
|
if (dateFormat == null) {
|
|
config._isValid = false;
|
|
return;
|
|
}
|
|
if (match[3]) {
|
|
for (i = 0, l = isoTimes.length; i < l; i++) {
|
|
if (isoTimes[i][1].exec(match[3])) {
|
|
// match[2] should be 'T' or space
|
|
timeFormat = (match[2] || ' ') + isoTimes[i][0];
|
|
break;
|
|
}
|
|
}
|
|
if (timeFormat == null) {
|
|
config._isValid = false;
|
|
return;
|
|
}
|
|
}
|
|
if (!allowTime && timeFormat != null) {
|
|
config._isValid = false;
|
|
return;
|
|
}
|
|
if (match[4]) {
|
|
if (tzRegex.exec(match[4])) {
|
|
tzFormat = 'Z';
|
|
} else {
|
|
config._isValid = false;
|
|
return;
|
|
}
|
|
}
|
|
config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
|
|
configFromStringAndFormat(config);
|
|
} else {
|
|
config._isValid = false;
|
|
}
|
|
}
|
|
|
|
// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
|
|
var basicRfcRegex = /^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;
|
|
|
|
// date and time from ref 2822 format
|
|
function configFromRFC2822(config) {
|
|
var string, match, dayFormat,
|
|
dateFormat, timeFormat, tzFormat;
|
|
var timezones = {
|
|
' GMT': ' +0000',
|
|
' EDT': ' -0400',
|
|
' EST': ' -0500',
|
|
' CDT': ' -0500',
|
|
' CST': ' -0600',
|
|
' MDT': ' -0600',
|
|
' MST': ' -0700',
|
|
' PDT': ' -0700',
|
|
' PST': ' -0800'
|
|
};
|
|
var military = 'YXWVUTSRQPONZABCDEFGHIKLM';
|
|
var timezone, timezoneIndex;
|
|
|
|
string = config._i
|
|
.replace(/\([^\)]*\)|[\n\t]/g, ' ') // Remove comments and folding whitespace
|
|
.replace(/(\s\s+)/g, ' ') // Replace multiple-spaces with a single space
|
|
.replace(/^\s|\s$/g, ''); // Remove leading and trailing spaces
|
|
match = basicRfcRegex.exec(string);
|
|
|
|
if (match) {
|
|
dayFormat = match[1] ? 'ddd' + ((match[1].length === 5) ? ', ' : ' ') : '';
|
|
dateFormat = 'D MMM ' + ((match[2].length > 10) ? 'YYYY ' : 'YY ');
|
|
timeFormat = 'HH:mm' + (match[4] ? ':ss' : '');
|
|
|
|
// TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
|
|
if (match[1]) { // day of week given
|
|
var momentDate = new Date(match[2]);
|
|
var momentDay = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][momentDate.getDay()];
|
|
|
|
if (match[1].substr(0,3) !== momentDay) {
|
|
getParsingFlags(config).weekdayMismatch = true;
|
|
config._isValid = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
switch (match[5].length) {
|
|
case 2: // military
|
|
if (timezoneIndex === 0) {
|
|
timezone = ' +0000';
|
|
} else {
|
|
timezoneIndex = military.indexOf(match[5][1].toUpperCase()) - 12;
|
|
timezone = ((timezoneIndex < 0) ? ' -' : ' +') +
|
|
(('' + timezoneIndex).replace(/^-?/, '0')).match(/..$/)[0] + '00';
|
|
}
|
|
break;
|
|
case 4: // Zone
|
|
timezone = timezones[match[5]];
|
|
break;
|
|
default: // UT or +/-9999
|
|
timezone = timezones[' GMT'];
|
|
}
|
|
match[5] = timezone;
|
|
config._i = match.splice(1).join('');
|
|
tzFormat = ' ZZ';
|
|
config._f = dayFormat + dateFormat + timeFormat + tzFormat;
|
|
configFromStringAndFormat(config);
|
|
getParsingFlags(config).rfc2822 = true;
|
|
} else {
|
|
config._isValid = false;
|
|
}
|
|
}
|
|
|
|
// date from iso format or fallback
|
|
function configFromString(config) {
|
|
var matched = aspNetJsonRegex.exec(config._i);
|
|
|
|
if (matched !== null) {
|
|
config._d = new Date(+matched[1]);
|
|
return;
|
|
}
|
|
|
|
configFromISO(config);
|
|
if (config._isValid === false) {
|
|
delete config._isValid;
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
configFromRFC2822(config);
|
|
if (config._isValid === false) {
|
|
delete config._isValid;
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
// Final attempt, use Input Fallback
|
|
hooks.createFromInputFallback(config);
|
|
}
|
|
|
|
hooks.createFromInputFallback = deprecate(
|
|
'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
|
|
'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
|
|
'discouraged and will be removed in an upcoming major release. Please refer to ' +
|
|
'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
|
|
function (config) {
|
|
config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
|
|
}
|
|
);
|
|
|
|
// Pick the first defined of two or three arguments.
|
|
function defaults(a, b, c) {
|
|
if (a != null) {
|
|
return a;
|
|
}
|
|
if (b != null) {
|
|
return b;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
function currentDateArray(config) {
|
|
// hooks is actually the exported moment object
|
|
var nowValue = new Date(hooks.now());
|
|
if (config._useUTC) {
|
|
return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
|
|
}
|
|
return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
|
|
}
|
|
|
|
// convert an array to a date.
|
|
// the array should mirror the parameters below
|
|
// note: all values past the year are optional and will default to the lowest possible value.
|
|
// [year, month, day , hour, minute, second, millisecond]
|
|
function configFromArray (config) {
|
|
var i, date, input = [], currentDate, yearToUse;
|
|
|
|
if (config._d) {
|
|
return;
|
|
}
|
|
|
|
currentDate = currentDateArray(config);
|
|
|
|
//compute day of the year from weeks and weekdays
|
|
if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
|
|
dayOfYearFromWeekInfo(config);
|
|
}
|
|
|
|
//if the day of the year is set, figure out what it is
|
|
if (config._dayOfYear != null) {
|
|
yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
|
|
|
|
if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
|
|
getParsingFlags(config)._overflowDayOfYear = true;
|
|
}
|
|
|
|
date = createUTCDate(yearToUse, 0, config._dayOfYear);
|
|
config._a[MONTH] = date.getUTCMonth();
|
|
config._a[DATE] = date.getUTCDate();
|
|
}
|
|
|
|
// Default to current date.
|
|
// * if no year, month, day of month are given, default to today
|
|
// * if day of month is given, default month and year
|
|
// * if month is given, default only year
|
|
// * if year is given, don't default anything
|
|
for (i = 0; i < 3 && config._a[i] == null; ++i) {
|
|
config._a[i] = input[i] = currentDate[i];
|
|
}
|
|
|
|
// Zero out whatever was not defaulted, including time
|
|
for (; i < 7; i++) {
|
|
config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
|
|
}
|
|
|
|
// Check for 24:00:00.000
|
|
if (config._a[HOUR] === 24 &&
|
|
config._a[MINUTE] === 0 &&
|
|
config._a[SECOND] === 0 &&
|
|
config._a[MILLISECOND] === 0) {
|
|
config._nextDay = true;
|
|
config._a[HOUR] = 0;
|
|
}
|
|
|
|
config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
|
|
// Apply timezone offset from input. The actual utcOffset can be changed
|
|
// with parseZone.
|
|
if (config._tzm != null) {
|
|
config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
|
|
}
|
|
|
|
if (config._nextDay) {
|
|
config._a[HOUR] = 24;
|
|
}
|
|
}
|
|
|
|
function dayOfYearFromWeekInfo(config) {
|
|
var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
|
|
|
|
w = config._w;
|
|
if (w.GG != null || w.W != null || w.E != null) {
|
|
dow = 1;
|
|
doy = 4;
|
|
|
|
// TODO: We need to take the current isoWeekYear, but that depends on
|
|
// how we interpret now (local, utc, fixed offset). So create
|
|
// a now version of current config (take local/utc/offset flags, and
|
|
// create now).
|
|
weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
|
|
week = defaults(w.W, 1);
|
|
weekday = defaults(w.E, 1);
|
|
if (weekday < 1 || weekday > 7) {
|
|
weekdayOverflow = true;
|
|
}
|
|
} else {
|
|
dow = config._locale._week.dow;
|
|
doy = config._locale._week.doy;
|
|
|
|
var curWeek = weekOfYear(createLocal(), dow, doy);
|
|
|
|
weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
|
|
|
|
// Default to current week.
|
|
week = defaults(w.w, curWeek.week);
|
|
|
|
if (w.d != null) {
|
|
// weekday -- low day numbers are considered next week
|
|
weekday = w.d;
|
|
if (weekday < 0 || weekday > 6) {
|
|
weekdayOverflow = true;
|
|
}
|
|
} else if (w.e != null) {
|
|
// local weekday -- counting starts from begining of week
|
|
weekday = w.e + dow;
|
|
if (w.e < 0 || w.e > 6) {
|
|
weekdayOverflow = true;
|
|
}
|
|
} else {
|
|
// default to begining of week
|
|
weekday = dow;
|
|
}
|
|
}
|
|
if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
|
|
getParsingFlags(config)._overflowWeeks = true;
|
|
} else if (weekdayOverflow != null) {
|
|
getParsingFlags(config)._overflowWeekday = true;
|
|
} else {
|
|
temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
|
|
config._a[YEAR] = temp.year;
|
|
config._dayOfYear = temp.dayOfYear;
|
|
}
|
|
}
|
|
|
|
// constant that refers to the ISO standard
|
|
hooks.ISO_8601 = function () {};
|
|
|
|
// constant that refers to the RFC 2822 form
|
|
hooks.RFC_2822 = function () {};
|
|
|
|
// date from string and format string
|
|
function configFromStringAndFormat(config) {
|
|
// TODO: Move this to another part of the creation flow to prevent circular deps
|
|
if (config._f === hooks.ISO_8601) {
|
|
configFromISO(config);
|
|
return;
|
|
}
|
|
if (config._f === hooks.RFC_2822) {
|
|
configFromRFC2822(config);
|
|
return;
|
|
}
|
|
config._a = [];
|
|
getParsingFlags(config).empty = true;
|
|
|
|
// This array is used to make a Date, either with `new Date` or `Date.UTC`
|
|
var string = '' + config._i,
|
|
i, parsedInput, tokens, token, skipped,
|
|
stringLength = string.length,
|
|
totalParsedInputLength = 0;
|
|
|
|
tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
|
|
|
|
for (i = 0; i < tokens.length; i++) {
|
|
token = tokens[i];
|
|
parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
|
|
// console.log('token', token, 'parsedInput', parsedInput,
|
|
// 'regex', getParseRegexForToken(token, config));
|
|
if (parsedInput) {
|
|
skipped = string.substr(0, string.indexOf(parsedInput));
|
|
if (skipped.length > 0) {
|
|
getParsingFlags(config).unusedInput.push(skipped);
|
|
}
|
|
string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
|
|
totalParsedInputLength += parsedInput.length;
|
|
}
|
|
// don't parse if it's not a known token
|
|
if (formatTokenFunctions[token]) {
|
|
if (parsedInput) {
|
|
getParsingFlags(config).empty = false;
|
|
}
|
|
else {
|
|
getParsingFlags(config).unusedTokens.push(token);
|
|
}
|
|
addTimeToArrayFromToken(token, parsedInput, config);
|
|
}
|
|
else if (config._strict && !parsedInput) {
|
|
getParsingFlags(config).unusedTokens.push(token);
|
|
}
|
|
}
|
|
|
|
// add remaining unparsed input length to the string
|
|
getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
|
|
if (string.length > 0) {
|
|
getParsingFlags(config).unusedInput.push(string);
|
|
}
|
|
|
|
// clear _12h flag if hour is <= 12
|
|
if (config._a[HOUR] <= 12 &&
|
|
getParsingFlags(config).bigHour === true &&
|
|
config._a[HOUR] > 0) {
|
|
getParsingFlags(config).bigHour = undefined;
|
|
}
|
|
|
|
getParsingFlags(config).parsedDateParts = config._a.slice(0);
|
|
getParsingFlags(config).meridiem = config._meridiem;
|
|
// handle meridiem
|
|
config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
|
|
|
|
configFromArray(config);
|
|
checkOverflow(config);
|
|
}
|
|
|
|
|
|
function meridiemFixWrap (locale, hour, meridiem) {
|
|
var isPm;
|
|
|
|
if (meridiem == null) {
|
|
// nothing to do
|
|
return hour;
|
|
}
|
|
if (locale.meridiemHour != null) {
|
|
return locale.meridiemHour(hour, meridiem);
|
|
} else if (locale.isPM != null) {
|
|
// Fallback
|
|
isPm = locale.isPM(meridiem);
|
|
if (isPm && hour < 12) {
|
|
hour += 12;
|
|
}
|
|
if (!isPm && hour === 12) {
|
|
hour = 0;
|
|
}
|
|
return hour;
|
|
} else {
|
|
// this is not supposed to happen
|
|
return hour;
|
|
}
|
|
}
|
|
|
|
// date from string and array of format strings
|
|
function configFromStringAndArray(config) {
|
|
var tempConfig,
|
|
bestMoment,
|
|
|
|
scoreToBeat,
|
|
i,
|
|
currentScore;
|
|
|
|
if (config._f.length === 0) {
|
|
getParsingFlags(config).invalidFormat = true;
|
|
config._d = new Date(NaN);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < config._f.length; i++) {
|
|
currentScore = 0;
|
|
tempConfig = copyConfig({}, config);
|
|
if (config._useUTC != null) {
|
|
tempConfig._useUTC = config._useUTC;
|
|
}
|
|
tempConfig._f = config._f[i];
|
|
configFromStringAndFormat(tempConfig);
|
|
|
|
if (!isValid(tempConfig)) {
|
|
continue;
|
|
}
|
|
|
|
// if there is any input that was not parsed add a penalty for that format
|
|
currentScore += getParsingFlags(tempConfig).charsLeftOver;
|
|
|
|
//or tokens
|
|
currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
|
|
|
|
getParsingFlags(tempConfig).score = currentScore;
|
|
|
|
if (scoreToBeat == null || currentScore < scoreToBeat) {
|
|
scoreToBeat = currentScore;
|
|
bestMoment = tempConfig;
|
|
}
|
|
}
|
|
|
|
extend(config, bestMoment || tempConfig);
|
|
}
|
|
|
|
function configFromObject(config) {
|
|
if (config._d) {
|
|
return;
|
|
}
|
|
|
|
var i = normalizeObjectUnits(config._i);
|
|
config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
|
|
return obj && parseInt(obj, 10);
|
|
});
|
|
|
|
configFromArray(config);
|
|
}
|
|
|
|
function createFromConfig (config) {
|
|
var res = new Moment(checkOverflow(prepareConfig(config)));
|
|
if (res._nextDay) {
|
|
// Adding is smart enough around DST
|
|
res.add(1, 'd');
|
|
res._nextDay = undefined;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
function prepareConfig (config) {
|
|
var input = config._i,
|
|
format = config._f;
|
|
|
|
config._locale = config._locale || getLocale(config._l);
|
|
|
|
if (input === null || (format === undefined && input === '')) {
|
|
return createInvalid({nullInput: true});
|
|
}
|
|
|
|
if (typeof input === 'string') {
|
|
config._i = input = config._locale.preparse(input);
|
|
}
|
|
|
|
if (isMoment(input)) {
|
|
return new Moment(checkOverflow(input));
|
|
} else if (isDate(input)) {
|
|
config._d = input;
|
|
} else if (isArray(format)) {
|
|
configFromStringAndArray(config);
|
|
} else if (format) {
|
|
configFromStringAndFormat(config);
|
|
} else {
|
|
configFromInput(config);
|
|
}
|
|
|
|
if (!isValid(config)) {
|
|
config._d = null;
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
function configFromInput(config) {
|
|
var input = config._i;
|
|
if (isUndefined(input)) {
|
|
config._d = new Date(hooks.now());
|
|
} else if (isDate(input)) {
|
|
config._d = new Date(input.valueOf());
|
|
} else if (typeof input === 'string') {
|
|
configFromString(config);
|
|
} else if (isArray(input)) {
|
|
config._a = map(input.slice(0), function (obj) {
|
|
return parseInt(obj, 10);
|
|
});
|
|
configFromArray(config);
|
|
} else if (isObject(input)) {
|
|
configFromObject(config);
|
|
} else if (isNumber(input)) {
|
|
// from milliseconds
|
|
config._d = new Date(input);
|
|
} else {
|
|
hooks.createFromInputFallback(config);
|
|
}
|
|
}
|
|
|
|
function createLocalOrUTC (input, format, locale, strict, isUTC) {
|
|
var c = {};
|
|
|
|
if (locale === true || locale === false) {
|
|
strict = locale;
|
|
locale = undefined;
|
|
}
|
|
|
|
if ((isObject(input) && isObjectEmpty(input)) ||
|
|
(isArray(input) && input.length === 0)) {
|
|
input = undefined;
|
|
}
|
|
// object construction must be done this way.
|
|
// https://github.com/moment/moment/issues/1423
|
|
c._isAMomentObject = true;
|
|
c._useUTC = c._isUTC = isUTC;
|
|
c._l = locale;
|
|
c._i = input;
|
|
c._f = format;
|
|
c._strict = strict;
|
|
|
|
return createFromConfig(c);
|
|
}
|
|
|
|
function createLocal (input, format, locale, strict) {
|
|
return createLocalOrUTC(input, format, locale, strict, false);
|
|
}
|
|
|
|
var prototypeMin = deprecate(
|
|
'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
|
|
function () {
|
|
var other = createLocal.apply(null, arguments);
|
|
if (this.isValid() && other.isValid()) {
|
|
return other < this ? this : other;
|
|
} else {
|
|
return createInvalid();
|
|
}
|
|
}
|
|
);
|
|
|
|
var prototypeMax = deprecate(
|
|
'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
|
|
function () {
|
|
var other = createLocal.apply(null, arguments);
|
|
if (this.isValid() && other.isValid()) {
|
|
return other > this ? this : other;
|
|
} else {
|
|
return createInvalid();
|
|
}
|
|
}
|
|
);
|
|
|
|
// Pick a moment m from moments so that m[fn](other) is true for all
|
|
// other. This relies on the function fn to be transitive.
|
|
//
|
|
// moments should either be an array of moment objects or an array, whose
|
|
// first element is an array of moment objects.
|
|
function pickBy(fn, moments) {
|
|
var res, i;
|
|
if (moments.length === 1 && isArray(moments[0])) {
|
|
moments = moments[0];
|
|
}
|
|
if (!moments.length) {
|
|
return createLocal();
|
|
}
|
|
res = moments[0];
|
|
for (i = 1; i < moments.length; ++i) {
|
|
if (!moments[i].isValid() || moments[i][fn](res)) {
|
|
res = moments[i];
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
// TODO: Use [].sort instead?
|
|
function min () {
|
|
var args = [].slice.call(arguments, 0);
|
|
|
|
return pickBy('isBefore', args);
|
|
}
|
|
|
|
function max () {
|
|
var args = [].slice.call(arguments, 0);
|
|
|
|
return pickBy('isAfter', args);
|
|
}
|
|
|
|
var now = function () {
|
|
return Date.now ? Date.now() : +(new Date());
|
|
};
|
|
|
|
var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
|
|
|
|
function isDurationValid(m) {
|
|
for (var key in m) {
|
|
if (!(ordering.indexOf(key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
var unitHasDecimal = false;
|
|
for (var i = 0; i < ordering.length; ++i) {
|
|
if (m[ordering[i]]) {
|
|
if (unitHasDecimal) {
|
|
return false; // only allow non-integers for smallest unit
|
|
}
|
|
if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
|
|
unitHasDecimal = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function isValid$1() {
|
|
return this._isValid;
|
|
}
|
|
|
|
function createInvalid$1() {
|
|
return createDuration(NaN);
|
|
}
|
|
|
|
function Duration (duration) {
|
|
var normalizedInput = normalizeObjectUnits(duration),
|
|
years = normalizedInput.year || 0,
|
|
quarters = normalizedInput.quarter || 0,
|
|
months = normalizedInput.month || 0,
|
|
weeks = normalizedInput.week || 0,
|
|
days = normalizedInput.day || 0,
|
|
hours = normalizedInput.hour || 0,
|
|
minutes = normalizedInput.minute || 0,
|
|
seconds = normalizedInput.second || 0,
|
|
milliseconds = normalizedInput.millisecond || 0;
|
|
|
|
this._isValid = isDurationValid(normalizedInput);
|
|
|
|
// representation for dateAddRemove
|
|
this._milliseconds = +milliseconds +
|
|
seconds * 1e3 + // 1000
|
|
minutes * 6e4 + // 1000 * 60
|
|
hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
|
|
// Because of dateAddRemove treats 24 hours as different from a
|
|
// day when working around DST, we need to store them separately
|
|
this._days = +days +
|
|
weeks * 7;
|
|
// It is impossible translate months into days without knowing
|
|
// which months you are are talking about, so we have to store
|
|
// it separately.
|
|
this._months = +months +
|
|
quarters * 3 +
|
|
years * 12;
|
|
|
|
this._data = {};
|
|
|
|
this._locale = getLocale();
|
|
|
|
this._bubble();
|
|
}
|
|
|
|
function isDuration (obj) {
|
|
return obj instanceof Duration;
|
|
}
|
|
|
|
function absRound (number) {
|
|
if (number < 0) {
|
|
return Math.round(-1 * number) * -1;
|
|
} else {
|
|
return Math.round(number);
|
|
}
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
function offset (token, separator) {
|
|
addFormatToken(token, 0, 0, function () {
|
|
var offset = this.utcOffset();
|
|
var sign = '+';
|
|
if (offset < 0) {
|
|
offset = -offset;
|
|
sign = '-';
|
|
}
|
|
return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
|
|
});
|
|
}
|
|
|
|
offset('Z', ':');
|
|
offset('ZZ', '');
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('Z', matchShortOffset);
|
|
addRegexToken('ZZ', matchShortOffset);
|
|
addParseToken(['Z', 'ZZ'], function (input, array, config) {
|
|
config._useUTC = true;
|
|
config._tzm = offsetFromString(matchShortOffset, input);
|
|
});
|
|
|
|
// HELPERS
|
|
|
|
// timezone chunker
|
|
// '+10:00' > ['10', '00']
|
|
// '-1530' > ['-15', '30']
|
|
var chunkOffset = /([\+\-]|\d\d)/gi;
|
|
|
|
function offsetFromString(matcher, string) {
|
|
var matches = (string || '').match(matcher);
|
|
|
|
if (matches === null) {
|
|
return null;
|
|
}
|
|
|
|
var chunk = matches[matches.length - 1] || [];
|
|
var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
|
|
var minutes = +(parts[1] * 60) + toInt(parts[2]);
|
|
|
|
return minutes === 0 ?
|
|
0 :
|
|
parts[0] === '+' ? minutes : -minutes;
|
|
}
|
|
|
|
// Return a moment from input, that is local/utc/zone equivalent to model.
|
|
function cloneWithOffset(input, model) {
|
|
var res, diff;
|
|
if (model._isUTC) {
|
|
res = model.clone();
|
|
diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
|
|
// Use low-level api, because this fn is low-level api.
|
|
res._d.setTime(res._d.valueOf() + diff);
|
|
hooks.updateOffset(res, false);
|
|
return res;
|
|
} else {
|
|
return createLocal(input).local();
|
|
}
|
|
}
|
|
|
|
function getDateOffset (m) {
|
|
// On Firefox.24 Date#getTimezoneOffset returns a floating point.
|
|
// https://github.com/moment/moment/pull/1871
|
|
return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
|
|
}
|
|
|
|
// HOOKS
|
|
|
|
// This function will be called whenever a moment is mutated.
|
|
// It is intended to keep the offset in sync with the timezone.
|
|
hooks.updateOffset = function () {};
|
|
|
|
// MOMENTS
|
|
|
|
// keepLocalTime = true means only change the timezone, without
|
|
// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
|
|
// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
|
|
// +0200, so we adjust the time as needed, to be valid.
|
|
//
|
|
// Keeping the time actually adds/subtracts (one hour)
|
|
// from the actual represented time. That is why we call updateOffset
|
|
// a second time. In case it wants us to change the offset again
|
|
// _changeInProgress == true case, then we have to adjust, because
|
|
// there is no such time in the given timezone.
|
|
function getSetOffset (input, keepLocalTime, keepMinutes) {
|
|
var offset = this._offset || 0,
|
|
localAdjust;
|
|
if (!this.isValid()) {
|
|
return input != null ? this : NaN;
|
|
}
|
|
if (input != null) {
|
|
if (typeof input === 'string') {
|
|
input = offsetFromString(matchShortOffset, input);
|
|
if (input === null) {
|
|
return this;
|
|
}
|
|
} else if (Math.abs(input) < 16 && !keepMinutes) {
|
|
input = input * 60;
|
|
}
|
|
if (!this._isUTC && keepLocalTime) {
|
|
localAdjust = getDateOffset(this);
|
|
}
|
|
this._offset = input;
|
|
this._isUTC = true;
|
|
if (localAdjust != null) {
|
|
this.add(localAdjust, 'm');
|
|
}
|
|
if (offset !== input) {
|
|
if (!keepLocalTime || this._changeInProgress) {
|
|
addSubtract(this, createDuration(input - offset, 'm'), 1, false);
|
|
} else if (!this._changeInProgress) {
|
|
this._changeInProgress = true;
|
|
hooks.updateOffset(this, true);
|
|
this._changeInProgress = null;
|
|
}
|
|
}
|
|
return this;
|
|
} else {
|
|
return this._isUTC ? offset : getDateOffset(this);
|
|
}
|
|
}
|
|
|
|
function getSetZone (input, keepLocalTime) {
|
|
if (input != null) {
|
|
if (typeof input !== 'string') {
|
|
input = -input;
|
|
}
|
|
|
|
this.utcOffset(input, keepLocalTime);
|
|
|
|
return this;
|
|
} else {
|
|
return -this.utcOffset();
|
|
}
|
|
}
|
|
|
|
function setOffsetToUTC (keepLocalTime) {
|
|
return this.utcOffset(0, keepLocalTime);
|
|
}
|
|
|
|
function setOffsetToLocal (keepLocalTime) {
|
|
if (this._isUTC) {
|
|
this.utcOffset(0, keepLocalTime);
|
|
this._isUTC = false;
|
|
|
|
if (keepLocalTime) {
|
|
this.subtract(getDateOffset(this), 'm');
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
function setOffsetToParsedOffset () {
|
|
if (this._tzm != null) {
|
|
this.utcOffset(this._tzm, false, true);
|
|
} else if (typeof this._i === 'string') {
|
|
var tZone = offsetFromString(matchOffset, this._i);
|
|
if (tZone != null) {
|
|
this.utcOffset(tZone);
|
|
}
|
|
else {
|
|
this.utcOffset(0, true);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
function hasAlignedHourOffset (input) {
|
|
if (!this.isValid()) {
|
|
return false;
|
|
}
|
|
input = input ? createLocal(input).utcOffset() : 0;
|
|
|
|
return (this.utcOffset() - input) % 60 === 0;
|
|
}
|
|
|
|
function isDaylightSavingTime () {
|
|
return (
|
|
this.utcOffset() > this.clone().month(0).utcOffset() ||
|
|
this.utcOffset() > this.clone().month(5).utcOffset()
|
|
);
|
|
}
|
|
|
|
function isDaylightSavingTimeShifted () {
|
|
if (!isUndefined(this._isDSTShifted)) {
|
|
return this._isDSTShifted;
|
|
}
|
|
|
|
var c = {};
|
|
|
|
copyConfig(c, this);
|
|
c = prepareConfig(c);
|
|
|
|
if (c._a) {
|
|
var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
|
|
this._isDSTShifted = this.isValid() &&
|
|
compareArrays(c._a, other.toArray()) > 0;
|
|
} else {
|
|
this._isDSTShifted = false;
|
|
}
|
|
|
|
return this._isDSTShifted;
|
|
}
|
|
|
|
function isLocal () {
|
|
return this.isValid() ? !this._isUTC : false;
|
|
}
|
|
|
|
function isUtcOffset () {
|
|
return this.isValid() ? this._isUTC : false;
|
|
}
|
|
|
|
function isUtc () {
|
|
return this.isValid() ? this._isUTC && this._offset === 0 : false;
|
|
}
|
|
|
|
// ASP.NET json date format regex
|
|
var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
|
|
|
|
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
|
|
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
|
|
// and further modified to allow for strings containing both week and day
|
|
var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
|
|
|
|
function createDuration (input, key) {
|
|
var duration = input,
|
|
// matching against regexp is expensive, do it on demand
|
|
match = null,
|
|
sign,
|
|
ret,
|
|
diffRes;
|
|
|
|
if (isDuration(input)) {
|
|
duration = {
|
|
ms : input._milliseconds,
|
|
d : input._days,
|
|
M : input._months
|
|
};
|
|
} else if (isNumber(input)) {
|
|
duration = {};
|
|
if (key) {
|
|
duration[key] = input;
|
|
} else {
|
|
duration.milliseconds = input;
|
|
}
|
|
} else if (!!(match = aspNetRegex.exec(input))) {
|
|
sign = (match[1] === '-') ? -1 : 1;
|
|
duration = {
|
|
y : 0,
|
|
d : toInt(match[DATE]) * sign,
|
|
h : toInt(match[HOUR]) * sign,
|
|
m : toInt(match[MINUTE]) * sign,
|
|
s : toInt(match[SECOND]) * sign,
|
|
ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
|
|
};
|
|
} else if (!!(match = isoRegex.exec(input))) {
|
|
sign = (match[1] === '-') ? -1 : 1;
|
|
duration = {
|
|
y : parseIso(match[2], sign),
|
|
M : parseIso(match[3], sign),
|
|
w : parseIso(match[4], sign),
|
|
d : parseIso(match[5], sign),
|
|
h : parseIso(match[6], sign),
|
|
m : parseIso(match[7], sign),
|
|
s : parseIso(match[8], sign)
|
|
};
|
|
} else if (duration == null) {// checks for null or undefined
|
|
duration = {};
|
|
} else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
|
|
diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
|
|
|
|
duration = {};
|
|
duration.ms = diffRes.milliseconds;
|
|
duration.M = diffRes.months;
|
|
}
|
|
|
|
ret = new Duration(duration);
|
|
|
|
if (isDuration(input) && hasOwnProp(input, '_locale')) {
|
|
ret._locale = input._locale;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
createDuration.fn = Duration.prototype;
|
|
createDuration.invalid = createInvalid$1;
|
|
|
|
function parseIso (inp, sign) {
|
|
// We'd normally use ~~inp for this, but unfortunately it also
|
|
// converts floats to ints.
|
|
// inp may be undefined, so careful calling replace on it.
|
|
var res = inp && parseFloat(inp.replace(',', '.'));
|
|
// apply sign while we're at it
|
|
return (isNaN(res) ? 0 : res) * sign;
|
|
}
|
|
|
|
function positiveMomentsDifference(base, other) {
|
|
var res = {milliseconds: 0, months: 0};
|
|
|
|
res.months = other.month() - base.month() +
|
|
(other.year() - base.year()) * 12;
|
|
if (base.clone().add(res.months, 'M').isAfter(other)) {
|
|
--res.months;
|
|
}
|
|
|
|
res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
|
|
|
|
return res;
|
|
}
|
|
|
|
function momentsDifference(base, other) {
|
|
var res;
|
|
if (!(base.isValid() && other.isValid())) {
|
|
return {milliseconds: 0, months: 0};
|
|
}
|
|
|
|
other = cloneWithOffset(other, base);
|
|
if (base.isBefore(other)) {
|
|
res = positiveMomentsDifference(base, other);
|
|
} else {
|
|
res = positiveMomentsDifference(other, base);
|
|
res.milliseconds = -res.milliseconds;
|
|
res.months = -res.months;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
// TODO: remove 'name' arg after deprecation is removed
|
|
function createAdder(direction, name) {
|
|
return function (val, period) {
|
|
var dur, tmp;
|
|
//invert the arguments, but complain about it
|
|
if (period !== null && !isNaN(+period)) {
|
|
deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
|
|
'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
|
|
tmp = val; val = period; period = tmp;
|
|
}
|
|
|
|
val = typeof val === 'string' ? +val : val;
|
|
dur = createDuration(val, period);
|
|
addSubtract(this, dur, direction);
|
|
return this;
|
|
};
|
|
}
|
|
|
|
function addSubtract (mom, duration, isAdding, updateOffset) {
|
|
var milliseconds = duration._milliseconds,
|
|
days = absRound(duration._days),
|
|
months = absRound(duration._months);
|
|
|
|
if (!mom.isValid()) {
|
|
// No op
|
|
return;
|
|
}
|
|
|
|
updateOffset = updateOffset == null ? true : updateOffset;
|
|
|
|
if (milliseconds) {
|
|
mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
|
|
}
|
|
if (days) {
|
|
set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
|
|
}
|
|
if (months) {
|
|
setMonth(mom, get(mom, 'Month') + months * isAdding);
|
|
}
|
|
if (updateOffset) {
|
|
hooks.updateOffset(mom, days || months);
|
|
}
|
|
}
|
|
|
|
var add = createAdder(1, 'add');
|
|
var subtract = createAdder(-1, 'subtract');
|
|
|
|
function getCalendarFormat(myMoment, now) {
|
|
var diff = myMoment.diff(now, 'days', true);
|
|
return diff < -6 ? 'sameElse' :
|
|
diff < -1 ? 'lastWeek' :
|
|
diff < 0 ? 'lastDay' :
|
|
diff < 1 ? 'sameDay' :
|
|
diff < 2 ? 'nextDay' :
|
|
diff < 7 ? 'nextWeek' : 'sameElse';
|
|
}
|
|
|
|
function calendar$1 (time, formats) {
|
|
// We want to compare the start of today, vs this.
|
|
// Getting start-of-today depends on whether we're local/utc/offset or not.
|
|
var now = time || createLocal(),
|
|
sod = cloneWithOffset(now, this).startOf('day'),
|
|
format = hooks.calendarFormat(this, sod) || 'sameElse';
|
|
|
|
var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
|
|
|
|
return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
|
|
}
|
|
|
|
function clone () {
|
|
return new Moment(this);
|
|
}
|
|
|
|
function isAfter (input, units) {
|
|
var localInput = isMoment(input) ? input : createLocal(input);
|
|
if (!(this.isValid() && localInput.isValid())) {
|
|
return false;
|
|
}
|
|
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
|
|
if (units === 'millisecond') {
|
|
return this.valueOf() > localInput.valueOf();
|
|
} else {
|
|
return localInput.valueOf() < this.clone().startOf(units).valueOf();
|
|
}
|
|
}
|
|
|
|
function isBefore (input, units) {
|
|
var localInput = isMoment(input) ? input : createLocal(input);
|
|
if (!(this.isValid() && localInput.isValid())) {
|
|
return false;
|
|
}
|
|
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
|
|
if (units === 'millisecond') {
|
|
return this.valueOf() < localInput.valueOf();
|
|
} else {
|
|
return this.clone().endOf(units).valueOf() < localInput.valueOf();
|
|
}
|
|
}
|
|
|
|
function isBetween (from, to, units, inclusivity) {
|
|
inclusivity = inclusivity || '()';
|
|
return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
|
|
(inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
|
|
}
|
|
|
|
function isSame (input, units) {
|
|
var localInput = isMoment(input) ? input : createLocal(input),
|
|
inputMs;
|
|
if (!(this.isValid() && localInput.isValid())) {
|
|
return false;
|
|
}
|
|
units = normalizeUnits(units || 'millisecond');
|
|
if (units === 'millisecond') {
|
|
return this.valueOf() === localInput.valueOf();
|
|
} else {
|
|
inputMs = localInput.valueOf();
|
|
return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
|
|
}
|
|
}
|
|
|
|
function isSameOrAfter (input, units) {
|
|
return this.isSame(input, units) || this.isAfter(input,units);
|
|
}
|
|
|
|
function isSameOrBefore (input, units) {
|
|
return this.isSame(input, units) || this.isBefore(input,units);
|
|
}
|
|
|
|
function diff (input, units, asFloat) {
|
|
var that,
|
|
zoneDelta,
|
|
delta, output;
|
|
|
|
if (!this.isValid()) {
|
|
return NaN;
|
|
}
|
|
|
|
that = cloneWithOffset(input, this);
|
|
|
|
if (!that.isValid()) {
|
|
return NaN;
|
|
}
|
|
|
|
zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
|
|
|
|
units = normalizeUnits(units);
|
|
|
|
if (units === 'year' || units === 'month' || units === 'quarter') {
|
|
output = monthDiff(this, that);
|
|
if (units === 'quarter') {
|
|
output = output / 3;
|
|
} else if (units === 'year') {
|
|
output = output / 12;
|
|
}
|
|
} else {
|
|
delta = this - that;
|
|
output = units === 'second' ? delta / 1e3 : // 1000
|
|
units === 'minute' ? delta / 6e4 : // 1000 * 60
|
|
units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
|
|
units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
|
|
units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
|
|
delta;
|
|
}
|
|
return asFloat ? output : absFloor(output);
|
|
}
|
|
|
|
function monthDiff (a, b) {
|
|
// difference in months
|
|
var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
|
|
// b is in (anchor - 1 month, anchor + 1 month)
|
|
anchor = a.clone().add(wholeMonthDiff, 'months'),
|
|
anchor2, adjust;
|
|
|
|
if (b - anchor < 0) {
|
|
anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
|
|
// linear across the month
|
|
adjust = (b - anchor) / (anchor - anchor2);
|
|
} else {
|
|
anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
|
|
// linear across the month
|
|
adjust = (b - anchor) / (anchor2 - anchor);
|
|
}
|
|
|
|
//check for negative zero, return zero if negative zero
|
|
return -(wholeMonthDiff + adjust) || 0;
|
|
}
|
|
|
|
hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
|
|
|
|
function toString () {
|
|
return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
|
|
}
|
|
|
|
function toISOString() {
|
|
if (!this.isValid()) {
|
|
return null;
|
|
}
|
|
var m = this.clone().utc();
|
|
if (m.year() < 0 || m.year() > 9999) {
|
|
return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
|
|
}
|
|
if (isFunction(Date.prototype.toISOString)) {
|
|
// native implementation is ~50x faster, use it when we can
|
|
return this.toDate().toISOString();
|
|
}
|
|
return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
|
|
}
|
|
|
|
/**
|
|
* Return a human readable representation of a moment that can
|
|
* also be evaluated to get a new moment which is the same
|
|
*
|
|
* @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
|
|
*/
|
|
function inspect () {
|
|
if (!this.isValid()) {
|
|
return 'moment.invalid(/* ' + this._i + ' */)';
|
|
}
|
|
var func = 'moment';
|
|
var zone = '';
|
|
if (!this.isLocal()) {
|
|
func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
|
|
zone = 'Z';
|
|
}
|
|
var prefix = '[' + func + '("]';
|
|
var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
|
|
var datetime = '-MM-DD[T]HH:mm:ss.SSS';
|
|
var suffix = zone + '[")]';
|
|
|
|
return this.format(prefix + year + datetime + suffix);
|
|
}
|
|
|
|
function format (inputString) {
|
|
if (!inputString) {
|
|
inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
|
|
}
|
|
var output = formatMoment(this, inputString);
|
|
return this.localeData().postformat(output);
|
|
}
|
|
|
|
function from (time, withoutSuffix) {
|
|
if (this.isValid() &&
|
|
((isMoment(time) && time.isValid()) ||
|
|
createLocal(time).isValid())) {
|
|
return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
|
|
} else {
|
|
return this.localeData().invalidDate();
|
|
}
|
|
}
|
|
|
|
function fromNow (withoutSuffix) {
|
|
return this.from(createLocal(), withoutSuffix);
|
|
}
|
|
|
|
function to (time, withoutSuffix) {
|
|
if (this.isValid() &&
|
|
((isMoment(time) && time.isValid()) ||
|
|
createLocal(time).isValid())) {
|
|
return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
|
|
} else {
|
|
return this.localeData().invalidDate();
|
|
}
|
|
}
|
|
|
|
function toNow (withoutSuffix) {
|
|
return this.to(createLocal(), withoutSuffix);
|
|
}
|
|
|
|
// If passed a locale key, it will set the locale for this
|
|
// instance. Otherwise, it will return the locale configuration
|
|
// variables for this instance.
|
|
function locale (key) {
|
|
var newLocaleData;
|
|
|
|
if (key === undefined) {
|
|
return this._locale._abbr;
|
|
} else {
|
|
newLocaleData = getLocale(key);
|
|
if (newLocaleData != null) {
|
|
this._locale = newLocaleData;
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
|
|
var lang = deprecate(
|
|
'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
|
|
function (key) {
|
|
if (key === undefined) {
|
|
return this.localeData();
|
|
} else {
|
|
return this.locale(key);
|
|
}
|
|
}
|
|
);
|
|
|
|
function localeData () {
|
|
return this._locale;
|
|
}
|
|
|
|
function startOf (units) {
|
|
units = normalizeUnits(units);
|
|
// the following switch intentionally omits break keywords
|
|
// to utilize falling through the cases.
|
|
switch (units) {
|
|
case 'year':
|
|
this.month(0);
|
|
/* falls through */
|
|
case 'quarter':
|
|
case 'month':
|
|
this.date(1);
|
|
/* falls through */
|
|
case 'week':
|
|
case 'isoWeek':
|
|
case 'day':
|
|
case 'date':
|
|
this.hours(0);
|
|
/* falls through */
|
|
case 'hour':
|
|
this.minutes(0);
|
|
/* falls through */
|
|
case 'minute':
|
|
this.seconds(0);
|
|
/* falls through */
|
|
case 'second':
|
|
this.milliseconds(0);
|
|
}
|
|
|
|
// weeks are a special case
|
|
if (units === 'week') {
|
|
this.weekday(0);
|
|
}
|
|
if (units === 'isoWeek') {
|
|
this.isoWeekday(1);
|
|
}
|
|
|
|
// quarters are also special
|
|
if (units === 'quarter') {
|
|
this.month(Math.floor(this.month() / 3) * 3);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
function endOf (units) {
|
|
units = normalizeUnits(units);
|
|
if (units === undefined || units === 'millisecond') {
|
|
return this;
|
|
}
|
|
|
|
// 'date' is an alias for 'day', so it should be considered as such.
|
|
if (units === 'date') {
|
|
units = 'day';
|
|
}
|
|
|
|
return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
|
|
}
|
|
|
|
function valueOf () {
|
|
return this._d.valueOf() - ((this._offset || 0) * 60000);
|
|
}
|
|
|
|
function unix () {
|
|
return Math.floor(this.valueOf() / 1000);
|
|
}
|
|
|
|
function toDate () {
|
|
return new Date(this.valueOf());
|
|
}
|
|
|
|
function toArray () {
|
|
var m = this;
|
|
return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
|
|
}
|
|
|
|
function toObject () {
|
|
var m = this;
|
|
return {
|
|
years: m.year(),
|
|
months: m.month(),
|
|
date: m.date(),
|
|
hours: m.hours(),
|
|
minutes: m.minutes(),
|
|
seconds: m.seconds(),
|
|
milliseconds: m.milliseconds()
|
|
};
|
|
}
|
|
|
|
function toJSON () {
|
|
// new Date(NaN).toJSON() === null
|
|
return this.isValid() ? this.toISOString() : null;
|
|
}
|
|
|
|
function isValid$2 () {
|
|
return isValid(this);
|
|
}
|
|
|
|
function parsingFlags () {
|
|
return extend({}, getParsingFlags(this));
|
|
}
|
|
|
|
function invalidAt () {
|
|
return getParsingFlags(this).overflow;
|
|
}
|
|
|
|
function creationData() {
|
|
return {
|
|
input: this._i,
|
|
format: this._f,
|
|
locale: this._locale,
|
|
isUTC: this._isUTC,
|
|
strict: this._strict
|
|
};
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken(0, ['gg', 2], 0, function () {
|
|
return this.weekYear() % 100;
|
|
});
|
|
|
|
addFormatToken(0, ['GG', 2], 0, function () {
|
|
return this.isoWeekYear() % 100;
|
|
});
|
|
|
|
function addWeekYearFormatToken (token, getter) {
|
|
addFormatToken(0, [token, token.length], 0, getter);
|
|
}
|
|
|
|
addWeekYearFormatToken('gggg', 'weekYear');
|
|
addWeekYearFormatToken('ggggg', 'weekYear');
|
|
addWeekYearFormatToken('GGGG', 'isoWeekYear');
|
|
addWeekYearFormatToken('GGGGG', 'isoWeekYear');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('weekYear', 'gg');
|
|
addUnitAlias('isoWeekYear', 'GG');
|
|
|
|
// PRIORITY
|
|
|
|
addUnitPriority('weekYear', 1);
|
|
addUnitPriority('isoWeekYear', 1);
|
|
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('G', matchSigned);
|
|
addRegexToken('g', matchSigned);
|
|
addRegexToken('GG', match1to2, match2);
|
|
addRegexToken('gg', match1to2, match2);
|
|
addRegexToken('GGGG', match1to4, match4);
|
|
addRegexToken('gggg', match1to4, match4);
|
|
addRegexToken('GGGGG', match1to6, match6);
|
|
addRegexToken('ggggg', match1to6, match6);
|
|
|
|
addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
|
|
week[token.substr(0, 2)] = toInt(input);
|
|
});
|
|
|
|
addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
|
|
week[token] = hooks.parseTwoDigitYear(input);
|
|
});
|
|
|
|
// MOMENTS
|
|
|
|
function getSetWeekYear (input) {
|
|
return getSetWeekYearHelper.call(this,
|
|
input,
|
|
this.week(),
|
|
this.weekday(),
|
|
this.localeData()._week.dow,
|
|
this.localeData()._week.doy);
|
|
}
|
|
|
|
function getSetISOWeekYear (input) {
|
|
return getSetWeekYearHelper.call(this,
|
|
input, this.isoWeek(), this.isoWeekday(), 1, 4);
|
|
}
|
|
|
|
function getISOWeeksInYear () {
|
|
return weeksInYear(this.year(), 1, 4);
|
|
}
|
|
|
|
function getWeeksInYear () {
|
|
var weekInfo = this.localeData()._week;
|
|
return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
|
|
}
|
|
|
|
function getSetWeekYearHelper(input, week, weekday, dow, doy) {
|
|
var weeksTarget;
|
|
if (input == null) {
|
|
return weekOfYear(this, dow, doy).year;
|
|
} else {
|
|
weeksTarget = weeksInYear(input, dow, doy);
|
|
if (week > weeksTarget) {
|
|
week = weeksTarget;
|
|
}
|
|
return setWeekAll.call(this, input, week, weekday, dow, doy);
|
|
}
|
|
}
|
|
|
|
function setWeekAll(weekYear, week, weekday, dow, doy) {
|
|
var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
|
|
date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
|
|
|
|
this.year(date.getUTCFullYear());
|
|
this.month(date.getUTCMonth());
|
|
this.date(date.getUTCDate());
|
|
return this;
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('Q', 0, 'Qo', 'quarter');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('quarter', 'Q');
|
|
|
|
// PRIORITY
|
|
|
|
addUnitPriority('quarter', 7);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('Q', match1);
|
|
addParseToken('Q', function (input, array) {
|
|
array[MONTH] = (toInt(input) - 1) * 3;
|
|
});
|
|
|
|
// MOMENTS
|
|
|
|
function getSetQuarter (input) {
|
|
return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('D', ['DD', 2], 'Do', 'date');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('date', 'D');
|
|
|
|
// PRIOROITY
|
|
addUnitPriority('date', 9);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('D', match1to2);
|
|
addRegexToken('DD', match1to2, match2);
|
|
addRegexToken('Do', function (isStrict, locale) {
|
|
// TODO: Remove "ordinalParse" fallback in next major release.
|
|
return isStrict ?
|
|
(locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
|
|
locale._dayOfMonthOrdinalParseLenient;
|
|
});
|
|
|
|
addParseToken(['D', 'DD'], DATE);
|
|
addParseToken('Do', function (input, array) {
|
|
array[DATE] = toInt(input.match(match1to2)[0], 10);
|
|
});
|
|
|
|
// MOMENTS
|
|
|
|
var getSetDayOfMonth = makeGetSet('Date', true);
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('dayOfYear', 'DDD');
|
|
|
|
// PRIORITY
|
|
addUnitPriority('dayOfYear', 4);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('DDD', match1to3);
|
|
addRegexToken('DDDD', match3);
|
|
addParseToken(['DDD', 'DDDD'], function (input, array, config) {
|
|
config._dayOfYear = toInt(input);
|
|
});
|
|
|
|
// HELPERS
|
|
|
|
// MOMENTS
|
|
|
|
function getSetDayOfYear (input) {
|
|
var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
|
|
return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
|
|
}
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('m', ['mm', 2], 0, 'minute');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('minute', 'm');
|
|
|
|
// PRIORITY
|
|
|
|
addUnitPriority('minute', 14);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('m', match1to2);
|
|
addRegexToken('mm', match1to2, match2);
|
|
addParseToken(['m', 'mm'], MINUTE);
|
|
|
|
// MOMENTS
|
|
|
|
var getSetMinute = makeGetSet('Minutes', false);
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('s', ['ss', 2], 0, 'second');
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('second', 's');
|
|
|
|
// PRIORITY
|
|
|
|
addUnitPriority('second', 15);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('s', match1to2);
|
|
addRegexToken('ss', match1to2, match2);
|
|
addParseToken(['s', 'ss'], SECOND);
|
|
|
|
// MOMENTS
|
|
|
|
var getSetSecond = makeGetSet('Seconds', false);
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('S', 0, 0, function () {
|
|
return ~~(this.millisecond() / 100);
|
|
});
|
|
|
|
addFormatToken(0, ['SS', 2], 0, function () {
|
|
return ~~(this.millisecond() / 10);
|
|
});
|
|
|
|
addFormatToken(0, ['SSS', 3], 0, 'millisecond');
|
|
addFormatToken(0, ['SSSS', 4], 0, function () {
|
|
return this.millisecond() * 10;
|
|
});
|
|
addFormatToken(0, ['SSSSS', 5], 0, function () {
|
|
return this.millisecond() * 100;
|
|
});
|
|
addFormatToken(0, ['SSSSSS', 6], 0, function () {
|
|
return this.millisecond() * 1000;
|
|
});
|
|
addFormatToken(0, ['SSSSSSS', 7], 0, function () {
|
|
return this.millisecond() * 10000;
|
|
});
|
|
addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
|
|
return this.millisecond() * 100000;
|
|
});
|
|
addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
|
|
return this.millisecond() * 1000000;
|
|
});
|
|
|
|
|
|
// ALIASES
|
|
|
|
addUnitAlias('millisecond', 'ms');
|
|
|
|
// PRIORITY
|
|
|
|
addUnitPriority('millisecond', 16);
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('S', match1to3, match1);
|
|
addRegexToken('SS', match1to3, match2);
|
|
addRegexToken('SSS', match1to3, match3);
|
|
|
|
var token;
|
|
for (token = 'SSSS'; token.length <= 9; token += 'S') {
|
|
addRegexToken(token, matchUnsigned);
|
|
}
|
|
|
|
function parseMs(input, array) {
|
|
array[MILLISECOND] = toInt(('0.' + input) * 1000);
|
|
}
|
|
|
|
for (token = 'S'; token.length <= 9; token += 'S') {
|
|
addParseToken(token, parseMs);
|
|
}
|
|
// MOMENTS
|
|
|
|
var getSetMillisecond = makeGetSet('Milliseconds', false);
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('z', 0, 0, 'zoneAbbr');
|
|
addFormatToken('zz', 0, 0, 'zoneName');
|
|
|
|
// MOMENTS
|
|
|
|
function getZoneAbbr () {
|
|
return this._isUTC ? 'UTC' : '';
|
|
}
|
|
|
|
function getZoneName () {
|
|
return this._isUTC ? 'Coordinated Universal Time' : '';
|
|
}
|
|
|
|
var proto = Moment.prototype;
|
|
|
|
proto.add = add;
|
|
proto.calendar = calendar$1;
|
|
proto.clone = clone;
|
|
proto.diff = diff;
|
|
proto.endOf = endOf;
|
|
proto.format = format;
|
|
proto.from = from;
|
|
proto.fromNow = fromNow;
|
|
proto.to = to;
|
|
proto.toNow = toNow;
|
|
proto.get = stringGet;
|
|
proto.invalidAt = invalidAt;
|
|
proto.isAfter = isAfter;
|
|
proto.isBefore = isBefore;
|
|
proto.isBetween = isBetween;
|
|
proto.isSame = isSame;
|
|
proto.isSameOrAfter = isSameOrAfter;
|
|
proto.isSameOrBefore = isSameOrBefore;
|
|
proto.isValid = isValid$2;
|
|
proto.lang = lang;
|
|
proto.locale = locale;
|
|
proto.localeData = localeData;
|
|
proto.max = prototypeMax;
|
|
proto.min = prototypeMin;
|
|
proto.parsingFlags = parsingFlags;
|
|
proto.set = stringSet;
|
|
proto.startOf = startOf;
|
|
proto.subtract = subtract;
|
|
proto.toArray = toArray;
|
|
proto.toObject = toObject;
|
|
proto.toDate = toDate;
|
|
proto.toISOString = toISOString;
|
|
proto.inspect = inspect;
|
|
proto.toJSON = toJSON;
|
|
proto.toString = toString;
|
|
proto.unix = unix;
|
|
proto.valueOf = valueOf;
|
|
proto.creationData = creationData;
|
|
|
|
// Year
|
|
proto.year = getSetYear;
|
|
proto.isLeapYear = getIsLeapYear;
|
|
|
|
// Week Year
|
|
proto.weekYear = getSetWeekYear;
|
|
proto.isoWeekYear = getSetISOWeekYear;
|
|
|
|
// Quarter
|
|
proto.quarter = proto.quarters = getSetQuarter;
|
|
|
|
// Month
|
|
proto.month = getSetMonth;
|
|
proto.daysInMonth = getDaysInMonth;
|
|
|
|
// Week
|
|
proto.week = proto.weeks = getSetWeek;
|
|
proto.isoWeek = proto.isoWeeks = getSetISOWeek;
|
|
proto.weeksInYear = getWeeksInYear;
|
|
proto.isoWeeksInYear = getISOWeeksInYear;
|
|
|
|
// Day
|
|
proto.date = getSetDayOfMonth;
|
|
proto.day = proto.days = getSetDayOfWeek;
|
|
proto.weekday = getSetLocaleDayOfWeek;
|
|
proto.isoWeekday = getSetISODayOfWeek;
|
|
proto.dayOfYear = getSetDayOfYear;
|
|
|
|
// Hour
|
|
proto.hour = proto.hours = getSetHour;
|
|
|
|
// Minute
|
|
proto.minute = proto.minutes = getSetMinute;
|
|
|
|
// Second
|
|
proto.second = proto.seconds = getSetSecond;
|
|
|
|
// Millisecond
|
|
proto.millisecond = proto.milliseconds = getSetMillisecond;
|
|
|
|
// Offset
|
|
proto.utcOffset = getSetOffset;
|
|
proto.utc = setOffsetToUTC;
|
|
proto.local = setOffsetToLocal;
|
|
proto.parseZone = setOffsetToParsedOffset;
|
|
proto.hasAlignedHourOffset = hasAlignedHourOffset;
|
|
proto.isDST = isDaylightSavingTime;
|
|
proto.isLocal = isLocal;
|
|
proto.isUtcOffset = isUtcOffset;
|
|
proto.isUtc = isUtc;
|
|
proto.isUTC = isUtc;
|
|
|
|
// Timezone
|
|
proto.zoneAbbr = getZoneAbbr;
|
|
proto.zoneName = getZoneName;
|
|
|
|
// Deprecations
|
|
proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
|
|
proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
|
|
proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
|
|
proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
|
|
proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
|
|
|
|
function createUnix (input) {
|
|
return createLocal(input * 1000);
|
|
}
|
|
|
|
function createInZone () {
|
|
return createLocal.apply(null, arguments).parseZone();
|
|
}
|
|
|
|
function preParsePostFormat (string) {
|
|
return string;
|
|
}
|
|
|
|
var proto$1 = Locale.prototype;
|
|
|
|
proto$1.calendar = calendar;
|
|
proto$1.longDateFormat = longDateFormat;
|
|
proto$1.invalidDate = invalidDate;
|
|
proto$1.ordinal = ordinal;
|
|
proto$1.preparse = preParsePostFormat;
|
|
proto$1.postformat = preParsePostFormat;
|
|
proto$1.relativeTime = relativeTime;
|
|
proto$1.pastFuture = pastFuture;
|
|
proto$1.set = set;
|
|
|
|
// Month
|
|
proto$1.months = localeMonths;
|
|
proto$1.monthsShort = localeMonthsShort;
|
|
proto$1.monthsParse = localeMonthsParse;
|
|
proto$1.monthsRegex = monthsRegex;
|
|
proto$1.monthsShortRegex = monthsShortRegex;
|
|
|
|
// Week
|
|
proto$1.week = localeWeek;
|
|
proto$1.firstDayOfYear = localeFirstDayOfYear;
|
|
proto$1.firstDayOfWeek = localeFirstDayOfWeek;
|
|
|
|
// Day of Week
|
|
proto$1.weekdays = localeWeekdays;
|
|
proto$1.weekdaysMin = localeWeekdaysMin;
|
|
proto$1.weekdaysShort = localeWeekdaysShort;
|
|
proto$1.weekdaysParse = localeWeekdaysParse;
|
|
|
|
proto$1.weekdaysRegex = weekdaysRegex;
|
|
proto$1.weekdaysShortRegex = weekdaysShortRegex;
|
|
proto$1.weekdaysMinRegex = weekdaysMinRegex;
|
|
|
|
// Hours
|
|
proto$1.isPM = localeIsPM;
|
|
proto$1.meridiem = localeMeridiem;
|
|
|
|
function get$1 (format, index, field, setter) {
|
|
var locale = getLocale();
|
|
var utc = createUTC().set(setter, index);
|
|
return locale[field](utc, format);
|
|
}
|
|
|
|
function listMonthsImpl (format, index, field) {
|
|
if (isNumber(format)) {
|
|
index = format;
|
|
format = undefined;
|
|
}
|
|
|
|
format = format || '';
|
|
|
|
if (index != null) {
|
|
return get$1(format, index, field, 'month');
|
|
}
|
|
|
|
var i;
|
|
var out = [];
|
|
for (i = 0; i < 12; i++) {
|
|
out[i] = get$1(format, i, field, 'month');
|
|
}
|
|
return out;
|
|
}
|
|
|
|
// ()
|
|
// (5)
|
|
// (fmt, 5)
|
|
// (fmt)
|
|
// (true)
|
|
// (true, 5)
|
|
// (true, fmt, 5)
|
|
// (true, fmt)
|
|
function listWeekdaysImpl (localeSorted, format, index, field) {
|
|
if (typeof localeSorted === 'boolean') {
|
|
if (isNumber(format)) {
|
|
index = format;
|
|
format = undefined;
|
|
}
|
|
|
|
format = format || '';
|
|
} else {
|
|
format = localeSorted;
|
|
index = format;
|
|
localeSorted = false;
|
|
|
|
if (isNumber(format)) {
|
|
index = format;
|
|
format = undefined;
|
|
}
|
|
|
|
format = format || '';
|
|
}
|
|
|
|
var locale = getLocale(),
|
|
shift = localeSorted ? locale._week.dow : 0;
|
|
|
|
if (index != null) {
|
|
return get$1(format, (index + shift) % 7, field, 'day');
|
|
}
|
|
|
|
var i;
|
|
var out = [];
|
|
for (i = 0; i < 7; i++) {
|
|
out[i] = get$1(format, (i + shift) % 7, field, 'day');
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function listMonths (format, index) {
|
|
return listMonthsImpl(format, index, 'months');
|
|
}
|
|
|
|
function listMonthsShort (format, index) {
|
|
return listMonthsImpl(format, index, 'monthsShort');
|
|
}
|
|
|
|
function listWeekdays (localeSorted, format, index) {
|
|
return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
|
|
}
|
|
|
|
function listWeekdaysShort (localeSorted, format, index) {
|
|
return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
|
|
}
|
|
|
|
function listWeekdaysMin (localeSorted, format, index) {
|
|
return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
|
|
}
|
|
|
|
getSetGlobalLocale('en', {
|
|
dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
|
|
ordinal : function (number) {
|
|
var b = number % 10,
|
|
output = (toInt(number % 100 / 10) === 1) ? 'th' :
|
|
(b === 1) ? 'st' :
|
|
(b === 2) ? 'nd' :
|
|
(b === 3) ? 'rd' : 'th';
|
|
return number + output;
|
|
}
|
|
});
|
|
|
|
// Side effect imports
|
|
hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
|
|
hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
|
|
|
|
var mathAbs = Math.abs;
|
|
|
|
function abs () {
|
|
var data = this._data;
|
|
|
|
this._milliseconds = mathAbs(this._milliseconds);
|
|
this._days = mathAbs(this._days);
|
|
this._months = mathAbs(this._months);
|
|
|
|
data.milliseconds = mathAbs(data.milliseconds);
|
|
data.seconds = mathAbs(data.seconds);
|
|
data.minutes = mathAbs(data.minutes);
|
|
data.hours = mathAbs(data.hours);
|
|
data.months = mathAbs(data.months);
|
|
data.years = mathAbs(data.years);
|
|
|
|
return this;
|
|
}
|
|
|
|
function addSubtract$1 (duration, input, value, direction) {
|
|
var other = createDuration(input, value);
|
|
|
|
duration._milliseconds += direction * other._milliseconds;
|
|
duration._days += direction * other._days;
|
|
duration._months += direction * other._months;
|
|
|
|
return duration._bubble();
|
|
}
|
|
|
|
// supports only 2.0-style add(1, 's') or add(duration)
|
|
function add$1 (input, value) {
|
|
return addSubtract$1(this, input, value, 1);
|
|
}
|
|
|
|
// supports only 2.0-style subtract(1, 's') or subtract(duration)
|
|
function subtract$1 (input, value) {
|
|
return addSubtract$1(this, input, value, -1);
|
|
}
|
|
|
|
function absCeil (number) {
|
|
if (number < 0) {
|
|
return Math.floor(number);
|
|
} else {
|
|
return Math.ceil(number);
|
|
}
|
|
}
|
|
|
|
function bubble () {
|
|
var milliseconds = this._milliseconds;
|
|
var days = this._days;
|
|
var months = this._months;
|
|
var data = this._data;
|
|
var seconds, minutes, hours, years, monthsFromDays;
|
|
|
|
// if we have a mix of positive and negative values, bubble down first
|
|
// check: https://github.com/moment/moment/issues/2166
|
|
if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
|
|
(milliseconds <= 0 && days <= 0 && months <= 0))) {
|
|
milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
|
|
days = 0;
|
|
months = 0;
|
|
}
|
|
|
|
// The following code bubbles up values, see the tests for
|
|
// examples of what that means.
|
|
data.milliseconds = milliseconds % 1000;
|
|
|
|
seconds = absFloor(milliseconds / 1000);
|
|
data.seconds = seconds % 60;
|
|
|
|
minutes = absFloor(seconds / 60);
|
|
data.minutes = minutes % 60;
|
|
|
|
hours = absFloor(minutes / 60);
|
|
data.hours = hours % 24;
|
|
|
|
days += absFloor(hours / 24);
|
|
|
|
// convert days to months
|
|
monthsFromDays = absFloor(daysToMonths(days));
|
|
months += monthsFromDays;
|
|
days -= absCeil(monthsToDays(monthsFromDays));
|
|
|
|
// 12 months -> 1 year
|
|
years = absFloor(months / 12);
|
|
months %= 12;
|
|
|
|
data.days = days;
|
|
data.months = months;
|
|
data.years = years;
|
|
|
|
return this;
|
|
}
|
|
|
|
function daysToMonths (days) {
|
|
// 400 years have 146097 days (taking into account leap year rules)
|
|
// 400 years have 12 months === 4800
|
|
return days * 4800 / 146097;
|
|
}
|
|
|
|
function monthsToDays (months) {
|
|
// the reverse of daysToMonths
|
|
return months * 146097 / 4800;
|
|
}
|
|
|
|
function as (units) {
|
|
if (!this.isValid()) {
|
|
return NaN;
|
|
}
|
|
var days;
|
|
var months;
|
|
var milliseconds = this._milliseconds;
|
|
|
|
units = normalizeUnits(units);
|
|
|
|
if (units === 'month' || units === 'year') {
|
|
days = this._days + milliseconds / 864e5;
|
|
months = this._months + daysToMonths(days);
|
|
return units === 'month' ? months : months / 12;
|
|
} else {
|
|
// handle milliseconds separately because of floating point math errors (issue #1867)
|
|
days = this._days + Math.round(monthsToDays(this._months));
|
|
switch (units) {
|
|
case 'week' : return days / 7 + milliseconds / 6048e5;
|
|
case 'day' : return days + milliseconds / 864e5;
|
|
case 'hour' : return days * 24 + milliseconds / 36e5;
|
|
case 'minute' : return days * 1440 + milliseconds / 6e4;
|
|
case 'second' : return days * 86400 + milliseconds / 1000;
|
|
// Math.floor prevents floating point math errors here
|
|
case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
|
|
default: throw new Error('Unknown unit ' + units);
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: Use this.as('ms')?
|
|
function valueOf$1 () {
|
|
if (!this.isValid()) {
|
|
return NaN;
|
|
}
|
|
return (
|
|
this._milliseconds +
|
|
this._days * 864e5 +
|
|
(this._months % 12) * 2592e6 +
|
|
toInt(this._months / 12) * 31536e6
|
|
);
|
|
}
|
|
|
|
function makeAs (alias) {
|
|
return function () {
|
|
return this.as(alias);
|
|
};
|
|
}
|
|
|
|
var asMilliseconds = makeAs('ms');
|
|
var asSeconds = makeAs('s');
|
|
var asMinutes = makeAs('m');
|
|
var asHours = makeAs('h');
|
|
var asDays = makeAs('d');
|
|
var asWeeks = makeAs('w');
|
|
var asMonths = makeAs('M');
|
|
var asYears = makeAs('y');
|
|
|
|
function get$2 (units) {
|
|
units = normalizeUnits(units);
|
|
return this.isValid() ? this[units + 's']() : NaN;
|
|
}
|
|
|
|
function makeGetter(name) {
|
|
return function () {
|
|
return this.isValid() ? this._data[name] : NaN;
|
|
};
|
|
}
|
|
|
|
var milliseconds = makeGetter('milliseconds');
|
|
var seconds = makeGetter('seconds');
|
|
var minutes = makeGetter('minutes');
|
|
var hours = makeGetter('hours');
|
|
var days = makeGetter('days');
|
|
var months = makeGetter('months');
|
|
var years = makeGetter('years');
|
|
|
|
function weeks () {
|
|
return absFloor(this.days() / 7);
|
|
}
|
|
|
|
var round = Math.round;
|
|
var thresholds = {
|
|
ss: 44, // a few seconds to seconds
|
|
s : 45, // seconds to minute
|
|
m : 45, // minutes to hour
|
|
h : 22, // hours to day
|
|
d : 26, // days to month
|
|
M : 11 // months to year
|
|
};
|
|
|
|
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
|
|
function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
|
|
return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
|
|
}
|
|
|
|
function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
|
|
var duration = createDuration(posNegDuration).abs();
|
|
var seconds = round(duration.as('s'));
|
|
var minutes = round(duration.as('m'));
|
|
var hours = round(duration.as('h'));
|
|
var days = round(duration.as('d'));
|
|
var months = round(duration.as('M'));
|
|
var years = round(duration.as('y'));
|
|
|
|
var a = seconds <= thresholds.ss && ['s', seconds] ||
|
|
seconds < thresholds.s && ['ss', seconds] ||
|
|
minutes <= 1 && ['m'] ||
|
|
minutes < thresholds.m && ['mm', minutes] ||
|
|
hours <= 1 && ['h'] ||
|
|
hours < thresholds.h && ['hh', hours] ||
|
|
days <= 1 && ['d'] ||
|
|
days < thresholds.d && ['dd', days] ||
|
|
months <= 1 && ['M'] ||
|
|
months < thresholds.M && ['MM', months] ||
|
|
years <= 1 && ['y'] || ['yy', years];
|
|
|
|
a[2] = withoutSuffix;
|
|
a[3] = +posNegDuration > 0;
|
|
a[4] = locale;
|
|
return substituteTimeAgo.apply(null, a);
|
|
}
|
|
|
|
// This function allows you to set the rounding function for relative time strings
|
|
function getSetRelativeTimeRounding (roundingFunction) {
|
|
if (roundingFunction === undefined) {
|
|
return round;
|
|
}
|
|
if (typeof(roundingFunction) === 'function') {
|
|
round = roundingFunction;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// This function allows you to set a threshold for relative time strings
|
|
function getSetRelativeTimeThreshold (threshold, limit) {
|
|
if (thresholds[threshold] === undefined) {
|
|
return false;
|
|
}
|
|
if (limit === undefined) {
|
|
return thresholds[threshold];
|
|
}
|
|
thresholds[threshold] = limit;
|
|
if (threshold === 's') {
|
|
thresholds.ss = limit - 1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function humanize (withSuffix) {
|
|
if (!this.isValid()) {
|
|
return this.localeData().invalidDate();
|
|
}
|
|
|
|
var locale = this.localeData();
|
|
var output = relativeTime$1(this, !withSuffix, locale);
|
|
|
|
if (withSuffix) {
|
|
output = locale.pastFuture(+this, output);
|
|
}
|
|
|
|
return locale.postformat(output);
|
|
}
|
|
|
|
var abs$1 = Math.abs;
|
|
|
|
function toISOString$1() {
|
|
// for ISO strings we do not use the normal bubbling rules:
|
|
// * milliseconds bubble up until they become hours
|
|
// * days do not bubble at all
|
|
// * months bubble up until they become years
|
|
// This is because there is no context-free conversion between hours and days
|
|
// (think of clock changes)
|
|
// and also not between days and months (28-31 days per month)
|
|
if (!this.isValid()) {
|
|
return this.localeData().invalidDate();
|
|
}
|
|
|
|
var seconds = abs$1(this._milliseconds) / 1000;
|
|
var days = abs$1(this._days);
|
|
var months = abs$1(this._months);
|
|
var minutes, hours, years;
|
|
|
|
// 3600 seconds -> 60 minutes -> 1 hour
|
|
minutes = absFloor(seconds / 60);
|
|
hours = absFloor(minutes / 60);
|
|
seconds %= 60;
|
|
minutes %= 60;
|
|
|
|
// 12 months -> 1 year
|
|
years = absFloor(months / 12);
|
|
months %= 12;
|
|
|
|
|
|
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
|
|
var Y = years;
|
|
var M = months;
|
|
var D = days;
|
|
var h = hours;
|
|
var m = minutes;
|
|
var s = seconds;
|
|
var total = this.asSeconds();
|
|
|
|
if (!total) {
|
|
// this is the same as C#'s (Noda) and python (isodate)...
|
|
// but not other JS (goog.date)
|
|
return 'P0D';
|
|
}
|
|
|
|
return (total < 0 ? '-' : '') +
|
|
'P' +
|
|
(Y ? Y + 'Y' : '') +
|
|
(M ? M + 'M' : '') +
|
|
(D ? D + 'D' : '') +
|
|
((h || m || s) ? 'T' : '') +
|
|
(h ? h + 'H' : '') +
|
|
(m ? m + 'M' : '') +
|
|
(s ? s + 'S' : '');
|
|
}
|
|
|
|
var proto$2 = Duration.prototype;
|
|
|
|
proto$2.isValid = isValid$1;
|
|
proto$2.abs = abs;
|
|
proto$2.add = add$1;
|
|
proto$2.subtract = subtract$1;
|
|
proto$2.as = as;
|
|
proto$2.asMilliseconds = asMilliseconds;
|
|
proto$2.asSeconds = asSeconds;
|
|
proto$2.asMinutes = asMinutes;
|
|
proto$2.asHours = asHours;
|
|
proto$2.asDays = asDays;
|
|
proto$2.asWeeks = asWeeks;
|
|
proto$2.asMonths = asMonths;
|
|
proto$2.asYears = asYears;
|
|
proto$2.valueOf = valueOf$1;
|
|
proto$2._bubble = bubble;
|
|
proto$2.get = get$2;
|
|
proto$2.milliseconds = milliseconds;
|
|
proto$2.seconds = seconds;
|
|
proto$2.minutes = minutes;
|
|
proto$2.hours = hours;
|
|
proto$2.days = days;
|
|
proto$2.weeks = weeks;
|
|
proto$2.months = months;
|
|
proto$2.years = years;
|
|
proto$2.humanize = humanize;
|
|
proto$2.toISOString = toISOString$1;
|
|
proto$2.toString = toISOString$1;
|
|
proto$2.toJSON = toISOString$1;
|
|
proto$2.locale = locale;
|
|
proto$2.localeData = localeData;
|
|
|
|
// Deprecations
|
|
proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
|
|
proto$2.lang = lang;
|
|
|
|
// Side effect imports
|
|
|
|
// FORMATTING
|
|
|
|
addFormatToken('X', 0, 0, 'unix');
|
|
addFormatToken('x', 0, 0, 'valueOf');
|
|
|
|
// PARSING
|
|
|
|
addRegexToken('x', matchSigned);
|
|
addRegexToken('X', matchTimestamp);
|
|
addParseToken('X', function (input, array, config) {
|
|
config._d = new Date(parseFloat(input, 10) * 1000);
|
|
});
|
|
addParseToken('x', function (input, array, config) {
|
|
config._d = new Date(toInt(input));
|
|
});
|
|
|
|
// Side effect imports
|
|
|
|
|
|
hooks.version = '2.18.1';
|
|
|
|
setHookCallback(createLocal);
|
|
|
|
hooks.fn = proto;
|
|
hooks.min = min;
|
|
hooks.max = max;
|
|
hooks.now = now;
|
|
hooks.utc = createUTC;
|
|
hooks.unix = createUnix;
|
|
hooks.months = listMonths;
|
|
hooks.isDate = isDate;
|
|
hooks.locale = getSetGlobalLocale;
|
|
hooks.invalid = createInvalid;
|
|
hooks.duration = createDuration;
|
|
hooks.isMoment = isMoment;
|
|
hooks.weekdays = listWeekdays;
|
|
hooks.parseZone = createInZone;
|
|
hooks.localeData = getLocale;
|
|
hooks.isDuration = isDuration;
|
|
hooks.monthsShort = listMonthsShort;
|
|
hooks.weekdaysMin = listWeekdaysMin;
|
|
hooks.defineLocale = defineLocale;
|
|
hooks.updateLocale = updateLocale;
|
|
hooks.locales = listLocales;
|
|
hooks.weekdaysShort = listWeekdaysShort;
|
|
hooks.normalizeUnits = normalizeUnits;
|
|
hooks.relativeTimeRounding = getSetRelativeTimeRounding;
|
|
hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
|
|
hooks.calendarFormat = getCalendarFormat;
|
|
hooks.prototype = proto;
|
|
|
|
return hooks;
|
|
|
|
})));
|
|
|
|
|
|
/*** EXPORTS FROM exports-to-window-loader ***/
|
|
window['moment'] = __webpack_require__(36);
|
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(420)(module)))
|
|
|
|
/***/ }),
|
|
/* 37 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.EditorState = undefined;
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var EditorState = exports.EditorState = {
|
|
VIRGIN: 'STATE_VIRGIN', // before editing
|
|
EDITING: 'STATE_EDITING',
|
|
WAITING: 'STATE_WAITING', // waiting for async validation
|
|
FINISHED: 'STATE_FINISHED'
|
|
};
|
|
|
|
function BaseEditor(instance) {
|
|
this.instance = instance;
|
|
this.state = EditorState.VIRGIN;
|
|
|
|
this._opened = false;
|
|
this._fullEditMode = false;
|
|
this._closeCallback = null;
|
|
|
|
this.init();
|
|
}
|
|
|
|
BaseEditor.prototype._fireCallbacks = function (result) {
|
|
if (this._closeCallback) {
|
|
this._closeCallback(result);
|
|
this._closeCallback = null;
|
|
}
|
|
};
|
|
|
|
BaseEditor.prototype.init = function () {};
|
|
|
|
BaseEditor.prototype.getValue = function () {
|
|
throw Error('Editor getValue() method unimplemented');
|
|
};
|
|
|
|
BaseEditor.prototype.setValue = function (newValue) {
|
|
throw Error('Editor setValue() method unimplemented');
|
|
};
|
|
|
|
BaseEditor.prototype.open = function () {
|
|
throw Error('Editor open() method unimplemented');
|
|
};
|
|
|
|
BaseEditor.prototype.close = function () {
|
|
throw Error('Editor close() method unimplemented');
|
|
};
|
|
|
|
BaseEditor.prototype.prepare = function (row, col, prop, td, originalValue, cellProperties) {
|
|
this.TD = td;
|
|
this.row = row;
|
|
this.col = col;
|
|
this.prop = prop;
|
|
this.originalValue = originalValue;
|
|
this.cellProperties = cellProperties;
|
|
this.state = EditorState.VIRGIN;
|
|
};
|
|
|
|
BaseEditor.prototype.extend = function () {
|
|
var baseClass = this.constructor;
|
|
|
|
function Editor() {
|
|
baseClass.apply(this, arguments);
|
|
}
|
|
|
|
function inherit(Child, Parent) {
|
|
function Bridge() {}
|
|
Bridge.prototype = Parent.prototype;
|
|
Child.prototype = new Bridge();
|
|
Child.prototype.constructor = Child;
|
|
|
|
return Child;
|
|
}
|
|
|
|
return inherit(Editor, baseClass);
|
|
};
|
|
|
|
BaseEditor.prototype.saveValue = function (value, ctrlDown) {
|
|
var selection = void 0;
|
|
var tmp = void 0;
|
|
|
|
// if ctrl+enter and multiple cells selected, behave like Excel (finish editing and apply to all cells)
|
|
if (ctrlDown) {
|
|
selection = this.instance.getSelected();
|
|
|
|
if (selection[0] > selection[2]) {
|
|
tmp = selection[0];
|
|
selection[0] = selection[2];
|
|
selection[2] = tmp;
|
|
}
|
|
if (selection[1] > selection[3]) {
|
|
tmp = selection[1];
|
|
selection[1] = selection[3];
|
|
selection[3] = tmp;
|
|
}
|
|
} else {
|
|
selection = [this.row, this.col, null, null];
|
|
}
|
|
|
|
this.instance.populateFromArray(selection[0], selection[1], value, selection[2], selection[3], 'edit');
|
|
};
|
|
|
|
BaseEditor.prototype.beginEditing = function (initialValue, event) {
|
|
if (this.state != EditorState.VIRGIN) {
|
|
return;
|
|
}
|
|
this.instance.view.scrollViewport(new _src.CellCoords(this.row, this.col));
|
|
this.instance.view.render();
|
|
this.state = EditorState.EDITING;
|
|
|
|
initialValue = typeof initialValue == 'string' ? initialValue : this.originalValue;
|
|
this.setValue((0, _mixed.stringify)(initialValue));
|
|
|
|
this.open(event);
|
|
this._opened = true;
|
|
this.focus();
|
|
|
|
// only rerender the selections (FillHandle should disappear when beginediting is triggered)
|
|
this.instance.view.render();
|
|
|
|
this.instance.runHooks('afterBeginEditing', this.row, this.col);
|
|
};
|
|
|
|
BaseEditor.prototype.finishEditing = function (restoreOriginalValue, ctrlDown, callback) {
|
|
var _this = this,
|
|
val;
|
|
|
|
if (callback) {
|
|
var previousCloseCallback = this._closeCallback;
|
|
|
|
this._closeCallback = function (result) {
|
|
if (previousCloseCallback) {
|
|
previousCloseCallback(result);
|
|
}
|
|
|
|
callback(result);
|
|
_this.instance.view.render();
|
|
};
|
|
}
|
|
|
|
if (this.isWaiting()) {
|
|
return;
|
|
}
|
|
|
|
if (this.state == EditorState.VIRGIN) {
|
|
this.instance._registerTimeout(setTimeout(function () {
|
|
_this._fireCallbacks(true);
|
|
}, 0));
|
|
|
|
return;
|
|
}
|
|
|
|
if (this.state == EditorState.EDITING) {
|
|
if (restoreOriginalValue) {
|
|
this.cancelChanges();
|
|
this.instance.view.render();
|
|
|
|
return;
|
|
}
|
|
|
|
var value = this.getValue();
|
|
|
|
if (this.instance.getSettings().trimWhitespace) {
|
|
// We trim only string values
|
|
val = [[typeof value === 'string' ? String.prototype.trim.call(value || '') : value]];
|
|
} else {
|
|
val = [[value]];
|
|
}
|
|
|
|
this.state = EditorState.WAITING;
|
|
this.saveValue(val, ctrlDown);
|
|
|
|
if (this.instance.getCellValidator(this.cellProperties)) {
|
|
this.instance.addHookOnce('postAfterValidate', function (result) {
|
|
_this.state = EditorState.FINISHED;
|
|
_this.discardEditor(result);
|
|
});
|
|
} else {
|
|
this.state = EditorState.FINISHED;
|
|
this.discardEditor(true);
|
|
}
|
|
}
|
|
};
|
|
|
|
BaseEditor.prototype.cancelChanges = function () {
|
|
this.state = EditorState.FINISHED;
|
|
this.discardEditor();
|
|
};
|
|
|
|
BaseEditor.prototype.discardEditor = function (result) {
|
|
if (this.state !== EditorState.FINISHED) {
|
|
return;
|
|
}
|
|
// validator was defined and failed
|
|
if (result === false && this.cellProperties.allowInvalid !== true) {
|
|
this.instance.selectCell(this.row, this.col);
|
|
this.focus();
|
|
this.state = EditorState.EDITING;
|
|
this._fireCallbacks(false);
|
|
} else {
|
|
this.close();
|
|
this._opened = false;
|
|
this._fullEditMode = false;
|
|
this.state = EditorState.VIRGIN;
|
|
this._fireCallbacks(true);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Switch editor into full edit mode. In this state navigation keys don't close editor. This mode is activated
|
|
* automatically after hit ENTER or F2 key on the cell or while editing cell press F2 key.
|
|
*/
|
|
BaseEditor.prototype.enableFullEditMode = function () {
|
|
this._fullEditMode = true;
|
|
};
|
|
|
|
/**
|
|
* Checks if editor is in full edit mode.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
BaseEditor.prototype.isInFullEditMode = function () {
|
|
return this._fullEditMode;
|
|
};
|
|
|
|
BaseEditor.prototype.isOpened = function () {
|
|
return this._opened;
|
|
};
|
|
|
|
BaseEditor.prototype.isWaiting = function () {
|
|
return this.state === EditorState.WAITING;
|
|
};
|
|
|
|
BaseEditor.prototype.checkEditorSection = function () {
|
|
var totalRows = this.instance.countRows();
|
|
var section = '';
|
|
|
|
if (this.row < this.instance.getSettings().fixedRowsTop) {
|
|
if (this.col < this.instance.getSettings().fixedColumnsLeft) {
|
|
section = 'top-left-corner';
|
|
} else {
|
|
section = 'top';
|
|
}
|
|
} else if (this.instance.getSettings().fixedRowsBottom && this.row >= totalRows - this.instance.getSettings().fixedRowsBottom) {
|
|
if (this.col < this.instance.getSettings().fixedColumnsLeft) {
|
|
section = 'bottom-left-corner';
|
|
} else {
|
|
section = 'bottom';
|
|
}
|
|
} else if (this.col < this.instance.getSettings().fixedColumnsLeft) {
|
|
section = 'left';
|
|
}
|
|
|
|
return section;
|
|
};
|
|
|
|
exports.default = BaseEditor;
|
|
|
|
/***/ }),
|
|
/* 38 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 22.1.3.31 Array.prototype[@@unscopables]
|
|
var UNSCOPABLES = __webpack_require__(10)('unscopables')
|
|
, ArrayProto = Array.prototype;
|
|
if(ArrayProto[UNSCOPABLES] == undefined)__webpack_require__(32)(ArrayProto, UNSCOPABLES, {});
|
|
module.exports = function(key){
|
|
ArrayProto[UNSCOPABLES][key] = true;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 39 */
|
|
/***/ (function(module, exports) {
|
|
|
|
var toString = {}.toString;
|
|
|
|
module.exports = function(it){
|
|
return toString.call(it).slice(8, -1);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 40 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 19.1.2.14 / 15.2.3.14 Object.keys(O)
|
|
var $keys = __webpack_require__(284)
|
|
, enumBugKeys = __webpack_require__(76);
|
|
|
|
module.exports = Object.keys || function keys(O){
|
|
return $keys(O, enumBugKeys);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 41 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function(bitmap, value){
|
|
return {
|
|
enumerable : !(bitmap & 1),
|
|
configurable: !(bitmap & 2),
|
|
writable : !(bitmap & 4),
|
|
value : value
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 42 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 7.1.13 ToObject(argument)
|
|
var defined = __webpack_require__(30);
|
|
module.exports = function(it){
|
|
return Object(defined(it));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 43 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* CellCoords holds cell coordinates (row, column) and few method to validate them and
|
|
* retrieve as an array or an object
|
|
*
|
|
* @class CellCoords
|
|
*/
|
|
var CellCoords = function () {
|
|
/**
|
|
* @param {Number} row Row index
|
|
* @param {Number} col Column index
|
|
*/
|
|
function CellCoords(row, col) {
|
|
_classCallCheck(this, CellCoords);
|
|
|
|
if (typeof row !== 'undefined' && typeof col !== 'undefined') {
|
|
this.row = row;
|
|
this.col = col;
|
|
} else {
|
|
this.row = null;
|
|
this.col = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if given set of coordinates is valid in context of a given Walkontable instance
|
|
*
|
|
* @param {Walkontable} wotInstance
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(CellCoords, [{
|
|
key: 'isValid',
|
|
value: function isValid(wotInstance) {
|
|
// is it a valid cell index (0 or higher)
|
|
if (this.row < 0 || this.col < 0) {
|
|
return false;
|
|
}
|
|
// is selection within total rows and columns
|
|
if (this.row >= wotInstance.getSetting('totalRows') || this.col >= wotInstance.getSetting('totalColumns')) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Checks if this cell coords are the same as cell coords given as a parameter
|
|
*
|
|
* @param {CellCoords} cellCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isEqual',
|
|
value: function isEqual(cellCoords) {
|
|
if (cellCoords === this) {
|
|
return true;
|
|
}
|
|
|
|
return this.row === cellCoords.row && this.col === cellCoords.col;
|
|
}
|
|
|
|
/**
|
|
* Checks if tested coordinates are positioned in south-east from this cell coords
|
|
*
|
|
* @param {Object} testedCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isSouthEastOf',
|
|
value: function isSouthEastOf(testedCoords) {
|
|
return this.row >= testedCoords.row && this.col >= testedCoords.col;
|
|
}
|
|
|
|
/**
|
|
* Checks if tested coordinates are positioned in north-east from this cell coords
|
|
*
|
|
* @param {Object} testedCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isNorthWestOf',
|
|
value: function isNorthWestOf(testedCoords) {
|
|
return this.row <= testedCoords.row && this.col <= testedCoords.col;
|
|
}
|
|
|
|
/**
|
|
* Checks if tested coordinates are positioned in south-west from this cell coords
|
|
*
|
|
* @param {Object} testedCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isSouthWestOf',
|
|
value: function isSouthWestOf(testedCoords) {
|
|
return this.row >= testedCoords.row && this.col <= testedCoords.col;
|
|
}
|
|
|
|
/**
|
|
* Checks if tested coordinates are positioned in north-east from this cell coords
|
|
*
|
|
* @param {Object} testedCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isNorthEastOf',
|
|
value: function isNorthEastOf(testedCoords) {
|
|
return this.row <= testedCoords.row && this.col >= testedCoords.col;
|
|
}
|
|
}]);
|
|
|
|
return CellCoords;
|
|
}();
|
|
|
|
exports.default = CellCoords;
|
|
|
|
/***/ }),
|
|
/* 44 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _autoResize = __webpack_require__(298);
|
|
|
|
var _autoResize2 = _interopRequireDefault(_autoResize);
|
|
|
|
var _baseEditor = __webpack_require__(37);
|
|
|
|
var _baseEditor2 = _interopRequireDefault(_baseEditor);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var TextEditor = _baseEditor2.default.prototype.extend();
|
|
|
|
/**
|
|
* @private
|
|
* @editor TextEditor
|
|
* @class TextEditor
|
|
* @dependencies autoResize
|
|
*/
|
|
TextEditor.prototype.init = function () {
|
|
var that = this;
|
|
this.createElements();
|
|
this.eventManager = new _eventManager2.default(this);
|
|
this.bindEvents();
|
|
this.autoResize = (0, _autoResize2.default)();
|
|
|
|
this.instance.addHook('afterDestroy', function () {
|
|
that.destroy();
|
|
});
|
|
};
|
|
|
|
TextEditor.prototype.getValue = function () {
|
|
return this.TEXTAREA.value;
|
|
};
|
|
|
|
TextEditor.prototype.setValue = function (newValue) {
|
|
this.TEXTAREA.value = newValue;
|
|
};
|
|
|
|
var onBeforeKeyDown = function onBeforeKeyDown(event) {
|
|
var instance = this,
|
|
that = instance.getActiveEditor(),
|
|
ctrlDown;
|
|
|
|
// catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
|
|
ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
|
|
|
|
// Process only events that have been fired in the editor
|
|
if (event.target !== that.TEXTAREA || (0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
|
|
if (event.keyCode === 17 || event.keyCode === 224 || event.keyCode === 91 || event.keyCode === 93) {
|
|
// when CTRL or its equivalent is pressed and cell is edited, don't prepare selectable text in textarea
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
return;
|
|
}
|
|
|
|
switch (event.keyCode) {
|
|
case _unicode.KEY_CODES.ARROW_RIGHT:
|
|
if (that.isInFullEditMode()) {
|
|
if (!that.isWaiting() && !that.allowKeyEventPropagation || !that.isWaiting() && that.allowKeyEventPropagation && !that.allowKeyEventPropagation(event.keyCode)) {
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
}
|
|
}
|
|
break;
|
|
case _unicode.KEY_CODES.ARROW_LEFT:
|
|
if (that.isInFullEditMode()) {
|
|
if (!that.isWaiting() && !that.allowKeyEventPropagation || !that.isWaiting() && that.allowKeyEventPropagation && !that.allowKeyEventPropagation(event.keyCode)) {
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
}
|
|
}
|
|
break;
|
|
case _unicode.KEY_CODES.ARROW_UP:
|
|
case _unicode.KEY_CODES.ARROW_DOWN:
|
|
if (that.isInFullEditMode()) {
|
|
if (!that.isWaiting() && !that.allowKeyEventPropagation || !that.isWaiting() && that.allowKeyEventPropagation && !that.allowKeyEventPropagation(event.keyCode)) {
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ENTER:
|
|
var selected = that.instance.getSelected();
|
|
var isMultipleSelection = !(selected[0] === selected[2] && selected[1] === selected[3]);
|
|
if (ctrlDown && !isMultipleSelection || event.altKey) {
|
|
// if ctrl+enter or alt+enter, add new line
|
|
if (that.isOpened()) {
|
|
var caretPosition = (0, _element.getCaretPosition)(that.TEXTAREA),
|
|
value = that.getValue();
|
|
|
|
var newValue = value.slice(0, caretPosition) + '\n' + value.slice(caretPosition);
|
|
|
|
that.setValue(newValue);
|
|
|
|
(0, _element.setCaretPosition)(that.TEXTAREA, caretPosition + 1);
|
|
} else {
|
|
that.beginEditing(that.originalValue + '\n');
|
|
}
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
}
|
|
event.preventDefault(); // don't add newline to field
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.A:
|
|
case _unicode.KEY_CODES.X:
|
|
case _unicode.KEY_CODES.C:
|
|
case _unicode.KEY_CODES.V:
|
|
if (ctrlDown) {
|
|
(0, _event.stopImmediatePropagation)(event); // CTRL+A, CTRL+C, CTRL+V, CTRL+X should only work locally when cell is edited (not in table context)
|
|
}
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.BACKSPACE:
|
|
case _unicode.KEY_CODES.DELETE:
|
|
case _unicode.KEY_CODES.HOME:
|
|
case _unicode.KEY_CODES.END:
|
|
(0, _event.stopImmediatePropagation)(event); // backspace, delete, home, end should only work locally when cell is edited (not in table context)
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ([_unicode.KEY_CODES.ARROW_UP, _unicode.KEY_CODES.ARROW_RIGHT, _unicode.KEY_CODES.ARROW_DOWN, _unicode.KEY_CODES.ARROW_LEFT].indexOf(event.keyCode) === -1) {
|
|
that.autoResize.resize(String.fromCharCode(event.keyCode));
|
|
}
|
|
};
|
|
|
|
TextEditor.prototype.open = function () {
|
|
this.refreshDimensions(); // need it instantly, to prevent https://github.com/handsontable/handsontable/issues/348
|
|
|
|
this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
|
|
};
|
|
|
|
TextEditor.prototype.close = function (tdOutside) {
|
|
this.textareaParentStyle.display = 'none';
|
|
|
|
this.autoResize.unObserve();
|
|
|
|
if (document.activeElement === this.TEXTAREA) {
|
|
this.instance.listen(); // don't refocus the table if user focused some cell outside of HT on purpose
|
|
}
|
|
this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
|
|
};
|
|
|
|
TextEditor.prototype.focus = function () {
|
|
this.TEXTAREA.focus();
|
|
(0, _element.setCaretPosition)(this.TEXTAREA, this.TEXTAREA.value.length);
|
|
};
|
|
|
|
TextEditor.prototype.createElements = function () {
|
|
// this.$body = $(document.body);
|
|
|
|
this.TEXTAREA = document.createElement('TEXTAREA');
|
|
|
|
(0, _element.addClass)(this.TEXTAREA, 'handsontableInput');
|
|
|
|
this.textareaStyle = this.TEXTAREA.style;
|
|
this.textareaStyle.width = 0;
|
|
this.textareaStyle.height = 0;
|
|
|
|
this.TEXTAREA_PARENT = document.createElement('DIV');
|
|
(0, _element.addClass)(this.TEXTAREA_PARENT, 'handsontableInputHolder');
|
|
|
|
this.textareaParentStyle = this.TEXTAREA_PARENT.style;
|
|
this.textareaParentStyle.top = 0;
|
|
this.textareaParentStyle.left = 0;
|
|
this.textareaParentStyle.display = 'none';
|
|
|
|
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
|
|
|
|
this.instance.rootElement.appendChild(this.TEXTAREA_PARENT);
|
|
|
|
var that = this;
|
|
this.instance._registerTimeout(setTimeout(function () {
|
|
that.refreshDimensions();
|
|
}, 0));
|
|
};
|
|
|
|
TextEditor.prototype.getEditedCell = function () {
|
|
var editorSection = this.checkEditorSection(),
|
|
editedCell;
|
|
|
|
switch (editorSection) {
|
|
case 'top':
|
|
editedCell = this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.textareaParentStyle.zIndex = 101;
|
|
break;
|
|
case 'top-left-corner':
|
|
editedCell = this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.textareaParentStyle.zIndex = 103;
|
|
break;
|
|
case 'bottom-left-corner':
|
|
editedCell = this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.textareaParentStyle.zIndex = 103;
|
|
break;
|
|
case 'left':
|
|
editedCell = this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.textareaParentStyle.zIndex = 102;
|
|
break;
|
|
case 'bottom':
|
|
editedCell = this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.textareaParentStyle.zIndex = 102;
|
|
break;
|
|
default:
|
|
editedCell = this.instance.getCell(this.row, this.col);
|
|
this.textareaParentStyle.zIndex = '';
|
|
break;
|
|
}
|
|
|
|
return editedCell != -1 && editedCell != -2 ? editedCell : void 0;
|
|
};
|
|
|
|
TextEditor.prototype.refreshValue = function () {
|
|
var sourceData = this.instance.getSourceDataAtCell(this.row, this.prop);
|
|
this.originalValue = sourceData;
|
|
|
|
this.setValue(sourceData);
|
|
this.refreshDimensions();
|
|
};
|
|
|
|
TextEditor.prototype.refreshDimensions = function () {
|
|
if (this.state !== _baseEditor.EditorState.EDITING) {
|
|
return;
|
|
}
|
|
this.TD = this.getEditedCell();
|
|
|
|
// TD is outside of the viewport.
|
|
if (!this.TD) {
|
|
this.close(true);
|
|
|
|
return;
|
|
}
|
|
var currentOffset = (0, _element.offset)(this.TD),
|
|
containerOffset = (0, _element.offset)(this.instance.rootElement),
|
|
scrollableContainer = (0, _element.getScrollableElement)(this.TD),
|
|
totalRowsCount = this.instance.countRows(),
|
|
|
|
|
|
// If colHeaders is disabled, cells in the first row have border-top
|
|
editTopModifier = currentOffset.top === containerOffset.top ? 0 : 1,
|
|
editTop = currentOffset.top - containerOffset.top - editTopModifier - (scrollableContainer.scrollTop || 0),
|
|
editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0),
|
|
settings = this.instance.getSettings(),
|
|
rowHeadersCount = this.instance.hasRowHeaders(),
|
|
colHeadersCount = this.instance.hasColHeaders(),
|
|
editorSection = this.checkEditorSection(),
|
|
backgroundColor = this.TD.style.backgroundColor,
|
|
cssTransformOffset;
|
|
|
|
// TODO: Refactor this to the new instance.getCell method (from #ply-59), after 0.12.1 is released
|
|
switch (editorSection) {
|
|
case 'top':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'left':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'top-left-corner':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'bottom-left-corner':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'bottom':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (colHeadersCount && this.instance.getSelected()[0] === 0 || settings.fixedRowsBottom && this.instance.getSelected()[0] === totalRowsCount - settings.fixedRowsBottom) {
|
|
editTop += 1;
|
|
}
|
|
|
|
if (this.instance.getSelected()[1] === 0) {
|
|
editLeft += 1;
|
|
}
|
|
|
|
if (cssTransformOffset && cssTransformOffset != -1) {
|
|
this.textareaParentStyle[cssTransformOffset[0]] = cssTransformOffset[1];
|
|
} else {
|
|
(0, _element.resetCssTransform)(this.TEXTAREA_PARENT);
|
|
}
|
|
|
|
this.textareaParentStyle.top = editTop + 'px';
|
|
this.textareaParentStyle.left = editLeft + 'px';
|
|
|
|
var firstRowOffset = this.instance.view.wt.wtViewport.rowsRenderCalculator.startPosition;
|
|
var firstColumnOffset = this.instance.view.wt.wtViewport.columnsRenderCalculator.startPosition;
|
|
var horizontalScrollPosition = this.instance.view.wt.wtOverlays.leftOverlay.getScrollPosition();
|
|
var verticalScrollPosition = this.instance.view.wt.wtOverlays.topOverlay.getScrollPosition();
|
|
var scrollbarWidth = (0, _element.getScrollbarWidth)();
|
|
|
|
var cellTopOffset = this.TD.offsetTop + firstRowOffset - verticalScrollPosition;
|
|
var cellLeftOffset = this.TD.offsetLeft + firstColumnOffset - horizontalScrollPosition;
|
|
|
|
var width = (0, _element.innerWidth)(this.TD) - 8;
|
|
var actualVerticalScrollbarWidth = (0, _element.hasVerticalScrollbar)(scrollableContainer) ? scrollbarWidth : 0;
|
|
var actualHorizontalScrollbarWidth = (0, _element.hasHorizontalScrollbar)(scrollableContainer) ? scrollbarWidth : 0;
|
|
var maxWidth = this.instance.view.maximumVisibleElementWidth(cellLeftOffset) - 9 - actualVerticalScrollbarWidth;
|
|
var height = this.TD.scrollHeight + 1;
|
|
var maxHeight = Math.max(this.instance.view.maximumVisibleElementHeight(cellTopOffset) - actualHorizontalScrollbarWidth, 23);
|
|
|
|
var cellComputedStyle = (0, _element.getComputedStyle)(this.TD);
|
|
|
|
this.TEXTAREA.style.fontSize = cellComputedStyle.fontSize;
|
|
this.TEXTAREA.style.fontFamily = cellComputedStyle.fontFamily;
|
|
this.TEXTAREA.style.backgroundColor = ''; // RESET STYLE
|
|
this.TEXTAREA.style.backgroundColor = backgroundColor ? backgroundColor : (0, _element.getComputedStyle)(this.TEXTAREA).backgroundColor;
|
|
|
|
this.autoResize.init(this.TEXTAREA, {
|
|
minHeight: Math.min(height, maxHeight),
|
|
maxHeight: maxHeight, // TEXTAREA should never be wider than visible part of the viewport (should not cover the scrollbar)
|
|
minWidth: Math.min(width, maxWidth),
|
|
maxWidth: maxWidth // TEXTAREA should never be wider than visible part of the viewport (should not cover the scrollbar)
|
|
}, true);
|
|
|
|
this.textareaParentStyle.display = 'block';
|
|
};
|
|
|
|
TextEditor.prototype.bindEvents = function () {
|
|
var editor = this;
|
|
|
|
this.eventManager.addEventListener(this.TEXTAREA, 'cut', function (event) {
|
|
(0, _event.stopPropagation)(event);
|
|
});
|
|
|
|
this.eventManager.addEventListener(this.TEXTAREA, 'paste', function (event) {
|
|
(0, _event.stopPropagation)(event);
|
|
});
|
|
|
|
this.instance.addHook('afterScrollHorizontally', function () {
|
|
editor.refreshDimensions();
|
|
});
|
|
|
|
this.instance.addHook('afterScrollVertically', function () {
|
|
editor.refreshDimensions();
|
|
});
|
|
|
|
this.instance.addHook('afterColumnResize', function () {
|
|
editor.refreshDimensions();
|
|
editor.focus();
|
|
});
|
|
|
|
this.instance.addHook('afterRowResize', function () {
|
|
editor.refreshDimensions();
|
|
editor.focus();
|
|
});
|
|
|
|
this.instance.addHook('afterDestroy', function () {
|
|
editor.eventManager.destroy();
|
|
});
|
|
};
|
|
|
|
TextEditor.prototype.destroy = function () {
|
|
this.eventManager.destroy();
|
|
};
|
|
|
|
exports.default = TextEditor;
|
|
|
|
/***/ }),
|
|
/* 45 */
|
|
/***/ (function(module, exports) {
|
|
|
|
var core = module.exports = {version: '2.4.0'};
|
|
if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
|
|
|
|
/***/ }),
|
|
/* 46 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = {};
|
|
|
|
/***/ }),
|
|
/* 47 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var META = __webpack_require__(50)('meta')
|
|
, isObject = __webpack_require__(15)
|
|
, has = __webpack_require__(22)
|
|
, setDesc = __webpack_require__(19).f
|
|
, id = 0;
|
|
var isExtensible = Object.isExtensible || function(){
|
|
return true;
|
|
};
|
|
var FREEZE = !__webpack_require__(31)(function(){
|
|
return isExtensible(Object.preventExtensions({}));
|
|
});
|
|
var setMeta = function(it){
|
|
setDesc(it, META, {value: {
|
|
i: 'O' + ++id, // object ID
|
|
w: {} // weak collections IDs
|
|
}});
|
|
};
|
|
var fastKey = function(it, create){
|
|
// return primitive with prefix
|
|
if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
|
|
if(!has(it, META)){
|
|
// can't set metadata to uncaught frozen object
|
|
if(!isExtensible(it))return 'F';
|
|
// not necessary to add metadata
|
|
if(!create)return 'E';
|
|
// add missing metadata
|
|
setMeta(it);
|
|
// return object ID
|
|
} return it[META].i;
|
|
};
|
|
var getWeak = function(it, create){
|
|
if(!has(it, META)){
|
|
// can't set metadata to uncaught frozen object
|
|
if(!isExtensible(it))return true;
|
|
// not necessary to add metadata
|
|
if(!create)return false;
|
|
// add missing metadata
|
|
setMeta(it);
|
|
// return hash weak collections IDs
|
|
} return it[META].w;
|
|
};
|
|
// add metadata on freeze-family methods calling
|
|
var onFreeze = function(it){
|
|
if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it);
|
|
return it;
|
|
};
|
|
var meta = module.exports = {
|
|
KEY: META,
|
|
NEED: false,
|
|
fastKey: fastKey,
|
|
getWeak: getWeak,
|
|
onFreeze: onFreeze
|
|
};
|
|
|
|
/***/ }),
|
|
/* 48 */
|
|
/***/ (function(module, exports) {
|
|
|
|
exports.f = {}.propertyIsEnumerable;
|
|
|
|
/***/ }),
|
|
/* 49 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var def = __webpack_require__(19).f
|
|
, has = __webpack_require__(22)
|
|
, TAG = __webpack_require__(10)('toStringTag');
|
|
|
|
module.exports = function(it, tag, stat){
|
|
if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 50 */
|
|
/***/ (function(module, exports) {
|
|
|
|
var id = 0
|
|
, px = Math.random();
|
|
module.exports = function(key){
|
|
return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 51 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
|
|
* numbro.js
|
|
* version : 1.11.0
|
|
* author : Företagsplatsen AB
|
|
* license : MIT
|
|
* http://www.foretagsplatsen.se
|
|
*/
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
/************************************
|
|
Constants
|
|
************************************/
|
|
|
|
var numbro,
|
|
VERSION = '1.11.0',
|
|
binarySuffixes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'],
|
|
decimalSuffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
|
|
bytes = {
|
|
general: { scale: 1024, suffixes: decimalSuffixes, marker: 'bd' },
|
|
binary: { scale: 1024, suffixes: binarySuffixes, marker: 'b' },
|
|
decimal: { scale: 1000, suffixes: decimalSuffixes, marker: 'd' }
|
|
},
|
|
// general must be before the others because it reuses their characters!
|
|
byteFormatOrder = [ bytes.general, bytes.binary, bytes.decimal ],
|
|
// internal storage for culture config files
|
|
cultures = {},
|
|
// Todo: Remove in 2.0.0
|
|
languages = cultures,
|
|
currentCulture = 'en-US',
|
|
zeroFormat = null,
|
|
defaultFormat = '0,0',
|
|
defaultCurrencyFormat = '0$',
|
|
// check for nodeJS
|
|
hasModule = (typeof module !== 'undefined' && module.exports),
|
|
// default culture
|
|
enUS = {
|
|
delimiters: {
|
|
thousands: ',',
|
|
decimal: '.'
|
|
},
|
|
abbreviations: {
|
|
thousand: 'k',
|
|
million: 'm',
|
|
billion: 'b',
|
|
trillion: 't'
|
|
},
|
|
ordinal: function(number) {
|
|
var b = number % 10;
|
|
return (~~(number % 100 / 10) === 1) ? 'th' :
|
|
(b === 1) ? 'st' :
|
|
(b === 2) ? 'nd' :
|
|
(b === 3) ? 'rd' : 'th';
|
|
},
|
|
currency: {
|
|
symbol: '$',
|
|
position: 'prefix'
|
|
},
|
|
defaults: {
|
|
currencyFormat: ',0000 a'
|
|
},
|
|
formats: {
|
|
fourDigits: '0000 a',
|
|
fullWithTwoDecimals: '$ ,0.00',
|
|
fullWithTwoDecimalsNoCurrency: ',0.00'
|
|
}
|
|
};
|
|
|
|
/************************************
|
|
Constructors
|
|
************************************/
|
|
|
|
|
|
// Numbro prototype object
|
|
function Numbro(number) {
|
|
this._value = number;
|
|
}
|
|
|
|
function numberLength(number) {
|
|
if (number === 0) { return 1; }
|
|
return Math.floor(Math.log(Math.abs(number)) / Math.LN10) + 1;
|
|
}
|
|
|
|
function zeroes(count) {
|
|
var i, ret = '';
|
|
|
|
for (i = 0; i < count; i++) {
|
|
ret += '0';
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
/**
|
|
* Implementation of toFixed() for numbers with exponents
|
|
* This function may return negative representations for zero values e.g. "-0.0"
|
|
*/
|
|
function toFixedLargeSmall(value, precision) {
|
|
var mantissa,
|
|
beforeDec,
|
|
afterDec,
|
|
exponent,
|
|
prefix,
|
|
endStr,
|
|
zerosStr,
|
|
str;
|
|
|
|
str = value.toString();
|
|
|
|
mantissa = str.split('e')[0];
|
|
exponent = str.split('e')[1];
|
|
|
|
beforeDec = mantissa.split('.')[0];
|
|
afterDec = mantissa.split('.')[1] || '';
|
|
|
|
if (+exponent > 0) {
|
|
// exponent is positive - add zeros after the numbers
|
|
str = beforeDec + afterDec + zeroes(exponent - afterDec.length);
|
|
} else {
|
|
// exponent is negative
|
|
|
|
if (+beforeDec < 0) {
|
|
prefix = '-0';
|
|
} else {
|
|
prefix = '0';
|
|
}
|
|
|
|
// tack on the decimal point if needed
|
|
if (precision > 0) {
|
|
prefix += '.';
|
|
}
|
|
|
|
zerosStr = zeroes((-1 * exponent) - 1);
|
|
// substring off the end to satisfy the precision
|
|
endStr = (zerosStr + Math.abs(beforeDec) + afterDec).substr(0, precision);
|
|
str = prefix + endStr;
|
|
}
|
|
|
|
// only add percision 0's if the exponent is positive
|
|
if (+exponent > 0 && precision > 0) {
|
|
str += '.' + zeroes(precision);
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
/**
|
|
* Implementation of toFixed() that treats floats more like decimals
|
|
*
|
|
* Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
|
|
* problems for accounting- and finance-related software.
|
|
*
|
|
* Also removes negative signs for zero-formatted numbers. e.g. -0.01 w/ precision 1 -> 0.0
|
|
*/
|
|
function toFixed(value, precision, roundingFunction, optionals) {
|
|
var power = Math.pow(10, precision),
|
|
optionalsRegExp,
|
|
output;
|
|
|
|
if (value.toString().indexOf('e') > -1) {
|
|
// toFixed returns scientific notation for numbers above 1e21 and below 1e-7
|
|
output = toFixedLargeSmall(value, precision);
|
|
// remove the leading negative sign if it exists and should not be present (e.g. -0.00)
|
|
if (output.charAt(0) === '-' && +output >= 0) {
|
|
output = output.substr(1); // chop off the '-'
|
|
}
|
|
}
|
|
else {
|
|
// Multiply up by precision, round accurately, then divide and use native toFixed():
|
|
output = (roundingFunction(value + 'e+' + precision) / power).toFixed(precision);
|
|
}
|
|
|
|
if (optionals) {
|
|
optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
|
|
output = output.replace(optionalsRegExp, '');
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
/************************************
|
|
Formatting
|
|
************************************/
|
|
|
|
// determine what type of formatting we need to do
|
|
function formatNumbro(n, format, roundingFunction) {
|
|
var output,
|
|
escapedFormat = format.replace(/\{[^\{\}]*\}/g, '');
|
|
|
|
// figure out what kind of format we are dealing with
|
|
if (escapedFormat.indexOf('$') > -1) { // currency!!!!!
|
|
output = formatCurrency(n, cultures[currentCulture].currency.symbol, format, roundingFunction);
|
|
} else if (escapedFormat.indexOf('%') > -1) { // percentage
|
|
output = formatPercentage(n, format, roundingFunction);
|
|
} else if (escapedFormat.indexOf(':') > -1) { // time
|
|
output = formatTime(n, format);
|
|
} else { // plain ol' numbers or bytes
|
|
output = formatNumber(n._value, format, roundingFunction);
|
|
}
|
|
|
|
// return string
|
|
return output;
|
|
}
|
|
|
|
// revert to number
|
|
function unformatNumbro(n, string) {
|
|
var stringOriginal = string,
|
|
thousandRegExp,
|
|
millionRegExp,
|
|
billionRegExp,
|
|
trillionRegExp,
|
|
bytesMultiplier = false,
|
|
power;
|
|
|
|
if (string.indexOf(':') > -1) {
|
|
n._value = unformatTime(string);
|
|
} else {
|
|
if (string === zeroFormat) {
|
|
n._value = 0;
|
|
} else {
|
|
if (cultures[currentCulture].delimiters.decimal !== '.') {
|
|
string = string.replace(/\./g, '').replace(cultures[currentCulture].delimiters.decimal, '.');
|
|
}
|
|
|
|
// see if abbreviations are there so that we can multiply to the correct number
|
|
thousandRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.thousand +
|
|
'(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
|
|
millionRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.million +
|
|
'(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
|
|
billionRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.billion +
|
|
'(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
|
|
trillionRegExp = new RegExp('[^a-zA-Z]' + cultures[currentCulture].abbreviations.trillion +
|
|
'(?:\\)|(\\' + cultures[currentCulture].currency.symbol + ')?(?:\\))?)?$');
|
|
|
|
// see if bytes are there so that we can multiply to the correct number
|
|
for (power = 1; power < binarySuffixes.length && !bytesMultiplier; ++power) {
|
|
if (string.indexOf(binarySuffixes[power]) > -1) {
|
|
bytesMultiplier = Math.pow(1024, power);
|
|
} else if (string.indexOf(decimalSuffixes[power]) > -1) {
|
|
bytesMultiplier = Math.pow(1000, power);
|
|
}
|
|
}
|
|
|
|
var str = string.replace(/[^0-9\.]+/g, '');
|
|
if (str === '') {
|
|
// An empty string is not a number.
|
|
n._value = NaN;
|
|
|
|
} else {
|
|
// do some math to create our number
|
|
n._value = ((bytesMultiplier) ? bytesMultiplier : 1) *
|
|
((stringOriginal.match(thousandRegExp)) ? Math.pow(10, 3) : 1) *
|
|
((stringOriginal.match(millionRegExp)) ? Math.pow(10, 6) : 1) *
|
|
((stringOriginal.match(billionRegExp)) ? Math.pow(10, 9) : 1) *
|
|
((stringOriginal.match(trillionRegExp)) ? Math.pow(10, 12) : 1) *
|
|
((string.indexOf('%') > -1) ? 0.01 : 1) *
|
|
(((string.split('-').length +
|
|
Math.min(string.split('(').length - 1, string.split(')').length - 1)) % 2) ? 1 : -1) *
|
|
Number(str);
|
|
|
|
// round if we are talking about bytes
|
|
n._value = (bytesMultiplier) ? Math.ceil(n._value) : n._value;
|
|
}
|
|
}
|
|
}
|
|
return n._value;
|
|
}
|
|
|
|
function formatCurrency(n, currencySymbol, originalFormat, roundingFunction) {
|
|
var format = originalFormat,
|
|
symbolIndex = format.indexOf('$'),
|
|
openParenIndex = format.indexOf('('),
|
|
plusSignIndex = format.indexOf('+'),
|
|
minusSignIndex = format.indexOf('-'),
|
|
space = '',
|
|
decimalSeparator = '',
|
|
spliceIndex,
|
|
output;
|
|
|
|
if(format.indexOf('$') === -1){
|
|
// Use defaults instead of the format provided
|
|
if (cultures[currentCulture].currency.position === 'infix') {
|
|
decimalSeparator = currencySymbol;
|
|
if (cultures[currentCulture].currency.spaceSeparated) {
|
|
decimalSeparator = ' ' + decimalSeparator + ' ';
|
|
}
|
|
} else if (cultures[currentCulture].currency.spaceSeparated) {
|
|
space = ' ';
|
|
}
|
|
} else {
|
|
// check for space before or after currency
|
|
if (format.indexOf(' $') > -1) {
|
|
space = ' ';
|
|
format = format.replace(' $', '');
|
|
} else if (format.indexOf('$ ') > -1) {
|
|
space = ' ';
|
|
format = format.replace('$ ', '');
|
|
} else {
|
|
format = format.replace('$', '');
|
|
}
|
|
}
|
|
|
|
// Format The Number
|
|
output = formatNumber(n._value, format, roundingFunction, decimalSeparator);
|
|
|
|
if (originalFormat.indexOf('$') === -1) {
|
|
// Use defaults instead of the format provided
|
|
switch (cultures[currentCulture].currency.position) {
|
|
case 'postfix':
|
|
if (output.indexOf(')') > -1) {
|
|
output = output.split('');
|
|
output.splice(-1, 0, space + currencySymbol);
|
|
output = output.join('');
|
|
} else {
|
|
output = output + space + currencySymbol;
|
|
}
|
|
break;
|
|
case 'infix':
|
|
break;
|
|
case 'prefix':
|
|
if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
|
|
output = output.split('');
|
|
spliceIndex = Math.max(openParenIndex, minusSignIndex) + 1;
|
|
|
|
output.splice(spliceIndex, 0, currencySymbol + space);
|
|
output = output.join('');
|
|
} else {
|
|
output = currencySymbol + space + output;
|
|
}
|
|
break;
|
|
default:
|
|
throw Error('Currency position should be among ["prefix", "infix", "postfix"]');
|
|
}
|
|
} else {
|
|
// position the symbol
|
|
if (symbolIndex <= 1) {
|
|
if (output.indexOf('(') > -1 || output.indexOf('+') > -1 || output.indexOf('-') > -1) {
|
|
output = output.split('');
|
|
spliceIndex = 1;
|
|
if (symbolIndex < openParenIndex || symbolIndex < plusSignIndex || symbolIndex < minusSignIndex) {
|
|
// the symbol appears before the "(", "+" or "-"
|
|
spliceIndex = 0;
|
|
}
|
|
output.splice(spliceIndex, 0, currencySymbol + space);
|
|
output = output.join('');
|
|
} else {
|
|
output = currencySymbol + space + output;
|
|
}
|
|
} else {
|
|
if (output.indexOf(')') > -1) {
|
|
output = output.split('');
|
|
output.splice(-1, 0, space + currencySymbol);
|
|
output = output.join('');
|
|
} else {
|
|
output = output + space + currencySymbol;
|
|
}
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
function formatForeignCurrency(n, foreignCurrencySymbol, originalFormat, roundingFunction) {
|
|
return formatCurrency(n, foreignCurrencySymbol, originalFormat, roundingFunction);
|
|
}
|
|
|
|
function formatPercentage(n, format, roundingFunction) {
|
|
var space = '',
|
|
output,
|
|
value = n._value * 100;
|
|
|
|
// check for space before %
|
|
if (format.indexOf(' %') > -1) {
|
|
space = ' ';
|
|
format = format.replace(' %', '');
|
|
} else {
|
|
format = format.replace('%', '');
|
|
}
|
|
|
|
output = formatNumber(value, format, roundingFunction);
|
|
|
|
if (output.indexOf(')') > -1) {
|
|
output = output.split('');
|
|
output.splice(-1, 0, space + '%');
|
|
output = output.join('');
|
|
} else {
|
|
output = output + space + '%';
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
function formatTime(n) {
|
|
var hours = Math.floor(n._value / 60 / 60),
|
|
minutes = Math.floor((n._value - (hours * 60 * 60)) / 60),
|
|
seconds = Math.round(n._value - (hours * 60 * 60) - (minutes * 60));
|
|
return hours + ':' +
|
|
((minutes < 10) ? '0' + minutes : minutes) + ':' +
|
|
((seconds < 10) ? '0' + seconds : seconds);
|
|
}
|
|
|
|
function unformatTime(string) {
|
|
var timeArray = string.split(':'),
|
|
seconds = 0;
|
|
// turn hours and minutes into seconds and add them all up
|
|
if (timeArray.length === 3) {
|
|
// hours
|
|
seconds = seconds + (Number(timeArray[0]) * 60 * 60);
|
|
// minutes
|
|
seconds = seconds + (Number(timeArray[1]) * 60);
|
|
// seconds
|
|
seconds = seconds + Number(timeArray[2]);
|
|
} else if (timeArray.length === 2) {
|
|
// minutes
|
|
seconds = seconds + (Number(timeArray[0]) * 60);
|
|
// seconds
|
|
seconds = seconds + Number(timeArray[1]);
|
|
}
|
|
return Number(seconds);
|
|
}
|
|
|
|
function formatByteUnits (value, suffixes, scale) {
|
|
var suffix = suffixes[0],
|
|
power,
|
|
min,
|
|
max,
|
|
abs = Math.abs(value);
|
|
|
|
if (abs >= scale) {
|
|
for (power = 1; power < suffixes.length; ++power) {
|
|
min = Math.pow(scale, power);
|
|
max = Math.pow(scale, power + 1);
|
|
|
|
if (abs >= min && abs < max) {
|
|
suffix = suffixes[power];
|
|
value = value / min;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// values greater than or equal to [scale] YB never set the suffix
|
|
if (suffix === suffixes[0]) {
|
|
value = value / Math.pow(scale, suffixes.length - 1);
|
|
suffix = suffixes[suffixes.length - 1];
|
|
}
|
|
}
|
|
|
|
return { value: value, suffix: suffix };
|
|
}
|
|
|
|
function formatNumber (value, format, roundingFunction, sep) {
|
|
var negP = false,
|
|
signed = false,
|
|
optDec = false,
|
|
abbr = '',
|
|
abbrK = false, // force abbreviation to thousands
|
|
abbrM = false, // force abbreviation to millions
|
|
abbrB = false, // force abbreviation to billions
|
|
abbrT = false, // force abbreviation to trillions
|
|
abbrForce = false, // force abbreviation
|
|
bytes = '',
|
|
byteFormat,
|
|
units,
|
|
ord = '',
|
|
abs = Math.abs(value),
|
|
totalLength,
|
|
length,
|
|
minimumPrecision,
|
|
pow,
|
|
w,
|
|
intPrecision,
|
|
precision,
|
|
prefix,
|
|
postfix,
|
|
thousands,
|
|
d = '',
|
|
forcedNeg = false,
|
|
neg = false,
|
|
indexOpenP,
|
|
indexMinus,
|
|
paren = '',
|
|
minlen,
|
|
i;
|
|
|
|
// check if number is zero and a custom zero format has been set
|
|
if (value === 0 && zeroFormat !== null) {
|
|
return zeroFormat;
|
|
}
|
|
|
|
if (!isFinite(value)) {
|
|
return '' + value;
|
|
}
|
|
|
|
if (format.indexOf('{') === 0) {
|
|
var end = format.indexOf('}');
|
|
if (end === -1) {
|
|
throw Error('Format should also contain a "}"');
|
|
}
|
|
prefix = format.slice(1, end);
|
|
format = format.slice(end + 1);
|
|
} else {
|
|
prefix = '';
|
|
}
|
|
|
|
if (format.indexOf('}') === format.length - 1 && format.length) {
|
|
var start = format.indexOf('{');
|
|
if (start === -1) {
|
|
throw Error('Format should also contain a "{"');
|
|
}
|
|
postfix = format.slice(start + 1, -1);
|
|
format = format.slice(0, start + 1);
|
|
} else {
|
|
postfix = '';
|
|
}
|
|
|
|
// check for min length
|
|
var info;
|
|
if (format.indexOf('.') === -1) {
|
|
info = format.match(/([0-9]+).*/);
|
|
} else {
|
|
info = format.match(/([0-9]+)\..*/);
|
|
}
|
|
minlen = info === null ? -1 : info[1].length;
|
|
|
|
// see if we should use parentheses for negative number or if we should prefix with a sign
|
|
// if both are present we default to parentheses
|
|
if (format.indexOf('-') !== -1) {
|
|
forcedNeg = true;
|
|
}
|
|
if (format.indexOf('(') > -1) {
|
|
negP = true;
|
|
format = format.slice(1, -1);
|
|
} else if (format.indexOf('+') > -1) {
|
|
signed = true;
|
|
format = format.replace(/\+/g, '');
|
|
}
|
|
|
|
// see if abbreviation is wanted
|
|
if (format.indexOf('a') > -1) {
|
|
intPrecision = format.split('.')[0].match(/[0-9]+/g) || ['0'];
|
|
intPrecision = parseInt(intPrecision[0], 10);
|
|
|
|
// check if abbreviation is specified
|
|
abbrK = format.indexOf('aK') >= 0;
|
|
abbrM = format.indexOf('aM') >= 0;
|
|
abbrB = format.indexOf('aB') >= 0;
|
|
abbrT = format.indexOf('aT') >= 0;
|
|
abbrForce = abbrK || abbrM || abbrB || abbrT;
|
|
|
|
// check for space before abbreviation
|
|
if (format.indexOf(' a') > -1) {
|
|
abbr = ' ';
|
|
format = format.replace(' a', '');
|
|
} else {
|
|
format = format.replace('a', '');
|
|
}
|
|
|
|
totalLength = numberLength(value);
|
|
minimumPrecision = totalLength % 3;
|
|
minimumPrecision = minimumPrecision === 0 ? 3 : minimumPrecision;
|
|
|
|
if (intPrecision && abs !== 0) {
|
|
pow = 3 * ~~((Math.min(intPrecision, totalLength) - minimumPrecision) / 3);
|
|
abs = abs / Math.pow(10, pow);
|
|
}
|
|
|
|
if (totalLength !== intPrecision) {
|
|
if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {
|
|
// trillion
|
|
abbr = abbr + cultures[currentCulture].abbreviations.trillion;
|
|
value = value / Math.pow(10, 12);
|
|
} else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {
|
|
// billion
|
|
abbr = abbr + cultures[currentCulture].abbreviations.billion;
|
|
value = value / Math.pow(10, 9);
|
|
} else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {
|
|
// million
|
|
abbr = abbr + cultures[currentCulture].abbreviations.million;
|
|
value = value / Math.pow(10, 6);
|
|
} else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {
|
|
// thousand
|
|
abbr = abbr + cultures[currentCulture].abbreviations.thousand;
|
|
value = value / Math.pow(10, 3);
|
|
}
|
|
}
|
|
|
|
length = numberLength(value);
|
|
if (intPrecision && length < intPrecision && format.indexOf('.') === -1) {
|
|
format += '[.]';
|
|
format += zeroes(intPrecision - length);
|
|
}
|
|
}
|
|
|
|
// see if we are formatting
|
|
// binary-decimal bytes (1024 MB), binary bytes (1024 MiB), or decimal bytes (1000 MB)
|
|
for (i = 0; i < byteFormatOrder.length; ++i) {
|
|
byteFormat = byteFormatOrder[i];
|
|
|
|
if (format.indexOf(byteFormat.marker) > -1) {
|
|
// check for space before
|
|
if (format.indexOf(' ' + byteFormat.marker) >-1) {
|
|
bytes = ' ';
|
|
}
|
|
|
|
// remove the marker (with the space if it had one)
|
|
format = format.replace(bytes + byteFormat.marker, '');
|
|
|
|
units = formatByteUnits(value, byteFormat.suffixes, byteFormat.scale);
|
|
|
|
value = units.value;
|
|
bytes = bytes + units.suffix;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// see if ordinal is wanted
|
|
if (format.indexOf('o') > -1) {
|
|
// check for space before
|
|
if (format.indexOf(' o') > -1) {
|
|
ord = ' ';
|
|
format = format.replace(' o', '');
|
|
} else {
|
|
format = format.replace('o', '');
|
|
}
|
|
|
|
if (cultures[currentCulture].ordinal) {
|
|
ord = ord + cultures[currentCulture].ordinal(value);
|
|
}
|
|
}
|
|
|
|
if (format.indexOf('[.]') > -1) {
|
|
optDec = true;
|
|
format = format.replace('[.]', '.');
|
|
}
|
|
|
|
precision = format.split('.')[1];
|
|
thousands = format.indexOf(',');
|
|
|
|
if (precision) {
|
|
var dSplit = [];
|
|
|
|
if (precision.indexOf('*') !== -1) {
|
|
d = value.toString();
|
|
dSplit = d.split('.');
|
|
if (dSplit.length > 1) {
|
|
d = toFixed(value, dSplit[1].length, roundingFunction);
|
|
}
|
|
} else {
|
|
if (precision.indexOf('[') > -1) {
|
|
precision = precision.replace(']', '');
|
|
precision = precision.split('[');
|
|
d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction,
|
|
precision[1].length);
|
|
} else {
|
|
d = toFixed(value, precision.length, roundingFunction);
|
|
}
|
|
}
|
|
|
|
dSplit = d.split('.');
|
|
w = dSplit[0];
|
|
|
|
if (dSplit.length > 1 && dSplit[1].length) {
|
|
var p = sep ? abbr + sep : cultures[currentCulture].delimiters.decimal;
|
|
d = p + dSplit[1];
|
|
} else {
|
|
d = '';
|
|
}
|
|
|
|
if (optDec && Number(d.slice(1)) === 0) {
|
|
d = '';
|
|
}
|
|
} else {
|
|
w = toFixed(value, 0, roundingFunction);
|
|
}
|
|
|
|
// format number
|
|
if (w.indexOf('-') > -1) {
|
|
w = w.slice(1);
|
|
neg = true;
|
|
}
|
|
|
|
if (w.length < minlen) {
|
|
w = zeroes(minlen - w.length) + w;
|
|
}
|
|
|
|
if (thousands > -1) {
|
|
w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' +
|
|
cultures[currentCulture].delimiters.thousands);
|
|
}
|
|
|
|
if (format.indexOf('.') === 0) {
|
|
w = '';
|
|
}
|
|
|
|
indexOpenP = format.indexOf('(');
|
|
indexMinus = format.indexOf('-');
|
|
|
|
if (indexOpenP < indexMinus) {
|
|
paren = ((negP && neg) ? '(' : '') + (((forcedNeg && neg) || (!negP && neg)) ? '-' : '');
|
|
} else {
|
|
paren = (((forcedNeg && neg) || (!negP && neg)) ? '-' : '') + ((negP && neg) ? '(' : '');
|
|
}
|
|
|
|
return prefix +
|
|
paren + ((!neg && signed && value !== 0) ? '+' : '') +
|
|
w + d +
|
|
((ord) ? ord : '') +
|
|
((abbr && !sep) ? abbr : '') +
|
|
((bytes) ? bytes : '') +
|
|
((negP && neg) ? ')' : '') +
|
|
postfix;
|
|
}
|
|
|
|
/************************************
|
|
Top Level Functions
|
|
************************************/
|
|
|
|
numbro = function(input) {
|
|
if (numbro.isNumbro(input)) {
|
|
input = input.value();
|
|
} else if (typeof input === 'string' || typeof input === 'number') {
|
|
input = numbro.fn.unformat(input);
|
|
} else {
|
|
input = NaN;
|
|
}
|
|
|
|
return new Numbro(Number(input));
|
|
};
|
|
|
|
// version number
|
|
numbro.version = VERSION;
|
|
|
|
// compare numbro object
|
|
numbro.isNumbro = function(obj) {
|
|
return obj instanceof Numbro;
|
|
};
|
|
|
|
/**
|
|
* This function allow the user to set a new language with a fallback if
|
|
* the language does not exist. If no fallback language is provided,
|
|
* it fallbacks to english.
|
|
*
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `setCulture` should be used instead.
|
|
*/
|
|
numbro.setLanguage = function(newLanguage, fallbackLanguage) {
|
|
console.warn('`setLanguage` is deprecated since version 1.6.0. Use `setCulture` instead');
|
|
var key = newLanguage,
|
|
prefix = newLanguage.split('-')[0],
|
|
matchingLanguage = null;
|
|
if (!languages[key]) {
|
|
Object.keys(languages).forEach(function(language) {
|
|
if (!matchingLanguage && language.split('-')[0] === prefix) {
|
|
matchingLanguage = language;
|
|
}
|
|
});
|
|
key = matchingLanguage || fallbackLanguage || 'en-US';
|
|
}
|
|
chooseCulture(key);
|
|
};
|
|
|
|
/**
|
|
* This function allow the user to set a new culture with a fallback if
|
|
* the culture does not exist. If no fallback culture is provided,
|
|
* it falls back to "en-US".
|
|
*/
|
|
numbro.setCulture = function(newCulture, fallbackCulture) {
|
|
var key = newCulture,
|
|
suffix = newCulture.split('-')[1],
|
|
matchingCulture = null;
|
|
if (!cultures[key]) {
|
|
if (suffix) {
|
|
Object.keys(cultures).forEach(function(language) {
|
|
if (!matchingCulture && language.split('-')[1] === suffix) {
|
|
matchingCulture = language;
|
|
}
|
|
});
|
|
}
|
|
|
|
key = matchingCulture || fallbackCulture || 'en-US';
|
|
}
|
|
chooseCulture(key);
|
|
};
|
|
|
|
/**
|
|
* This function will load languages and then set the global language. If
|
|
* no arguments are passed in, it will simply return the current global
|
|
* language key.
|
|
*
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `culture` should be used instead.
|
|
*/
|
|
numbro.language = function(key, values) {
|
|
console.warn('`language` is deprecated since version 1.6.0. Use `culture` instead');
|
|
|
|
if (!key) {
|
|
return currentCulture;
|
|
}
|
|
|
|
if (key && !values) {
|
|
if (!languages[key]) {
|
|
throw new Error('Unknown language : ' + key);
|
|
}
|
|
chooseCulture(key);
|
|
}
|
|
|
|
if (values || !languages[key]) {
|
|
setCulture(key, values);
|
|
}
|
|
|
|
return numbro;
|
|
};
|
|
|
|
/**
|
|
* This function will load cultures and then set the global culture. If
|
|
* no arguments are passed in, it will simply return the current global
|
|
* culture code.
|
|
*/
|
|
numbro.culture = function(code, values) {
|
|
if (!code) {
|
|
return currentCulture;
|
|
}
|
|
|
|
if (code && !values) {
|
|
if (!cultures[code]) {
|
|
throw new Error('Unknown culture : ' + code);
|
|
}
|
|
chooseCulture(code);
|
|
}
|
|
|
|
if (values || !cultures[code]) {
|
|
setCulture(code, values);
|
|
}
|
|
|
|
return numbro;
|
|
};
|
|
|
|
/**
|
|
* This function provides access to the loaded language data. If
|
|
* no arguments are passed in, it will simply return the current
|
|
* global language object.
|
|
*
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `culture` should be used instead.
|
|
*/
|
|
numbro.languageData = function(key) {
|
|
console.warn('`languageData` is deprecated since version 1.6.0. Use `cultureData` instead');
|
|
|
|
if (!key) {
|
|
return languages[currentCulture];
|
|
}
|
|
|
|
if (!languages[key]) {
|
|
throw new Error('Unknown language : ' + key);
|
|
}
|
|
|
|
return languages[key];
|
|
};
|
|
|
|
/**
|
|
* This function provides access to the loaded culture data. If
|
|
* no arguments are passed in, it will simply return the current
|
|
* global culture object.
|
|
*/
|
|
numbro.cultureData = function(code) {
|
|
if (!code) {
|
|
return cultures[currentCulture];
|
|
}
|
|
|
|
if (!cultures[code]) {
|
|
throw new Error('Unknown culture : ' + code);
|
|
}
|
|
|
|
return cultures[code];
|
|
};
|
|
|
|
numbro.culture('en-US', enUS);
|
|
|
|
/**
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `cultures` should be used instead.
|
|
*/
|
|
numbro.languages = function() {
|
|
console.warn('`languages` is deprecated since version 1.6.0. Use `cultures` instead');
|
|
|
|
return languages;
|
|
};
|
|
|
|
numbro.cultures = function() {
|
|
return cultures;
|
|
};
|
|
|
|
numbro.zeroFormat = function(format) {
|
|
zeroFormat = typeof(format) === 'string' ? format : null;
|
|
};
|
|
|
|
numbro.defaultFormat = function(format) {
|
|
defaultFormat = typeof(format) === 'string' ? format : '0.0';
|
|
};
|
|
|
|
numbro.defaultCurrencyFormat = function (format) {
|
|
defaultCurrencyFormat = typeof(format) === 'string' ? format : '0$';
|
|
};
|
|
|
|
numbro.validate = function(val, culture) {
|
|
|
|
var _decimalSep,
|
|
_thousandSep,
|
|
_currSymbol,
|
|
_valArray,
|
|
_abbrObj,
|
|
_thousandRegEx,
|
|
cultureData,
|
|
temp;
|
|
|
|
//coerce val to string
|
|
if (typeof val !== 'string') {
|
|
val += '';
|
|
if (console.warn) {
|
|
console.warn('Numbro.js: Value is not string. It has been co-erced to: ', val);
|
|
}
|
|
}
|
|
|
|
//trim whitespaces from either sides
|
|
val = val.trim();
|
|
|
|
//replace the initial '+' or '-' sign if present
|
|
val = val.replace(/^[+-]?/, '');
|
|
|
|
//if val is just digits return true
|
|
if ( !! val.match(/^\d+$/)) {
|
|
return true;
|
|
}
|
|
|
|
//if val is empty return false
|
|
if (val === '') {
|
|
return false;
|
|
}
|
|
|
|
//get the decimal and thousands separator from numbro.cultureData
|
|
try {
|
|
//check if the culture is understood by numbro. if not, default it to current culture
|
|
cultureData = numbro.cultureData(culture);
|
|
} catch (e) {
|
|
cultureData = numbro.cultureData(numbro.culture());
|
|
}
|
|
|
|
//setup the delimiters and currency symbol based on culture
|
|
_currSymbol = cultureData.currency.symbol;
|
|
_abbrObj = cultureData.abbreviations;
|
|
_decimalSep = cultureData.delimiters.decimal;
|
|
if (cultureData.delimiters.thousands === '.') {
|
|
_thousandSep = '\\.';
|
|
} else {
|
|
_thousandSep = cultureData.delimiters.thousands;
|
|
}
|
|
|
|
// validating currency symbol
|
|
temp = val.match(/^[^\d\.\,]+/);
|
|
if (temp !== null) {
|
|
val = val.substr(1);
|
|
if (temp[0] !== _currSymbol) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//validating abbreviation symbol
|
|
temp = val.match(/[^\d]+$/);
|
|
if (temp !== null) {
|
|
val = val.slice(0, -1);
|
|
if (temp[0] !== _abbrObj.thousand && temp[0] !== _abbrObj.million &&
|
|
temp[0] !== _abbrObj.billion && temp[0] !== _abbrObj.trillion) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
_thousandRegEx = new RegExp(_thousandSep + '{2}');
|
|
|
|
if (!val.match(/[^\d.,]/g)) {
|
|
_valArray = val.split(_decimalSep);
|
|
if (_valArray.length > 2) {
|
|
return false;
|
|
} else {
|
|
if (_valArray.length < 2) {
|
|
return ( !! _valArray[0].match(/^\d+.*\d$/) && !_valArray[0].match(_thousandRegEx));
|
|
} else {
|
|
if (_valArray[0] === '') {
|
|
// for values without leading zero eg. .984
|
|
return (!_valArray[0].match(_thousandRegEx) &&
|
|
!!_valArray[1].match(/^\d+$/));
|
|
|
|
} else if (_valArray[0].length === 1) {
|
|
return ( !! _valArray[0].match(/^\d+$/) &&
|
|
!_valArray[0].match(_thousandRegEx) &&
|
|
!! _valArray[1].match(/^\d+$/));
|
|
} else {
|
|
return ( !! _valArray[0].match(/^\d+.*\d$/) &&
|
|
!_valArray[0].match(_thousandRegEx) &&
|
|
!! _valArray[1].match(/^\d+$/));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `loadCulturesInNode` should be used instead.
|
|
*/
|
|
numbro.loadLanguagesInNode = function() {
|
|
console.warn('`loadLanguagesInNode` is deprecated since version 1.6.0. Use `loadCulturesInNode` instead');
|
|
|
|
numbro.loadCulturesInNode();
|
|
};
|
|
|
|
numbro.loadCulturesInNode = function() {
|
|
// TODO: Rename the folder in 2.0.0
|
|
var cultures = __webpack_require__(297);
|
|
|
|
for(var langLocaleCode in cultures) {
|
|
if(langLocaleCode) {
|
|
numbro.culture(langLocaleCode, cultures[langLocaleCode]);
|
|
}
|
|
}
|
|
};
|
|
|
|
/************************************
|
|
Helpers
|
|
************************************/
|
|
|
|
function setCulture(code, values) {
|
|
cultures[code] = values;
|
|
}
|
|
|
|
function chooseCulture(code) {
|
|
currentCulture = code;
|
|
var defaults = cultures[code].defaults;
|
|
if (defaults && defaults.format) {
|
|
numbro.defaultFormat(defaults.format);
|
|
}
|
|
if (defaults && defaults.currencyFormat) {
|
|
numbro.defaultCurrencyFormat(defaults.currencyFormat);
|
|
}
|
|
}
|
|
|
|
function inNodejsRuntime() {
|
|
return (typeof process !== 'undefined') &&
|
|
(process.browser === undefined) &&
|
|
process.title &&
|
|
(
|
|
process.title.indexOf('node') !== -1 ||
|
|
process.title.indexOf('meteor-tool') > 0 ||
|
|
process.title === 'grunt' ||
|
|
process.title === 'gulp'
|
|
) &&
|
|
("function" !== 'undefined');
|
|
}
|
|
|
|
/************************************
|
|
Floating-point helpers
|
|
************************************/
|
|
|
|
// The floating-point helper functions and implementation
|
|
// borrows heavily from sinful.js: http://guipn.github.io/sinful.js/
|
|
|
|
/**
|
|
* Array.prototype.reduce for browsers that don't support it
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce#Compatibility
|
|
*/
|
|
if ('function' !== typeof Array.prototype.reduce) {
|
|
Array.prototype.reduce = function(callback, optInitialValue) {
|
|
|
|
if (null === this || 'undefined' === typeof this) {
|
|
// At the moment all modern browsers, that support strict mode, have
|
|
// native implementation of Array.prototype.reduce. For instance, IE8
|
|
// does not support strict mode, so this check is actually useless.
|
|
throw new TypeError('Array.prototype.reduce called on null or undefined');
|
|
}
|
|
|
|
if ('function' !== typeof callback) {
|
|
throw new TypeError(callback + ' is not a function');
|
|
}
|
|
|
|
var index,
|
|
value,
|
|
length = this.length >>> 0,
|
|
isValueSet = false;
|
|
|
|
if (1 < arguments.length) {
|
|
value = optInitialValue;
|
|
isValueSet = true;
|
|
}
|
|
|
|
for (index = 0; length > index; ++index) {
|
|
if (this.hasOwnProperty(index)) {
|
|
if (isValueSet) {
|
|
value = callback(value, this[index], index, this);
|
|
} else {
|
|
value = this[index];
|
|
isValueSet = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isValueSet) {
|
|
throw new TypeError('Reduce of empty array with no initial value');
|
|
}
|
|
|
|
return value;
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
* Computes the multiplier necessary to make x >= 1,
|
|
* effectively eliminating miscalculations caused by
|
|
* finite precision.
|
|
*/
|
|
function multiplier(x) {
|
|
var parts = x.toString().split('.');
|
|
if (parts.length < 2) {
|
|
return 1;
|
|
}
|
|
return Math.pow(10, parts[1].length);
|
|
}
|
|
|
|
/**
|
|
* Given a variable number of arguments, returns the maximum
|
|
* multiplier that must be used to normalize an operation involving
|
|
* all of them.
|
|
*/
|
|
function correctionFactor() {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
return args.reduce(function(prev, next) {
|
|
var mp = multiplier(prev),
|
|
mn = multiplier(next);
|
|
return mp > mn ? mp : mn;
|
|
}, -Infinity);
|
|
}
|
|
|
|
/************************************
|
|
Numbro Prototype
|
|
************************************/
|
|
|
|
|
|
numbro.fn = Numbro.prototype = {
|
|
|
|
clone: function() {
|
|
return numbro(this);
|
|
},
|
|
|
|
format: function(inputString, roundingFunction) {
|
|
return formatNumbro(this,
|
|
inputString ? inputString : defaultFormat,
|
|
(roundingFunction !== undefined) ? roundingFunction : Math.round
|
|
);
|
|
},
|
|
|
|
formatCurrency: function(inputString, roundingFunction) {
|
|
return formatCurrency(this,
|
|
cultures[currentCulture].currency.symbol,
|
|
inputString ? inputString : defaultCurrencyFormat,
|
|
(roundingFunction !== undefined) ? roundingFunction : Math.round
|
|
);
|
|
},
|
|
|
|
formatForeignCurrency: function(currencySymbol, inputString, roundingFunction) {
|
|
return formatForeignCurrency(this,
|
|
currencySymbol,
|
|
inputString ? inputString : defaultCurrencyFormat,
|
|
(roundingFunction !== undefined) ? roundingFunction : Math.round
|
|
);
|
|
},
|
|
|
|
unformat: function(inputString) {
|
|
if (typeof inputString === 'number') {
|
|
return inputString;
|
|
} else if (typeof inputString === 'string') {
|
|
var result = unformatNumbro(this, inputString);
|
|
|
|
// Any unparseable string (represented as NaN in the result) is
|
|
// converted into undefined.
|
|
return isNaN(result) ? undefined : result;
|
|
} else {
|
|
return undefined;
|
|
}
|
|
},
|
|
|
|
binaryByteUnits: function() {
|
|
return formatByteUnits(this._value, bytes.binary.suffixes, bytes.binary.scale).suffix;
|
|
},
|
|
|
|
byteUnits: function() {
|
|
return formatByteUnits(this._value, bytes.general.suffixes, bytes.general.scale).suffix;
|
|
},
|
|
|
|
decimalByteUnits: function() {
|
|
return formatByteUnits(this._value, bytes.decimal.suffixes, bytes.decimal.scale).suffix;
|
|
},
|
|
|
|
value: function() {
|
|
return this._value;
|
|
},
|
|
|
|
valueOf: function() {
|
|
return this._value;
|
|
},
|
|
|
|
set: function(value) {
|
|
this._value = Number(value);
|
|
return this;
|
|
},
|
|
|
|
add: function(value) {
|
|
var corrFactor = correctionFactor.call(null, this._value, value);
|
|
|
|
function cback(accum, curr) {
|
|
return accum + corrFactor * curr;
|
|
}
|
|
this._value = [this._value, value].reduce(cback, 0) / corrFactor;
|
|
return this;
|
|
},
|
|
|
|
subtract: function(value) {
|
|
var corrFactor = correctionFactor.call(null, this._value, value);
|
|
|
|
function cback(accum, curr) {
|
|
return accum - corrFactor * curr;
|
|
}
|
|
this._value = [value].reduce(cback, this._value * corrFactor) / corrFactor;
|
|
return this;
|
|
},
|
|
|
|
multiply: function(value) {
|
|
function cback(accum, curr) {
|
|
var corrFactor = correctionFactor(accum, curr),
|
|
result = accum * corrFactor;
|
|
result *= curr * corrFactor;
|
|
result /= corrFactor * corrFactor;
|
|
return result;
|
|
}
|
|
this._value = [this._value, value].reduce(cback, 1);
|
|
return this;
|
|
},
|
|
|
|
divide: function(value) {
|
|
function cback(accum, curr) {
|
|
var corrFactor = correctionFactor(accum, curr);
|
|
return (accum * corrFactor) / (curr * corrFactor);
|
|
}
|
|
this._value = [this._value, value].reduce(cback);
|
|
return this;
|
|
},
|
|
|
|
difference: function(value) {
|
|
return Math.abs(numbro(this._value).subtract(value).value());
|
|
}
|
|
|
|
};
|
|
|
|
/************************************
|
|
Exposing Numbro
|
|
************************************/
|
|
|
|
if (inNodejsRuntime()) {
|
|
//Todo: Rename the folder in 2.0.0
|
|
numbro.loadCulturesInNode();
|
|
}
|
|
|
|
// CommonJS module is defined
|
|
if (hasModule) {
|
|
module.exports = numbro;
|
|
} else {
|
|
/*global ender:false */
|
|
if (typeof ender === 'undefined') {
|
|
// here, `this` means `window` in the browser, or `global` on the server
|
|
// add `numbro` as a global object via a string identifier,
|
|
// for Closure Compiler 'advanced' mode
|
|
this.numbro = numbro;
|
|
}
|
|
|
|
/*global define:false */
|
|
if (true) {
|
|
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
|
|
return numbro;
|
|
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
|
|
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
|
}
|
|
}
|
|
|
|
}.call(typeof window === 'undefined' ? this : window));
|
|
|
|
|
|
/*** EXPORTS FROM exports-to-window-loader ***/
|
|
window['numbro'] = __webpack_require__(51);
|
|
|
|
/***/ }),
|
|
/* 52 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = staticRegister;
|
|
|
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
|
|
var collection = exports.collection = new Map();
|
|
|
|
function staticRegister() {
|
|
var namespace = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'common';
|
|
|
|
if (!collection.has(namespace)) {
|
|
collection.set(namespace, new Map());
|
|
}
|
|
var subCollection = collection.get(namespace);
|
|
|
|
/**
|
|
* Register an item to the collection. If the item under the same was exist earlier then this item will be replaced with new one.
|
|
*
|
|
* @param {String} name Identification of the item.
|
|
* @param {*} item Item to save in the collection.
|
|
*/
|
|
function register(name, item) {
|
|
subCollection.set(name, item);
|
|
}
|
|
|
|
/**
|
|
* Retrieve the item from the collection.
|
|
*
|
|
* @param {String} name Identification of the item.
|
|
* @returns {*} Returns item which was saved in the collection.
|
|
*/
|
|
function getItem(name) {
|
|
return subCollection.get(name);
|
|
}
|
|
|
|
/**
|
|
* Check if item under specyfied name is exists.
|
|
*
|
|
* @param {String} name Identification of the item.
|
|
* @returns {Boolean} Returns `true` or `false` depends on if element exists in the collection.
|
|
*/
|
|
function hasItem(name) {
|
|
return subCollection.has(name);
|
|
}
|
|
|
|
/**
|
|
* Retrieve list of names registered from the collection.
|
|
*
|
|
* @returns {Array} Returns an array of strings with all names under which objects are stored.
|
|
*/
|
|
function getNames() {
|
|
return [].concat(_toConsumableArray(subCollection.keys()));
|
|
}
|
|
|
|
/**
|
|
* Retrieve all registered values from the collection.
|
|
*
|
|
* @returns {Array} Returns an array with all values stored in the collection.
|
|
*/
|
|
function getValues() {
|
|
return [].concat(_toConsumableArray(subCollection.values()));
|
|
}
|
|
|
|
return {
|
|
register: register,
|
|
getItem: getItem,
|
|
hasItem: hasItem,
|
|
getNames: getNames,
|
|
getValues: getValues
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 53 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function(it, Constructor, name, forbiddenField){
|
|
if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){
|
|
throw TypeError(name + ': incorrect invocation!');
|
|
} return it;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 54 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 0 -> Array#forEach
|
|
// 1 -> Array#map
|
|
// 2 -> Array#filter
|
|
// 3 -> Array#some
|
|
// 4 -> Array#every
|
|
// 5 -> Array#find
|
|
// 6 -> Array#findIndex
|
|
var ctx = __webpack_require__(29)
|
|
, IObject = __webpack_require__(78)
|
|
, toObject = __webpack_require__(42)
|
|
, toLength = __webpack_require__(24)
|
|
, asc = __webpack_require__(395);
|
|
module.exports = function(TYPE, $create){
|
|
var IS_MAP = TYPE == 1
|
|
, IS_FILTER = TYPE == 2
|
|
, IS_SOME = TYPE == 3
|
|
, IS_EVERY = TYPE == 4
|
|
, IS_FIND_INDEX = TYPE == 6
|
|
, NO_HOLES = TYPE == 5 || IS_FIND_INDEX
|
|
, create = $create || asc;
|
|
return function($this, callbackfn, that){
|
|
var O = toObject($this)
|
|
, self = IObject(O)
|
|
, f = ctx(callbackfn, that, 3)
|
|
, length = toLength(self.length)
|
|
, index = 0
|
|
, result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined
|
|
, val, res;
|
|
for(;length > index; index++)if(NO_HOLES || index in self){
|
|
val = self[index];
|
|
res = f(val, index, O);
|
|
if(TYPE){
|
|
if(IS_MAP)result[index] = res; // map
|
|
else if(res)switch(TYPE){
|
|
case 3: return true; // some
|
|
case 5: return val; // find
|
|
case 6: return index; // findIndex
|
|
case 2: result.push(val); // filter
|
|
} else if(IS_EVERY)return false; // every
|
|
}
|
|
}
|
|
return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 55 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var global = __webpack_require__(13)
|
|
, $export = __webpack_require__(3)
|
|
, redefine = __webpack_require__(33)
|
|
, redefineAll = __webpack_require__(60)
|
|
, meta = __webpack_require__(47)
|
|
, forOf = __webpack_require__(57)
|
|
, anInstance = __webpack_require__(53)
|
|
, isObject = __webpack_require__(15)
|
|
, fails = __webpack_require__(31)
|
|
, $iterDetect = __webpack_require__(79)
|
|
, setToStringTag = __webpack_require__(49)
|
|
, inheritIfRequired = __webpack_require__(398);
|
|
|
|
module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){
|
|
var Base = global[NAME]
|
|
, C = Base
|
|
, ADDER = IS_MAP ? 'set' : 'add'
|
|
, proto = C && C.prototype
|
|
, O = {};
|
|
var fixMethod = function(KEY){
|
|
var fn = proto[KEY];
|
|
redefine(proto, KEY,
|
|
KEY == 'delete' ? function(a){
|
|
return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
|
|
} : KEY == 'has' ? function has(a){
|
|
return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
|
|
} : KEY == 'get' ? function get(a){
|
|
return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
|
|
} : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; }
|
|
: function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; }
|
|
);
|
|
};
|
|
if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){
|
|
new C().entries().next();
|
|
}))){
|
|
// create collection constructor
|
|
C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
|
|
redefineAll(C.prototype, methods);
|
|
meta.NEED = true;
|
|
} else {
|
|
var instance = new C
|
|
// early implementations not supports chaining
|
|
, HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance
|
|
// V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
|
|
, THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); })
|
|
// most early implementations doesn't supports iterables, most modern - not close it correctly
|
|
, ACCEPT_ITERABLES = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new
|
|
// for early implementations -0 and +0 not the same
|
|
, BUGGY_ZERO = !IS_WEAK && fails(function(){
|
|
// V8 ~ Chromium 42- fails only with 5+ elements
|
|
var $instance = new C()
|
|
, index = 5;
|
|
while(index--)$instance[ADDER](index, index);
|
|
return !$instance.has(-0);
|
|
});
|
|
if(!ACCEPT_ITERABLES){
|
|
C = wrapper(function(target, iterable){
|
|
anInstance(target, C, NAME);
|
|
var that = inheritIfRequired(new Base, target, C);
|
|
if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
|
|
return that;
|
|
});
|
|
C.prototype = proto;
|
|
proto.constructor = C;
|
|
}
|
|
if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){
|
|
fixMethod('delete');
|
|
fixMethod('has');
|
|
IS_MAP && fixMethod('get');
|
|
}
|
|
if(BUGGY_ZERO || HASNT_CHAINING)fixMethod(ADDER);
|
|
// weak collections should not contains .clear method
|
|
if(IS_WEAK && proto.clear)delete proto.clear;
|
|
}
|
|
|
|
setToStringTag(C, NAME);
|
|
|
|
O[NAME] = C;
|
|
$export($export.G + $export.W + $export.F * (C != Base), O);
|
|
|
|
if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP);
|
|
|
|
return C;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 56 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var hide = __webpack_require__(32)
|
|
, redefine = __webpack_require__(33)
|
|
, fails = __webpack_require__(31)
|
|
, defined = __webpack_require__(30)
|
|
, wks = __webpack_require__(10);
|
|
|
|
module.exports = function(KEY, length, exec){
|
|
var SYMBOL = wks(KEY)
|
|
, fns = exec(defined, SYMBOL, ''[KEY])
|
|
, strfn = fns[0]
|
|
, rxfn = fns[1];
|
|
if(fails(function(){
|
|
var O = {};
|
|
O[SYMBOL] = function(){ return 7; };
|
|
return ''[KEY](O) != 7;
|
|
})){
|
|
redefine(String.prototype, KEY, strfn);
|
|
hide(RegExp.prototype, SYMBOL, length == 2
|
|
// 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
|
|
// 21.2.5.11 RegExp.prototype[@@split](string, limit)
|
|
? function(string, arg){ return rxfn.call(string, this, arg); }
|
|
// 21.2.5.6 RegExp.prototype[@@match](string)
|
|
// 21.2.5.9 RegExp.prototype[@@search](string)
|
|
: function(string){ return rxfn.call(string, this); }
|
|
);
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 57 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var ctx = __webpack_require__(29)
|
|
, call = __webpack_require__(280)
|
|
, isArrayIter = __webpack_require__(276)
|
|
, anObject = __webpack_require__(18)
|
|
, toLength = __webpack_require__(24)
|
|
, getIterFn = __webpack_require__(291)
|
|
, BREAK = {}
|
|
, RETURN = {};
|
|
var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){
|
|
var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable)
|
|
, f = ctx(fn, that, entries ? 2 : 1)
|
|
, index = 0
|
|
, length, step, iterator, result;
|
|
if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');
|
|
// fast case for arrays with default iterator
|
|
if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){
|
|
result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
|
|
if(result === BREAK || result === RETURN)return result;
|
|
} else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){
|
|
result = call(iterator, f, step.value, entries);
|
|
if(result === BREAK || result === RETURN)return result;
|
|
}
|
|
};
|
|
exports.BREAK = BREAK;
|
|
exports.RETURN = RETURN;
|
|
|
|
/***/ }),
|
|
/* 58 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = false;
|
|
|
|
/***/ }),
|
|
/* 59 */
|
|
/***/ (function(module, exports) {
|
|
|
|
exports.f = Object.getOwnPropertySymbols;
|
|
|
|
/***/ }),
|
|
/* 60 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var redefine = __webpack_require__(33);
|
|
module.exports = function(target, src, safe){
|
|
for(var key in src)redefine(target, key, src[key], safe);
|
|
return target;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 61 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var toInteger = __webpack_require__(62)
|
|
, max = Math.max
|
|
, min = Math.min;
|
|
module.exports = function(index, length){
|
|
index = toInteger(index);
|
|
return index < 0 ? max(index + length, 0) : min(index, length);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 62 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// 7.1.4 ToInteger
|
|
var ceil = Math.ceil
|
|
, floor = Math.floor;
|
|
module.exports = function(it){
|
|
return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 63 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.getRegisteredCellTypes = exports.getRegisteredCellTypeNames = exports.hasCellType = exports.getCellType = exports.registerCellType = undefined;
|
|
|
|
var _staticRegister2 = __webpack_require__(52);
|
|
|
|
var _staticRegister3 = _interopRequireDefault(_staticRegister2);
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var _autocompleteType = __webpack_require__(304);
|
|
|
|
var _autocompleteType2 = _interopRequireDefault(_autocompleteType);
|
|
|
|
var _checkboxType = __webpack_require__(305);
|
|
|
|
var _checkboxType2 = _interopRequireDefault(_checkboxType);
|
|
|
|
var _dateType = __webpack_require__(306);
|
|
|
|
var _dateType2 = _interopRequireDefault(_dateType);
|
|
|
|
var _dropdownType = __webpack_require__(307);
|
|
|
|
var _dropdownType2 = _interopRequireDefault(_dropdownType);
|
|
|
|
var _handsontableType = __webpack_require__(308);
|
|
|
|
var _handsontableType2 = _interopRequireDefault(_handsontableType);
|
|
|
|
var _numericType = __webpack_require__(309);
|
|
|
|
var _numericType2 = _interopRequireDefault(_numericType);
|
|
|
|
var _passwordType = __webpack_require__(310);
|
|
|
|
var _passwordType2 = _interopRequireDefault(_passwordType);
|
|
|
|
var _textType = __webpack_require__(311);
|
|
|
|
var _textType2 = _interopRequireDefault(_textType);
|
|
|
|
var _timeType = __webpack_require__(312);
|
|
|
|
var _timeType2 = _interopRequireDefault(_timeType);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var _staticRegister = (0, _staticRegister3.default)('cellTypes'),
|
|
register = _staticRegister.register,
|
|
getItem = _staticRegister.getItem,
|
|
hasItem = _staticRegister.hasItem,
|
|
getNames = _staticRegister.getNames,
|
|
getValues = _staticRegister.getValues;
|
|
|
|
_register('autocomplete', _autocompleteType2.default);
|
|
_register('checkbox', _checkboxType2.default);
|
|
_register('date', _dateType2.default);
|
|
_register('dropdown', _dropdownType2.default);
|
|
_register('handsontable', _handsontableType2.default);
|
|
_register('numeric', _numericType2.default);
|
|
_register('password', _passwordType2.default);
|
|
_register('text', _textType2.default);
|
|
_register('time', _timeType2.default);
|
|
|
|
/**
|
|
* Retrieve cell type object.
|
|
*
|
|
* @param {String} name Cell type identification.
|
|
* @returns {Object} Returns cell type object.
|
|
*/
|
|
function _getItem(name) {
|
|
if (!hasItem(name)) {
|
|
throw Error('You declared cell type "' + name + '" as a string that is not mapped to a known object.\n Cell type must be an object or a string mapped to an object registered by "Handsontable.cellTypes.registerCellType" method');
|
|
}
|
|
|
|
return getItem(name);
|
|
}
|
|
|
|
/**
|
|
* Register cell type under specified name.
|
|
*
|
|
* @param {String} name Cell type identification.
|
|
* @param {Object} type An object with contains keys (eq: `editor`, `renderer`, `validator`) which describes specified behaviour of the cell.
|
|
*/
|
|
function _register(name, type) {
|
|
var editor = type.editor,
|
|
renderer = type.renderer,
|
|
validator = type.validator;
|
|
|
|
|
|
if (editor) {
|
|
(0, _editors.registerEditor)(name, editor);
|
|
}
|
|
if (renderer) {
|
|
(0, _renderers.registerRenderer)(name, renderer);
|
|
}
|
|
if (validator) {
|
|
(0, _validators.registerValidator)(name, validator);
|
|
}
|
|
|
|
register(name, type);
|
|
}
|
|
|
|
exports.registerCellType = _register;
|
|
exports.getCellType = _getItem;
|
|
exports.hasCellType = hasItem;
|
|
exports.getRegisteredCellTypeNames = getNames;
|
|
exports.getRegisteredCellTypes = getValues;
|
|
|
|
/***/ }),
|
|
/* 64 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
exports.default = Core;
|
|
|
|
var _numbro = __webpack_require__(51);
|
|
|
|
var _numbro2 = _interopRequireDefault(_numbro);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _setting = __webpack_require__(66);
|
|
|
|
var _function = __webpack_require__(35);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _dataMap = __webpack_require__(313);
|
|
|
|
var _dataMap2 = _interopRequireDefault(_dataMap);
|
|
|
|
var _editorManager = __webpack_require__(315);
|
|
|
|
var _editorManager2 = _interopRequireDefault(_editorManager);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _tableView = __webpack_require__(384);
|
|
|
|
var _tableView2 = _interopRequireDefault(_tableView);
|
|
|
|
var _dataSource = __webpack_require__(314);
|
|
|
|
var _dataSource2 = _interopRequireDefault(_dataSource);
|
|
|
|
var _data = __webpack_require__(65);
|
|
|
|
var _recordTranslator = __webpack_require__(268);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _defaultSettings = __webpack_require__(88);
|
|
|
|
var _defaultSettings2 = _interopRequireDefault(_defaultSettings);
|
|
|
|
var _cellTypes = __webpack_require__(63);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
|
|
var activeGuid = null;
|
|
|
|
/**
|
|
* Handsontable constructor
|
|
*
|
|
* @core
|
|
* @dependencies numbro
|
|
* @constructor Core
|
|
* @description
|
|
*
|
|
* After Handsontable is constructed, you can modify the grid behavior using the available public methods.
|
|
*
|
|
* ---
|
|
* ## How to call methods
|
|
*
|
|
* These are 2 equal ways to call a Handsontable method:
|
|
*
|
|
* ```js
|
|
* // all following examples assume that you constructed Handsontable like this
|
|
* var ht = new Handsontable(document.getElementById('example1'), options);
|
|
*
|
|
* // now, to use setDataAtCell method, you can either:
|
|
* ht.setDataAtCell(0, 0, 'new value');
|
|
* ```
|
|
*
|
|
* Alternatively, you can call the method using jQuery wrapper (__obsolete__, requires initialization using our jQuery guide
|
|
* ```js
|
|
* $('#example1').handsontable('setDataAtCell', 0, 0, 'new value');
|
|
* ```
|
|
* ---
|
|
*/
|
|
function Core(rootElement, userSettings) {
|
|
var priv,
|
|
datamap,
|
|
dataSource,
|
|
grid,
|
|
selection,
|
|
editorManager,
|
|
instance = this,
|
|
GridSettings = function GridSettings() {},
|
|
eventManager = new _eventManager2.default(instance);
|
|
|
|
(0, _object.extend)(GridSettings.prototype, _defaultSettings2.default.prototype); // create grid settings as a copy of default settings
|
|
(0, _object.extend)(GridSettings.prototype, userSettings); // overwrite defaults with user settings
|
|
(0, _object.extend)(GridSettings.prototype, expandType(userSettings));
|
|
|
|
this.rootElement = rootElement;
|
|
this.isHotTableEnv = (0, _element.isChildOfWebComponentTable)(this.rootElement);
|
|
_eventManager2.default.isHotTableEnv = this.isHotTableEnv;
|
|
|
|
this.container = document.createElement('DIV');
|
|
this.renderCall = false;
|
|
|
|
rootElement.insertBefore(this.container, rootElement.firstChild);
|
|
|
|
this.guid = 'ht_' + (0, _string.randomString)(); // this is the namespace for global events
|
|
|
|
var recordTranslator = (0, _recordTranslator.getTranslator)(instance);
|
|
|
|
dataSource = new _dataSource2.default(instance);
|
|
|
|
if (!this.rootElement.id || this.rootElement.id.substring(0, 3) === 'ht_') {
|
|
this.rootElement.id = this.guid; // if root element does not have an id, assign a random id
|
|
}
|
|
priv = {
|
|
cellSettings: [],
|
|
columnSettings: [],
|
|
columnsSettingConflicts: ['data', 'width'],
|
|
settings: new GridSettings(), // current settings instance
|
|
selRange: null, // exposed by public method `getSelectedRange`
|
|
isPopulated: null,
|
|
scrollable: null,
|
|
firstRun: true
|
|
};
|
|
|
|
grid = {
|
|
/**
|
|
* Inserts or removes rows and columns
|
|
*
|
|
* @memberof Core#
|
|
* @function alter
|
|
* @private
|
|
* @param {String} action Possible values: "insert_row", "insert_col", "remove_row", "remove_col"
|
|
* @param {Number} index
|
|
* @param {Number} amount
|
|
* @param {String} [source] Optional. Source of hook runner.
|
|
* @param {Boolean} [keepEmptyRows] Optional. Flag for preventing deletion of empty rows.
|
|
*/
|
|
alter: function alter(action, index, amount, source, keepEmptyRows) {
|
|
var delta;
|
|
|
|
amount = amount || 1;
|
|
|
|
function spliceWith(data, index, count, toInject) {
|
|
var valueFactory = function valueFactory() {
|
|
var result = void 0;
|
|
|
|
if (toInject === 'array') {
|
|
result = [];
|
|
} else if (toInject === 'object') {
|
|
result = {};
|
|
}
|
|
|
|
return result;
|
|
};
|
|
var spliceArgs = (0, _array.arrayMap)(new Array(count), function () {
|
|
return valueFactory();
|
|
});
|
|
|
|
spliceArgs.unshift(index, 0);
|
|
data.splice.apply(data, _toConsumableArray(spliceArgs));
|
|
}
|
|
|
|
/* eslint-disable no-case-declarations */
|
|
switch (action) {
|
|
case 'insert_row':
|
|
|
|
var numberOfSourceRows = instance.countSourceRows();
|
|
|
|
if (instance.getSettings().maxRows === numberOfSourceRows) {
|
|
return;
|
|
}
|
|
|
|
index = (0, _mixed.isDefined)(index) ? index : numberOfSourceRows;
|
|
|
|
delta = datamap.createRow(index, amount, source);
|
|
spliceWith(priv.cellSettings, index, amount, 'array');
|
|
|
|
if (delta) {
|
|
if (selection.isSelected() && priv.selRange.from.row >= index) {
|
|
priv.selRange.from.row += delta;
|
|
selection.transformEnd(delta, 0); // will call render() internally
|
|
} else {
|
|
selection.refreshBorders(); // it will call render and prepare methods
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'insert_col':
|
|
delta = datamap.createCol(index, amount, source);
|
|
|
|
for (var row = 0, len = instance.countSourceRows(); row < len; row++) {
|
|
if (priv.cellSettings[row]) {
|
|
spliceWith(priv.cellSettings[row], index, amount);
|
|
}
|
|
}
|
|
|
|
if (delta) {
|
|
if (Array.isArray(instance.getSettings().colHeaders)) {
|
|
var spliceArray = [index, 0];
|
|
spliceArray.length += delta; // inserts empty (undefined) elements at the end of an array
|
|
Array.prototype.splice.apply(instance.getSettings().colHeaders, spliceArray); // inserts empty (undefined) elements into the colHeader array
|
|
}
|
|
|
|
if (selection.isSelected() && priv.selRange.from.col >= index) {
|
|
priv.selRange.from.col += delta;
|
|
selection.transformEnd(0, delta); // will call render() internally
|
|
} else {
|
|
selection.refreshBorders(); // it will call render and prepare methods
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'remove_row':
|
|
datamap.removeRow(index, amount, source);
|
|
priv.cellSettings.splice(index, amount);
|
|
|
|
var totalRows = instance.countRows();
|
|
var fixedRowsTop = instance.getSettings().fixedRowsTop;
|
|
if (fixedRowsTop >= index + 1) {
|
|
instance.getSettings().fixedRowsTop -= Math.min(amount, fixedRowsTop - index);
|
|
}
|
|
|
|
var fixedRowsBottom = instance.getSettings().fixedRowsBottom;
|
|
if (fixedRowsBottom && index >= totalRows - fixedRowsBottom) {
|
|
instance.getSettings().fixedRowsBottom -= Math.min(amount, fixedRowsBottom);
|
|
}
|
|
|
|
grid.adjustRowsAndCols();
|
|
selection.refreshBorders(); // it will call render and prepare methods
|
|
break;
|
|
|
|
case 'remove_col':
|
|
var visualColumnIndex = recordTranslator.toPhysicalColumn(index);
|
|
|
|
datamap.removeCol(index, amount, source);
|
|
|
|
for (var _row = 0, _len = instance.countSourceRows(); _row < _len; _row++) {
|
|
if (priv.cellSettings[_row]) {
|
|
// if row hasn't been rendered it wouldn't have cellSettings
|
|
priv.cellSettings[_row].splice(visualColumnIndex, amount);
|
|
}
|
|
}
|
|
var fixedColumnsLeft = instance.getSettings().fixedColumnsLeft;
|
|
|
|
if (fixedColumnsLeft >= index + 1) {
|
|
instance.getSettings().fixedColumnsLeft -= Math.min(amount, fixedColumnsLeft - index);
|
|
}
|
|
|
|
if (Array.isArray(instance.getSettings().colHeaders)) {
|
|
if (typeof visualColumnIndex === 'undefined') {
|
|
visualColumnIndex = -1;
|
|
}
|
|
instance.getSettings().colHeaders.splice(visualColumnIndex, amount);
|
|
}
|
|
|
|
grid.adjustRowsAndCols();
|
|
selection.refreshBorders(); // it will call render and prepare methods
|
|
|
|
break;
|
|
default:
|
|
throw new Error('There is no such action "' + action + '"');
|
|
}
|
|
|
|
if (!keepEmptyRows) {
|
|
grid.adjustRowsAndCols(); // makes sure that we did not add rows that will be removed in next refresh
|
|
}
|
|
},
|
|
|
|
|
|
/**
|
|
* Makes sure there are empty rows at the bottom of the table
|
|
*/
|
|
adjustRowsAndCols: function adjustRowsAndCols() {
|
|
if (priv.settings.minRows) {
|
|
// should I add empty rows to data source to meet minRows?
|
|
var rows = instance.countRows();
|
|
|
|
if (rows < priv.settings.minRows) {
|
|
for (var r = 0, minRows = priv.settings.minRows; r < minRows - rows; r++) {
|
|
datamap.createRow(instance.countRows(), 1, 'auto');
|
|
}
|
|
}
|
|
}
|
|
if (priv.settings.minSpareRows) {
|
|
var emptyRows = instance.countEmptyRows(true);
|
|
|
|
// should I add empty rows to meet minSpareRows?
|
|
if (emptyRows < priv.settings.minSpareRows) {
|
|
for (; emptyRows < priv.settings.minSpareRows && instance.countSourceRows() < priv.settings.maxRows; emptyRows++) {
|
|
datamap.createRow(instance.countRows(), 1, 'auto');
|
|
}
|
|
}
|
|
}
|
|
{
|
|
var emptyCols = void 0;
|
|
|
|
// count currently empty cols
|
|
if (priv.settings.minCols || priv.settings.minSpareCols) {
|
|
emptyCols = instance.countEmptyCols(true);
|
|
}
|
|
|
|
// should I add empty cols to meet minCols?
|
|
if (priv.settings.minCols && !priv.settings.columns && instance.countCols() < priv.settings.minCols) {
|
|
for (; instance.countCols() < priv.settings.minCols; emptyCols++) {
|
|
datamap.createCol(instance.countCols(), 1, 'auto');
|
|
}
|
|
}
|
|
// should I add empty cols to meet minSpareCols?
|
|
if (priv.settings.minSpareCols && !priv.settings.columns && instance.dataType === 'array' && emptyCols < priv.settings.minSpareCols) {
|
|
for (; emptyCols < priv.settings.minSpareCols && instance.countCols() < priv.settings.maxCols; emptyCols++) {
|
|
datamap.createCol(instance.countCols(), 1, 'auto');
|
|
}
|
|
}
|
|
}
|
|
var rowCount = instance.countRows();
|
|
var colCount = instance.countCols();
|
|
|
|
if (rowCount === 0 || colCount === 0) {
|
|
selection.deselect();
|
|
}
|
|
|
|
if (selection.isSelected()) {
|
|
var selectionChanged = false;
|
|
var fromRow = priv.selRange.from.row;
|
|
var fromCol = priv.selRange.from.col;
|
|
var toRow = priv.selRange.to.row;
|
|
var toCol = priv.selRange.to.col;
|
|
|
|
// if selection is outside, move selection to last row
|
|
if (fromRow > rowCount - 1) {
|
|
fromRow = rowCount - 1;
|
|
selectionChanged = true;
|
|
|
|
if (toRow > fromRow) {
|
|
toRow = fromRow;
|
|
}
|
|
} else if (toRow > rowCount - 1) {
|
|
toRow = rowCount - 1;
|
|
selectionChanged = true;
|
|
|
|
if (fromRow > toRow) {
|
|
fromRow = toRow;
|
|
}
|
|
}
|
|
// if selection is outside, move selection to last row
|
|
if (fromCol > colCount - 1) {
|
|
fromCol = colCount - 1;
|
|
selectionChanged = true;
|
|
|
|
if (toCol > fromCol) {
|
|
toCol = fromCol;
|
|
}
|
|
} else if (toCol > colCount - 1) {
|
|
toCol = colCount - 1;
|
|
selectionChanged = true;
|
|
|
|
if (fromCol > toCol) {
|
|
fromCol = toCol;
|
|
}
|
|
}
|
|
|
|
if (selectionChanged) {
|
|
instance.selectCell(fromRow, fromCol, toRow, toCol);
|
|
}
|
|
}
|
|
if (instance.view) {
|
|
instance.view.wt.wtOverlays.adjustElementsSize();
|
|
}
|
|
},
|
|
|
|
|
|
/**
|
|
* Populate the data from the provided 2d array from the given cell coordinates.
|
|
*
|
|
* @private
|
|
* @param {Object} start Start selection position. Visual indexes.
|
|
* @param {Array} input 2d data array.
|
|
* @param {Object} [end] End selection position (only for drag-down mode). Visual indexes.
|
|
* @param {String} [source="populateFromArray"] Source information string.
|
|
* @param {String} [method="overwrite"] Populate method. Possible options: `shift_down`, `shift_right`, `overwrite`.
|
|
* @param {String} direction (left|right|up|down) String specifying the direction.
|
|
* @param {Array} deltas The deltas array. A difference between values of adjacent cells.
|
|
* Useful **only** when the type of handled cells is `numeric`.
|
|
* @returns {Object|undefined} ending td in pasted area (only if any cell was changed).
|
|
*/
|
|
populateFromArray: function populateFromArray(start, input, end, source, method, direction, deltas) {
|
|
// TODO: either remove or implement the `direction` argument. Currently it's not working at all.
|
|
var r,
|
|
rlen,
|
|
c,
|
|
clen,
|
|
setData = [],
|
|
current = {};
|
|
|
|
rlen = input.length;
|
|
|
|
if (rlen === 0) {
|
|
return false;
|
|
}
|
|
|
|
var repeatCol,
|
|
repeatRow,
|
|
cmax,
|
|
rmax,
|
|
baseEnd = {
|
|
row: end === null ? null : end.row,
|
|
col: end === null ? null : end.col
|
|
};
|
|
|
|
/* eslint-disable no-case-declarations */
|
|
// insert data with specified pasteMode method
|
|
switch (method) {
|
|
case 'shift_down':
|
|
repeatCol = end ? end.col - start.col + 1 : 0;
|
|
repeatRow = end ? end.row - start.row + 1 : 0;
|
|
input = (0, _data.translateRowsToColumns)(input);
|
|
for (c = 0, clen = input.length, cmax = Math.max(clen, repeatCol); c < cmax; c++) {
|
|
if (c < clen) {
|
|
var _instance;
|
|
|
|
for (r = 0, rlen = input[c].length; r < repeatRow - rlen; r++) {
|
|
input[c].push(input[c][r % rlen]);
|
|
}
|
|
input[c].unshift(start.col + c, start.row, 0);
|
|
(_instance = instance).spliceCol.apply(_instance, _toConsumableArray(input[c]));
|
|
} else {
|
|
var _instance2;
|
|
|
|
input[c % clen][0] = start.col + c;
|
|
(_instance2 = instance).spliceCol.apply(_instance2, _toConsumableArray(input[c % clen]));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'shift_right':
|
|
repeatCol = end ? end.col - start.col + 1 : 0;
|
|
repeatRow = end ? end.row - start.row + 1 : 0;
|
|
for (r = 0, rlen = input.length, rmax = Math.max(rlen, repeatRow); r < rmax; r++) {
|
|
if (r < rlen) {
|
|
var _instance3;
|
|
|
|
for (c = 0, clen = input[r].length; c < repeatCol - clen; c++) {
|
|
input[r].push(input[r][c % clen]);
|
|
}
|
|
input[r].unshift(start.row + r, start.col, 0);
|
|
(_instance3 = instance).spliceRow.apply(_instance3, _toConsumableArray(input[r]));
|
|
} else {
|
|
var _instance4;
|
|
|
|
input[r % rlen][0] = start.row + r;
|
|
(_instance4 = instance).spliceRow.apply(_instance4, _toConsumableArray(input[r % rlen]));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'overwrite':
|
|
default:
|
|
// overwrite and other not specified options
|
|
current.row = start.row;
|
|
current.col = start.col;
|
|
|
|
var selected = { // selected range
|
|
row: end && start ? end.row - start.row + 1 : 1,
|
|
col: end && start ? end.col - start.col + 1 : 1
|
|
};
|
|
var skippedRow = 0;
|
|
var skippedColumn = 0;
|
|
var pushData = true;
|
|
var cellMeta = void 0;
|
|
|
|
var getInputValue = function getInputValue(row) {
|
|
var col = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
|
|
var rowValue = input[row % input.length];
|
|
|
|
if (col !== null) {
|
|
return rowValue[col % rowValue.length];
|
|
}
|
|
|
|
return rowValue;
|
|
};
|
|
var rowInputLength = input.length;
|
|
var rowSelectionLength = end ? end.row - start.row + 1 : 0;
|
|
|
|
if (end) {
|
|
rlen = rowSelectionLength;
|
|
} else {
|
|
rlen = Math.max(rowInputLength, rowSelectionLength);
|
|
}
|
|
for (r = 0; r < rlen; r++) {
|
|
if (end && current.row > end.row && rowSelectionLength > rowInputLength || !priv.settings.allowInsertRow && current.row > instance.countRows() - 1 || current.row >= priv.settings.maxRows) {
|
|
break;
|
|
}
|
|
var visualRow = r - skippedRow;
|
|
var colInputLength = getInputValue(visualRow).length;
|
|
var colSelectionLength = end ? end.col - start.col + 1 : 0;
|
|
|
|
if (end) {
|
|
clen = colSelectionLength;
|
|
} else {
|
|
clen = Math.max(colInputLength, colSelectionLength);
|
|
}
|
|
current.col = start.col;
|
|
cellMeta = instance.getCellMeta(current.row, current.col);
|
|
|
|
if ((source === 'CopyPaste.paste' || source === 'Autofill.autofill') && cellMeta.skipRowOnPaste) {
|
|
skippedRow++;
|
|
current.row++;
|
|
rlen++;
|
|
/* eslint-disable no-continue */
|
|
continue;
|
|
}
|
|
skippedColumn = 0;
|
|
|
|
for (c = 0; c < clen; c++) {
|
|
if (end && current.col > end.col && colSelectionLength > colInputLength || !priv.settings.allowInsertColumn && current.col > instance.countCols() - 1 || current.col >= priv.settings.maxCols) {
|
|
break;
|
|
}
|
|
cellMeta = instance.getCellMeta(current.row, current.col);
|
|
|
|
if ((source === 'CopyPaste.paste' || source === 'Autofill.fill') && cellMeta.skipColumnOnPaste) {
|
|
skippedColumn++;
|
|
current.col++;
|
|
clen++;
|
|
continue;
|
|
}
|
|
if (cellMeta.readOnly) {
|
|
current.col++;
|
|
/* eslint-disable no-continue */
|
|
continue;
|
|
}
|
|
var visualColumn = c - skippedColumn;
|
|
var value = getInputValue(visualRow, visualColumn);
|
|
var orgValue = instance.getDataAtCell(current.row, current.col);
|
|
var index = {
|
|
row: visualRow,
|
|
col: visualColumn
|
|
};
|
|
|
|
if (source === 'Autofill.fill') {
|
|
var result = instance.runHooks('beforeAutofillInsidePopulate', index, direction, input, deltas, {}, selected);
|
|
|
|
if (result) {
|
|
value = (0, _mixed.isUndefined)(result.value) ? value : result.value;
|
|
}
|
|
}
|
|
if (value !== null && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
|
|
if (orgValue === null || (typeof orgValue === 'undefined' ? 'undefined' : _typeof(orgValue)) !== 'object') {
|
|
pushData = false;
|
|
} else {
|
|
var orgValueSchema = (0, _object.duckSchema)(orgValue[0] || orgValue);
|
|
var valueSchema = (0, _object.duckSchema)(value[0] || value);
|
|
|
|
/* eslint-disable max-depth */
|
|
if ((0, _object.isObjectEquals)(orgValueSchema, valueSchema)) {
|
|
value = (0, _object.deepClone)(value);
|
|
} else {
|
|
pushData = false;
|
|
}
|
|
}
|
|
} else if (orgValue !== null && (typeof orgValue === 'undefined' ? 'undefined' : _typeof(orgValue)) === 'object') {
|
|
pushData = false;
|
|
}
|
|
if (pushData) {
|
|
setData.push([current.row, current.col, value]);
|
|
}
|
|
pushData = true;
|
|
current.col++;
|
|
}
|
|
current.row++;
|
|
}
|
|
instance.setDataAtCell(setData, null, null, source || 'populateFromArray');
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
/* eslint-disable no-multi-assign */
|
|
this.selection = selection = { // this public assignment is only temporary
|
|
inProgress: false,
|
|
|
|
selectedHeader: {
|
|
cols: false,
|
|
rows: false
|
|
},
|
|
|
|
/**
|
|
* @param {Boolean} [rows=false]
|
|
* @param {Boolean} [cols=false]
|
|
* @param {Boolean} [corner=false]
|
|
*/
|
|
setSelectedHeaders: function setSelectedHeaders() {
|
|
var rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
var cols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
var corner = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
|
|
instance.selection.selectedHeader.rows = rows;
|
|
instance.selection.selectedHeader.cols = cols;
|
|
instance.selection.selectedHeader.corner = corner;
|
|
},
|
|
|
|
|
|
/**
|
|
* Sets inProgress to `true`. This enables onSelectionEnd and onSelectionEndByProp to function as desired.
|
|
*/
|
|
begin: function begin() {
|
|
instance.selection.inProgress = true;
|
|
},
|
|
|
|
|
|
/**
|
|
* Sets inProgress to `false`. Triggers onSelectionEnd and onSelectionEndByProp.
|
|
*/
|
|
finish: function finish() {
|
|
var sel = instance.getSelected();
|
|
instance.runHooks('afterSelectionEnd', sel[0], sel[1], sel[2], sel[3]);
|
|
instance.runHooks('afterSelectionEndByProp', sel[0], instance.colToProp(sel[1]), sel[2], instance.colToProp(sel[3]));
|
|
instance.selection.inProgress = false;
|
|
},
|
|
|
|
|
|
/**
|
|
* @returns {Boolean}
|
|
*/
|
|
isInProgress: function isInProgress() {
|
|
return instance.selection.inProgress;
|
|
},
|
|
|
|
|
|
/**
|
|
* Starts selection range on given td object.
|
|
*
|
|
* @param {CellCoords} coords Visual coords.
|
|
* @param keepEditorOpened
|
|
*/
|
|
setRangeStart: function setRangeStart(coords, keepEditorOpened) {
|
|
instance.runHooks('beforeSetRangeStart', coords);
|
|
priv.selRange = new _src.CellRange(coords, coords, coords);
|
|
selection.setRangeEnd(coords, null, keepEditorOpened);
|
|
},
|
|
|
|
|
|
/**
|
|
* Starts selection range on given td object.
|
|
*
|
|
* @param {CellCoords} coords Visual coords.
|
|
* @param keepEditorOpened
|
|
*/
|
|
setRangeStartOnly: function setRangeStartOnly(coords) {
|
|
instance.runHooks('beforeSetRangeStartOnly', coords);
|
|
priv.selRange = new _src.CellRange(coords, coords, coords);
|
|
},
|
|
|
|
|
|
/**
|
|
* Ends selection range on given td object.
|
|
*
|
|
* @param {CellCoords} coords Visual coords.
|
|
* @param {Boolean} [scrollToCell=true] If `true`, viewport will be scrolled to range end
|
|
* @param {Boolean} [keepEditorOpened] If `true`, cell editor will be still opened after changing selection range
|
|
*/
|
|
setRangeEnd: function setRangeEnd(coords, scrollToCell, keepEditorOpened) {
|
|
if (priv.selRange === null) {
|
|
return;
|
|
}
|
|
var disableVisualSelection,
|
|
isHeaderSelected = false,
|
|
areCoordsPositive = true;
|
|
|
|
var firstVisibleRow = instance.view.wt.wtTable.getFirstVisibleRow();
|
|
var firstVisibleColumn = instance.view.wt.wtTable.getFirstVisibleColumn();
|
|
var newRangeCoords = {
|
|
row: null,
|
|
col: null
|
|
};
|
|
|
|
// trigger handlers
|
|
instance.runHooks('beforeSetRangeEnd', coords);
|
|
instance.selection.begin();
|
|
|
|
newRangeCoords.row = coords.row < 0 ? firstVisibleRow : coords.row;
|
|
newRangeCoords.col = coords.col < 0 ? firstVisibleColumn : coords.col;
|
|
|
|
priv.selRange.to = new _src.CellCoords(newRangeCoords.row, newRangeCoords.col);
|
|
|
|
if (!priv.settings.multiSelect) {
|
|
priv.selRange.from = coords;
|
|
}
|
|
// set up current selection
|
|
instance.view.wt.selections.current.clear();
|
|
|
|
disableVisualSelection = instance.getCellMeta(priv.selRange.highlight.row, priv.selRange.highlight.col).disableVisualSelection;
|
|
|
|
if (typeof disableVisualSelection === 'string') {
|
|
disableVisualSelection = [disableVisualSelection];
|
|
}
|
|
|
|
if (disableVisualSelection === false || Array.isArray(disableVisualSelection) && disableVisualSelection.indexOf('current') === -1) {
|
|
instance.view.wt.selections.current.add(priv.selRange.highlight);
|
|
}
|
|
// set up area selection
|
|
instance.view.wt.selections.area.clear();
|
|
|
|
if ((disableVisualSelection === false || Array.isArray(disableVisualSelection) && disableVisualSelection.indexOf('area') === -1) && selection.isMultiple()) {
|
|
instance.view.wt.selections.area.add(priv.selRange.from);
|
|
instance.view.wt.selections.area.add(priv.selRange.to);
|
|
}
|
|
// set up highlight
|
|
if (priv.settings.currentHeaderClassName || priv.settings.currentRowClassName || priv.settings.currentColClassName) {
|
|
instance.view.wt.selections.highlight.clear();
|
|
instance.view.wt.selections.highlight.add(priv.selRange.from);
|
|
instance.view.wt.selections.highlight.add(priv.selRange.to);
|
|
}
|
|
|
|
var preventScrolling = (0, _object.createObjectPropListener)('value');
|
|
|
|
// trigger handlers
|
|
instance.runHooks('afterSelection', priv.selRange.from.row, priv.selRange.from.col, priv.selRange.to.row, priv.selRange.to.col, preventScrolling);
|
|
instance.runHooks('afterSelectionByProp', priv.selRange.from.row, datamap.colToProp(priv.selRange.from.col), priv.selRange.to.row, datamap.colToProp(priv.selRange.to.col), preventScrolling);
|
|
|
|
if (priv.selRange.from.row === 0 && priv.selRange.to.row === instance.countRows() - 1 && instance.countRows() > 1 || priv.selRange.from.col === 0 && priv.selRange.to.col === instance.countCols() - 1 && instance.countCols() > 1) {
|
|
isHeaderSelected = true;
|
|
}
|
|
|
|
if (coords.row < 0 || coords.col < 0) {
|
|
areCoordsPositive = false;
|
|
}
|
|
|
|
if (preventScrolling.isTouched()) {
|
|
scrollToCell = !preventScrolling.value;
|
|
}
|
|
|
|
if (scrollToCell !== false && !isHeaderSelected && areCoordsPositive) {
|
|
if (priv.selRange.from && !selection.isMultiple()) {
|
|
instance.view.scrollViewport(priv.selRange.from);
|
|
} else {
|
|
instance.view.scrollViewport(coords);
|
|
}
|
|
}
|
|
|
|
if (selection.selectedHeader.rows && selection.selectedHeader.cols) {
|
|
(0, _element.addClass)(instance.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
|
|
} else if (selection.selectedHeader.rows) {
|
|
(0, _element.removeClass)(instance.rootElement, 'ht__selection--columns');
|
|
(0, _element.addClass)(instance.rootElement, 'ht__selection--rows');
|
|
} else if (selection.selectedHeader.cols) {
|
|
(0, _element.removeClass)(instance.rootElement, 'ht__selection--rows');
|
|
(0, _element.addClass)(instance.rootElement, 'ht__selection--columns');
|
|
} else {
|
|
(0, _element.removeClass)(instance.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
|
|
}
|
|
|
|
selection.refreshBorders(null, keepEditorOpened);
|
|
},
|
|
|
|
|
|
/**
|
|
* Destroys editor, redraws borders around cells, prepares editor.
|
|
*
|
|
* @param {Boolean} [revertOriginal]
|
|
* @param {Boolean} [keepEditor]
|
|
*/
|
|
refreshBorders: function refreshBorders(revertOriginal, keepEditor) {
|
|
if (!keepEditor) {
|
|
editorManager.destroyEditor(revertOriginal);
|
|
}
|
|
instance.view.render();
|
|
|
|
if (selection.isSelected() && !keepEditor) {
|
|
editorManager.prepareEditor();
|
|
}
|
|
},
|
|
|
|
|
|
/**
|
|
* Returns information if we have a multiselection.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
isMultiple: function isMultiple() {
|
|
var isMultiple = !(priv.selRange.to.col === priv.selRange.from.col && priv.selRange.to.row === priv.selRange.from.row),
|
|
modifier = instance.runHooks('afterIsMultipleSelection', isMultiple);
|
|
|
|
if (isMultiple) {
|
|
return modifier;
|
|
}
|
|
},
|
|
|
|
|
|
/**
|
|
* Selects cell relative to current cell (if possible).
|
|
*/
|
|
transformStart: function transformStart(rowDelta, colDelta, force, keepEditorOpened) {
|
|
var delta = new _src.CellCoords(rowDelta, colDelta),
|
|
rowTransformDir = 0,
|
|
colTransformDir = 0,
|
|
totalRows,
|
|
totalCols,
|
|
coords,
|
|
fixedRowsBottom;
|
|
|
|
instance.runHooks('modifyTransformStart', delta);
|
|
totalRows = instance.countRows();
|
|
totalCols = instance.countCols();
|
|
fixedRowsBottom = instance.getSettings().fixedRowsBottom;
|
|
|
|
if (priv.selRange.highlight.row + rowDelta > totalRows - 1) {
|
|
if (force && priv.settings.minSpareRows > 0 && !(fixedRowsBottom && priv.selRange.highlight.row >= totalRows - fixedRowsBottom - 1)) {
|
|
instance.alter('insert_row', totalRows);
|
|
totalRows = instance.countRows();
|
|
} else if (priv.settings.autoWrapCol) {
|
|
delta.row = 1 - totalRows;
|
|
delta.col = priv.selRange.highlight.col + delta.col == totalCols - 1 ? 1 - totalCols : 1;
|
|
}
|
|
} else if (priv.settings.autoWrapCol && priv.selRange.highlight.row + delta.row < 0 && priv.selRange.highlight.col + delta.col >= 0) {
|
|
delta.row = totalRows - 1;
|
|
delta.col = priv.selRange.highlight.col + delta.col == 0 ? totalCols - 1 : -1;
|
|
}
|
|
|
|
if (priv.selRange.highlight.col + delta.col > totalCols - 1) {
|
|
if (force && priv.settings.minSpareCols > 0) {
|
|
instance.alter('insert_col', totalCols);
|
|
totalCols = instance.countCols();
|
|
} else if (priv.settings.autoWrapRow) {
|
|
delta.row = priv.selRange.highlight.row + delta.row == totalRows - 1 ? 1 - totalRows : 1;
|
|
delta.col = 1 - totalCols;
|
|
}
|
|
} else if (priv.settings.autoWrapRow && priv.selRange.highlight.col + delta.col < 0 && priv.selRange.highlight.row + delta.row >= 0) {
|
|
delta.row = priv.selRange.highlight.row + delta.row == 0 ? totalRows - 1 : -1;
|
|
delta.col = totalCols - 1;
|
|
}
|
|
|
|
coords = new _src.CellCoords(priv.selRange.highlight.row + delta.row, priv.selRange.highlight.col + delta.col);
|
|
|
|
if (coords.row < 0) {
|
|
rowTransformDir = -1;
|
|
coords.row = 0;
|
|
} else if (coords.row > 0 && coords.row >= totalRows) {
|
|
rowTransformDir = 1;
|
|
coords.row = totalRows - 1;
|
|
}
|
|
|
|
if (coords.col < 0) {
|
|
colTransformDir = -1;
|
|
coords.col = 0;
|
|
} else if (coords.col > 0 && coords.col >= totalCols) {
|
|
colTransformDir = 1;
|
|
coords.col = totalCols - 1;
|
|
}
|
|
instance.runHooks('afterModifyTransformStart', coords, rowTransformDir, colTransformDir);
|
|
selection.setRangeStart(coords, keepEditorOpened);
|
|
},
|
|
|
|
|
|
/**
|
|
* Sets selection end cell relative to current selection end cell (if possible).
|
|
*/
|
|
transformEnd: function transformEnd(rowDelta, colDelta) {
|
|
var delta = new _src.CellCoords(rowDelta, colDelta),
|
|
rowTransformDir = 0,
|
|
colTransformDir = 0,
|
|
totalRows,
|
|
totalCols,
|
|
coords;
|
|
|
|
instance.runHooks('modifyTransformEnd', delta);
|
|
|
|
totalRows = instance.countRows();
|
|
totalCols = instance.countCols();
|
|
coords = new _src.CellCoords(priv.selRange.to.row + delta.row, priv.selRange.to.col + delta.col);
|
|
|
|
if (coords.row < 0) {
|
|
rowTransformDir = -1;
|
|
coords.row = 0;
|
|
} else if (coords.row > 0 && coords.row >= totalRows) {
|
|
rowTransformDir = 1;
|
|
coords.row = totalRows - 1;
|
|
}
|
|
|
|
if (coords.col < 0) {
|
|
colTransformDir = -1;
|
|
coords.col = 0;
|
|
} else if (coords.col > 0 && coords.col >= totalCols) {
|
|
colTransformDir = 1;
|
|
coords.col = totalCols - 1;
|
|
}
|
|
instance.runHooks('afterModifyTransformEnd', coords, rowTransformDir, colTransformDir);
|
|
selection.setRangeEnd(coords, true);
|
|
},
|
|
|
|
|
|
/**
|
|
* Returns `true` if currently there is a selection on screen, `false` otherwise.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
isSelected: function isSelected() {
|
|
return priv.selRange !== null;
|
|
},
|
|
|
|
|
|
/**
|
|
* Returns `true` if coords is within current selection coords.
|
|
*
|
|
* @param {CellCoords} coords
|
|
* @returns {Boolean}
|
|
*/
|
|
inInSelection: function inInSelection(coords) {
|
|
if (!selection.isSelected()) {
|
|
return false;
|
|
}
|
|
|
|
return priv.selRange.includes(coords);
|
|
},
|
|
|
|
|
|
/**
|
|
* Deselects all selected cells
|
|
*/
|
|
deselect: function deselect() {
|
|
if (!selection.isSelected()) {
|
|
return;
|
|
}
|
|
instance.selection.inProgress = false; // needed by HT inception
|
|
priv.selRange = null;
|
|
instance.view.wt.selections.current.clear();
|
|
instance.view.wt.selections.area.clear();
|
|
if (priv.settings.currentHeaderClassName || priv.settings.currentRowClassName || priv.settings.currentColClassName) {
|
|
instance.view.wt.selections.highlight.clear();
|
|
}
|
|
editorManager.destroyEditor();
|
|
selection.refreshBorders();
|
|
(0, _element.removeClass)(instance.rootElement, ['ht__selection--rows', 'ht__selection--columns']);
|
|
instance.runHooks('afterDeselect');
|
|
},
|
|
|
|
|
|
/**
|
|
* Select all cells
|
|
*/
|
|
selectAll: function selectAll() {
|
|
if (!priv.settings.multiSelect) {
|
|
return;
|
|
}
|
|
selection.setSelectedHeaders(true, true, true);
|
|
selection.setRangeStart(new _src.CellCoords(0, 0));
|
|
selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, instance.countCols() - 1), false);
|
|
},
|
|
|
|
|
|
/**
|
|
* Deletes data from selected cells
|
|
*/
|
|
empty: function empty() {
|
|
if (!selection.isSelected()) {
|
|
return;
|
|
}
|
|
var topLeft = priv.selRange.getTopLeftCorner();
|
|
var bottomRight = priv.selRange.getBottomRightCorner();
|
|
var r,
|
|
c,
|
|
changes = [];
|
|
|
|
for (r = topLeft.row; r <= bottomRight.row; r++) {
|
|
for (c = topLeft.col; c <= bottomRight.col; c++) {
|
|
if (!instance.getCellMeta(r, c).readOnly) {
|
|
changes.push([r, c, '']);
|
|
}
|
|
}
|
|
}
|
|
instance.setDataAtCell(changes);
|
|
}
|
|
};
|
|
|
|
this.init = function () {
|
|
dataSource.setData(priv.settings.data);
|
|
instance.runHooks('beforeInit');
|
|
|
|
if ((0, _browser.isMobileBrowser)()) {
|
|
(0, _element.addClass)(instance.rootElement, 'mobile');
|
|
}
|
|
|
|
this.updateSettings(priv.settings, true);
|
|
|
|
this.view = new _tableView2.default(this);
|
|
editorManager = new _editorManager2.default(instance, priv, selection, datamap);
|
|
|
|
this.forceFullRender = true; // used when data was changed
|
|
|
|
instance.runHooks('init');
|
|
this.view.render();
|
|
|
|
if (_typeof(priv.firstRun) === 'object') {
|
|
instance.runHooks('afterChange', priv.firstRun[0], priv.firstRun[1]);
|
|
priv.firstRun = false;
|
|
}
|
|
instance.runHooks('afterInit');
|
|
};
|
|
|
|
function ValidatorsQueue() {
|
|
// moved this one level up so it can be used in any function here. Probably this should be moved to a separate file
|
|
var resolved = false;
|
|
|
|
return {
|
|
validatorsInQueue: 0,
|
|
valid: true,
|
|
addValidatorToQueue: function addValidatorToQueue() {
|
|
this.validatorsInQueue++;
|
|
resolved = false;
|
|
},
|
|
removeValidatorFormQueue: function removeValidatorFormQueue() {
|
|
this.validatorsInQueue = this.validatorsInQueue - 1 < 0 ? 0 : this.validatorsInQueue - 1;
|
|
this.checkIfQueueIsEmpty();
|
|
},
|
|
onQueueEmpty: function onQueueEmpty(valid) {},
|
|
checkIfQueueIsEmpty: function checkIfQueueIsEmpty() {
|
|
if (this.validatorsInQueue == 0 && resolved == false) {
|
|
resolved = true;
|
|
this.onQueueEmpty(this.valid);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
function validateChanges(changes, source, callback) {
|
|
var waitingForValidator = new ValidatorsQueue();
|
|
waitingForValidator.onQueueEmpty = resolve;
|
|
|
|
for (var i = changes.length - 1; i >= 0; i--) {
|
|
if (changes[i] === null) {
|
|
changes.splice(i, 1);
|
|
} else {
|
|
var row = changes[i][0];
|
|
var col = datamap.propToCol(changes[i][1]);
|
|
|
|
var cellProperties = instance.getCellMeta(row, col);
|
|
|
|
if (cellProperties.type === 'numeric' && typeof changes[i][3] === 'string') {
|
|
if (changes[i][3].length > 0 && (/^-?[\d\s]*(\.|,)?\d*$/.test(changes[i][3]) || cellProperties.format)) {
|
|
var len = changes[i][3].length;
|
|
|
|
if ((0, _mixed.isUndefined)(cellProperties.language)) {
|
|
_numbro2.default.culture('en-US');
|
|
} else if (changes[i][3].indexOf('.') === len - 3 && changes[i][3].indexOf(',') === -1) {
|
|
// this input in format XXXX.XX is likely to come from paste. Let's parse it using international rules
|
|
_numbro2.default.culture('en-US');
|
|
} else {
|
|
|
|
_numbro2.default.culture(cellProperties.language);
|
|
}
|
|
|
|
var _numbro$cultureData = _numbro2.default.cultureData(_numbro2.default.culture()),
|
|
delimiters = _numbro$cultureData.delimiters;
|
|
|
|
// try to parse to float - https://github.com/foretagsplatsen/numbro/pull/183
|
|
|
|
|
|
if (_numbro2.default.validate(changes[i][3]) && !isNaN(changes[i][3])) {
|
|
changes[i][3] = parseFloat(changes[i][3]);
|
|
} else {
|
|
changes[i][3] = (0, _numbro2.default)().unformat(changes[i][3]) || changes[i][3];
|
|
}
|
|
}
|
|
}
|
|
|
|
/* eslint-disable no-loop-func */
|
|
if (instance.getCellValidator(cellProperties)) {
|
|
waitingForValidator.addValidatorToQueue();
|
|
instance.validateCell(changes[i][3], cellProperties, function (i, cellProperties) {
|
|
return function (result) {
|
|
if (typeof result !== 'boolean') {
|
|
throw new Error('Validation error: result is not boolean');
|
|
}
|
|
if (result === false && cellProperties.allowInvalid === false) {
|
|
changes.splice(i, 1); // cancel the change
|
|
cellProperties.valid = true; // we cancelled the change, so cell value is still valid
|
|
var cell = instance.getCell(cellProperties.row, cellProperties.col);
|
|
(0, _element.removeClass)(cell, instance.getSettings().invalidCellClassName);
|
|
--i;
|
|
}
|
|
waitingForValidator.removeValidatorFormQueue();
|
|
};
|
|
}(i, cellProperties), source);
|
|
}
|
|
}
|
|
}
|
|
waitingForValidator.checkIfQueueIsEmpty();
|
|
|
|
function resolve() {
|
|
var beforeChangeResult;
|
|
|
|
if (changes.length) {
|
|
beforeChangeResult = instance.runHooks('beforeChange', changes, source);
|
|
if ((0, _function.isFunction)(beforeChangeResult)) {
|
|
console.warn('Your beforeChange callback returns a function. It\'s not supported since Handsontable 0.12.1 (and the returned function will not be executed).');
|
|
} else if (beforeChangeResult === false) {
|
|
changes.splice(0, changes.length); // invalidate all changes (remove everything from array)
|
|
}
|
|
}
|
|
callback(); // called when async validators are resolved and beforeChange was not async
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal function to apply changes. Called after validateChanges
|
|
*
|
|
* @private
|
|
* @param {Array} changes Array in form of [row, prop, oldValue, newValue]
|
|
* @param {String} source String that identifies how this change will be described in changes array (useful in onChange callback)
|
|
* @fires Hooks#beforeChangeRender
|
|
* @fires Hooks#afterChange
|
|
*/
|
|
function applyChanges(changes, source) {
|
|
var i = changes.length - 1;
|
|
|
|
if (i < 0) {
|
|
return;
|
|
}
|
|
|
|
for (; i >= 0; i--) {
|
|
var skipThisChange = false;
|
|
|
|
if (changes[i] === null) {
|
|
changes.splice(i, 1);
|
|
/* eslint-disable no-continue */
|
|
continue;
|
|
}
|
|
|
|
if (changes[i][2] == null && changes[i][3] == null) {
|
|
/* eslint-disable no-continue */
|
|
continue;
|
|
}
|
|
|
|
if (priv.settings.allowInsertRow) {
|
|
while (changes[i][0] > instance.countRows() - 1) {
|
|
var numberOfCreatedRows = datamap.createRow(void 0, void 0, source);
|
|
|
|
if (numberOfCreatedRows === 0) {
|
|
skipThisChange = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (skipThisChange) {
|
|
/* eslint-disable no-continue */
|
|
continue;
|
|
}
|
|
|
|
if (instance.dataType === 'array' && (!priv.settings.columns || priv.settings.columns.length === 0) && priv.settings.allowInsertColumn) {
|
|
while (datamap.propToCol(changes[i][1]) > instance.countCols() - 1) {
|
|
datamap.createCol(void 0, void 0, source);
|
|
}
|
|
}
|
|
|
|
datamap.set(changes[i][0], changes[i][1], changes[i][3]);
|
|
}
|
|
|
|
instance.forceFullRender = true; // used when data was changed
|
|
grid.adjustRowsAndCols();
|
|
instance.runHooks('beforeChangeRender', changes, source);
|
|
selection.refreshBorders(null, true);
|
|
instance.view.wt.wtOverlays.adjustElementsSize();
|
|
instance.runHooks('afterChange', changes, source || 'edit');
|
|
|
|
var activeEditor = instance.getActiveEditor();
|
|
|
|
if (activeEditor && (0, _mixed.isDefined)(activeEditor.refreshValue)) {
|
|
activeEditor.refreshValue();
|
|
}
|
|
}
|
|
|
|
this.validateCell = function (value, cellProperties, callback, source) {
|
|
var validator = instance.getCellValidator(cellProperties);
|
|
|
|
function done(valid) {
|
|
var col = cellProperties.visualCol,
|
|
row = cellProperties.visualRow,
|
|
td = instance.getCell(row, col, true);
|
|
|
|
if (td && td.nodeName != 'TH') {
|
|
instance.view.wt.wtSettings.settings.cellRenderer(row, col, td);
|
|
}
|
|
callback(valid);
|
|
}
|
|
|
|
if ((0, _mixed.isRegExp)(validator)) {
|
|
validator = function (validator) {
|
|
return function (value, callback) {
|
|
callback(validator.test(value));
|
|
};
|
|
}(validator);
|
|
}
|
|
|
|
if ((0, _function.isFunction)(validator)) {
|
|
|
|
value = instance.runHooks('beforeValidate', value, cellProperties.visualRow, cellProperties.prop, source);
|
|
|
|
// To provide consistent behaviour, validation should be always asynchronous
|
|
instance._registerTimeout(setTimeout(function () {
|
|
validator.call(cellProperties, value, function (valid) {
|
|
valid = instance.runHooks('afterValidate', valid, value, cellProperties.visualRow, cellProperties.prop, source);
|
|
cellProperties.valid = valid;
|
|
|
|
done(valid);
|
|
instance.runHooks('postAfterValidate', valid, value, cellProperties.visualRow, cellProperties.prop, source);
|
|
});
|
|
}, 0));
|
|
} else {
|
|
// resolve callback even if validator function was not found
|
|
instance._registerTimeout(setTimeout(function () {
|
|
cellProperties.valid = true;
|
|
done(cellProperties.valid);
|
|
}, 0));
|
|
}
|
|
};
|
|
|
|
function setDataInputToArray(row, propOrCol, value) {
|
|
if ((typeof row === 'undefined' ? 'undefined' : _typeof(row)) === 'object') {
|
|
// is it an array of changes
|
|
return row;
|
|
}
|
|
return [[row, propOrCol, value]];
|
|
}
|
|
|
|
/**
|
|
* @description
|
|
* Set new value to a cell. To change many cells at once, pass an array of `changes` in format `[[row, col, value], ...]` as
|
|
* the only parameter. `col` is the index of a __visible__ column (note that if columns were reordered,
|
|
* the current visible order will be used). `source` is a flag for before/afterChange events. If you pass only array of
|
|
* changes then `source` could be set as second parameter.
|
|
*
|
|
* @memberof Core#
|
|
* @function setDataAtCell
|
|
* @param {Number|Array} row Visual row index or array of changes in format `[[row, col, value], ...]`.
|
|
* @param {Number} col Visual column index.
|
|
* @param {String} value New value.
|
|
* @param {String} [source] String that identifies how this change will be described in the changes array (useful in onAfterChange or onBeforeChange callback).
|
|
*/
|
|
this.setDataAtCell = function (row, col, value, source) {
|
|
var input = setDataInputToArray(row, col, value),
|
|
i,
|
|
ilen,
|
|
changes = [],
|
|
prop;
|
|
|
|
for (i = 0, ilen = input.length; i < ilen; i++) {
|
|
if (_typeof(input[i]) !== 'object') {
|
|
throw new Error('Method `setDataAtCell` accepts row number or changes array of arrays as its first parameter');
|
|
}
|
|
if (typeof input[i][1] !== 'number') {
|
|
throw new Error('Method `setDataAtCell` accepts row and column number as its parameters. If you want to use object property name, use method `setDataAtRowProp`');
|
|
}
|
|
prop = datamap.colToProp(input[i][1]);
|
|
changes.push([input[i][0], prop, dataSource.getAtCell(recordTranslator.toPhysicalRow(input[i][0]), input[i][1]), input[i][2]]);
|
|
}
|
|
|
|
if (!source && (typeof row === 'undefined' ? 'undefined' : _typeof(row)) === 'object') {
|
|
source = col;
|
|
}
|
|
|
|
instance.runHooks('afterSetDataAtCell', changes, source);
|
|
|
|
validateChanges(changes, source, function () {
|
|
applyChanges(changes, source);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @description
|
|
* Set new value to a cell. To change many cells at once, pass an array of `changes` in format `[[row, prop, value], ...]` as
|
|
* the only parameter. `prop` is the name of the object property (e.g. `first.name`). `source` is a flag for before/afterChange events.
|
|
* If you pass only array of changes then `source` could be set as second parameter.
|
|
*
|
|
* @memberof Core#
|
|
* @function setDataAtRowProp
|
|
* @param {Number|Array} row Visual row index or array of changes in format `[[row, prop, value], ...]`.
|
|
* @param {String} prop Property name or the source string.
|
|
* @param {String} value Value to be set.
|
|
* @param {String} [source] String that identifies how this change will be described in changes array (useful in onChange callback).
|
|
*/
|
|
this.setDataAtRowProp = function (row, prop, value, source) {
|
|
var input = setDataInputToArray(row, prop, value),
|
|
i,
|
|
ilen,
|
|
changes = [];
|
|
|
|
for (i = 0, ilen = input.length; i < ilen; i++) {
|
|
changes.push([input[i][0], input[i][1], dataSource.getAtCell(recordTranslator.toPhysicalRow(input[i][0]), input[i][1]), input[i][2]]);
|
|
}
|
|
|
|
if (!source && (typeof row === 'undefined' ? 'undefined' : _typeof(row)) === 'object') {
|
|
source = prop;
|
|
}
|
|
|
|
instance.runHooks('afterSetDataAtRowProp', changes, source);
|
|
|
|
validateChanges(changes, source, function () {
|
|
applyChanges(changes, source);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Listen to the keyboard input on document body.
|
|
*
|
|
* @memberof Core#
|
|
* @function listen
|
|
* @since 0.11
|
|
*/
|
|
this.listen = function () {
|
|
var invalidActiveElement = !document.activeElement || document.activeElement && document.activeElement.nodeName === void 0;
|
|
|
|
if (document.activeElement && document.activeElement !== document.body && !invalidActiveElement) {
|
|
document.activeElement.blur();
|
|
} else if (invalidActiveElement) {
|
|
// IE
|
|
document.body.focus();
|
|
}
|
|
|
|
activeGuid = instance.guid;
|
|
};
|
|
|
|
/**
|
|
* Stop listening to keyboard input on the document body.
|
|
*
|
|
* @memberof Core#
|
|
* @function unlisten
|
|
* @since 0.11
|
|
*/
|
|
this.unlisten = function () {
|
|
if (this.isListening()) {
|
|
activeGuid = null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns `true` if the current Handsontable instance is listening to keyboard input on document body.
|
|
*
|
|
* @memberof Core#
|
|
* @function isListening
|
|
* @since 0.11
|
|
* @returns {Boolean} `true` if the instance is listening, `false` otherwise.
|
|
*/
|
|
this.isListening = function () {
|
|
return activeGuid === instance.guid;
|
|
};
|
|
|
|
/**
|
|
* Destroys the current editor, renders and selects the current cell.
|
|
*
|
|
* @memberof Core#
|
|
* @function destroyEditor
|
|
* @param {Boolean} [revertOriginal] If != `true`, edited data is saved. Otherwise the previous value is restored.
|
|
*/
|
|
this.destroyEditor = function (revertOriginal) {
|
|
selection.refreshBorders(revertOriginal);
|
|
};
|
|
|
|
/**
|
|
* Populate cells at position with 2D input array (e.g. `[[1, 2], [3, 4]]`).
|
|
* Use `endRow`, `endCol` when you want to cut input when a certain row is reached.
|
|
* Optional `source` parameter (default value "populateFromArray") is used to identify this call in the resulting events (beforeChange, afterChange).
|
|
* Optional `populateMethod` parameter (default value "overwrite", possible values "shift_down" and "shift_right")
|
|
* has the same effect as pasteMode option {@link Options#pasteMode}
|
|
*
|
|
* @memberof Core#
|
|
* @function populateFromArray
|
|
* @since 0.9.0
|
|
* @param {Number} row Start visual row index.
|
|
* @param {Number} col Start visual column index.
|
|
* @param {Array} input 2d array
|
|
* @param {Number} [endRow] End visual row index (use when you want to cut input when certain row is reached).
|
|
* @param {Number} [endCol] End visual column index (use when you want to cut input when certain column is reached).
|
|
* @param {String} [source="populateFromArray"] Source string.
|
|
* @param {String} [method="overwrite"] Populate method. Possible options: `shift_down`, `shift_right`, `overwrite`.
|
|
* @param {String} direction Populate direction. (left|right|up|down)
|
|
* @param {Array} deltas Deltas array.
|
|
* @returns {Object|undefined} The ending TD element in pasted area (only if any cells were changed).
|
|
*/
|
|
this.populateFromArray = function (row, col, input, endRow, endCol, source, method, direction, deltas) {
|
|
var c;
|
|
|
|
if (!((typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object' && _typeof(input[0]) === 'object')) {
|
|
throw new Error('populateFromArray parameter `input` must be an array of arrays'); // API changed in 0.9-beta2, let's check if you use it correctly
|
|
}
|
|
c = typeof endRow === 'number' ? new _src.CellCoords(endRow, endCol) : null;
|
|
|
|
return grid.populateFromArray(new _src.CellCoords(row, col), input, c, source, method, direction, deltas);
|
|
};
|
|
|
|
/**
|
|
* Adds/removes data from the column. This function is modelled after Array.splice.
|
|
* Parameter `col` is the index of the column in which do you want to do splice.
|
|
* Parameter `index` is the row index at which to start changing the array.
|
|
* If negative, will begin that many elements from the end. Parameter `amount`, is the number of the old array elements to remove.
|
|
* If the amount is 0, no elements are removed. Fourth and further parameters are the `elements` to add to the array.
|
|
* If you don't specify any elements, spliceCol simply removes elements from the array.
|
|
* {@link DataMap#spliceCol}
|
|
*
|
|
* @memberof Core#
|
|
* @function spliceCol
|
|
* @since 0.9-beta2
|
|
* @param {Number} col Index of the column in which do you want to do splice.
|
|
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end.
|
|
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed.
|
|
* @param {*} [elements] The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array.
|
|
*/
|
|
this.spliceCol = function (col, index, amount /* , elements... */) {
|
|
var _datamap;
|
|
|
|
return (_datamap = datamap).spliceCol.apply(_datamap, arguments);
|
|
};
|
|
|
|
/**
|
|
* Adds/removes data from the row. This function works is modelled after Array.splice.
|
|
* Parameter `row` is the index of row in which do you want to do splice.
|
|
* Parameter `index` is the column index at which to start changing the array.
|
|
* If negative, will begin that many elements from the end. Parameter `amount`, is the number of old array elements to remove.
|
|
* If the amount is 0, no elements are removed. Fourth and further parameters are the `elements` to add to the array.
|
|
* If you don't specify any elements, spliceCol simply removes elements from the array.
|
|
* {@link DataMap#spliceRow}
|
|
*
|
|
* @memberof Core#
|
|
* @function spliceRow
|
|
* @since 0.11
|
|
* @param {Number} row Index of column in which do you want to do splice.
|
|
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end.
|
|
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed.
|
|
* @param {*} [elements] The elements to add to the array. If you don't specify any elements, spliceCol simply removes elements from the array.
|
|
*/
|
|
this.spliceRow = function (row, index, amount /* , elements... */) {
|
|
var _datamap2;
|
|
|
|
return (_datamap2 = datamap).spliceRow.apply(_datamap2, arguments);
|
|
};
|
|
|
|
/**
|
|
* Returns indexes of the currently selected cells as an array `[startRow, startCol, endRow, endCol]`.
|
|
*
|
|
* Start row and start col are the coordinates of the active cell (where the selection was started).
|
|
*
|
|
* @memberof Core#
|
|
* @function getSelected
|
|
* @returns {Array} Array of the selection's indexes.
|
|
*/
|
|
this.getSelected = function () {
|
|
// https://github.com/handsontable/handsontable/issues/44 //cjl
|
|
if (selection.isSelected()) {
|
|
return [priv.selRange.from.row, priv.selRange.from.col, priv.selRange.to.row, priv.selRange.to.col];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns the current selection as a CellRange object.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSelectedRange
|
|
* @since 0.11
|
|
* @returns {CellRange} Selected range object or undefined` if there is no selection.
|
|
*/
|
|
this.getSelectedRange = function () {
|
|
// https://github.com/handsontable/handsontable/issues/44 //cjl
|
|
if (selection.isSelected()) {
|
|
return priv.selRange;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Rerender the table.
|
|
*
|
|
* @memberof Core#
|
|
* @function render
|
|
*/
|
|
this.render = function () {
|
|
if (instance.view) {
|
|
instance.renderCall = true;
|
|
instance.forceFullRender = true; // used when data was changed
|
|
selection.refreshBorders(null, true);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Reset all cells in the grid to contain data from the data array.
|
|
*
|
|
* @memberof Core#
|
|
* @function loadData
|
|
* @param {Array} data Array of arrays or array of objects containing data.
|
|
* @fires Hooks#afterLoadData
|
|
* @fires Hooks#afterChange
|
|
*/
|
|
this.loadData = function (data) {
|
|
if (Array.isArray(priv.settings.dataSchema)) {
|
|
instance.dataType = 'array';
|
|
} else if ((0, _function.isFunction)(priv.settings.dataSchema)) {
|
|
instance.dataType = 'function';
|
|
} else {
|
|
instance.dataType = 'object';
|
|
}
|
|
|
|
if (datamap) {
|
|
datamap.destroy();
|
|
}
|
|
datamap = new _dataMap2.default(instance, priv, GridSettings);
|
|
|
|
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object' && data !== null) {
|
|
if (!(data.push && data.splice)) {
|
|
// check if data is array. Must use duck-type check so Backbone Collections also pass it
|
|
// when data is not an array, attempt to make a single-row array of it
|
|
data = [data];
|
|
}
|
|
} else if (data === null) {
|
|
data = [];
|
|
var row;
|
|
var r = 0;
|
|
var rlen = 0;
|
|
var dataSchema = datamap.getSchema();
|
|
|
|
for (r = 0, rlen = priv.settings.startRows; r < rlen; r++) {
|
|
if ((instance.dataType === 'object' || instance.dataType === 'function') && priv.settings.dataSchema) {
|
|
row = (0, _object.deepClone)(dataSchema);
|
|
data.push(row);
|
|
} else if (instance.dataType === 'array') {
|
|
row = (0, _object.deepClone)(dataSchema[0]);
|
|
data.push(row);
|
|
} else {
|
|
row = [];
|
|
|
|
for (var c = 0, clen = priv.settings.startCols; c < clen; c++) {
|
|
row.push(null);
|
|
}
|
|
|
|
data.push(row);
|
|
}
|
|
}
|
|
} else {
|
|
throw new Error('loadData only accepts array of objects or array of arrays (' + (typeof data === 'undefined' ? 'undefined' : _typeof(data)) + ' given)');
|
|
}
|
|
|
|
priv.isPopulated = false;
|
|
GridSettings.prototype.data = data;
|
|
|
|
if (Array.isArray(data[0])) {
|
|
instance.dataType = 'array';
|
|
}
|
|
|
|
datamap.dataSource = data;
|
|
dataSource.data = data;
|
|
dataSource.dataType = instance.dataType;
|
|
dataSource.colToProp = datamap.colToProp.bind(datamap);
|
|
dataSource.propToCol = datamap.propToCol.bind(datamap);
|
|
|
|
clearCellSettingCache();
|
|
|
|
grid.adjustRowsAndCols();
|
|
instance.runHooks('afterLoadData', priv.firstRun);
|
|
|
|
if (priv.firstRun) {
|
|
priv.firstRun = [null, 'loadData'];
|
|
} else {
|
|
instance.runHooks('afterChange', null, 'loadData');
|
|
instance.render();
|
|
}
|
|
priv.isPopulated = true;
|
|
|
|
function clearCellSettingCache() {
|
|
priv.cellSettings.length = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns the current data object (the same one that was passed by `data` configuration option or `loadData` method,
|
|
* unless the `modifyRow` hook was used to trim some of the rows. If that's the case - use the {@link Core#getSourceData} method.).
|
|
* Optionally you can provide cell range by defining `row`, `col`, `row2`, `col2` to get only a fragment of grid data.
|
|
*
|
|
* Note: getData functionality changed with the release of version 0.20. If you're looking for the previous functionality,
|
|
* you should use the {@link Core#getSourceData} method.
|
|
*
|
|
* @memberof Core#
|
|
* @function getData
|
|
* @param {Number} [r] From visual row index.
|
|
* @param {Number} [c] From visual column index.
|
|
* @param {Number} [r2] To visual row index.
|
|
* @param {Number} [c2] To visual column index.
|
|
* @returns {Array} Array with the data.
|
|
*/
|
|
this.getData = function (r, c, r2, c2) {
|
|
if ((0, _mixed.isUndefined)(r)) {
|
|
return datamap.getAll();
|
|
}
|
|
return datamap.getRange(new _src.CellCoords(r, c), new _src.CellCoords(r2, c2), datamap.DESTINATION_RENDERER);
|
|
};
|
|
|
|
/**
|
|
* Returns a string value of the selected range. Each column is separated by tab, each row is separated by a new line character.
|
|
* {@link DataMap#getCopyableText}
|
|
*
|
|
* @memberof Core#
|
|
* @function getCopyableText
|
|
* @since 0.11
|
|
* @param {Number} startRow From visual row index.
|
|
* @param {Number} startCol From visual column index.
|
|
* @param {Number} endRow To visual row index.
|
|
* @param {Number} endCol To visual column index.
|
|
* @returns {String}
|
|
*/
|
|
this.getCopyableText = function (startRow, startCol, endRow, endCol) {
|
|
return datamap.getCopyableText(new _src.CellCoords(startRow, startCol), new _src.CellCoords(endRow, endCol));
|
|
};
|
|
|
|
/**
|
|
* Returns the data's copyable value at specified row and column index ({@link DataMap#getCopyable}).
|
|
*
|
|
* @memberof Core#
|
|
* @function getCopyableData
|
|
* @since 0.19.0
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} column Visual column index.
|
|
* @returns {String}
|
|
*/
|
|
this.getCopyableData = function (row, column) {
|
|
return datamap.getCopyable(row, datamap.colToProp(column));
|
|
};
|
|
|
|
/**
|
|
* Returns schema provided by constructor settings. If it doesn't exist then it returns the schema based on the data
|
|
* structure in the first row.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSchema
|
|
* @since 0.13.2
|
|
* @returns {Object} Schema object.
|
|
*/
|
|
this.getSchema = function () {
|
|
return datamap.getSchema();
|
|
};
|
|
|
|
/**
|
|
* Use it if you need to change configuration after initialization. The `settings` parameter is an object containing the new
|
|
* settings, declared the same way as in the initial settings object.
|
|
* Note, that although the `updateSettings` method doesn't overwrite the previously declared settings, it might reset
|
|
* the settings made post-initialization. (for example - ignore changes made using the columnResize feature).
|
|
*
|
|
* @memberof Core#
|
|
* @function updateSettings
|
|
* @param {Object} settings New settings object.
|
|
* @param {Boolean} init Calls this method in the initialization mode. Internal use only.
|
|
* Used by API could be cause of the unexpected behaviour of the Handsontable.
|
|
* @example
|
|
* ```js
|
|
* hot.updateSettings({
|
|
* contextMenu: true,
|
|
* colHeaders: true,
|
|
* fixedRowsTop: 2
|
|
* });
|
|
* ```
|
|
* @fires Hooks#afterCellMetaReset
|
|
* @fires Hooks#afterUpdateSettings
|
|
*/
|
|
this.updateSettings = function (settings, init) {
|
|
var columnsAsFunc = false;
|
|
var i = void 0;
|
|
var j = void 0;
|
|
var clen = void 0;
|
|
|
|
if ((0, _mixed.isDefined)(settings.rows)) {
|
|
throw new Error('"rows" setting is no longer supported. do you mean startRows, minRows or maxRows?');
|
|
}
|
|
if ((0, _mixed.isDefined)(settings.cols)) {
|
|
throw new Error('"cols" setting is no longer supported. do you mean startCols, minCols or maxCols?');
|
|
}
|
|
|
|
for (i in settings) {
|
|
if (i === 'data') {
|
|
/* eslint-disable no-continue */
|
|
continue; // loadData will be triggered later
|
|
} else if (_pluginHooks2.default.getSingleton().getRegistered().indexOf(i) > -1) {
|
|
if ((0, _function.isFunction)(settings[i]) || Array.isArray(settings[i])) {
|
|
settings[i].initialHook = true;
|
|
instance.addHook(i, settings[i]);
|
|
}
|
|
} else if (!init && (0, _object.hasOwnProperty)(settings, i)) {
|
|
// Update settings
|
|
GridSettings.prototype[i] = settings[i];
|
|
}
|
|
}
|
|
|
|
// Load data or create data map
|
|
if (settings.data === void 0 && priv.settings.data === void 0) {
|
|
instance.loadData(null); // data source created just now
|
|
} else if (settings.data !== void 0) {
|
|
instance.loadData(settings.data); // data source given as option
|
|
} else if (settings.columns !== void 0) {
|
|
datamap.createMap();
|
|
}
|
|
|
|
clen = instance.countCols();
|
|
|
|
var columnSetting = settings.columns || GridSettings.prototype.columns;
|
|
|
|
// Init columns constructors configuration
|
|
if (columnSetting && (0, _function.isFunction)(columnSetting)) {
|
|
clen = instance.countSourceCols();
|
|
columnsAsFunc = true;
|
|
}
|
|
|
|
// Clear cellSettings cache
|
|
if (settings.cell !== void 0 || settings.cells !== void 0 || settings.columns !== void 0) {
|
|
priv.cellSettings.length = 0;
|
|
}
|
|
|
|
if (clen > 0) {
|
|
var proto = void 0;
|
|
var column = void 0;
|
|
|
|
for (i = 0, j = 0; i < clen; i++) {
|
|
if (columnsAsFunc && !columnSetting(i)) {
|
|
/* eslint-disable no-continue */
|
|
continue;
|
|
}
|
|
priv.columnSettings[j] = (0, _setting.columnFactory)(GridSettings, priv.columnsSettingConflicts);
|
|
|
|
// shortcut for prototype
|
|
proto = priv.columnSettings[j].prototype;
|
|
|
|
// Use settings provided by user
|
|
if (columnSetting) {
|
|
if (columnsAsFunc) {
|
|
column = columnSetting(i);
|
|
} else {
|
|
column = columnSetting[j];
|
|
}
|
|
|
|
if (column) {
|
|
(0, _object.extend)(proto, column);
|
|
(0, _object.extend)(proto, expandType(column));
|
|
}
|
|
}
|
|
|
|
j++;
|
|
}
|
|
}
|
|
|
|
if ((0, _mixed.isDefined)(settings.cell)) {
|
|
for (var key in settings.cell) {
|
|
if ((0, _object.hasOwnProperty)(settings.cell, key)) {
|
|
var cell = settings.cell[key];
|
|
|
|
instance.setCellMetaObject(cell.row, cell.col, cell);
|
|
}
|
|
}
|
|
}
|
|
|
|
instance.runHooks('afterCellMetaReset');
|
|
|
|
if ((0, _mixed.isDefined)(settings.className)) {
|
|
if (GridSettings.prototype.className) {
|
|
(0, _element.removeClass)(instance.rootElement, GridSettings.prototype.className);
|
|
}
|
|
if (settings.className) {
|
|
(0, _element.addClass)(instance.rootElement, settings.className);
|
|
}
|
|
}
|
|
|
|
var currentHeight = instance.rootElement.style.height;
|
|
if (currentHeight !== '') {
|
|
currentHeight = parseInt(instance.rootElement.style.height, 10);
|
|
}
|
|
|
|
var height = settings.height;
|
|
if ((0, _function.isFunction)(height)) {
|
|
height = height();
|
|
}
|
|
|
|
if (init) {
|
|
var initialStyle = instance.rootElement.getAttribute('style');
|
|
|
|
if (initialStyle) {
|
|
instance.rootElement.setAttribute('data-initialstyle', instance.rootElement.getAttribute('style'));
|
|
}
|
|
}
|
|
|
|
if (height === null) {
|
|
var _initialStyle = instance.rootElement.getAttribute('data-initialstyle');
|
|
|
|
if (_initialStyle && (_initialStyle.indexOf('height') > -1 || _initialStyle.indexOf('overflow') > -1)) {
|
|
instance.rootElement.setAttribute('style', _initialStyle);
|
|
} else {
|
|
instance.rootElement.style.height = '';
|
|
instance.rootElement.style.overflow = '';
|
|
}
|
|
} else if (height !== void 0) {
|
|
instance.rootElement.style.height = height + 'px';
|
|
instance.rootElement.style.overflow = 'hidden';
|
|
}
|
|
|
|
if (typeof settings.width !== 'undefined') {
|
|
var width = settings.width;
|
|
|
|
if ((0, _function.isFunction)(width)) {
|
|
width = width();
|
|
}
|
|
|
|
instance.rootElement.style.width = width + 'px';
|
|
}
|
|
|
|
if (!init) {
|
|
datamap.clearLengthCache(); // force clear cache length on updateSettings() #3416
|
|
|
|
if (instance.view) {
|
|
instance.view.wt.wtViewport.resetHasOversizedColumnHeadersMarked();
|
|
}
|
|
|
|
instance.runHooks('afterUpdateSettings');
|
|
}
|
|
|
|
grid.adjustRowsAndCols();
|
|
if (instance.view && !priv.firstRun) {
|
|
instance.forceFullRender = true; // used when data was changed
|
|
selection.refreshBorders(null, true);
|
|
}
|
|
|
|
if (!init && instance.view && (currentHeight === '' || height === '' || height === void 0) && currentHeight !== height) {
|
|
instance.view.wt.wtOverlays.updateMainScrollableElements();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get value from the selected cell.
|
|
*
|
|
* @memberof Core#
|
|
* @function getValue
|
|
* @since 0.11
|
|
* @returns {*} Value of selected cell.
|
|
*/
|
|
this.getValue = function () {
|
|
var sel = instance.getSelected();
|
|
if (GridSettings.prototype.getValue) {
|
|
if ((0, _function.isFunction)(GridSettings.prototype.getValue)) {
|
|
return GridSettings.prototype.getValue.call(instance);
|
|
} else if (sel) {
|
|
return instance.getData()[sel[0]][GridSettings.prototype.getValue];
|
|
}
|
|
} else if (sel) {
|
|
return instance.getDataAtCell(sel[0], sel[1]);
|
|
}
|
|
};
|
|
|
|
function expandType(obj) {
|
|
if (!(0, _object.hasOwnProperty)(obj, 'type')) {
|
|
// ignore obj.prototype.type
|
|
return;
|
|
}
|
|
|
|
var type,
|
|
expandedType = {};
|
|
|
|
if (_typeof(obj.type) === 'object') {
|
|
type = obj.type;
|
|
} else if (typeof obj.type === 'string') {
|
|
type = (0, _cellTypes.getCellType)(obj.type);
|
|
}
|
|
|
|
for (var i in type) {
|
|
if ((0, _object.hasOwnProperty)(type, i) && !(0, _object.hasOwnProperty)(obj, i)) {
|
|
expandedType[i] = type[i];
|
|
}
|
|
}
|
|
|
|
return expandedType;
|
|
}
|
|
|
|
/**
|
|
* Returns the object settings.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSettings
|
|
* @returns {Object} Object containing the current grid settings.
|
|
*/
|
|
this.getSettings = function () {
|
|
return priv.settings;
|
|
};
|
|
|
|
/**
|
|
* Clears the data from the grid. (The table settings remain intact.)
|
|
*
|
|
* @memberof Core#
|
|
* @function clear
|
|
* @since 0.11
|
|
*/
|
|
this.clear = function () {
|
|
selection.selectAll();
|
|
selection.empty();
|
|
};
|
|
|
|
/**
|
|
* @memberof Core#
|
|
* @function alter
|
|
* @param {String} action See grid.alter for possible values: `"insert_row"`, `"insert_col"`, `"remove_row"`, `"remove_col"`
|
|
* @param {Number} index Visual index of the row/column before which the new row/column will be inserted/removed.
|
|
* @param {Number} [amount = 1] Amound of rows/columns to be inserted/removed.
|
|
* @param {String} [source] Source indicator.
|
|
* @param {Boolean} [keepEmptyRows] Flag for preventing deletion of empty rows.
|
|
* @description
|
|
*
|
|
* Allows altering the table structure by either inserting/removing rows or inserting/removing columns:
|
|
*
|
|
* Insert new row(s) above the row with a given `index`. If index is `null` or `undefined`, the new row will be
|
|
* added after the last row.
|
|
* ```js
|
|
* var hot = new Handsontable(document.getElementById('example'));
|
|
* hot.alter('insert_row', 10);
|
|
* ```
|
|
*
|
|
* Insert new column(s) before the column with a given `index`. If index is `null` or `undefined`, the new column
|
|
* will be added after the last column.
|
|
* ```js
|
|
* var hot = new Handsontable(document.getElementById('example'));
|
|
* hot.alter('insert_col', 10);
|
|
* ```
|
|
*
|
|
* Remove the row(s) at the given `index`.
|
|
* ```js
|
|
* var hot = new Handsontable(document.getElementById('example'));
|
|
* hot.alter('remove_row', 10);
|
|
* ```
|
|
*
|
|
* Remove the column(s) at the given `index`.
|
|
* ```js
|
|
* var hot = new Handsontable(document.getElementById('example'));
|
|
* hot.alter('remove_col', 10);
|
|
* ```
|
|
*/
|
|
this.alter = function (action, index, amount, source, keepEmptyRows) {
|
|
grid.alter(action, index, amount, source, keepEmptyRows);
|
|
};
|
|
|
|
/**
|
|
* Returns a TD element for the given `row` and `col` arguments, if it is rendered on screen.
|
|
* Returns `null` if the TD is not rendered on screen (probably because that part of the table is not visible).
|
|
*
|
|
* @memberof Core#
|
|
* @function getCell
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col 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.
|
|
* @returns {Element} The cell's TD element.
|
|
*/
|
|
this.getCell = function (row, col, topmost) {
|
|
return instance.view.getCellAtCoords(new _src.CellCoords(row, col), topmost);
|
|
};
|
|
|
|
/**
|
|
* Returns the coordinates of the cell, provided as a HTML Element.
|
|
*
|
|
* @memberof Core#
|
|
* @function getCoords
|
|
* @param {Element} elem The HTML Element representing the cell.
|
|
* @returns {CellCoords} Visual coordinates object.
|
|
*/
|
|
this.getCoords = function (elem) {
|
|
return this.view.wt.wtTable.getCoords.call(this.view.wt.wtTable, elem);
|
|
};
|
|
|
|
/**
|
|
* Returns the property name that corresponds with the given column index. {@link DataMap#colToProp}
|
|
* If the data source is an array of arrays, it returns the columns index.
|
|
*
|
|
* @memberof Core#
|
|
* @function colToProp
|
|
* @param {Number} col Visual column index.
|
|
* @returns {String|Number} Column property or physical column index.
|
|
*/
|
|
this.colToProp = function (col) {
|
|
return datamap.colToProp(col);
|
|
};
|
|
|
|
/**
|
|
* Returns column index that corresponds with the given property. {@link DataMap#propToCol}
|
|
*
|
|
* @memberof Core#
|
|
* @function propToCol
|
|
* @param {String|Number} prop Property name or physical column index.
|
|
* @returns {Number} Visual column index.
|
|
*/
|
|
this.propToCol = function (prop) {
|
|
return datamap.propToCol(prop);
|
|
};
|
|
|
|
/**
|
|
* Translate physical row index into visual.
|
|
*
|
|
* @since 0.29.0
|
|
* @memberof Core#
|
|
* @function toVisualRow
|
|
* @param {Number} row Physical row index.
|
|
* @returns {Number} Returns visual row index.
|
|
*/
|
|
this.toVisualRow = function (row) {
|
|
return recordTranslator.toVisualRow(row);
|
|
};
|
|
|
|
/**
|
|
* Translate physical column index into visual.
|
|
*
|
|
* @since 0.29.0
|
|
* @memberof Core#
|
|
* @function toVisualColumn
|
|
* @param {Number} column Physical column index.
|
|
* @returns {Number} Returns visual column index.
|
|
*/
|
|
this.toVisualColumn = function (column) {
|
|
return recordTranslator.toVisualColumn(column);
|
|
};
|
|
|
|
/**
|
|
* Translate visual row index into physical.
|
|
* If displayed rows order is different than the order of rows stored in memory (i.e. sorting is applied)
|
|
* to retrieve valid physical row index you can use this method.
|
|
*
|
|
* @since 0.29.0
|
|
* @memberof Core#
|
|
* @function toPhysicalRow
|
|
* @param {Number} row Visual row index.
|
|
* @returns {Number} Returns physical row index.
|
|
*/
|
|
this.toPhysicalRow = function (row) {
|
|
return recordTranslator.toPhysicalRow(row);
|
|
};
|
|
|
|
/**
|
|
* Translate visual column index into physical.
|
|
* If displayed columns order is different than the order of columns stored in memory (i.e. manual column move is applied)
|
|
* to retrieve valid physical column index you can use this method.
|
|
*
|
|
* @since 0.29.0
|
|
* @memberof Core#
|
|
* @function toPhysicalColumn
|
|
* @param {Number} column Visual column index.
|
|
* @returns {Number} Returns physical column index.
|
|
*/
|
|
this.toPhysicalColumn = function (column) {
|
|
return recordTranslator.toPhysicalColumn(column);
|
|
};
|
|
|
|
/**
|
|
* @description
|
|
* Returns the cell value at `row`, `col`. `row` and `col` are the __visible__ indexes (note, that if columns were reordered or sorted,
|
|
* the currently visible order will be used).
|
|
*
|
|
* @memberof Core#
|
|
* @function getDataAtCell
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @returns {String|Boolean|null} Data at cell.
|
|
*/
|
|
this.getDataAtCell = function (row, col) {
|
|
return datamap.get(row, datamap.colToProp(col));
|
|
};
|
|
|
|
/**
|
|
* Return value at `row`, `prop`. (Uses {@link DataMap#get})
|
|
*
|
|
* @memberof Core#
|
|
* @function getDataAtRowProp
|
|
* @param {Number} row Visual row index.
|
|
* @param {String} prop Property name.
|
|
* @returns {*} Cell value.
|
|
*/
|
|
this.getDataAtRowProp = function (row, prop) {
|
|
return datamap.get(row, prop);
|
|
};
|
|
|
|
/**
|
|
* @description
|
|
* Returns array of column values from the data source. `col` is the __visible__ index of the column.
|
|
* Note, that if columns were reordered or sorted, the currently visible order will be used.
|
|
*
|
|
* @memberof Core#
|
|
* @function getDataAtCol
|
|
* @since 0.9-beta2
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Array} Array of cell values.
|
|
*/
|
|
this.getDataAtCol = function (col) {
|
|
var out = [];
|
|
return out.concat.apply(out, _toConsumableArray(datamap.getRange(new _src.CellCoords(0, col), new _src.CellCoords(priv.settings.data.length - 1, col), datamap.DESTINATION_RENDERER)));
|
|
};
|
|
|
|
/**
|
|
* Given the object property name (e.g. `'first.name'`), returns an array of column's values from the data source.
|
|
* You can also provide a column index as the first argument.
|
|
*
|
|
* @memberof Core#
|
|
* @function getDataAtProp
|
|
* @since 0.9-beta2
|
|
* @param {String|Number} prop Property name / physical column index.
|
|
* @returns {Array} Array of cell values.
|
|
*/
|
|
// TODO: Getting data from `datamap` should work on visual indexes.
|
|
this.getDataAtProp = function (prop) {
|
|
var out = [],
|
|
range;
|
|
|
|
range = datamap.getRange(new _src.CellCoords(0, datamap.propToCol(prop)), new _src.CellCoords(priv.settings.data.length - 1, datamap.propToCol(prop)), datamap.DESTINATION_RENDERER);
|
|
|
|
return out.concat.apply(out, _toConsumableArray(range));
|
|
};
|
|
|
|
/**
|
|
* Returns the source data object (the same that was passed by `data` configuration option or `loadData` method).
|
|
* Optionally you can provide a cell range by using the `row`, `col`, `row2`, `col2` arguments, to get only a fragment of grid data.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSourceData
|
|
* @since 0.20.0
|
|
* @param {Number} [r] From physical row index.
|
|
* @param {Number} [c] From physical column index (or visual index, if data type is an array of objects).
|
|
* @param {Number} [r2] To physical row index.
|
|
* @param {Number} [c2] To physical column index (or visual index, if data type is an array of objects).
|
|
* @returns {Array} Array of grid data.
|
|
*/
|
|
this.getSourceData = function (r, c, r2, c2) {
|
|
var data = void 0;
|
|
|
|
if (r === void 0) {
|
|
data = dataSource.getData();
|
|
} else {
|
|
data = dataSource.getByRange(new _src.CellCoords(r, c), new _src.CellCoords(r2, c2));
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Returns the source data object as an arrays of arrays format even when source data was provided in another format.
|
|
* Optionally you can provide a cell range by using the `row`, `col`, `row2`, `col2` arguments, to get only a fragment of grid data.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSourceDataArray
|
|
* @since 0.28.0
|
|
* @param {Number} [r] From physical row index.
|
|
* @param {Number} [c] From physical column index (or visual index, if data type is an array of objects).
|
|
* @param {Number} [r2] To physical row index.
|
|
* @param {Number} [c2] To physical column index (or visual index, if data type is an array of objects).
|
|
* @returns {Array} An array of arrays.
|
|
*/
|
|
this.getSourceDataArray = function (r, c, r2, c2) {
|
|
var data = void 0;
|
|
|
|
if (r === void 0) {
|
|
data = dataSource.getData(true);
|
|
} else {
|
|
data = dataSource.getByRange(new _src.CellCoords(r, c), new _src.CellCoords(r2, c2), true);
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Returns an array of column values from the data source. `col` is the index of the row in the data source.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSourceDataAtCol
|
|
* @since 0.11.0-beta3
|
|
* @param {Number} column Visual column index.
|
|
* @returns {Array} Array of the column's cell values.
|
|
*/
|
|
// TODO: Getting data from `sourceData` should work always on physical indexes.
|
|
this.getSourceDataAtCol = function (column) {
|
|
return dataSource.getAtColumn(column);
|
|
};
|
|
|
|
/**
|
|
* Returns a single row of the data (array or object, depending on what you have). `row` is the index of the row in the data source.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSourceDataAtRow
|
|
* @since 0.11.0-beta3
|
|
* @param {Number} row Physical row index.
|
|
* @returns {Array|Object} Single row of data.
|
|
*/
|
|
this.getSourceDataAtRow = function (row) {
|
|
return dataSource.getAtRow(row);
|
|
};
|
|
|
|
/**
|
|
* Returns a single value from the data source.
|
|
*
|
|
* @memberof Core#
|
|
* @function getSourceDataAtCell
|
|
* @param {Number} row Physical row index.
|
|
* @param {Number} column Visual column index.
|
|
* @returns {*} Cell data.
|
|
* @since 0.20.0
|
|
*/
|
|
// TODO: Getting data from `sourceData` should work always on physical indexes.
|
|
this.getSourceDataAtCell = function (row, column) {
|
|
return dataSource.getAtCell(row, column);
|
|
};
|
|
|
|
/**
|
|
* @description
|
|
* Returns a single row of the data. The `row` argument is the __visible__ index of the row.
|
|
*
|
|
* @memberof Core#
|
|
* @function getDataAtRow
|
|
* @param {Number} row Visual row index.
|
|
* @returns {Array} Array of row's cell data.
|
|
* @since 0.9-beta2
|
|
*/
|
|
this.getDataAtRow = function (row) {
|
|
var data = datamap.getRange(new _src.CellCoords(row, 0), new _src.CellCoords(row, this.countCols() - 1), datamap.DESTINATION_RENDERER);
|
|
|
|
return data[0] || [];
|
|
};
|
|
|
|
/**
|
|
* @description
|
|
* Returns a data type defined in the Handsontable settings under the `type` key ([Options#type](http://docs.handsontable.com/Options.html#type)).
|
|
* If there are cells with different types in the selected range, it returns `'mixed'`.
|
|
*
|
|
* @since 0.18.1
|
|
* @memberof Core#
|
|
* @function getDataType
|
|
* @param {Number} rowFrom From visual row index.
|
|
* @param {Number} columnFrom From visual column index.
|
|
* @param {Number} rowTo To visual row index.
|
|
* @param {Number} columnTo To visual column index.
|
|
* @returns {String} Cell type (e.q: `'mixed'`, `'text'`, `'numeric'`, `'autocomplete'`).
|
|
*/
|
|
this.getDataType = function (rowFrom, columnFrom, rowTo, columnTo) {
|
|
var _this = this;
|
|
|
|
var previousType = null;
|
|
var currentType = null;
|
|
|
|
if (rowFrom === void 0) {
|
|
rowFrom = 0;
|
|
rowTo = this.countRows();
|
|
columnFrom = 0;
|
|
columnTo = this.countCols();
|
|
}
|
|
if (rowTo === void 0) {
|
|
rowTo = rowFrom;
|
|
}
|
|
if (columnTo === void 0) {
|
|
columnTo = columnFrom;
|
|
}
|
|
var type = 'mixed';
|
|
|
|
(0, _number.rangeEach)(Math.min(rowFrom, rowTo), Math.max(rowFrom, rowTo), function (row) {
|
|
var isTypeEqual = true;
|
|
|
|
(0, _number.rangeEach)(Math.min(columnFrom, columnTo), Math.max(columnFrom, columnTo), function (column) {
|
|
var cellType = _this.getCellMeta(row, column);
|
|
|
|
currentType = cellType.type;
|
|
|
|
if (previousType) {
|
|
isTypeEqual = previousType === currentType;
|
|
} else {
|
|
previousType = currentType;
|
|
}
|
|
|
|
return isTypeEqual;
|
|
});
|
|
type = isTypeEqual ? currentType : 'mixed';
|
|
|
|
return isTypeEqual;
|
|
});
|
|
|
|
return type;
|
|
};
|
|
|
|
/**
|
|
* Remove a property defined by the `key` argument from the cell meta object for the provided `row` and `col` coordinates.
|
|
*
|
|
* @memberof Core#
|
|
* @function removeCellMeta
|
|
* @param {Number} row Visual/physical row index.
|
|
* @param {Number} col Visual/physical column index.
|
|
* @param {String} key Property name.
|
|
*/
|
|
this.removeCellMeta = function (row, col, key) {
|
|
// TODO: First we use indexes as visual, after that, the same indexes are used as physical. This MUST be improved.
|
|
var cellMeta = instance.getCellMeta(row, col);
|
|
if (cellMeta[key] != undefined) {
|
|
delete priv.cellSettings[row][col][key];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Remove one or more rows from the cell meta object.
|
|
*
|
|
* @since 0.30.0
|
|
* @param {Number} index An integer that specifies at what position to add/remove items, Use negative values to specify the position from the end of the array.
|
|
* @param {Number} deleteAmount The number of items to be removed. If set to 0, no items will be removed.
|
|
* @param {Array} items The new items to be added to the array.
|
|
*/
|
|
this.spliceCellsMeta = function (index, deleteAmount) {
|
|
var _priv$cellSettings;
|
|
|
|
for (var _len2 = arguments.length, items = Array(_len2 > 2 ? _len2 - 2 : 0), _key = 2; _key < _len2; _key++) {
|
|
items[_key - 2] = arguments[_key];
|
|
}
|
|
|
|
(_priv$cellSettings = priv.cellSettings).splice.apply(_priv$cellSettings, [index, deleteAmount].concat(items));
|
|
};
|
|
|
|
/**
|
|
* Set cell meta data object defined by `prop` to the corresponding params `row` and `col`.
|
|
*
|
|
* @memberof Core#
|
|
* @function setCellMetaObject
|
|
* @since 0.11
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {Object} prop Meta object.
|
|
*/
|
|
this.setCellMetaObject = function (row, col, prop) {
|
|
if ((typeof prop === 'undefined' ? 'undefined' : _typeof(prop)) === 'object') {
|
|
for (var key in prop) {
|
|
if ((0, _object.hasOwnProperty)(prop, key)) {
|
|
var value = prop[key];
|
|
this.setCellMeta(row, col, key, value);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Sets a property defined by the `key` object to the meta object of a cell corresponding to params `row` and `col`.
|
|
*
|
|
* @memberof Core#
|
|
* @function setCellMeta
|
|
* @since 0.11
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {String} key Property name.
|
|
* @param {String} val Property value.
|
|
* @fires Hooks#afterSetCellMeta
|
|
*/
|
|
this.setCellMeta = function (row, col, key, val) {
|
|
var _recordTranslator$toP = recordTranslator.toPhysical(row, col);
|
|
|
|
var _recordTranslator$toP2 = _slicedToArray(_recordTranslator$toP, 2);
|
|
|
|
row = _recordTranslator$toP2[0];
|
|
col = _recordTranslator$toP2[1];
|
|
|
|
|
|
if (!priv.columnSettings[col]) {
|
|
priv.columnSettings[col] = (0, _setting.columnFactory)(GridSettings, priv.columnsSettingConflicts);
|
|
}
|
|
|
|
if (!priv.cellSettings[row]) {
|
|
priv.cellSettings[row] = [];
|
|
}
|
|
if (!priv.cellSettings[row][col]) {
|
|
priv.cellSettings[row][col] = new priv.columnSettings[col]();
|
|
}
|
|
priv.cellSettings[row][col][key] = val;
|
|
instance.runHooks('afterSetCellMeta', row, col, key, val);
|
|
};
|
|
|
|
/**
|
|
* Get all the cells meta settings at least once generated in the table (in order of cell initialization).
|
|
*
|
|
* @since 0.19.0
|
|
* @returns {Array} Returns Array of ColumnSettings object.
|
|
*/
|
|
this.getCellsMeta = function () {
|
|
return (0, _array.arrayFlatten)(priv.cellSettings);
|
|
};
|
|
|
|
/**
|
|
* Returns the cell properties object for the given `row` and `col` coordinates.
|
|
*
|
|
* @memberof Core#
|
|
* @function getCellMeta
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Object} The cell properties object.
|
|
* @fires Hooks#beforeGetCellMeta
|
|
* @fires Hooks#afterGetCellMeta
|
|
*/
|
|
this.getCellMeta = function (row, col) {
|
|
var prop = datamap.colToProp(col),
|
|
cellProperties;
|
|
|
|
var visualRow = row;
|
|
var visualCol = col;
|
|
|
|
var _recordTranslator$toP3 = recordTranslator.toPhysical(row, col);
|
|
|
|
var _recordTranslator$toP4 = _slicedToArray(_recordTranslator$toP3, 2);
|
|
|
|
row = _recordTranslator$toP4[0];
|
|
col = _recordTranslator$toP4[1];
|
|
|
|
|
|
if (!priv.columnSettings[col]) {
|
|
priv.columnSettings[col] = (0, _setting.columnFactory)(GridSettings, priv.columnsSettingConflicts);
|
|
}
|
|
|
|
if (!priv.cellSettings[row]) {
|
|
priv.cellSettings[row] = [];
|
|
}
|
|
if (!priv.cellSettings[row][col]) {
|
|
priv.cellSettings[row][col] = new priv.columnSettings[col]();
|
|
}
|
|
|
|
cellProperties = priv.cellSettings[row][col]; // retrieve cellProperties from cache
|
|
|
|
cellProperties.row = row;
|
|
cellProperties.col = col;
|
|
cellProperties.visualRow = visualRow;
|
|
cellProperties.visualCol = visualCol;
|
|
cellProperties.prop = prop;
|
|
cellProperties.instance = instance;
|
|
|
|
instance.runHooks('beforeGetCellMeta', row, col, cellProperties);
|
|
(0, _object.extend)(cellProperties, expandType(cellProperties)); // for `type` added in beforeGetCellMeta
|
|
|
|
if (cellProperties.cells) {
|
|
var settings = cellProperties.cells.call(cellProperties, row, col, prop);
|
|
|
|
if (settings) {
|
|
(0, _object.extend)(cellProperties, settings);
|
|
(0, _object.extend)(cellProperties, expandType(settings)); // for `type` added in cells
|
|
}
|
|
}
|
|
|
|
instance.runHooks('afterGetCellMeta', row, col, cellProperties);
|
|
|
|
return cellProperties;
|
|
};
|
|
|
|
/**
|
|
* Returns a row off the cell meta array.
|
|
*
|
|
* @memberof Core#
|
|
* @function getCellMetaAtRow
|
|
* @since 0.30.0
|
|
* @param {Number} row Physical index of the row to return cell meta for.
|
|
* @returns {Array}
|
|
*/
|
|
this.getCellMetaAtRow = function (row) {
|
|
return priv.cellSettings[row];
|
|
};
|
|
|
|
/**
|
|
* Checks if the data format and config allows user to modify the column structure.
|
|
* @returns {boolean}
|
|
*/
|
|
this.isColumnModificationAllowed = function () {
|
|
return !(instance.dataType === 'object' || instance.getSettings().columns);
|
|
};
|
|
|
|
var rendererLookup = (0, _data.cellMethodLookupFactory)('renderer');
|
|
|
|
/**
|
|
* Returns the cell renderer function by given `row` and `col` arguments.
|
|
*
|
|
* @memberof Core#
|
|
* @function getCellRenderer
|
|
* @since 0.11
|
|
* @param {Number|Object} row Visual row index or cell meta object.
|
|
* @param {Number} [col] Visual column index.
|
|
* @returns {Function} The renderer function.
|
|
*/
|
|
this.getCellRenderer = function (row, col) {
|
|
return (0, _renderers.getRenderer)(rendererLookup.call(this, row, col));
|
|
};
|
|
|
|
/**
|
|
* Returns the cell editor by the provided `row` and `col` arguments.
|
|
*
|
|
* @memberof Core#
|
|
* @function getCellEditor
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Object} The Editor object.
|
|
*/
|
|
this.getCellEditor = (0, _data.cellMethodLookupFactory)('editor');
|
|
|
|
var validatorLookup = (0, _data.cellMethodLookupFactory)('validator');
|
|
|
|
/**
|
|
* Returns the cell validator by `row` and `col`, provided a validator is defined. If not - it doesn't return anything.
|
|
*
|
|
* @memberof Core#
|
|
* @function getCellValidator
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Function|RegExp|undefined} The validator function.
|
|
*/
|
|
this.getCellValidator = function (row, col) {
|
|
var validator = validatorLookup.call(this, row, col);
|
|
|
|
if (typeof validator === 'string') {
|
|
validator = (0, _validators.getValidator)(validator);
|
|
}
|
|
|
|
return validator;
|
|
};
|
|
|
|
/**
|
|
* Validates all cells using their validator functions and calls callback when finished.
|
|
*
|
|
* If one of the cells is invalid, the callback will be fired with `'valid'` arguments as `false` - otherwise it would equal `true`.
|
|
*
|
|
* @memberof Core#
|
|
* @function validateCells
|
|
* @param {Function} [callback] The callback function.
|
|
*/
|
|
this.validateCells = function (callback) {
|
|
var waitingForValidator = new ValidatorsQueue();
|
|
|
|
if (callback) {
|
|
waitingForValidator.onQueueEmpty = callback;
|
|
}
|
|
|
|
var i = instance.countRows() - 1;
|
|
|
|
while (i >= 0) {
|
|
var j = instance.countCols() - 1;
|
|
|
|
while (j >= 0) {
|
|
waitingForValidator.addValidatorToQueue();
|
|
|
|
instance.validateCell(instance.getDataAtCell(i, j), instance.getCellMeta(i, j), function (result) {
|
|
if (typeof result !== 'boolean') {
|
|
throw new Error('Validation error: result is not boolean');
|
|
}
|
|
if (result === false) {
|
|
waitingForValidator.valid = false;
|
|
}
|
|
waitingForValidator.removeValidatorFormQueue();
|
|
}, 'validateCells');
|
|
j--;
|
|
}
|
|
i--;
|
|
}
|
|
waitingForValidator.checkIfQueueIsEmpty();
|
|
};
|
|
|
|
/**
|
|
* Returns an array of row headers' values (if they are enabled). If param `row` was given, it returns the header of the given row as a string.
|
|
*
|
|
* @memberof Core#
|
|
* @function getRowHeader
|
|
* @param {Number} [row] Visual row index.
|
|
* @fires Hooks#modifyRowHeader
|
|
* @returns {Array|String} Array of header values / single header value.
|
|
*/
|
|
this.getRowHeader = function (row) {
|
|
var rowHeader = priv.settings.rowHeaders;
|
|
|
|
if (row !== void 0) {
|
|
row = instance.runHooks('modifyRowHeader', row);
|
|
}
|
|
if (row === void 0) {
|
|
rowHeader = [];
|
|
(0, _number.rangeEach)(instance.countRows() - 1, function (i) {
|
|
rowHeader.push(instance.getRowHeader(i));
|
|
});
|
|
} else if (Array.isArray(rowHeader) && rowHeader[row] !== void 0) {
|
|
rowHeader = rowHeader[row];
|
|
} else if ((0, _function.isFunction)(rowHeader)) {
|
|
rowHeader = rowHeader(row);
|
|
} else if (rowHeader && typeof rowHeader !== 'string' && typeof rowHeader !== 'number') {
|
|
rowHeader = row + 1;
|
|
}
|
|
|
|
return rowHeader;
|
|
};
|
|
|
|
/**
|
|
* Returns information about if this table is configured to display row headers.
|
|
*
|
|
* @memberof Core#
|
|
* @function hasRowHeaders
|
|
* @returns {Boolean} `true` if the instance has the row headers enabled, `false` otherwise.
|
|
* @since 0.11
|
|
*/
|
|
this.hasRowHeaders = function () {
|
|
return !!priv.settings.rowHeaders;
|
|
};
|
|
|
|
/**
|
|
* Returns information about if this table is configured to display column headers.
|
|
*
|
|
* @memberof Core#
|
|
* @function hasColHeaders
|
|
* @since 0.11
|
|
* @returns {Boolean} `True` if the instance has the column headers enabled, `false` otherwise.
|
|
*/
|
|
this.hasColHeaders = function () {
|
|
if (priv.settings.colHeaders !== void 0 && priv.settings.colHeaders !== null) {
|
|
// Polymer has empty value = null
|
|
return !!priv.settings.colHeaders;
|
|
}
|
|
for (var i = 0, ilen = instance.countCols(); i < ilen; i++) {
|
|
if (instance.getColHeader(i)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Returns an array of column headers (in string format, if they are enabled). If param `col` is given, it returns the header at the given column as a string.
|
|
*
|
|
* @memberof Core#
|
|
* @function getColHeader
|
|
* @param {Number} [col] Visual column index.
|
|
* @fires Hooks#modifyColHeader
|
|
* @returns {Array|String} The column header(s).
|
|
*/
|
|
this.getColHeader = function (col) {
|
|
var columnsAsFunc = priv.settings.columns && (0, _function.isFunction)(priv.settings.columns);
|
|
var result = priv.settings.colHeaders;
|
|
|
|
col = instance.runHooks('modifyColHeader', col);
|
|
|
|
if (col === void 0) {
|
|
var out = [];
|
|
var ilen = columnsAsFunc ? instance.countSourceCols() : instance.countCols();
|
|
|
|
for (var i = 0; i < ilen; i++) {
|
|
out.push(instance.getColHeader(i));
|
|
}
|
|
|
|
result = out;
|
|
} else {
|
|
var translateVisualIndexToColumns = function translateVisualIndexToColumns(col) {
|
|
var arr = [];
|
|
var columnsLen = instance.countSourceCols();
|
|
var index = 0;
|
|
|
|
for (; index < columnsLen; index++) {
|
|
if ((0, _function.isFunction)(instance.getSettings().columns) && instance.getSettings().columns(index)) {
|
|
arr.push(index);
|
|
}
|
|
}
|
|
|
|
return arr[col];
|
|
};
|
|
var baseCol = col;
|
|
col = instance.runHooks('modifyCol', col);
|
|
|
|
var prop = translateVisualIndexToColumns(col);
|
|
|
|
if (priv.settings.columns && (0, _function.isFunction)(priv.settings.columns) && priv.settings.columns(prop) && priv.settings.columns(prop).title) {
|
|
result = priv.settings.columns(prop).title;
|
|
} else if (priv.settings.columns && priv.settings.columns[col] && priv.settings.columns[col].title) {
|
|
result = priv.settings.columns[col].title;
|
|
} else if (Array.isArray(priv.settings.colHeaders) && priv.settings.colHeaders[col] !== void 0) {
|
|
result = priv.settings.colHeaders[col];
|
|
} else if ((0, _function.isFunction)(priv.settings.colHeaders)) {
|
|
result = priv.settings.colHeaders(col);
|
|
} else if (priv.settings.colHeaders && typeof priv.settings.colHeaders !== 'string' && typeof priv.settings.colHeaders !== 'number') {
|
|
result = (0, _data.spreadsheetColumnLabel)(baseCol); // see #1458
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Return column width from settings (no guessing). Private use intended.
|
|
*
|
|
* @private
|
|
* @memberof Core#
|
|
* @function _getColWidthFromSettings
|
|
* @param {Number} col Visual col index.
|
|
* @returns {Number}
|
|
*/
|
|
this._getColWidthFromSettings = function (col) {
|
|
var cellProperties = instance.getCellMeta(0, col);
|
|
var width = cellProperties.width;
|
|
|
|
if (width === void 0 || width === priv.settings.width) {
|
|
width = cellProperties.colWidths;
|
|
}
|
|
if (width !== void 0 && width !== null) {
|
|
switch (typeof width === 'undefined' ? 'undefined' : _typeof(width)) {
|
|
case 'object':
|
|
// array
|
|
width = width[col];
|
|
break;
|
|
|
|
case 'function':
|
|
width = width(col);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (typeof width === 'string') {
|
|
width = parseInt(width, 10);
|
|
}
|
|
}
|
|
|
|
return width;
|
|
};
|
|
|
|
/**
|
|
* Returns the width of the requested column.
|
|
*
|
|
* @memberof Core#
|
|
* @function getColWidth
|
|
* @since 0.11
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Number} Column width.
|
|
* @fires Hooks#modifyColWidth
|
|
*/
|
|
this.getColWidth = function (col) {
|
|
var width = instance._getColWidthFromSettings(col);
|
|
|
|
width = instance.runHooks('modifyColWidth', width, col);
|
|
|
|
if (width === void 0) {
|
|
width = _src.ViewportColumnsCalculator.DEFAULT_WIDTH;
|
|
}
|
|
|
|
return width;
|
|
};
|
|
|
|
/**
|
|
* Return row height from settings (no guessing). Private use intended.
|
|
*
|
|
* @private
|
|
* @memberof Core#
|
|
* @function _getRowHeightFromSettings
|
|
* @param {Number} row Visual row index.
|
|
* @returns {Number}
|
|
*/
|
|
this._getRowHeightFromSettings = function (row) {
|
|
// let cellProperties = instance.getCellMeta(row, 0);
|
|
// let height = cellProperties.height;
|
|
//
|
|
// if (height === void 0 || height === priv.settings.height) {
|
|
// height = cellProperties.rowHeights;
|
|
// }
|
|
var height = priv.settings.rowHeights;
|
|
|
|
if (height !== void 0 && height !== null) {
|
|
switch (typeof height === 'undefined' ? 'undefined' : _typeof(height)) {
|
|
case 'object':
|
|
// array
|
|
height = height[row];
|
|
break;
|
|
|
|
case 'function':
|
|
height = height(row);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (typeof height === 'string') {
|
|
height = parseInt(height, 10);
|
|
}
|
|
}
|
|
|
|
return height;
|
|
};
|
|
|
|
/**
|
|
* Returns the row height.
|
|
*
|
|
* @memberof Core#
|
|
* @function getRowHeight
|
|
* @since 0.11
|
|
* @param {Number} row Visual row index.
|
|
* @returns {Number} The given row's height.
|
|
* @fires Hooks#modifyRowHeight
|
|
*/
|
|
this.getRowHeight = function (row) {
|
|
var height = instance._getRowHeightFromSettings(row);
|
|
|
|
height = instance.runHooks('modifyRowHeight', height, row);
|
|
|
|
return height;
|
|
};
|
|
|
|
/**
|
|
* Returns the total number of rows in the data source.
|
|
*
|
|
* @memberof Core#
|
|
* @function countSourceRows
|
|
* @since 0.20.0
|
|
* @returns {Number} Total number in rows in data source.
|
|
*/
|
|
this.countSourceRows = function () {
|
|
var sourceLength = instance.runHooks('modifySourceLength');
|
|
return sourceLength || (instance.getSourceData() ? instance.getSourceData().length : 0);
|
|
};
|
|
|
|
/**
|
|
* Returns the total number of columns in the data source.
|
|
*
|
|
* @memberof Core#
|
|
* @function countSourceCols
|
|
* @since 0.26.1
|
|
* @returns {Number} Total number in columns in data source.
|
|
*/
|
|
this.countSourceCols = function () {
|
|
var len = 0;
|
|
var obj = instance.getSourceData() && instance.getSourceData()[0] ? instance.getSourceData()[0] : [];
|
|
|
|
if ((0, _object.isObject)(obj)) {
|
|
len = (0, _object.deepObjectSize)(obj);
|
|
} else {
|
|
len = obj.length || 0;
|
|
}
|
|
|
|
return len;
|
|
};
|
|
|
|
/**
|
|
* Returns the total number of rows in the grid.
|
|
*
|
|
* @memberof Core#
|
|
* @function countRows
|
|
* @returns {Number} Total number in rows the grid.
|
|
*/
|
|
this.countRows = function () {
|
|
return datamap.getLength();
|
|
};
|
|
|
|
/**
|
|
* Returns the total number of columns in the grid.
|
|
*
|
|
* @memberof Core#
|
|
* @function countCols
|
|
* @returns {Number} Total number of columns.
|
|
*/
|
|
this.countCols = function () {
|
|
var maxCols = this.getSettings().maxCols;
|
|
var dataHasLength = false;
|
|
var dataLen = 0;
|
|
|
|
if (instance.dataType === 'array') {
|
|
dataHasLength = priv.settings.data && priv.settings.data[0] && priv.settings.data[0].length;
|
|
}
|
|
|
|
if (dataHasLength) {
|
|
dataLen = priv.settings.data[0].length;
|
|
}
|
|
|
|
if (priv.settings.columns) {
|
|
var columnsIsFunction = (0, _function.isFunction)(priv.settings.columns);
|
|
|
|
if (columnsIsFunction) {
|
|
if (instance.dataType === 'array') {
|
|
var columnLen = 0;
|
|
|
|
for (var i = 0; i < dataLen; i++) {
|
|
if (priv.settings.columns(i)) {
|
|
columnLen++;
|
|
}
|
|
}
|
|
|
|
dataLen = columnLen;
|
|
} else if (instance.dataType === 'object' || instance.dataType === 'function') {
|
|
dataLen = datamap.colToPropCache.length;
|
|
}
|
|
} else {
|
|
dataLen = priv.settings.columns.length;
|
|
}
|
|
} else if (instance.dataType === 'object' || instance.dataType === 'function') {
|
|
dataLen = datamap.colToPropCache.length;
|
|
}
|
|
|
|
return Math.min(maxCols, dataLen);
|
|
};
|
|
|
|
/**
|
|
* Returns an visual index of the first rendered row.
|
|
*
|
|
* @memberof Core#
|
|
* @function rowOffset
|
|
* @returns {Number} Visual index of first rendered row.
|
|
*/
|
|
this.rowOffset = function () {
|
|
return instance.view.wt.wtTable.getFirstRenderedRow();
|
|
};
|
|
|
|
/**
|
|
* Returns the visual index of the first rendered column.
|
|
*
|
|
* @memberof Core#
|
|
* @function colOffset
|
|
* @returns {Number} Visual index of the first visible column.
|
|
*/
|
|
this.colOffset = function () {
|
|
return instance.view.wt.wtTable.getFirstRenderedColumn();
|
|
};
|
|
|
|
/**
|
|
* Returns the number of rendered rows (including rows partially or fully rendered outside viewport).
|
|
*
|
|
* @memberof Core#
|
|
* @function countRenderedRows
|
|
* @returns {Number} Returns -1 if table is not visible.
|
|
*/
|
|
this.countRenderedRows = function () {
|
|
return instance.view.wt.drawn ? instance.view.wt.wtTable.getRenderedRowsCount() : -1;
|
|
};
|
|
|
|
/**
|
|
* Returns the number of visible rows (rendered rows that fully fit inside viewport).
|
|
*
|
|
* @memberof Core#
|
|
* @function countVisibleRows
|
|
* @returns {Number} Number of visible rows or -1.
|
|
*/
|
|
this.countVisibleRows = function () {
|
|
return instance.view.wt.drawn ? instance.view.wt.wtTable.getVisibleRowsCount() : -1;
|
|
};
|
|
|
|
/**
|
|
* Returns the number of rendered columns (including columns partially or fully rendered outside viewport).
|
|
*
|
|
* @memberof Core#
|
|
* @function countRenderedCols
|
|
* @returns {Number} Returns -1 if table is not visible.
|
|
*/
|
|
this.countRenderedCols = function () {
|
|
return instance.view.wt.drawn ? instance.view.wt.wtTable.getRenderedColumnsCount() : -1;
|
|
};
|
|
|
|
/**
|
|
* Returns the number of visible columns. Returns -1 if table is not visible
|
|
*
|
|
* @memberof Core#
|
|
* @function countVisibleCols
|
|
* @return {Number} Number of visible columns or -1.
|
|
*/
|
|
this.countVisibleCols = function () {
|
|
return instance.view.wt.drawn ? instance.view.wt.wtTable.getVisibleColumnsCount() : -1;
|
|
};
|
|
|
|
/**
|
|
* Returns the number of empty rows. If the optional ending parameter is `true`, returns the
|
|
* number of empty rows at the bottom of the table.
|
|
*
|
|
* @memberof Core#
|
|
* @function countEmptyRows
|
|
* @param {Boolean} [ending] If `true`, will only count empty rows at the end of the data source.
|
|
* @returns {Number} Count empty rows
|
|
* @fires Hooks#modifyRow
|
|
*/
|
|
this.countEmptyRows = function (ending) {
|
|
var i = instance.countRows() - 1,
|
|
empty = 0,
|
|
row;
|
|
|
|
while (i >= 0) {
|
|
row = instance.runHooks('modifyRow', i);
|
|
|
|
if (instance.isEmptyRow(row)) {
|
|
empty++;
|
|
} else if (ending) {
|
|
break;
|
|
}
|
|
i--;
|
|
}
|
|
|
|
return empty;
|
|
};
|
|
|
|
/**
|
|
* Returns the number of empty columns. If the optional ending parameter is `true`, returns the number of empty
|
|
* columns at right hand edge of the table.
|
|
*
|
|
* @memberof Core#
|
|
* @function countEmptyCols
|
|
* @param {Boolean} [ending] If `true`, will only count empty columns at the end of the data source row.
|
|
* @returns {Number} Count empty cols
|
|
*/
|
|
this.countEmptyCols = function (ending) {
|
|
if (instance.countRows() < 1) {
|
|
return 0;
|
|
}
|
|
var i = instance.countCols() - 1,
|
|
empty = 0;
|
|
|
|
while (i >= 0) {
|
|
if (instance.isEmptyCol(i)) {
|
|
empty++;
|
|
} else if (ending) {
|
|
break;
|
|
}
|
|
i--;
|
|
}
|
|
|
|
return empty;
|
|
};
|
|
|
|
/**
|
|
* Check if all cells in the row declared by the `row` argument are empty.
|
|
*
|
|
* @memberof Core#
|
|
* @function isEmptyRow
|
|
* @param {Number} row Row index.
|
|
* @returns {Boolean} `true` if the row at the given `row` is empty, `false` otherwise.
|
|
*/
|
|
this.isEmptyRow = function (row) {
|
|
return priv.settings.isEmptyRow.call(instance, row);
|
|
};
|
|
|
|
/**
|
|
* Check if all cells in the the column declared by the `col` argument are empty.
|
|
*
|
|
* @memberof Core#
|
|
* @function isEmptyCol
|
|
* @param {Number} col Column index.
|
|
* @returns {Boolean} `true` if the column at the given `col` is empty, `false` otherwise.
|
|
*/
|
|
this.isEmptyCol = function (col) {
|
|
return priv.settings.isEmptyCol.call(instance, col);
|
|
};
|
|
|
|
/**
|
|
* Select cell specified by `row` and `col` values or a range of cells finishing at `endRow`, `endCol`.
|
|
* By default, viewport will be scrolled to selection.
|
|
* After the `selectCell` method had finished, the instance will be listening to keyboard input on the document.
|
|
*
|
|
* @memberof Core#
|
|
* @function selectCell
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {Number} [endRow] Visual end row index (if selecting a range).
|
|
* @param {Number} [endCol] Visual end column index (if selecting a range).
|
|
* @param {Boolean} [scrollToCell=true] If `true`, the viewport will be scrolled to the selection.
|
|
* @param {Boolean} [changeListener=true] If `false`, Handsontable will not change keyboard events listener to himself.
|
|
* @returns {Boolean} `true` if selection was successful, `false` otherwise.
|
|
*/
|
|
this.selectCell = function (row, col, endRow, endCol, scrollToCell, changeListener) {
|
|
var coords;
|
|
|
|
changeListener = (0, _mixed.isUndefined)(changeListener) || changeListener === true;
|
|
|
|
if (typeof row !== 'number' || row < 0 || row >= instance.countRows()) {
|
|
return false;
|
|
}
|
|
if (typeof col !== 'number' || col < 0 || col >= instance.countCols()) {
|
|
return false;
|
|
}
|
|
if ((0, _mixed.isDefined)(endRow)) {
|
|
if (typeof endRow !== 'number' || endRow < 0 || endRow >= instance.countRows()) {
|
|
return false;
|
|
}
|
|
if (typeof endCol !== 'number' || endCol < 0 || endCol >= instance.countCols()) {
|
|
return false;
|
|
}
|
|
}
|
|
coords = new _src.CellCoords(row, col);
|
|
priv.selRange = new _src.CellRange(coords, coords, coords);
|
|
|
|
if (changeListener) {
|
|
instance.listen();
|
|
}
|
|
|
|
if ((0, _mixed.isUndefined)(endRow)) {
|
|
selection.setRangeEnd(priv.selRange.from, scrollToCell);
|
|
} else {
|
|
selection.setRangeEnd(new _src.CellCoords(endRow, endCol), scrollToCell);
|
|
}
|
|
instance.selection.finish();
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Select the cell specified by the `row` and `prop` arguments, or a range finishing at `endRow`, `endProp`.
|
|
* By default, viewport will be scrolled to selection.
|
|
*
|
|
* @memberof Core#
|
|
* @function selectCellByProp
|
|
* @param {Number} row Visual row index.
|
|
* @param {String} prop Property name.
|
|
* @param {Number} [endRow] visual end row index (if selecting a range).
|
|
* @param {String} [endProp] End property name (if selecting a range).
|
|
* @param {Boolean} [scrollToCell=true] If `true`, viewport will be scrolled to the selection.
|
|
* @returns {Boolean} `true` if selection was successful, `false` otherwise.
|
|
*/
|
|
this.selectCellByProp = function (row, prop, endRow, endProp, scrollToCell) {
|
|
var _instance5;
|
|
|
|
arguments[1] = datamap.propToCol(arguments[1]);
|
|
|
|
if ((0, _mixed.isDefined)(arguments[3])) {
|
|
arguments[3] = datamap.propToCol(arguments[3]);
|
|
}
|
|
|
|
return (_instance5 = instance).selectCell.apply(_instance5, arguments);
|
|
};
|
|
|
|
/**
|
|
* Deselects the current cell selection on grid.
|
|
*
|
|
* @memberof Core#
|
|
* @function deselectCell
|
|
*/
|
|
this.deselectCell = function () {
|
|
selection.deselect();
|
|
};
|
|
|
|
/**
|
|
* Scroll viewport to coords specified by the `row` and `column` arguments.
|
|
*
|
|
* @since 0.24.3
|
|
* @memberof Core#
|
|
* @function scrollViewportTo
|
|
* @param {Number} [row] Visual row index.
|
|
* @param {Number} [column] Visual column index.
|
|
* @param {Boolean} [snapToBottom = false] If `true`, viewport is scrolled to show the cell on the bottom of the table.
|
|
* @param {Boolean} [snapToRight = false] If `true`, viewport is scrolled to show the cell on the right side of the table.
|
|
* @returns {Boolean} `true` if scroll was successful, `false` otherwise.
|
|
*/
|
|
this.scrollViewportTo = function (row, column) {
|
|
var snapToBottom = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
var snapToRight = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
|
|
if (row !== void 0 && (row < 0 || row >= instance.countRows())) {
|
|
return false;
|
|
}
|
|
if (column !== void 0 && (column < 0 || column >= instance.countCols())) {
|
|
return false;
|
|
}
|
|
|
|
var result = false;
|
|
|
|
if (row !== void 0 && column !== void 0) {
|
|
instance.view.wt.wtOverlays.topOverlay.scrollTo(row, snapToBottom);
|
|
instance.view.wt.wtOverlays.leftOverlay.scrollTo(column, snapToRight);
|
|
|
|
result = true;
|
|
}
|
|
if (typeof row === 'number' && typeof column !== 'number') {
|
|
instance.view.wt.wtOverlays.topOverlay.scrollTo(row, snapToBottom);
|
|
|
|
result = true;
|
|
}
|
|
if (typeof column === 'number' && typeof row !== 'number') {
|
|
instance.view.wt.wtOverlays.leftOverlay.scrollTo(column, snapToRight);
|
|
|
|
result = true;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Removes grid from the DOM.
|
|
*
|
|
* @memberof Core#
|
|
* @function destroy
|
|
* @fires Hooks#afterDestroy
|
|
*/
|
|
this.destroy = function () {
|
|
|
|
instance._clearTimeouts();
|
|
if (instance.view) {
|
|
// in case HT is destroyed before initialization has finished
|
|
instance.view.destroy();
|
|
}
|
|
if (dataSource) {
|
|
dataSource.destroy();
|
|
}
|
|
dataSource = null;
|
|
|
|
(0, _element.empty)(instance.rootElement);
|
|
eventManager.destroy();
|
|
|
|
instance.runHooks('afterDestroy');
|
|
_pluginHooks2.default.getSingleton().destroy(instance);
|
|
|
|
for (var i in instance) {
|
|
if ((0, _object.hasOwnProperty)(instance, i)) {
|
|
// replace instance methods with post mortem
|
|
if ((0, _function.isFunction)(instance[i])) {
|
|
instance[i] = postMortem;
|
|
} else if (i !== 'guid') {
|
|
// replace instance properties with null (restores memory)
|
|
// it should not be necessary but this prevents a memory leak side effects that show itself in Jasmine tests
|
|
instance[i] = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
// replace private properties with null (restores memory)
|
|
// it should not be necessary but this prevents a memory leak side effects that show itself in Jasmine tests
|
|
if (datamap) {
|
|
datamap.destroy();
|
|
}
|
|
datamap = null;
|
|
priv = null;
|
|
grid = null;
|
|
selection = null;
|
|
editorManager = null;
|
|
instance = null;
|
|
GridSettings = null;
|
|
};
|
|
|
|
/**
|
|
* Replacement for all methods after Handsotnable was destroyed.
|
|
*
|
|
* @private
|
|
*/
|
|
function postMortem() {
|
|
throw new Error('This method cannot be called because this Handsontable instance has been destroyed');
|
|
}
|
|
|
|
/**
|
|
* Returns the active editor object.
|
|
*
|
|
* @memberof Core#
|
|
* @function getActiveEditor
|
|
* @returns {Object} The active editor object.
|
|
*/
|
|
this.getActiveEditor = function () {
|
|
return editorManager.getActiveEditor();
|
|
};
|
|
|
|
/**
|
|
* Returns plugin instance using the plugin name provided.
|
|
*
|
|
* @memberof Core#
|
|
* @function getPlugin
|
|
* @param {String} pluginName The plugin name.
|
|
* @returns {*} The plugin instance.
|
|
* @since 0.15.0
|
|
*/
|
|
this.getPlugin = function (pluginName) {
|
|
return (0, _plugins.getPlugin)(this, pluginName);
|
|
};
|
|
|
|
/**
|
|
* Returns the Handsontable instance.
|
|
*
|
|
* @memberof Core#
|
|
* @function getInstance
|
|
* @returns {Handsontable} The Handsontable instance.
|
|
*/
|
|
this.getInstance = function () {
|
|
return instance;
|
|
};
|
|
|
|
/**
|
|
* Adds listener to the specified hook name (only for this Handsontable instance).
|
|
*
|
|
* @memberof Core#
|
|
* @function addHook
|
|
* @see Hooks#add
|
|
* @param {String} key Hook name.
|
|
* @param {Function|Array} callback Function or array of Functions.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* hot.addHook('beforeInit', myCallback);
|
|
* ```
|
|
*/
|
|
this.addHook = function (key, callback) {
|
|
_pluginHooks2.default.getSingleton().add(key, callback, instance);
|
|
};
|
|
|
|
/**
|
|
* Check if for a specified hook name there are added listeners (only for this Handsontable instance).
|
|
*
|
|
* @memberof Core#
|
|
* @function hasHook
|
|
* @see Hooks#has
|
|
* @param {String} key Hook name
|
|
* @return {Boolean}
|
|
*
|
|
* @example
|
|
* ```js
|
|
* var hasBeforeInitListeners = hot.hasHook('beforeInit');
|
|
* ```
|
|
*/
|
|
this.hasHook = function (key) {
|
|
return _pluginHooks2.default.getSingleton().has(key, instance);
|
|
};
|
|
|
|
/**
|
|
* Adds listener to specified hook name (only for this Handsontable instance).
|
|
* After the listener is triggered, it will be automatically removed.
|
|
*
|
|
* @memberof Core#
|
|
* @function addHookOnce
|
|
* @see Hooks#once
|
|
* @param {String} key Hook name.
|
|
* @param {Function|Array} callback Function or array of Functions.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* hot.addHookOnce('beforeInit', myCallback);
|
|
* ```
|
|
*/
|
|
this.addHookOnce = function (key, callback) {
|
|
_pluginHooks2.default.getSingleton().once(key, callback, instance);
|
|
};
|
|
|
|
/**
|
|
* Removes the hook listener previously registered with {@link Core#addHook}.
|
|
*
|
|
* @memberof Core#
|
|
* @function removeHook
|
|
* @see Hooks#remove
|
|
* @param {String} key Hook name.
|
|
* @param {Function} callback Function which have been registered via {@link Core#addHook}.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* hot.removeHook('beforeInit', myCallback);
|
|
* ```
|
|
*/
|
|
this.removeHook = function (key, callback) {
|
|
_pluginHooks2.default.getSingleton().remove(key, callback, instance);
|
|
};
|
|
|
|
/**
|
|
* Run the callbacks for the hook provided in the `key` argument using the parameters given in the other arguments.
|
|
*
|
|
* @memberof Core#
|
|
* @function runHooks
|
|
* @see Hooks#run
|
|
* @param {String} key Hook name.
|
|
* @param {*} [p1] Argument passed to the callback.
|
|
* @param {*} [p2] Argument passed to the callback.
|
|
* @param {*} [p3] Argument passed to the callback.
|
|
* @param {*} [p4] Argument passed to the callback.
|
|
* @param {*} [p5] Argument passed to the callback.
|
|
* @param {*} [p6] Argument passed to the callback.
|
|
* @returns {*}
|
|
*
|
|
* @example
|
|
* ```js
|
|
* hot.runHooks('beforeInit');
|
|
* ```
|
|
*/
|
|
this.runHooks = function (key, p1, p2, p3, p4, p5, p6) {
|
|
return _pluginHooks2.default.getSingleton().run(instance, key, p1, p2, p3, p4, p5, p6);
|
|
};
|
|
|
|
this.timeouts = [];
|
|
|
|
/**
|
|
* Sets timeout. Purpose of this method is to clear all known timeouts when `destroy` method is called.
|
|
*
|
|
* @param {*} handle
|
|
* @private
|
|
*/
|
|
this._registerTimeout = function (handle) {
|
|
this.timeouts.push(handle);
|
|
};
|
|
|
|
/**
|
|
* Clears all known timeouts.
|
|
*
|
|
* @private
|
|
*/
|
|
this._clearTimeouts = function () {
|
|
for (var i = 0, ilen = this.timeouts.length; i < ilen; i++) {
|
|
clearTimeout(this.timeouts[i]);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handsontable version
|
|
*
|
|
* @type {String}
|
|
*/
|
|
// this.version = Handsontable.version;
|
|
|
|
_pluginHooks2.default.getSingleton().run(instance, 'construct');
|
|
};
|
|
|
|
/***/ }),
|
|
/* 65 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.spreadsheetColumnLabel = spreadsheetColumnLabel;
|
|
exports.spreadsheetColumnIndex = spreadsheetColumnIndex;
|
|
exports.createSpreadsheetData = createSpreadsheetData;
|
|
exports.createSpreadsheetObjectData = createSpreadsheetObjectData;
|
|
exports.createEmptySpreadsheetData = createEmptySpreadsheetData;
|
|
exports.translateRowsToColumns = translateRowsToColumns;
|
|
exports.cellMethodLookupFactory = cellMethodLookupFactory;
|
|
|
|
var _cellTypes = __webpack_require__(63);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var COLUMN_LABEL_BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
|
|
|
|
/**
|
|
* Generates spreadsheet-like column names: A, B, C, ..., Z, AA, AB, etc.
|
|
*
|
|
* @param {Number} index Column index.
|
|
* @returns {String}
|
|
*/
|
|
function spreadsheetColumnLabel(index) {
|
|
var dividend = index + 1;
|
|
var columnLabel = '';
|
|
var modulo = void 0;
|
|
|
|
while (dividend > 0) {
|
|
modulo = (dividend - 1) % COLUMN_LABEL_BASE_LENGTH;
|
|
columnLabel = String.fromCharCode(65 + modulo) + columnLabel;
|
|
dividend = parseInt((dividend - modulo) / COLUMN_LABEL_BASE_LENGTH, 10);
|
|
}
|
|
|
|
return columnLabel;
|
|
}
|
|
|
|
/**
|
|
* Generates spreadsheet-like column index from theirs labels: A, B, C ...., Z, AA, AB, etc.
|
|
*
|
|
* @param {String} label Column label.
|
|
* @returns {Number}
|
|
*/
|
|
function spreadsheetColumnIndex(label) {
|
|
var result = 0;
|
|
|
|
if (label) {
|
|
for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
|
|
result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
|
|
}
|
|
}
|
|
--result;
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates 2D array of Excel-like values "A1", "A2", ...
|
|
*
|
|
* @param {Number} rows Number of rows to generate.
|
|
* @param {Number} columns Number of columns to generate.
|
|
* @returns {Array}
|
|
*/
|
|
function createSpreadsheetData() {
|
|
var rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
|
|
var columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
|
|
|
|
var _rows = [],
|
|
i,
|
|
j;
|
|
|
|
for (i = 0; i < rows; i++) {
|
|
var row = [];
|
|
|
|
for (j = 0; j < columns; j++) {
|
|
row.push(spreadsheetColumnLabel(j) + (i + 1));
|
|
}
|
|
_rows.push(row);
|
|
}
|
|
|
|
return _rows;
|
|
}
|
|
|
|
/**
|
|
* Creates 2D array of Excel-like values "A1", "A2", as an array of objects.
|
|
*
|
|
* @param {Number} rows Number of rows to generate.
|
|
* @param {Number} colCount Number of columns to generate.
|
|
* @returns {Array}
|
|
*/
|
|
function createSpreadsheetObjectData() {
|
|
var rows = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 100;
|
|
var colCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
|
|
|
|
var _rows = [],
|
|
i,
|
|
j;
|
|
|
|
for (i = 0; i < rows; i++) {
|
|
var row = {};
|
|
|
|
for (j = 0; j < colCount; j++) {
|
|
row['prop' + j] = spreadsheetColumnLabel(j) + (i + 1);
|
|
}
|
|
_rows.push(row);
|
|
}
|
|
|
|
return _rows;
|
|
}
|
|
|
|
/**
|
|
* Generates an empty data object.
|
|
*
|
|
* @param {Number} rows Number of rows to generate.
|
|
* @param {Number} columns Number of columns to generate
|
|
* @returns {Array}
|
|
*/
|
|
function createEmptySpreadsheetData(rows, columns) {
|
|
var data = [];
|
|
var row = void 0;
|
|
|
|
for (var i = 0; i < rows; i++) {
|
|
row = [];
|
|
for (var j = 0; j < columns; j++) {
|
|
row.push('');
|
|
}
|
|
data.push(row);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function translateRowsToColumns(input) {
|
|
var i,
|
|
ilen,
|
|
j,
|
|
jlen,
|
|
output = [],
|
|
olen = 0;
|
|
|
|
for (i = 0, ilen = input.length; i < ilen; i++) {
|
|
for (j = 0, jlen = input[i].length; j < jlen; j++) {
|
|
if (j == olen) {
|
|
output.push([]);
|
|
olen++;
|
|
}
|
|
output[j].push(input[i][j]);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
/**
|
|
* Factory that produces a function for searching methods (or any properties) which could be defined directly in
|
|
* table configuration or implicitly, within cell type definition.
|
|
*
|
|
* For example: renderer can be defined explicitly using "renderer" property in column configuration or it can be
|
|
* defined implicitly using "type" property.
|
|
*
|
|
* Methods/properties defined explicitly always takes precedence over those defined through "type".
|
|
*
|
|
* If the method/property is not found in an object, searching is continued recursively through prototype chain, until
|
|
* it reaches the Object.prototype.
|
|
*
|
|
*
|
|
* @param methodName {String} name of the method/property to search (i.e. 'renderer', 'validator', 'copyable')
|
|
* @param allowUndefined {Boolean} [optional] if false, the search is continued if methodName has not been found in cell "type"
|
|
* @returns {Function}
|
|
*/
|
|
function cellMethodLookupFactory(methodName, allowUndefined) {
|
|
|
|
allowUndefined = typeof allowUndefined == 'undefined' ? true : allowUndefined;
|
|
|
|
return function cellMethodLookup(row, col) {
|
|
return function getMethodFromProperties(properties) {
|
|
|
|
if (!properties) {
|
|
return; // method not found
|
|
} else if ((0, _object.hasOwnProperty)(properties, methodName) && properties[methodName] !== void 0) {
|
|
// check if it is own and is not empty
|
|
return properties[methodName]; // method defined directly
|
|
} else if ((0, _object.hasOwnProperty)(properties, 'type') && properties.type) {
|
|
// check if it is own and is not empty
|
|
var type;
|
|
|
|
if (typeof properties.type != 'string') {
|
|
throw new Error('Cell type must be a string ');
|
|
}
|
|
type = (0, _cellTypes.getCellType)(properties.type);
|
|
|
|
if ((0, _object.hasOwnProperty)(type, methodName)) {
|
|
return type[methodName]; // method defined in type.
|
|
} else if (allowUndefined) {
|
|
return; // method does not defined in type (eg. validator), returns undefined
|
|
}
|
|
}
|
|
|
|
return getMethodFromProperties(Object.getPrototypeOf(properties));
|
|
}(typeof row == 'number' ? this.getCellMeta(row, col) : row);
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 66 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.columnFactory = columnFactory;
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
/* eslint-disable import/prefer-default-export */
|
|
/**
|
|
* Factory for columns constructors.
|
|
*
|
|
* @param {Object} GridSettings
|
|
* @param {Array} conflictList
|
|
* @return {Object} ColumnSettings
|
|
*/
|
|
function columnFactory(GridSettings, conflictList) {
|
|
function ColumnSettings() {};
|
|
|
|
(0, _object.inherit)(ColumnSettings, GridSettings);
|
|
|
|
// Clear conflict settings
|
|
for (var i = 0, len = conflictList.length; i < len; i++) {
|
|
ColumnSettings.prototype[conflictList[i]] = void 0;
|
|
}
|
|
|
|
return ColumnSettings;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 67 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class GhostTable
|
|
* @util
|
|
*/
|
|
var GhostTable = function () {
|
|
function GhostTable(hotInstance) {
|
|
_classCallCheck(this, GhostTable);
|
|
|
|
/**
|
|
* Handsontable instance.
|
|
*
|
|
* @type {Core}
|
|
*/
|
|
this.hot = hotInstance;
|
|
/**
|
|
* Container element where every table will be injected.
|
|
*
|
|
* @type {HTMLElement|null}
|
|
*/
|
|
this.container = null;
|
|
/**
|
|
* Flag which determine is table was injected to DOM.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
this.injected = false;
|
|
/**
|
|
* Added rows collection.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
this.rows = [];
|
|
/**
|
|
* Added columns collection.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
this.columns = [];
|
|
/**
|
|
* Samples prepared for calculations.
|
|
*
|
|
* @type {Map}
|
|
* @default {null}
|
|
*/
|
|
this.samples = null;
|
|
/**
|
|
* Ghost table settings.
|
|
*
|
|
* @type {Object}
|
|
* @default {Object}
|
|
*/
|
|
this.settings = {
|
|
useHeaders: true
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Add row.
|
|
*
|
|
* @param {Number} row Row index.
|
|
* @param {Map} samples Samples Map object.
|
|
*/
|
|
|
|
|
|
_createClass(GhostTable, [{
|
|
key: 'addRow',
|
|
value: function addRow(row, samples) {
|
|
if (this.columns.length) {
|
|
throw new Error('Doesn\'t support multi-dimensional table');
|
|
}
|
|
if (!this.rows.length) {
|
|
this.container = this.createContainer(this.hot.rootElement.className);
|
|
}
|
|
var rowObject = { row: row };
|
|
this.rows.push(rowObject);
|
|
|
|
this.samples = samples;
|
|
this.table = this.createTable(this.hot.table.className);
|
|
this.table.colGroup.appendChild(this.createColGroupsCol());
|
|
this.table.tr.appendChild(this.createRow(row));
|
|
this.container.container.appendChild(this.table.fragment);
|
|
|
|
rowObject.table = this.table.table;
|
|
}
|
|
|
|
/**
|
|
* Add a row consisting of the column headers.
|
|
*/
|
|
|
|
}, {
|
|
key: 'addColumnHeadersRow',
|
|
value: function addColumnHeadersRow(samples) {
|
|
if (this.hot.getColHeader(0) != null) {
|
|
var rowObject = { row: -1 };
|
|
this.rows.push(rowObject);
|
|
|
|
this.container = this.createContainer(this.hot.rootElement.className);
|
|
|
|
this.samples = samples;
|
|
this.table = this.createTable(this.hot.table.className);
|
|
this.table.colGroup.appendChild(this.createColGroupsCol());
|
|
this.table.tHead.appendChild(this.createColumnHeadersRow());
|
|
this.container.container.appendChild(this.table.fragment);
|
|
|
|
rowObject.table = this.table.table;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add column.
|
|
*
|
|
* @param {Number} column Column index.
|
|
* @param {Map} samples Samples Map object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'addColumn',
|
|
value: function addColumn(column, samples) {
|
|
if (this.rows.length) {
|
|
throw new Error('Doesn\'t support multi-dimensional table');
|
|
}
|
|
if (!this.columns.length) {
|
|
this.container = this.createContainer(this.hot.rootElement.className);
|
|
}
|
|
var columnObject = { col: column };
|
|
this.columns.push(columnObject);
|
|
|
|
this.samples = samples;
|
|
this.table = this.createTable(this.hot.table.className);
|
|
|
|
if (this.getSetting('useHeaders') && this.hot.getColHeader(column) !== null) {
|
|
this.hot.view.appendColHeader(column, this.table.th);
|
|
}
|
|
this.table.tBody.appendChild(this.createCol(column));
|
|
this.container.container.appendChild(this.table.fragment);
|
|
|
|
columnObject.table = this.table.table;
|
|
}
|
|
|
|
/**
|
|
* Get calculated heights.
|
|
*
|
|
* @param {Function} callback Callback which will be fired for each calculated row.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getHeights',
|
|
value: function getHeights(callback) {
|
|
if (!this.injected) {
|
|
this.injectTable();
|
|
}
|
|
(0, _array.arrayEach)(this.rows, function (row) {
|
|
// -1 <- reduce border-top from table
|
|
callback(row.row, (0, _element.outerHeight)(row.table) - 1);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get calculated widths.
|
|
*
|
|
* @param {Function} callback Callback which will be fired for each calculated column.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getWidths',
|
|
value: function getWidths(callback) {
|
|
if (!this.injected) {
|
|
this.injectTable();
|
|
}
|
|
(0, _array.arrayEach)(this.columns, function (column) {
|
|
callback(column.col, (0, _element.outerWidth)(column.table));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Set the Ghost Table settings to the provided object.
|
|
*
|
|
* @param {Object} settings New Ghost Table Settings
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSettings',
|
|
value: function setSettings(settings) {
|
|
this.settings = settings;
|
|
}
|
|
|
|
/**
|
|
* Set a single setting of the Ghost Table.
|
|
*
|
|
* @param {String} name Setting name.
|
|
* @param {*} value Setting value.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSetting',
|
|
value: function setSetting(name, value) {
|
|
if (!this.settings) {
|
|
this.settings = {};
|
|
}
|
|
|
|
this.settings[name] = value;
|
|
}
|
|
|
|
/**
|
|
* Get the Ghost Table settings.
|
|
*
|
|
* @returns {Object|null}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSettings',
|
|
value: function getSettings() {
|
|
return this.settings;
|
|
}
|
|
|
|
/**
|
|
* Get a single Ghost Table setting.
|
|
*
|
|
* @param {String} name
|
|
* @returns {Boolean|null}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSetting',
|
|
value: function getSetting(name) {
|
|
if (this.settings) {
|
|
return this.settings[name];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Create colgroup col elements.
|
|
*
|
|
* @returns {DocumentFragment}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createColGroupsCol',
|
|
value: function createColGroupsCol() {
|
|
var _this = this;
|
|
|
|
var d = document;
|
|
var fragment = d.createDocumentFragment();
|
|
|
|
if (this.hot.hasRowHeaders()) {
|
|
fragment.appendChild(this.createColElement(-1));
|
|
}
|
|
|
|
this.samples.forEach(function (sample) {
|
|
(0, _array.arrayEach)(sample.strings, function (string) {
|
|
fragment.appendChild(_this.createColElement(string.col));
|
|
});
|
|
});
|
|
|
|
return fragment;
|
|
}
|
|
|
|
/**
|
|
* Create table row element.
|
|
*
|
|
* @param {Number} row Row index.
|
|
* @returns {DocumentFragment} Returns created table row elements.
|
|
*/
|
|
|
|
}, {
|
|
key: 'createRow',
|
|
value: function createRow(row) {
|
|
var _this2 = this;
|
|
|
|
var d = document;
|
|
var fragment = d.createDocumentFragment();
|
|
var th = d.createElement('th');
|
|
|
|
if (this.hot.hasRowHeaders()) {
|
|
this.hot.view.appendRowHeader(row, th);
|
|
|
|
fragment.appendChild(th);
|
|
}
|
|
|
|
this.samples.forEach(function (sample) {
|
|
(0, _array.arrayEach)(sample.strings, function (string) {
|
|
var column = string.col;
|
|
var cellProperties = _this2.hot.getCellMeta(row, column);
|
|
|
|
cellProperties.col = column;
|
|
cellProperties.row = row;
|
|
|
|
var renderer = _this2.hot.getCellRenderer(cellProperties);
|
|
var td = d.createElement('td');
|
|
|
|
renderer(_this2.hot, td, row, column, _this2.hot.colToProp(column), string.value, cellProperties);
|
|
fragment.appendChild(td);
|
|
});
|
|
});
|
|
|
|
return fragment;
|
|
}
|
|
}, {
|
|
key: 'createColumnHeadersRow',
|
|
value: function createColumnHeadersRow() {
|
|
var _this3 = this;
|
|
|
|
var d = document;
|
|
var fragment = d.createDocumentFragment();
|
|
|
|
if (this.hot.hasRowHeaders()) {
|
|
var th = d.createElement('th');
|
|
this.hot.view.appendColHeader(-1, th);
|
|
fragment.appendChild(th);
|
|
}
|
|
|
|
this.samples.forEach(function (sample) {
|
|
(0, _array.arrayEach)(sample.strings, function (string) {
|
|
var column = string.col;
|
|
|
|
var th = d.createElement('th');
|
|
|
|
_this3.hot.view.appendColHeader(column, th);
|
|
fragment.appendChild(th);
|
|
});
|
|
});
|
|
|
|
return fragment;
|
|
}
|
|
|
|
/**
|
|
* Create table column elements.
|
|
*
|
|
* @param {Number} column Column index.
|
|
* @returns {DocumentFragment} Returns created column table column elements.
|
|
*/
|
|
|
|
}, {
|
|
key: 'createCol',
|
|
value: function createCol(column) {
|
|
var _this4 = this;
|
|
|
|
var d = document;
|
|
var fragment = d.createDocumentFragment();
|
|
|
|
this.samples.forEach(function (sample) {
|
|
(0, _array.arrayEach)(sample.strings, function (string) {
|
|
var row = string.row;
|
|
var cellProperties = _this4.hot.getCellMeta(row, column);
|
|
|
|
cellProperties.col = column;
|
|
cellProperties.row = row;
|
|
|
|
var renderer = _this4.hot.getCellRenderer(cellProperties);
|
|
var td = d.createElement('td');
|
|
var tr = d.createElement('tr');
|
|
|
|
renderer(_this4.hot, td, row, column, _this4.hot.colToProp(column), string.value, cellProperties);
|
|
tr.appendChild(td);
|
|
fragment.appendChild(tr);
|
|
});
|
|
});
|
|
|
|
return fragment;
|
|
}
|
|
|
|
/**
|
|
* Remove table from document and reset internal state.
|
|
*/
|
|
|
|
}, {
|
|
key: 'clean',
|
|
value: function clean() {
|
|
this.rows.length = 0;
|
|
this.rows[-1] = void 0;
|
|
this.columns.length = 0;
|
|
|
|
if (this.samples) {
|
|
this.samples.clear();
|
|
}
|
|
this.samples = null;
|
|
this.removeTable();
|
|
}
|
|
|
|
/**
|
|
* Inject generated table into document.
|
|
*
|
|
* @param {HTMLElement} [parent=null]
|
|
*/
|
|
|
|
}, {
|
|
key: 'injectTable',
|
|
value: function injectTable() {
|
|
var parent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
|
|
if (!this.injected) {
|
|
(parent || this.hot.rootElement).appendChild(this.container.fragment);
|
|
this.injected = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove table from document.
|
|
*/
|
|
|
|
}, {
|
|
key: 'removeTable',
|
|
value: function removeTable() {
|
|
if (this.injected && this.container.container.parentNode) {
|
|
this.container.container.parentNode.removeChild(this.container.container);
|
|
this.container = null;
|
|
this.injected = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create col element.
|
|
*
|
|
* @param {Number} column Column index.
|
|
* @returns {HTMLElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createColElement',
|
|
value: function createColElement(column) {
|
|
var d = document;
|
|
var col = d.createElement('col');
|
|
|
|
col.style.width = this.hot.view.wt.wtTable.getStretchedColumnWidth(column) + 'px';
|
|
|
|
return col;
|
|
}
|
|
|
|
/**
|
|
* Create table element.
|
|
*
|
|
* @param {String} className
|
|
* @returns {Object}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createTable',
|
|
value: function createTable() {
|
|
var className = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
|
|
var d = document;
|
|
var fragment = d.createDocumentFragment();
|
|
var table = d.createElement('table');
|
|
var tHead = d.createElement('thead');
|
|
var tBody = d.createElement('tbody');
|
|
var colGroup = d.createElement('colgroup');
|
|
var tr = d.createElement('tr');
|
|
var th = d.createElement('th');
|
|
|
|
if (this.isVertical()) {
|
|
table.appendChild(colGroup);
|
|
}
|
|
if (this.isHorizontal()) {
|
|
tr.appendChild(th);
|
|
tHead.appendChild(tr);
|
|
table.style.tableLayout = 'auto';
|
|
table.style.width = 'auto';
|
|
}
|
|
table.appendChild(tHead);
|
|
|
|
if (this.isVertical()) {
|
|
tBody.appendChild(tr);
|
|
}
|
|
table.appendChild(tBody);
|
|
(0, _element.addClass)(table, className);
|
|
fragment.appendChild(table);
|
|
|
|
return { fragment: fragment, table: table, tHead: tHead, tBody: tBody, colGroup: colGroup, tr: tr, th: th };
|
|
}
|
|
|
|
/**
|
|
* Create container for tables.
|
|
*
|
|
* @param {String} className
|
|
* @returns {Object}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createContainer',
|
|
value: function createContainer() {
|
|
var className = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
|
|
var d = document;
|
|
var fragment = d.createDocumentFragment();
|
|
var container = d.createElement('div');
|
|
|
|
className = 'htGhostTable htAutoSize ' + className.trim();
|
|
(0, _element.addClass)(container, className);
|
|
fragment.appendChild(container);
|
|
|
|
return { fragment: fragment, container: container };
|
|
}
|
|
|
|
/**
|
|
* Checks if table is raised vertically (checking rows).
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isVertical',
|
|
value: function isVertical() {
|
|
return !!(this.rows.length && !this.columns.length);
|
|
}
|
|
|
|
/**
|
|
* Checks if table is raised horizontally (checking columns).
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isHorizontal',
|
|
value: function isHorizontal() {
|
|
return !!(this.columns.length && !this.rows.length);
|
|
}
|
|
}]);
|
|
|
|
return GhostTable;
|
|
}();
|
|
|
|
exports.default = GhostTable;
|
|
|
|
/***/ }),
|
|
/* 68 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var addToUnscopables = __webpack_require__(38)
|
|
, step = __webpack_require__(282)
|
|
, Iterators = __webpack_require__(46)
|
|
, toIObject = __webpack_require__(23);
|
|
|
|
// 22.1.3.4 Array.prototype.entries()
|
|
// 22.1.3.13 Array.prototype.keys()
|
|
// 22.1.3.29 Array.prototype.values()
|
|
// 22.1.3.30 Array.prototype[@@iterator]()
|
|
module.exports = __webpack_require__(281)(Array, 'Array', function(iterated, kind){
|
|
this._t = toIObject(iterated); // target
|
|
this._i = 0; // next index
|
|
this._k = kind; // kind
|
|
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
|
|
}, function(){
|
|
var O = this._t
|
|
, kind = this._k
|
|
, index = this._i++;
|
|
if(!O || index >= O.length){
|
|
this._t = undefined;
|
|
return step(1);
|
|
}
|
|
if(kind == 'keys' )return step(0, index);
|
|
if(kind == 'values')return step(0, O[index]);
|
|
return step(0, [index, O[index]]);
|
|
}, 'values');
|
|
|
|
// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
|
|
Iterators.Arguments = Iterators.Array;
|
|
|
|
addToUnscopables('keys');
|
|
addToUnscopables('values');
|
|
addToUnscopables('entries');
|
|
|
|
/***/ }),
|
|
/* 69 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _coords = __webpack_require__(43);
|
|
|
|
var _coords2 = _interopRequireDefault(_coords);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* A cell range is a set of exactly two CellCoords (that can be the same or different)
|
|
*
|
|
* @class CellRange
|
|
*/
|
|
var CellRange = function () {
|
|
/**
|
|
* @param {CellCoords} highlight Used to draw bold border around a cell where selection was
|
|
* started and to edit the cell when you press Enter
|
|
* @param {CellCoords} from Usually the same as highlight, but in Excel there is distinction - one can change
|
|
* highlight within a selection
|
|
* @param {CellCoords} to End selection
|
|
*/
|
|
function CellRange(highlight, from, to) {
|
|
_classCallCheck(this, CellRange);
|
|
|
|
this.highlight = highlight;
|
|
this.from = from;
|
|
this.to = to;
|
|
}
|
|
|
|
/**
|
|
* Checks if given coords are valid in context of a given Walkontable instance
|
|
*
|
|
* @param {Walkontable} wotInstance
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(CellRange, [{
|
|
key: 'isValid',
|
|
value: function isValid(wotInstance) {
|
|
return this.from.isValid(wotInstance) && this.to.isValid(wotInstance);
|
|
}
|
|
|
|
/**
|
|
* Checks if this cell range is restricted to one cell
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isSingle',
|
|
value: function isSingle() {
|
|
return this.from.row === this.to.row && this.from.col === this.to.col;
|
|
}
|
|
|
|
/**
|
|
* Returns selected range height (in number of rows)
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getHeight',
|
|
value: function getHeight() {
|
|
return Math.max(this.from.row, this.to.row) - Math.min(this.from.row, this.to.row) + 1;
|
|
}
|
|
|
|
/**
|
|
* Returns selected range width (in number of columns)
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getWidth',
|
|
value: function getWidth() {
|
|
return Math.max(this.from.col, this.to.col) - Math.min(this.from.col, this.to.col) + 1;
|
|
}
|
|
|
|
/**
|
|
* Checks if given cell coords is within `from` and `to` cell coords of this range
|
|
*
|
|
* @param {CellCoords} cellCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'includes',
|
|
value: function includes(cellCoords) {
|
|
var row = cellCoords.row,
|
|
col = cellCoords.col;
|
|
|
|
var topLeft = this.getTopLeftCorner();
|
|
var bottomRight = this.getBottomRightCorner();
|
|
|
|
return topLeft.row <= row && bottomRight.row >= row && topLeft.col <= col && bottomRight.col >= col;
|
|
}
|
|
|
|
/**
|
|
* Checks if given range is within of this range
|
|
*
|
|
* @param {CellRange} testedRange
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'includesRange',
|
|
value: function includesRange(testedRange) {
|
|
return this.includes(testedRange.getTopLeftCorner()) && this.includes(testedRange.getBottomRightCorner());
|
|
}
|
|
|
|
/**
|
|
* Checks if given range is equal to this range
|
|
*
|
|
* @param {CellRange} testedRange
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isEqual',
|
|
value: function isEqual(testedRange) {
|
|
return Math.min(this.from.row, this.to.row) == Math.min(testedRange.from.row, testedRange.to.row) && Math.max(this.from.row, this.to.row) == Math.max(testedRange.from.row, testedRange.to.row) && Math.min(this.from.col, this.to.col) == Math.min(testedRange.from.col, testedRange.to.col) && Math.max(this.from.col, this.to.col) == Math.max(testedRange.from.col, testedRange.to.col);
|
|
}
|
|
|
|
/**
|
|
* Checks if tested range overlaps with the range.
|
|
* Range A is considered to to be overlapping with range B if intersection of A and B or B and A is not empty.
|
|
*
|
|
* @param {CellRange} testedRange
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'overlaps',
|
|
value: function overlaps(testedRange) {
|
|
return testedRange.isSouthEastOf(this.getTopLeftCorner()) && testedRange.isNorthWestOf(this.getBottomRightCorner());
|
|
}
|
|
|
|
/**
|
|
* @param {CellRange} testedCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isSouthEastOf',
|
|
value: function isSouthEastOf(testedCoords) {
|
|
return this.getTopLeftCorner().isSouthEastOf(testedCoords) || this.getBottomRightCorner().isSouthEastOf(testedCoords);
|
|
}
|
|
|
|
/**
|
|
* @param {CellRange} testedCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isNorthWestOf',
|
|
value: function isNorthWestOf(testedCoords) {
|
|
return this.getTopLeftCorner().isNorthWestOf(testedCoords) || this.getBottomRightCorner().isNorthWestOf(testedCoords);
|
|
}
|
|
|
|
/**
|
|
* Adds a cell to a range (only if exceeds corners of the range). Returns information if range was expanded
|
|
*
|
|
* @param {CellCoords} cellCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'expand',
|
|
value: function expand(cellCoords) {
|
|
var topLeft = this.getTopLeftCorner();
|
|
var bottomRight = this.getBottomRightCorner();
|
|
|
|
if (cellCoords.row < topLeft.row || cellCoords.col < topLeft.col || cellCoords.row > bottomRight.row || cellCoords.col > bottomRight.col) {
|
|
this.from = new _coords2.default(Math.min(topLeft.row, cellCoords.row), Math.min(topLeft.col, cellCoords.col));
|
|
this.to = new _coords2.default(Math.max(bottomRight.row, cellCoords.row), Math.max(bottomRight.col, cellCoords.col));
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param {CellRange} expandingRange
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'expandByRange',
|
|
value: function expandByRange(expandingRange) {
|
|
if (this.includesRange(expandingRange) || !this.overlaps(expandingRange)) {
|
|
return false;
|
|
}
|
|
|
|
var topLeft = this.getTopLeftCorner();
|
|
var bottomRight = this.getBottomRightCorner();
|
|
var topRight = this.getTopRightCorner();
|
|
var bottomLeft = this.getBottomLeftCorner();
|
|
|
|
var expandingTopLeft = expandingRange.getTopLeftCorner();
|
|
var expandingBottomRight = expandingRange.getBottomRightCorner();
|
|
|
|
var resultTopRow = Math.min(topLeft.row, expandingTopLeft.row);
|
|
var resultTopCol = Math.min(topLeft.col, expandingTopLeft.col);
|
|
var resultBottomRow = Math.max(bottomRight.row, expandingBottomRight.row);
|
|
var resultBottomCol = Math.max(bottomRight.col, expandingBottomRight.col);
|
|
|
|
var finalFrom = new _coords2.default(resultTopRow, resultTopCol),
|
|
finalTo = new _coords2.default(resultBottomRow, resultBottomCol);
|
|
var isCorner = new CellRange(finalFrom, finalFrom, finalTo).isCorner(this.from, expandingRange),
|
|
onlyMerge = expandingRange.isEqual(new CellRange(finalFrom, finalFrom, finalTo));
|
|
|
|
if (isCorner && !onlyMerge) {
|
|
if (this.from.col > finalFrom.col) {
|
|
finalFrom.col = resultBottomCol;
|
|
finalTo.col = resultTopCol;
|
|
}
|
|
if (this.from.row > finalFrom.row) {
|
|
finalFrom.row = resultBottomRow;
|
|
finalTo.row = resultTopRow;
|
|
}
|
|
}
|
|
this.from = finalFrom;
|
|
this.to = finalTo;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @returns {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getDirection',
|
|
value: function getDirection() {
|
|
if (this.from.isNorthWestOf(this.to)) {
|
|
// NorthWest - SouthEast
|
|
return 'NW-SE';
|
|
} else if (this.from.isNorthEastOf(this.to)) {
|
|
// NorthEast - SouthWest
|
|
return 'NE-SW';
|
|
} else if (this.from.isSouthEastOf(this.to)) {
|
|
// SouthEast - NorthWest
|
|
return 'SE-NW';
|
|
} else if (this.from.isSouthWestOf(this.to)) {
|
|
// SouthWest - NorthEast
|
|
return 'SW-NE';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {String} direction
|
|
*/
|
|
|
|
}, {
|
|
key: 'setDirection',
|
|
value: function setDirection(direction) {
|
|
switch (direction) {
|
|
case 'NW-SE':
|
|
var _ref = [this.getTopLeftCorner(), this.getBottomRightCorner()];
|
|
this.from = _ref[0];
|
|
this.to = _ref[1];
|
|
|
|
break;
|
|
case 'NE-SW':
|
|
var _ref2 = [this.getTopRightCorner(), this.getBottomLeftCorner()];
|
|
this.from = _ref2[0];
|
|
this.to = _ref2[1];
|
|
|
|
break;
|
|
case 'SE-NW':
|
|
var _ref3 = [this.getBottomRightCorner(), this.getTopLeftCorner()];
|
|
this.from = _ref3[0];
|
|
this.to = _ref3[1];
|
|
|
|
break;
|
|
case 'SW-NE':
|
|
var _ref4 = [this.getBottomLeftCorner(), this.getTopRightCorner()];
|
|
this.from = _ref4[0];
|
|
this.to = _ref4[1];
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get top left corner of this range
|
|
*
|
|
* @returns {CellCoords}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getTopLeftCorner',
|
|
value: function getTopLeftCorner() {
|
|
return new _coords2.default(Math.min(this.from.row, this.to.row), Math.min(this.from.col, this.to.col));
|
|
}
|
|
|
|
/**
|
|
* Get bottom right corner of this range
|
|
*
|
|
* @returns {CellCoords}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getBottomRightCorner',
|
|
value: function getBottomRightCorner() {
|
|
return new _coords2.default(Math.max(this.from.row, this.to.row), Math.max(this.from.col, this.to.col));
|
|
}
|
|
|
|
/**
|
|
* Get top right corner of this range
|
|
*
|
|
* @returns {CellCoords}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getTopRightCorner',
|
|
value: function getTopRightCorner() {
|
|
return new _coords2.default(Math.min(this.from.row, this.to.row), Math.max(this.from.col, this.to.col));
|
|
}
|
|
|
|
/**
|
|
* Get bottom left corner of this range
|
|
*
|
|
* @returns {CellCoords}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getBottomLeftCorner',
|
|
value: function getBottomLeftCorner() {
|
|
return new _coords2.default(Math.max(this.from.row, this.to.row), Math.min(this.from.col, this.to.col));
|
|
}
|
|
|
|
/**
|
|
* @param {CellCoords} coords
|
|
* @param {CellRange} expandedRange
|
|
* @returns {*}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isCorner',
|
|
value: function isCorner(coords, expandedRange) {
|
|
if (expandedRange) {
|
|
if (expandedRange.includes(coords)) {
|
|
if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col)) || this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col)) || this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col)) || this.getBottomRightCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.to.col))) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return coords.isEqual(this.getTopLeftCorner()) || coords.isEqual(this.getTopRightCorner()) || coords.isEqual(this.getBottomLeftCorner()) || coords.isEqual(this.getBottomRightCorner());
|
|
}
|
|
|
|
/**
|
|
* @param {CellCoords} coords
|
|
* @param {CellRange} expandedRange
|
|
* @returns {CellCoords}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getOppositeCorner',
|
|
value: function getOppositeCorner(coords, expandedRange) {
|
|
if (!(coords instanceof _coords2.default)) {
|
|
return false;
|
|
}
|
|
|
|
if (expandedRange) {
|
|
if (expandedRange.includes(coords)) {
|
|
if (this.getTopLeftCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.from.col))) {
|
|
return this.getBottomRightCorner();
|
|
}
|
|
if (this.getTopRightCorner().isEqual(new _coords2.default(expandedRange.from.row, expandedRange.to.col))) {
|
|
return this.getBottomLeftCorner();
|
|
}
|
|
if (this.getBottomLeftCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.from.col))) {
|
|
return this.getTopRightCorner();
|
|
}
|
|
if (this.getBottomRightCorner().isEqual(new _coords2.default(expandedRange.to.row, expandedRange.to.col))) {
|
|
return this.getTopLeftCorner();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (coords.isEqual(this.getBottomRightCorner())) {
|
|
return this.getTopLeftCorner();
|
|
} else if (coords.isEqual(this.getTopLeftCorner())) {
|
|
return this.getBottomRightCorner();
|
|
} else if (coords.isEqual(this.getTopRightCorner())) {
|
|
return this.getBottomLeftCorner();
|
|
} else if (coords.isEqual(this.getBottomLeftCorner())) {
|
|
return this.getTopRightCorner();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {CellRange} range
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getBordersSharedWith',
|
|
value: function getBordersSharedWith(range) {
|
|
if (!this.includesRange(range)) {
|
|
return [];
|
|
}
|
|
|
|
var thisBorders = {
|
|
top: Math.min(this.from.row, this.to.row),
|
|
bottom: Math.max(this.from.row, this.to.row),
|
|
left: Math.min(this.from.col, this.to.col),
|
|
right: Math.max(this.from.col, this.to.col)
|
|
};
|
|
var rangeBorders = {
|
|
top: Math.min(range.from.row, range.to.row),
|
|
bottom: Math.max(range.from.row, range.to.row),
|
|
left: Math.min(range.from.col, range.to.col),
|
|
right: Math.max(range.from.col, range.to.col)
|
|
};
|
|
var result = [];
|
|
|
|
if (thisBorders.top == rangeBorders.top) {
|
|
result.push('top');
|
|
}
|
|
if (thisBorders.right == rangeBorders.right) {
|
|
result.push('right');
|
|
}
|
|
if (thisBorders.bottom == rangeBorders.bottom) {
|
|
result.push('bottom');
|
|
}
|
|
if (thisBorders.left == rangeBorders.left) {
|
|
result.push('left');
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get inner selected cell coords defined by this range
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getInner',
|
|
value: function getInner() {
|
|
var topLeft = this.getTopLeftCorner();
|
|
var bottomRight = this.getBottomRightCorner();
|
|
var out = [];
|
|
|
|
for (var r = topLeft.row; r <= bottomRight.row; r++) {
|
|
for (var c = topLeft.col; c <= bottomRight.col; c++) {
|
|
if (!(this.from.row === r && this.from.col === c) && !(this.to.row === r && this.to.col === c)) {
|
|
out.push(new _coords2.default(r, c));
|
|
}
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Get all selected cell coords defined by this range
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getAll',
|
|
value: function getAll() {
|
|
var topLeft = this.getTopLeftCorner();
|
|
var bottomRight = this.getBottomRightCorner();
|
|
var out = [];
|
|
|
|
for (var r = topLeft.row; r <= bottomRight.row; r++) {
|
|
for (var c = topLeft.col; c <= bottomRight.col; c++) {
|
|
if (topLeft.row === r && topLeft.col === c) {
|
|
out.push(topLeft);
|
|
} else if (bottomRight.row === r && bottomRight.col === c) {
|
|
out.push(bottomRight);
|
|
} else {
|
|
out.push(new _coords2.default(r, c));
|
|
}
|
|
}
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* Runs a callback function against all cells in the range. You can break the iteration by returning
|
|
* `false` in the callback function
|
|
*
|
|
* @param callback {Function}
|
|
*/
|
|
|
|
}, {
|
|
key: 'forAll',
|
|
value: function forAll(callback) {
|
|
var topLeft = this.getTopLeftCorner();
|
|
var bottomRight = this.getBottomRightCorner();
|
|
|
|
for (var r = topLeft.row; r <= bottomRight.row; r++) {
|
|
for (var c = topLeft.col; c <= bottomRight.col; c++) {
|
|
var breakIteration = callback(r, c);
|
|
|
|
if (breakIteration === false) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return CellRange;
|
|
}();
|
|
|
|
exports.default = CellRange;
|
|
|
|
/***/ }),
|
|
/* 70 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
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
|
|
*/
|
|
addLocalHook: function addLocalHook(key, callback) {
|
|
if (!this._localHooks[key]) {
|
|
this._localHooks[key] = [];
|
|
}
|
|
this._localHooks[key].push(callback);
|
|
},
|
|
|
|
|
|
/**
|
|
* Run hooks.
|
|
*
|
|
* @param {String} key Hook name.
|
|
* @param {*} params
|
|
*/
|
|
runLocalHooks: function runLocalHooks(key) {
|
|
var _this = this;
|
|
|
|
for (var _len = arguments.length, params = 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.
|
|
*/
|
|
clearLocalHooks: function clearLocalHooks() {
|
|
this._localHooks = {};
|
|
}
|
|
};
|
|
|
|
(0, _object.defineGetter)(localHooks, 'MIXIN_NAME', MIXIN_NAME, {
|
|
writable: false,
|
|
enumerable: false
|
|
});
|
|
|
|
exports.default = localHooks;
|
|
|
|
/***/ }),
|
|
/* 71 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.ITEMS = exports.UNDO = exports.SEPARATOR = exports.ROW_BELOW = exports.ROW_ABOVE = exports.REMOVE_ROW = exports.REMOVE_COLUMN = exports.REDO = exports.READ_ONLY = exports.COLUMN_RIGHT = exports.COLUMN_LEFT = exports.CLEAR_COLUMN = exports.ALIGNMENT = undefined;
|
|
|
|
var _predefinedItems2;
|
|
|
|
var _alignment = __webpack_require__(338);
|
|
|
|
Object.defineProperty(exports, 'ALIGNMENT', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _alignment.KEY;
|
|
}
|
|
});
|
|
|
|
var _clearColumn = __webpack_require__(339);
|
|
|
|
Object.defineProperty(exports, 'CLEAR_COLUMN', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _clearColumn.KEY;
|
|
}
|
|
});
|
|
|
|
var _columnLeft = __webpack_require__(340);
|
|
|
|
Object.defineProperty(exports, 'COLUMN_LEFT', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _columnLeft.KEY;
|
|
}
|
|
});
|
|
|
|
var _columnRight = __webpack_require__(341);
|
|
|
|
Object.defineProperty(exports, 'COLUMN_RIGHT', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _columnRight.KEY;
|
|
}
|
|
});
|
|
|
|
var _readOnly = __webpack_require__(342);
|
|
|
|
Object.defineProperty(exports, 'READ_ONLY', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _readOnly.KEY;
|
|
}
|
|
});
|
|
|
|
var _redo = __webpack_require__(343);
|
|
|
|
Object.defineProperty(exports, 'REDO', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _redo.KEY;
|
|
}
|
|
});
|
|
|
|
var _removeColumn = __webpack_require__(344);
|
|
|
|
Object.defineProperty(exports, 'REMOVE_COLUMN', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _removeColumn.KEY;
|
|
}
|
|
});
|
|
|
|
var _removeRow = __webpack_require__(345);
|
|
|
|
Object.defineProperty(exports, 'REMOVE_ROW', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _removeRow.KEY;
|
|
}
|
|
});
|
|
|
|
var _rowAbove = __webpack_require__(346);
|
|
|
|
Object.defineProperty(exports, 'ROW_ABOVE', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _rowAbove.KEY;
|
|
}
|
|
});
|
|
|
|
var _rowBelow = __webpack_require__(347);
|
|
|
|
Object.defineProperty(exports, 'ROW_BELOW', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _rowBelow.KEY;
|
|
}
|
|
});
|
|
|
|
var _separator = __webpack_require__(72);
|
|
|
|
Object.defineProperty(exports, 'SEPARATOR', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _separator.KEY;
|
|
}
|
|
});
|
|
|
|
var _undo = __webpack_require__(348);
|
|
|
|
Object.defineProperty(exports, 'UNDO', {
|
|
enumerable: true,
|
|
get: function get() {
|
|
return _undo.KEY;
|
|
}
|
|
});
|
|
exports.predefinedItems = predefinedItems;
|
|
exports.addItem = addItem;
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _alignment2 = _interopRequireDefault(_alignment);
|
|
|
|
var _clearColumn2 = _interopRequireDefault(_clearColumn);
|
|
|
|
var _columnLeft2 = _interopRequireDefault(_columnLeft);
|
|
|
|
var _columnRight2 = _interopRequireDefault(_columnRight);
|
|
|
|
var _readOnly2 = _interopRequireDefault(_readOnly);
|
|
|
|
var _redo2 = _interopRequireDefault(_redo);
|
|
|
|
var _removeColumn2 = _interopRequireDefault(_removeColumn);
|
|
|
|
var _removeRow2 = _interopRequireDefault(_removeRow);
|
|
|
|
var _rowAbove2 = _interopRequireDefault(_rowAbove);
|
|
|
|
var _rowBelow2 = _interopRequireDefault(_rowBelow);
|
|
|
|
var _separator2 = _interopRequireDefault(_separator);
|
|
|
|
var _undo2 = _interopRequireDefault(_undo);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
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; }
|
|
|
|
var ITEMS = exports.ITEMS = [_rowAbove.KEY, _rowBelow.KEY, _columnLeft.KEY, _columnRight.KEY, _clearColumn.KEY, _removeRow.KEY, _removeColumn.KEY, _undo.KEY, _redo.KEY, _readOnly.KEY, _alignment.KEY, _separator.KEY];
|
|
|
|
var _predefinedItems = (_predefinedItems2 = {}, _defineProperty(_predefinedItems2, _separator.KEY, _separator2.default), _defineProperty(_predefinedItems2, _rowAbove.KEY, _rowAbove2.default), _defineProperty(_predefinedItems2, _rowBelow.KEY, _rowBelow2.default), _defineProperty(_predefinedItems2, _columnLeft.KEY, _columnLeft2.default), _defineProperty(_predefinedItems2, _columnRight.KEY, _columnRight2.default), _defineProperty(_predefinedItems2, _clearColumn.KEY, _clearColumn2.default), _defineProperty(_predefinedItems2, _removeRow.KEY, _removeRow2.default), _defineProperty(_predefinedItems2, _removeColumn.KEY, _removeColumn2.default), _defineProperty(_predefinedItems2, _undo.KEY, _undo2.default), _defineProperty(_predefinedItems2, _redo.KEY, _redo2.default), _defineProperty(_predefinedItems2, _readOnly.KEY, _readOnly2.default), _defineProperty(_predefinedItems2, _alignment.KEY, _alignment2.default), _predefinedItems2);
|
|
|
|
/**
|
|
* Gets new object with all predefined menu items.
|
|
*
|
|
* @returns {Object}
|
|
*/
|
|
function predefinedItems() {
|
|
var items = {};
|
|
|
|
(0, _object.objectEach)(_predefinedItems, function (itemFactory, key) {
|
|
items[key] = itemFactory();
|
|
});
|
|
|
|
return items;
|
|
}
|
|
|
|
/**
|
|
* Add new predefined menu item to the collection.
|
|
*
|
|
* @param {String} key Menu command id.
|
|
* @param {Object} item Object command descriptor.
|
|
*/
|
|
function addItem(key, item) {
|
|
if (ITEMS.indexOf(key) === -1) {
|
|
_predefinedItems[key] = item;
|
|
}
|
|
}
|
|
|
|
/***/ }),
|
|
/* 72 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = separatorItem;
|
|
var KEY = exports.KEY = '---------';
|
|
|
|
function separatorItem() {
|
|
return {
|
|
name: KEY
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 73 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function(it){
|
|
if(typeof it != 'function')throw TypeError(it + ' is not a function!');
|
|
return it;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 74 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var $defineProperty = __webpack_require__(19)
|
|
, createDesc = __webpack_require__(41);
|
|
|
|
module.exports = function(object, index, value){
|
|
if(index in object)$defineProperty.f(object, index, createDesc(0, value));
|
|
else object[index] = value;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 75 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(15)
|
|
, document = __webpack_require__(13).document
|
|
// in old IE typeof document.createElement is 'object'
|
|
, is = isObject(document) && isObject(document.createElement);
|
|
module.exports = function(it){
|
|
return is ? document.createElement(it) : {};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 76 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// IE 8- don't enum bug keys
|
|
module.exports = (
|
|
'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
|
|
).split(',');
|
|
|
|
/***/ }),
|
|
/* 77 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var MATCH = __webpack_require__(10)('match');
|
|
module.exports = function(KEY){
|
|
var re = /./;
|
|
try {
|
|
'/./'[KEY](re);
|
|
} catch(e){
|
|
try {
|
|
re[MATCH] = false;
|
|
return !'/./'[KEY](re);
|
|
} catch(f){ /* empty */ }
|
|
} return true;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 78 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// fallback for non-array-like ES3 and non-enumerable old V8 strings
|
|
var cof = __webpack_require__(39);
|
|
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
|
|
return cof(it) == 'String' ? it.split('') : Object(it);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 79 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var ITERATOR = __webpack_require__(10)('iterator')
|
|
, SAFE_CLOSING = false;
|
|
|
|
try {
|
|
var riter = [7][ITERATOR]();
|
|
riter['return'] = function(){ SAFE_CLOSING = true; };
|
|
Array.from(riter, function(){ throw 2; });
|
|
} catch(e){ /* empty */ }
|
|
|
|
module.exports = function(exec, skipClosing){
|
|
if(!skipClosing && !SAFE_CLOSING)return false;
|
|
var safe = false;
|
|
try {
|
|
var arr = [7]
|
|
, iter = arr[ITERATOR]();
|
|
iter.next = function(){ return {done: safe = true}; };
|
|
arr[ITERATOR] = function(){ return iter; };
|
|
exec(arr);
|
|
} catch(e){ /* empty */ }
|
|
return safe;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 80 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
|
|
var anObject = __webpack_require__(18)
|
|
, dPs = __webpack_require__(403)
|
|
, enumBugKeys = __webpack_require__(76)
|
|
, IE_PROTO = __webpack_require__(83)('IE_PROTO')
|
|
, Empty = function(){ /* empty */ }
|
|
, PROTOTYPE = 'prototype';
|
|
|
|
// Create object with fake `null` prototype: use iframe Object with cleared prototype
|
|
var createDict = function(){
|
|
// Thrash, waste and sodomy: IE GC bug
|
|
var iframe = __webpack_require__(75)('iframe')
|
|
, i = enumBugKeys.length
|
|
, lt = '<'
|
|
, gt = '>'
|
|
, iframeDocument;
|
|
iframe.style.display = 'none';
|
|
__webpack_require__(274).appendChild(iframe);
|
|
iframe.src = 'javascript:'; // eslint-disable-line no-script-url
|
|
// createDict = iframe.contentWindow.Object;
|
|
// html.removeChild(iframe);
|
|
iframeDocument = iframe.contentWindow.document;
|
|
iframeDocument.open();
|
|
iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
|
|
iframeDocument.close();
|
|
createDict = iframeDocument.F;
|
|
while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]];
|
|
return createDict();
|
|
};
|
|
|
|
module.exports = Object.create || function create(O, Properties){
|
|
var result;
|
|
if(O !== null){
|
|
Empty[PROTOTYPE] = anObject(O);
|
|
result = new Empty;
|
|
Empty[PROTOTYPE] = null;
|
|
// add "__proto__" for Object.getPrototypeOf polyfill
|
|
result[IE_PROTO] = O;
|
|
} else result = createDict();
|
|
return Properties === undefined ? result : dPs(result, Properties);
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 81 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var pIE = __webpack_require__(48)
|
|
, createDesc = __webpack_require__(41)
|
|
, toIObject = __webpack_require__(23)
|
|
, toPrimitive = __webpack_require__(87)
|
|
, has = __webpack_require__(22)
|
|
, IE8_DOM_DEFINE = __webpack_require__(275)
|
|
, gOPD = Object.getOwnPropertyDescriptor;
|
|
|
|
exports.f = __webpack_require__(21) ? gOPD : function getOwnPropertyDescriptor(O, P){
|
|
O = toIObject(O);
|
|
P = toPrimitive(P, true);
|
|
if(IE8_DOM_DEFINE)try {
|
|
return gOPD(O, P);
|
|
} catch(e){ /* empty */ }
|
|
if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 82 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
|
|
var $keys = __webpack_require__(284)
|
|
, hiddenKeys = __webpack_require__(76).concat('length', 'prototype');
|
|
|
|
exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){
|
|
return $keys(O, hiddenKeys);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 83 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var shared = __webpack_require__(84)('keys')
|
|
, uid = __webpack_require__(50);
|
|
module.exports = function(key){
|
|
return shared[key] || (shared[key] = uid(key));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 84 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var global = __webpack_require__(13)
|
|
, SHARED = '__core-js_shared__'
|
|
, store = global[SHARED] || (global[SHARED] = {});
|
|
module.exports = function(key){
|
|
return store[key] || (store[key] = {});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 85 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// helper for String#{startsWith, endsWith, includes}
|
|
var isRegExp = __webpack_require__(279)
|
|
, defined = __webpack_require__(30);
|
|
|
|
module.exports = function(that, searchString, NAME){
|
|
if(isRegExp(searchString))throw TypeError('String#' + NAME + " doesn't accept regex!");
|
|
return String(defined(that));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 86 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var ctx = __webpack_require__(29)
|
|
, invoke = __webpack_require__(399)
|
|
, html = __webpack_require__(274)
|
|
, cel = __webpack_require__(75)
|
|
, global = __webpack_require__(13)
|
|
, process = global.process
|
|
, setTask = global.setImmediate
|
|
, clearTask = global.clearImmediate
|
|
, MessageChannel = global.MessageChannel
|
|
, counter = 0
|
|
, queue = {}
|
|
, ONREADYSTATECHANGE = 'onreadystatechange'
|
|
, defer, channel, port;
|
|
var run = function(){
|
|
var id = +this;
|
|
if(queue.hasOwnProperty(id)){
|
|
var fn = queue[id];
|
|
delete queue[id];
|
|
fn();
|
|
}
|
|
};
|
|
var listener = function(event){
|
|
run.call(event.data);
|
|
};
|
|
// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
|
|
if(!setTask || !clearTask){
|
|
setTask = function setImmediate(fn){
|
|
var args = [], i = 1;
|
|
while(arguments.length > i)args.push(arguments[i++]);
|
|
queue[++counter] = function(){
|
|
invoke(typeof fn == 'function' ? fn : Function(fn), args);
|
|
};
|
|
defer(counter);
|
|
return counter;
|
|
};
|
|
clearTask = function clearImmediate(id){
|
|
delete queue[id];
|
|
};
|
|
// Node.js 0.8-
|
|
if(__webpack_require__(39)(process) == 'process'){
|
|
defer = function(id){
|
|
process.nextTick(ctx(run, id, 1));
|
|
};
|
|
// Browsers with MessageChannel, includes WebWorkers
|
|
} else if(MessageChannel){
|
|
channel = new MessageChannel;
|
|
port = channel.port2;
|
|
channel.port1.onmessage = listener;
|
|
defer = ctx(port.postMessage, port, 1);
|
|
// Browsers with postMessage, skip WebWorkers
|
|
// IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
|
|
} else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
|
|
defer = function(id){
|
|
global.postMessage(id + '', '*');
|
|
};
|
|
global.addEventListener('message', listener, false);
|
|
// IE8-
|
|
} else if(ONREADYSTATECHANGE in cel('script')){
|
|
defer = function(id){
|
|
html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
|
|
html.removeChild(this);
|
|
run.call(id);
|
|
};
|
|
};
|
|
// Rest old browsers
|
|
} else {
|
|
defer = function(id){
|
|
setTimeout(ctx(run, id, 1), 0);
|
|
};
|
|
}
|
|
}
|
|
module.exports = {
|
|
set: setTask,
|
|
clear: clearTask
|
|
};
|
|
|
|
/***/ }),
|
|
/* 87 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 7.1.1 ToPrimitive(input [, PreferredType])
|
|
var isObject = __webpack_require__(15);
|
|
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
|
|
// and the second argument - flag - preferred type is a string
|
|
module.exports = function(it, S){
|
|
if(!isObject(it))return it;
|
|
var fn, val;
|
|
if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
|
|
if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
|
|
if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
|
|
throw TypeError("Can't convert object to primitive value");
|
|
};
|
|
|
|
/***/ }),
|
|
/* 88 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
/**
|
|
* @alias Options
|
|
* @constructor
|
|
* @description
|
|
|
|
* ## Constructor options
|
|
*
|
|
* Constructor options are applied using an object literal passed as a second argument to the Handsontable constructor.
|
|
*
|
|
* ```js
|
|
* var hot = new Handsontable(document.getElementById('example1'), {
|
|
* data: myArray,
|
|
* width: 400,
|
|
* height: 300
|
|
* });
|
|
* ```
|
|
*
|
|
* ---
|
|
* ## Cascading configuration
|
|
*
|
|
* Handsontable 0.9 and newer is using *Cascading Configuration*, which is a fast way to provide configuration options
|
|
* for the entire table, including its columns and particular cells.
|
|
*
|
|
* Consider the following example:
|
|
* ```js
|
|
* var hot = new Handsontable(document.getElementById('example'), {
|
|
* readOnly: true,
|
|
* columns: [
|
|
* {readOnly: false},
|
|
* {},
|
|
* {}
|
|
* ],
|
|
* cells: function (row, col, prop) {
|
|
* var cellProperties = {};
|
|
*
|
|
* if (row === 0 && col === 0) {
|
|
* cellProperties.readOnly = true;
|
|
* }
|
|
*
|
|
* return cellProperties;
|
|
* }
|
|
* });
|
|
* ```
|
|
*
|
|
* The above notation will result in all TDs being *read only*, except for first column TDs which will be *editable*, except for the TD in top left corner which will still be *read only*.
|
|
*
|
|
* ### The Cascading Configuration model
|
|
*
|
|
* ##### 1. Constructor
|
|
*
|
|
* Configuration options that are provided using first-level `handsontable(container, {option: "value"})` and `updateSettings` method.
|
|
*
|
|
* ##### 2. Columns
|
|
*
|
|
* Configuration options that are provided using second-level object `handsontable(container, {columns: {option: "value"}]})`
|
|
*
|
|
* ##### 3. Cells
|
|
*
|
|
* Configuration options that are provided using second-level function `handsontable(container, {cells: function: (row, col, prop){ }})`
|
|
*
|
|
* ---
|
|
* ## Architecture performance
|
|
*
|
|
* The Cascading Configuration model is based on prototypical inheritance. It is much faster and memory efficient compared
|
|
* to the previous model that used jQuery extend. See: [http://jsperf.com/extending-settings](http://jsperf.com/extending-settings).
|
|
*
|
|
* ---
|
|
* __Important notice:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`.
|
|
*/
|
|
function DefaultSettings() {};
|
|
|
|
DefaultSettings.prototype = {
|
|
/**
|
|
* @description
|
|
* Initial data source that will be bound to the data grid __by reference__ (editing data grid alters the data source).
|
|
* Can be declared as an Array of Arrays, Array of Objects or a Function.
|
|
*
|
|
* See [Understanding binding as reference](http://docs.handsontable.com/tutorial-data-binding.html#page-reference).
|
|
*
|
|
* @type {Array|Function}
|
|
* @default undefined
|
|
*/
|
|
data: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Defines the structure of a new row when data source is an array of objects.
|
|
*
|
|
* See [data-schema](http://docs.handsontable.com/tutorial-data-sources.html#page-data-schema) for examples.
|
|
*
|
|
* @type {Object}
|
|
* @default undefined
|
|
*/
|
|
dataSchema: void 0,
|
|
|
|
/**
|
|
* Width of the grid. Can be a value or a function that returns a value.
|
|
*
|
|
* @type {Number|Function}
|
|
* @default undefined
|
|
*/
|
|
width: void 0,
|
|
|
|
/**
|
|
* Height of the grid. Can be a number or a function that returns a number.
|
|
*
|
|
* @type {Number|Function}
|
|
* @default undefined
|
|
*/
|
|
height: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Initial number of rows.
|
|
*
|
|
* __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided
|
|
*
|
|
* @type {Number}
|
|
* @default 5
|
|
*/
|
|
startRows: 5,
|
|
|
|
/**
|
|
* @description
|
|
* Initial number of columns.
|
|
*
|
|
* __Notice:__ This option only has effect in Handsontable constructor and only if `data` option is not provided
|
|
*
|
|
* @type {Number}
|
|
* @default 5
|
|
*/
|
|
startCols: 5,
|
|
|
|
/**
|
|
* Setting `true` or `false` will enable or disable the default row headers (1, 2, 3).
|
|
* You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers.
|
|
* If a function is set the index of the row is passed as a parameter.
|
|
*
|
|
* @type {Boolean|Array|Function}
|
|
* @default null
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* rowHeaders: true,
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as array
|
|
* rowHeaders: [1, 2, 3],
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as function
|
|
* rowHeaders: function(index) {
|
|
* return index + ': AB';
|
|
* },
|
|
* ...
|
|
* ```
|
|
*/
|
|
rowHeaders: void 0,
|
|
|
|
/**
|
|
* Setting `true` or `false` will enable or disable the default column headers (A, B, C).
|
|
* You can also define an array `['One', 'Two', 'Three', ...]` or a function to define the headers.
|
|
* If a function is set, then the index of the column is passed as a parameter.
|
|
*
|
|
* @type {Boolean|Array|Function}
|
|
* @default null
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* colHeaders: true,
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as array
|
|
* colHeaders: ['A', 'B', 'C'],
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as function
|
|
* colHeaders: function(index) {
|
|
* return index + ': AB';
|
|
* },
|
|
* ...
|
|
* ```
|
|
*/
|
|
colHeaders: null,
|
|
|
|
/**
|
|
* Defines column widths in pixels. Accepts number, string (that will be converted to a number),
|
|
* array of numbers (if you want to define column width separately for each column) or a
|
|
* function (if you want to set column width dynamically on each render).
|
|
*
|
|
* @type {Array|Function|Number|String}
|
|
* @default undefined
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as numeric, for each column.
|
|
* colWidths: 100,
|
|
* ...
|
|
*
|
|
* * ...
|
|
* // as string, for each column.
|
|
* colWidths: '100px',
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as array, based on visual indexes. The rest of the columns have a default width.
|
|
* colWidths: [100, 120, 90],
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as function, based on visual indexes.
|
|
* colWidths: function(index) {
|
|
* return index * 10;
|
|
* },
|
|
* ...
|
|
* ```
|
|
*/
|
|
colWidths: void 0,
|
|
|
|
/**
|
|
* Defines row heights in pixels. Accepts numbers, strings (that will be converted into a number),
|
|
* array of numbers (if you want to define row height separately for each row) or a
|
|
* function (if you want to set row height dynamically on each render).
|
|
* If the ManualRowResize or AutoRowSize plugins are enabled, this is also the minimum height that can be set
|
|
* via either of those two plugins.
|
|
* Height should be equal or greater than 23px. Table is rendered incorrectly if height is less than 23px.
|
|
*
|
|
* @type {Array|Function|Number|String}
|
|
* @default undefined
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as numeric, for each row.
|
|
* rowHeights: 100,
|
|
* ...
|
|
*
|
|
* * ...
|
|
* // as string, for each row.
|
|
* rowHeights: '100px',
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as array, based on visual indexes. The rest of the rows have a default height.
|
|
* rowHeights: [100, 120, 90],
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as function, based on visual indexes.
|
|
* rowHeights: function(index) {
|
|
* return index * 10;
|
|
* },
|
|
* ...
|
|
* ```
|
|
*/
|
|
rowHeights: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Defines the cell properties and data binding for certain columns.
|
|
*
|
|
* __Notice:__ Using this option sets a fixed number of columns (options `startCols`, `minCols`, `maxCols` will be ignored).
|
|
*
|
|
* See [documentation -> datasources.html](http://docs.handsontable.com/tutorial-data-sources.html#page-nested) for examples.
|
|
*
|
|
* @type {Array|Function}
|
|
* @default undefined
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as an array of objects. Order of the objects in array is representation of physical indexes.
|
|
* columns: [
|
|
* {
|
|
* // column options for the first column
|
|
* type: 'numeric',
|
|
* format: '0,0.00 $'
|
|
* },
|
|
* {
|
|
* // column options for the second column
|
|
* type: 'text',
|
|
* readOnly: true
|
|
* }
|
|
* ],
|
|
* ...
|
|
*
|
|
* // or as function, based on physical indexes
|
|
* ...
|
|
* columns: function(index) {
|
|
* return {
|
|
* type: index > 0 ? 'numeric' : 'text',
|
|
* readOnly: index < 1
|
|
* }
|
|
* }
|
|
* ...
|
|
* ```
|
|
*/
|
|
columns: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Defines the cell properties for given `row`, `col`, `prop` coordinates.
|
|
* Any constructor or column option may be overwritten for a particular cell (row/column combination)
|
|
* using the `cells` property in the Handsontable constructor.
|
|
*
|
|
* __Note:__ Parameters `row` and `col` always represent __physical indexes__. Example below show how to execute
|
|
* operations based on the __visual__ representation of Handsontable.
|
|
*
|
|
* Possible values of `prop`:
|
|
* - property name for column's data source object, when dataset is an [array of objects](/tutorial-data-sources.html#page-object)
|
|
* - the same number as `col`, when dataset is an [array of arrays](/tutorial-data-sources.html#page-array)
|
|
*
|
|
* @type {Function}
|
|
* @default undefined
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* cells: function (row, col, prop) {
|
|
* var cellProperties = {};
|
|
* var visualRowIndex = this.instance.toVisualRow(row);
|
|
* var visualColIndex = this.instance.toVisualColumn(col);
|
|
*
|
|
* if (visualRowIndex === 0 && visualColIndex === 0) {
|
|
* cellProperties.readOnly = true;
|
|
* }
|
|
*
|
|
* return cellProperties;
|
|
* },
|
|
* ...
|
|
* ```
|
|
*/
|
|
cells: void 0,
|
|
|
|
/**
|
|
* Any constructor or column option may be overwritten for a particular cell (row/column combination), using `cell`
|
|
* array passed to the Handsontable constructor.
|
|
*
|
|
* @type {Array}
|
|
* @default []
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* cell: [
|
|
* {row: 0, col: 0, readOnly: true}
|
|
* ],
|
|
* ...
|
|
* ```
|
|
*/
|
|
cell: [],
|
|
|
|
/**
|
|
* @description
|
|
* If `true`, enables the {@link Comments} plugin, which enables an option to apply cell comments through the context menu
|
|
* (configurable with context menu keys `commentsAddEdit`, `commentsRemove`).
|
|
*
|
|
* To initialize Handsontable with predefined comments, provide cell coordinates and comment text values in a form of an array.
|
|
*
|
|
* See [Comments](http://docs.handsontable.com/demo-comments_.html) demo for examples.
|
|
*
|
|
* @since 0.11.0
|
|
* @type {Boolean|Array}
|
|
* @default false
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* comments: [{row: 1, col: 1, comment: {value: "Test comment"}}],
|
|
* ...
|
|
* ```
|
|
*/
|
|
comments: false,
|
|
|
|
/**
|
|
* @description
|
|
* If `true`, enables the Custom Borders plugin, which 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 examples.
|
|
*
|
|
* @since 0.11.0
|
|
* @type {Boolean|Array}
|
|
* @default false
|
|
* @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: ''}
|
|
* ],
|
|
* ...
|
|
* ```
|
|
*/
|
|
customBorders: false,
|
|
|
|
/**
|
|
* Minimum number of rows. At least that number of rows will be created during initialization.
|
|
*
|
|
* @type {Number}
|
|
* @default 0
|
|
*/
|
|
minRows: 0,
|
|
|
|
/**
|
|
* Minimum number of columns. At least that number of columns will be created during initialization.
|
|
*
|
|
* @type {Number}
|
|
* @default 0
|
|
*/
|
|
minCols: 0,
|
|
|
|
/**
|
|
* Maximum number of rows. If set to a value lower than the initial row count, the data will be trimmed to the provided value as the number of rows.
|
|
*
|
|
* @type {Number}
|
|
* @default Infinity
|
|
*/
|
|
maxRows: Infinity,
|
|
|
|
/**
|
|
* Maximum number of cols. If set to a value lower than the initial col count, the data will be trimmed to the provided value as the number of cols.
|
|
*
|
|
* @type {Number}
|
|
* @default Infinity
|
|
*/
|
|
maxCols: Infinity,
|
|
|
|
/**
|
|
* When set to 1 (or more), Handsontable will add a new row at the end of grid if there are no more empty rows.
|
|
* (unless the number of rows exceeds the one set in the `maxRows` property)
|
|
*
|
|
* @type {Number}
|
|
* @default 0
|
|
*/
|
|
minSpareRows: 0,
|
|
|
|
/**
|
|
* When set to 1 (or more), Handsontable will add a new column at the end of grid if there are no more empty columns.
|
|
* (unless the number of rows exceeds the one set in the `maxCols` property)
|
|
*
|
|
* @type {Number}
|
|
* @default 0
|
|
*/
|
|
minSpareCols: 0,
|
|
|
|
/**
|
|
* If set to `false`, there won't be an option to insert new rows in the Context Menu.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
allowInsertRow: true,
|
|
|
|
/**
|
|
* If set to `false`, there won't be an option to insert new columns in the Context Menu.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
allowInsertColumn: true,
|
|
|
|
/**
|
|
* If set to `false`, there won't be an option to remove rows in the Context Menu.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
allowRemoveRow: true,
|
|
|
|
/**
|
|
* If set to `false`, there won't be an option to remove columns in the Context Menu.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
allowRemoveColumn: true,
|
|
|
|
/**
|
|
* If true, selection of multiple cells using keyboard or mouse is allowed.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
multiSelect: true,
|
|
|
|
/**
|
|
* Enables the fill handle (drag-down and copy-down) functionality, which shows a small rectangle in bottom
|
|
* right corner of the selected area, that let's you expand values to the adjacent cells.
|
|
*
|
|
* Possible values: `true` (to enable in all directions), `'vertical'` or `'horizontal'` (to enable in one direction),
|
|
* `false` (to disable completely). Setting to `true` enables the fillHandle plugin.
|
|
*
|
|
* Since 0.23.0 you can pass object to plugin which allows you to add more options for this functionality. If `autoInsertRow`
|
|
* option is `true`, fill-handler will create new rows till it reaches the last row. It is enabled by default.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* fillHandle: true // enable plugin in all directions and with autoInsertRow as true
|
|
* ...
|
|
* // or
|
|
* ...
|
|
* fillHandle: 'vertical' // enable plugin in vertical direction and with autoInsertRow as true
|
|
* ...
|
|
* // or
|
|
* ...
|
|
* fillHandle: { // enable plugin in both directions and with autoInsertRow as false
|
|
* autoInsertRow: false,
|
|
* }
|
|
* // or
|
|
* ...
|
|
* fillHandle: { // enable plugin in vertical direction and with autoInsertRow as false
|
|
* autoInsertRow: false,
|
|
* direction: 'vertical' // 'vertical' or 'horizontal'
|
|
* }
|
|
* ```
|
|
*
|
|
* @type {Boolean|String|Object}
|
|
* @default true
|
|
*/
|
|
fillHandle: true,
|
|
|
|
/**
|
|
* Allows to specify the number of fixed (or *frozen*) rows at the top of the table.
|
|
*
|
|
* @type {Number}
|
|
* @default 0
|
|
* @example
|
|
* ```js
|
|
* fixedRowsTop: 3 // This would freeze the top 3 rows of the table.
|
|
* ```
|
|
*/
|
|
fixedRowsTop: 0,
|
|
|
|
/**
|
|
* Allows to specify the number of fixed (or *frozen*) rows at the bottom of the table.
|
|
*
|
|
* @pro
|
|
* @type {Number}
|
|
* @default 0
|
|
* @example
|
|
* ```js
|
|
* fixedRowsBottom: 3 // This would freeze the top 3 rows of the table.
|
|
* ```
|
|
*/
|
|
fixedRowsBottom: 0,
|
|
|
|
/**
|
|
* Allows to specify the number of fixed (or *frozen*) columns on the left of the table.
|
|
*
|
|
* @type {Number}
|
|
* @default 0
|
|
* @example
|
|
* ```js
|
|
* fixedColumnsLeft: 3 // This would freeze the top 3 rows of the table.
|
|
* ```
|
|
*/
|
|
fixedColumnsLeft: 0,
|
|
|
|
/**
|
|
* If `true`, mouse click outside the grid will deselect the current selection.
|
|
* Can be a function that takes the click event target and returns a boolean.
|
|
*
|
|
* @type {Boolean|Function}
|
|
* @default true
|
|
*/
|
|
outsideClickDeselects: true,
|
|
|
|
/**
|
|
* If `true`, <kbd>ENTER</kbd> begins editing mode (like in Google Docs). If `false`, <kbd>ENTER</kbd> moves to next
|
|
* row (like Excel) and adds a new row if necessary. <kbd>TAB</kbd> adds new column if necessary.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
enterBeginsEditing: true,
|
|
|
|
/**
|
|
* Defines the cursor movement after <kbd>ENTER</kbd> was pressed (<kbd>SHIFT</kbd> + <kbd>ENTER</kbd> uses a negative vector).
|
|
* Can be an object or a function that returns an object. The event argument passed to the function
|
|
* is a DOM Event object received after the <kbd>ENTER</kbd> key has been pressed. This event object can be used to check
|
|
* whether user pressed <kbd>ENTER</kbd> or <kbd>SHIFT</kbd> + <kbd>ENTER</kbd>.
|
|
*
|
|
* @type {Object|Function}
|
|
* @default {row: 1, col: 0}
|
|
*/
|
|
enterMoves: { row: 1, col: 0 },
|
|
|
|
/**
|
|
* Defines the cursor movement after <kbd>TAB</kbd> is pressed (<kbd>SHIFT</kbd> + <kbd>TAB</kbd> uses a negative vector).
|
|
* Can be an object or a function that returns an object. The event argument passed to the function
|
|
* is a DOM Event object received after the <kbd>TAB</kbd> key has been pressed. This event object can be used to check
|
|
* whether user pressed <kbd>TAB</kbd> or <kbd>SHIFT</kbd> + <kbd>TAB</kbd>.
|
|
*
|
|
* @type {Object}
|
|
* @default {row: 0, col: 1}
|
|
*/
|
|
tabMoves: { row: 0, col: 1 },
|
|
|
|
/**
|
|
* If `true`, pressing <kbd>TAB</kbd> or right arrow in the last column will move to first column in next row.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
autoWrapRow: false,
|
|
|
|
/**
|
|
* If `true`, pressing <kbd>ENTER</kbd> or down arrow in the last row will move to the first row in the next column.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
autoWrapCol: false,
|
|
|
|
/**
|
|
* @description
|
|
* Turns on saving the state of column sorting, column positions and column sizes in local storage.
|
|
*
|
|
* You can save any sort of data in local storage to preserve table state between page reloads.
|
|
* In order to enable data storage mechanism, `persistentState` option must be set to `true` (you can set it
|
|
* either during Handsontable initialization or using the `updateSettings` method). When `persistentState` is enabled it exposes 3 hooks:
|
|
*
|
|
* __persistentStateSave__ (key: String, value: Mixed)
|
|
*
|
|
* * Saves value under given key in browser local storage.
|
|
*
|
|
* __persistentStateLoad__ (key: String, valuePlaceholder: Object)
|
|
*
|
|
* * Loads `value`, saved under given key, form browser local storage. The loaded `value` will be saved in `valuePlaceholder.value`
|
|
* (this is due to specific behaviour of `Hooks.run()` method). If no value have been saved under key `valuePlaceholder.value`
|
|
* will be `undefined`.
|
|
*
|
|
* __persistentStateReset__ (key: String)
|
|
*
|
|
* * Clears the value saved under `key`. If no `key` is given, all values associated with table will be cleared.
|
|
*
|
|
* __Note:__ The main reason behind using `persistentState` hooks rather than regular LocalStorage API is that it
|
|
* ensures separation of data stored by multiple Handsontable instances. In other words, if you have two (or more)
|
|
* instances of Handsontable on one page, data saved by one instance won't be accessible by the second instance.
|
|
* Those two instances can store data under the same key and no data would be overwritten.
|
|
*
|
|
* __Important:__ In order for the data separation to work properly, make sure that each instance of Handsontable has a unique `id`.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
persistentState: void 0,
|
|
|
|
/**
|
|
* Class name for all visible rows in the current selection.
|
|
*
|
|
* @type {String}
|
|
* @default undefined
|
|
* @example
|
|
* ```js
|
|
* currentRowClassName: 'currentRow' // This will add a 'currentRow' class name to appropriate table cells.
|
|
* ```
|
|
*/
|
|
currentRowClassName: void 0,
|
|
|
|
/**
|
|
* Class name for all visible columns in the current selection.
|
|
*
|
|
* @type {String}
|
|
* @default undefined
|
|
* @example
|
|
* ```js
|
|
* currentColClassName: 'currentColumn' // This will add a 'currentColumn' class name to appropriate table cells.
|
|
* ```
|
|
*/
|
|
currentColClassName: void 0,
|
|
|
|
/**
|
|
* Class name for all visible headers in current selection.
|
|
*
|
|
* @type {String}
|
|
* @since 0.27.0
|
|
* @default 'ht__highlight'
|
|
* @example
|
|
* ```js
|
|
* currentHeaderClassName: 'ht__highlight' // This will add a 'ht__highlight' class name to appropriate table headers.
|
|
* ```
|
|
*/
|
|
currentHeaderClassName: 'ht__highlight',
|
|
/**
|
|
* Class name for the Handsontable container element.
|
|
*
|
|
* @type {String|Array}
|
|
* @default undefined
|
|
*/
|
|
className: void 0,
|
|
|
|
/**
|
|
* Class name for all tables inside container element.
|
|
*
|
|
* @since 0.17.0
|
|
* @type {String|Array}
|
|
* @default undefined
|
|
*/
|
|
tableClassName: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Defines how the columns react, when the declared table width is different than the calculated sum of all column widths.
|
|
* [See more](http://docs.handsontable.com/demo-stretching.html) mode. Possible values:
|
|
* * `'none'` Disable stretching
|
|
* * `'last'` Stretch only the last column
|
|
* * `'all'` Stretch all the columns evenly
|
|
*
|
|
* @type {String}
|
|
* @default 'none'
|
|
*/
|
|
stretchH: 'none',
|
|
|
|
/**
|
|
* Lets you overwrite the default `isEmptyRow` method, which checks if row at the provided index is empty.
|
|
*
|
|
* @type {Function}
|
|
* @param {Number} row Visual row index.
|
|
* @returns {Boolean}
|
|
*/
|
|
isEmptyRow: function isEmptyRow(row) {
|
|
var col, colLen, value, meta;
|
|
|
|
for (col = 0, colLen = this.countCols(); col < colLen; col++) {
|
|
value = this.getDataAtCell(row, col);
|
|
|
|
if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) {
|
|
if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
|
|
meta = this.getCellMeta(row, col);
|
|
|
|
return (0, _object.isObjectEquals)(this.getSchema()[meta.prop], value);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
|
|
/**
|
|
* Lets you overwrite the default `isEmptyCol` method, which checks if column at the provided index is empty.
|
|
*
|
|
* @type {Function}
|
|
* @param {Number} col Visual column index
|
|
* @returns {Boolean}
|
|
*/
|
|
isEmptyCol: function isEmptyCol(col) {
|
|
var row, rowLen, value;
|
|
|
|
for (row = 0, rowLen = this.countRows(); row < rowLen; row++) {
|
|
value = this.getDataAtCell(row, col);
|
|
|
|
if (value !== '' && value !== null && (0, _mixed.isDefined)(value)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
|
|
/**
|
|
* When set to `true`, the table is re-rendered when it is detected that it was made visible in DOM.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
observeDOMVisibility: true,
|
|
|
|
/**
|
|
* If set to `true`, Handsontable will accept values that were marked as invalid by the cell `validator`.
|
|
* It will result with *invalid* cells being treated as *valid* (will save the *invalid* value into the Handsontable data source).
|
|
* If set to `false`, Handsontable will *not* accept the invalid values and won't allow the user to close the editor.
|
|
* This option will be particularly useful when used with the Autocomplete's `strict` mode.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
* @since 0.9.5
|
|
*/
|
|
allowInvalid: true,
|
|
|
|
/**
|
|
* If set to `true`, Handsontable will accept values that are empty (`null`, `undefined` or `''`).
|
|
* If set to `false`, Handsontable will *not* accept the empty values and mark cell as invalid.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* allowEmpty: true // allow empty values for all cells (whole table)
|
|
* ...
|
|
* // or
|
|
* ...
|
|
* columns: [
|
|
* // allow empty values only for 'date' column
|
|
* {data: 'date', dateFormat: 'DD/MM/YYYY', allowEmpty: true}
|
|
* ]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
* @since 0.23.0
|
|
*/
|
|
allowEmpty: true,
|
|
|
|
/**
|
|
* CSS class name for cells that did not pass validation.
|
|
*
|
|
* @type {String}
|
|
* @default 'htInvalid'
|
|
*/
|
|
invalidCellClassName: 'htInvalid',
|
|
|
|
/**
|
|
* When set to an non-empty string, displayed as the cell content for empty cells. If a value of a different type is provided,
|
|
* it will be stringified and applied as a string.
|
|
*
|
|
* @type {Mixed}
|
|
* @default false
|
|
*/
|
|
placeholder: false,
|
|
|
|
/**
|
|
* CSS class name for cells that have a placeholder in use.
|
|
*
|
|
* @type {String}
|
|
* @default 'htPlaceholder'
|
|
*/
|
|
placeholderCellClassName: 'htPlaceholder',
|
|
|
|
/**
|
|
* CSS class name for read-only cells.
|
|
*
|
|
* @type {String}
|
|
* @default 'htDimmed'
|
|
*/
|
|
readOnlyCellClassName: 'htDimmed',
|
|
|
|
/**
|
|
* @description
|
|
* If a string is provided, it may be one of the following predefined values:
|
|
* * `autocomplete`,
|
|
* * `checkbox`,
|
|
* * `html`,
|
|
* * `numeric`,
|
|
* * `password`.
|
|
* * `text`.
|
|
*
|
|
* Or you can [register](http://docs.handsontable.com/demo-custom-renderers.html) the custom renderer under specified name and use
|
|
* its name as an alias in your configuration.
|
|
*
|
|
* If a function is provided, it will receive the following arguments:
|
|
* ```js
|
|
* function(instance, TD, row, col, prop, value, cellProperties) {}
|
|
* ```
|
|
*
|
|
* You can read more about custom renderes [in the documentation](http://docs.handsontable.com/demo-custom-renderers.html).
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* Handsontable.renderers.registerRenderer('my.renderer', function(instance, TD, row, col, prop, value, cellProperties) {
|
|
* TD.innerHTML = value;
|
|
* });
|
|
* ...
|
|
* columns: [
|
|
* {
|
|
* editor: 'select',
|
|
* renderer: 'autocomplete' // as string
|
|
* },
|
|
* {
|
|
* renderer: 'my.renderer' // custom renderer as an alias
|
|
* },
|
|
* {
|
|
* // renderer as custom function
|
|
* renderer: function(hotInstance, TD, row, col, prop, value, cellProperties) {
|
|
* TD.style.color = 'blue';
|
|
* TD.innerHTML = value;
|
|
* }
|
|
* }
|
|
* ]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String|Function}
|
|
* @default undefined
|
|
*/
|
|
renderer: void 0,
|
|
|
|
/**
|
|
* CSS class name added to the commented cells.
|
|
*
|
|
* @type {String}
|
|
* @default 'htCommentCell'
|
|
*/
|
|
commentedCellClassName: 'htCommentCell',
|
|
|
|
/**
|
|
* If set to `true`, it enables the browser's native selection of a fragment of the text within a single cell, between adjacent cells or in a whole table.
|
|
* If set to `'cell'`, it enables the possibility of selecting a fragment of the text within a single cell's body.
|
|
*
|
|
* @type {Boolean|String}
|
|
* @default false
|
|
*/
|
|
fragmentSelection: false,
|
|
|
|
/**
|
|
* @description
|
|
* Make cell [read only](http://docs.handsontable.com/demo-read-only.html).
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
readOnly: false,
|
|
|
|
/**
|
|
* @description
|
|
* When added to a `column` property, it skips the column on paste and pastes the data on the next column to the right.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
skipColumnOnPaste: false,
|
|
|
|
/**
|
|
* @description
|
|
* Setting to true enables the search plugin (see [demo](http://docs.handsontable.com/demo-search-for-values.html)).
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
search: false,
|
|
|
|
/**
|
|
* @description
|
|
* Shortcut to define the combination of the cell renderer, editor and validator for the column, cell or whole table.
|
|
*
|
|
* Possible values:
|
|
* * [autocomplete](http://docs.handsontable.com/demo-autocomplete.html)
|
|
* * [checkbox](http://docs.handsontable.com/demo-checkbox.html)
|
|
* * [date](http://docs.handsontable.com/demo-date.html)
|
|
* * [dropdown](http://docs.handsontable.com/demo-dropdown.html)
|
|
* * [handsontable](http://docs.handsontable.com/demo-handsontable.html)
|
|
* * [numeric](http://docs.handsontable.com/demo-numeric.html)
|
|
* * [password](http://docs.handsontable.com/demo-password.html)
|
|
* * text
|
|
* * [time](http://docs.handsontable.com/demo-time.html)
|
|
*
|
|
* Or you can register the custom cell type under specified name and use
|
|
* its name as an alias in your configuration.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* Handsontable.cellTypes.registerCellType('my.type', {
|
|
* editor: MyEditorClass,
|
|
* renderer: function(hot, td, row, col, prop, value, cellProperties) {
|
|
* td.innerHTML = value;
|
|
* },
|
|
* validator: function(value, callback) {
|
|
* callback(value === 'foo' ? true : false);
|
|
* }
|
|
* });
|
|
* ...
|
|
* columns: [
|
|
* {
|
|
* type: 'text'
|
|
* },
|
|
* {
|
|
* type: 'my.type' // an alias to custom type
|
|
* },
|
|
* {
|
|
* type: 'checkbox'
|
|
* }
|
|
* ]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String}
|
|
* @default 'text'
|
|
*/
|
|
type: 'text',
|
|
|
|
/**
|
|
* @description
|
|
* Make cell copyable (pressing <kbd>CTRL</kbd> + <kbd>C</kbd> on your keyboard moves its value to system clipboard).
|
|
*
|
|
* __Note:__ this setting is `false` by default for cells with type `password`.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
* @since 0.10.2
|
|
*/
|
|
copyable: true,
|
|
|
|
/**
|
|
* Defines the editor for the table/column/cell.
|
|
*
|
|
* If a string is provided, it may be one of the following predefined values:
|
|
* * [autocomplete](http://docs.handsontable.com/demo-autocomplete.html)
|
|
* * [checkbox](http://docs.handsontable.com/demo-checkbox.html)
|
|
* * [date](http://docs.handsontable.com/demo-date.html)
|
|
* * [dropdown](http://docs.handsontable.com/demo-dropdown.html)
|
|
* * [handsontable](http://docs.handsontable.com/demo-handsontable.html)
|
|
* * [mobile](http://docs.handsontable.com/demo-mobiles-and-tablets.html)
|
|
* * [password](http://docs.handsontable.com/demo-password.html)
|
|
* * [select](http://docs.handsontable.com/demo-select.html)
|
|
* * text
|
|
*
|
|
* Or you can [register](http://docs.handsontable.com/tutorial-cell-editor.html#registering-an-editor) the custom editor under specified name and use
|
|
* its name as an alias in your configuration.
|
|
*
|
|
* To disable cell editing completely set `editor` property to `false`.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [
|
|
* {
|
|
* editor: 'select'
|
|
* },
|
|
* {
|
|
* editor: false
|
|
* }
|
|
* ]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String|Function|Boolean}
|
|
* @default 'text'
|
|
*/
|
|
editor: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Autocomplete definitions. See [autocomplete demo](http://docs.handsontable.com/demo-autocomplete.html) for examples and definitions.
|
|
*
|
|
* @type {Array}
|
|
* @default undefined
|
|
*/
|
|
autoComplete: void 0,
|
|
|
|
/**
|
|
* Control number of choices for the autocomplete (or dropdown) typed cells. After exceeding it, a scrollbar for the dropdown list of choices will appear.
|
|
*
|
|
* @since 0.18.0
|
|
* @type {Number}
|
|
* @default 10
|
|
*/
|
|
visibleRows: 10,
|
|
|
|
/**
|
|
* Makes autocomplete or dropdown width the same as the edited cell width. If `false` then editor will be scaled
|
|
* according to its content.
|
|
*
|
|
* @since 0.17.0
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
trimDropdown: true,
|
|
|
|
/**
|
|
* Setting to true enables the debug mode, currently used to test the correctness of the row and column
|
|
* header fixed positioning on a layer above the master table.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
debug: false,
|
|
|
|
/**
|
|
* When set to `true`, the text of the cell content is wrapped if it does not fit in the fixed column width.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
* @since 0.11.0
|
|
*/
|
|
wordWrap: true,
|
|
|
|
/**
|
|
* CSS class name added to cells with cell meta `wordWrap: false`.
|
|
*
|
|
* @type {String}
|
|
* @default 'htNoWrap'
|
|
* @since 0.11.0
|
|
*/
|
|
noWordWrapClassName: 'htNoWrap',
|
|
|
|
/**
|
|
* @description
|
|
* Defines if the right-click context menu should be enabled. Context menu allows to create 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)
|
|
* * an array of [predefined options](https://docs.handsontable.com/demo-context-menu.html#page-specific),
|
|
* * an object [with defined structure](http://docs.handsontable.com/demo-context-menu.html#page-custom)
|
|
*
|
|
* See [the context menu demo](http://docs.handsontable.com/demo-context-menu.html) for examples.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as a boolean
|
|
* contextMenu: true
|
|
* ...
|
|
* // as an array
|
|
* contextMenu: ['row_above', 'row_below', '--------', 'undo', 'redo']
|
|
* ...
|
|
* ```
|
|
* ...
|
|
* // as an object (`name` attribute is required in the custom keys)
|
|
* contextMenu: {
|
|
* items: {
|
|
* "option1": {
|
|
* name: "option1"
|
|
* },
|
|
* "option2": {
|
|
* name: "option2",
|
|
* submenu: {
|
|
* items: [
|
|
* {
|
|
* key: "option2:suboption1",
|
|
* name: "option2:suboption1",
|
|
* callback: function(key, options) {
|
|
* ...
|
|
* }
|
|
* },
|
|
* ...
|
|
* ]
|
|
* }
|
|
* }
|
|
* }
|
|
* }
|
|
* ...
|
|
* ```
|
|
* @type {Boolean|Array|Object}
|
|
* @default undefined
|
|
*/
|
|
contextMenu: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Disable or enable the copy/paste functionality.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* copyPaste: false,
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
copyPaste: true,
|
|
|
|
/**
|
|
* If `true`, undo/redo functionality is enabled.
|
|
*
|
|
* @type {Boolean}
|
|
* @default undefined
|
|
*/
|
|
undo: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Turns on [Column sorting](http://docs.handsontable.com/demo-sorting-data.html).
|
|
* Can be either a boolean (true/false) or an object with a declared sorting options. See the below example:
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* columnSorting: true
|
|
* ...
|
|
* // as a object with initial order (sort ascending column at index 2)
|
|
* columnSorting: {
|
|
* column: 2,
|
|
* sortOrder: true, // true = ascending, false = descending, undefined = original order
|
|
* sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
|
|
* }
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean|Object}
|
|
* @default undefined
|
|
*/
|
|
columnSorting: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Turns on [Manual column move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial
|
|
* column order, if set to an array of column indexes.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* manualColumnMove: true
|
|
* ...
|
|
* // as a array with initial order (move column index at 0 to 1 and move column index at 1 to 4)
|
|
* manualColumnMove: [1, 4]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean|Array}
|
|
* @default undefined
|
|
*/
|
|
manualColumnMove: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Turns on [Manual column resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial
|
|
* column resized widths, if set to an array of numbers.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* manualColumnResize: true
|
|
* ...
|
|
* // as a array with initial widths (column at 0 index has 40px and column at 1 index has 50px)
|
|
* manualColumnResize: [40, 50]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean|Array}
|
|
* @default undefined
|
|
*/
|
|
manualColumnResize: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Turns on [Manual row move](http://docs.handsontable.com/demo-moving-rows-and-columns.html), if set to a boolean or define initial
|
|
* row order, if set to an array of row indexes.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* manualRowMove: true
|
|
* ...
|
|
* // as a array with initial order (move row index at 0 to 1 and move row index at 1 to 4)
|
|
* manualRowMove: [1, 4]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean|Array}
|
|
* @default undefined
|
|
* @since 0.11.0
|
|
*/
|
|
manualRowMove: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Turns on [Manual row resize](http://docs.handsontable.com/demo-resizing.html), if set to a boolean or define initial
|
|
* row resized heights, if set to an array of numbers.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* manualRowResize: true
|
|
* ...
|
|
* // as a array with initial heights (row at 0 index has 40px and row at 1 index has 50px)
|
|
* manualRowResize: [40, 50]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean|Array}
|
|
* @default undefined
|
|
* @since 0.11.0
|
|
*/
|
|
manualRowResize: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* If set to `true`, it enables a possibility to merge cells. If set to an array of objects, it merges the cells provided in the objects (see the example below).
|
|
* [More information on the demo page.](http://docs.handsontable.com/demo-merge-cells.html)
|
|
*
|
|
* @example
|
|
* ```js
|
|
* // enables the mergeCells plugin:
|
|
* margeCells: true
|
|
* ...
|
|
* // declares a list of merged sections:
|
|
* mergeCells: [
|
|
* {row: 1, col: 1, rowspan: 3, colspan: 3}, // rowspan and colspan properties declare the width and height of a merged section in cells
|
|
* {row: 3, col: 4, rowspan: 2, colspan: 2},
|
|
* {row: 5, col: 6, rowspan: 3, colspan: 3}
|
|
* ]
|
|
* ```
|
|
* @type {Boolean|Array}
|
|
* @default false
|
|
*/
|
|
mergeCells: false,
|
|
|
|
/**
|
|
* Number of rows to be rendered outside of the visible part of the table.
|
|
* By default, it's set to `'auto'`, which makes Handsontable to attempt to calculate the best offset performance-wise.
|
|
*
|
|
* You may test out different values to find the best one that works for your specific implementation.
|
|
*
|
|
* @type {Number|String}
|
|
* @default 'auto'
|
|
*/
|
|
viewportRowRenderingOffset: 'auto',
|
|
|
|
/**
|
|
* Number of columns to be rendered outside of the visible part of the table.
|
|
* By default, it's set to `'auto'`, which makes Handsontable try calculating the best offset performance-wise.
|
|
*
|
|
* You may experiment with the value to find the one that works best for your specific implementation.
|
|
*
|
|
* @type {Number|String}
|
|
* @default 'auto'
|
|
*/
|
|
viewportColumnRenderingOffset: 'auto',
|
|
|
|
/**
|
|
* A function, regular expression or a string, which will be used in the process of cell validation.
|
|
* If a function is used, be sure to execute the callback argument with either `true` (`callback(true)`) if the validation passed
|
|
* or with `false` (`callback(false)`), if the validation failed.
|
|
* Note, that `this` in the function points to the `cellProperties` object.
|
|
*
|
|
* If a string is provided, it may be one of the following predefined values:
|
|
* * `autocomplete`,
|
|
* * `date`,
|
|
* * `numeric`,
|
|
* * `time`.
|
|
*
|
|
* Or you can [register](http://docs.handsontable.com/demo-data-validation.html) the validator function under specified name and use
|
|
* its name as an alias in your configuration.
|
|
*
|
|
* See more [in the demo](http://docs.handsontable.com/demo-data-validation.html).
|
|
*
|
|
* @example
|
|
* ```js
|
|
* // as a function
|
|
* columns: [
|
|
* {
|
|
* validator: function(value, callback) { // validation rules }
|
|
* }
|
|
* ]
|
|
* ...
|
|
* // as a regexp
|
|
* columns: [
|
|
* {
|
|
* validator: /^[0-9]$/ // regular expression
|
|
* }
|
|
* ]
|
|
* // as a string
|
|
* columns: [
|
|
* {
|
|
* validator: 'numeric'
|
|
* }
|
|
* ]
|
|
* ```
|
|
* @type {Function|RegExp|String}
|
|
* @default undefined
|
|
* @since 0.9.5
|
|
*/
|
|
validator: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Disable visual cells selection.
|
|
*
|
|
* Possible values:
|
|
* * `true` - Disables any type of visual selection (current and area selection),
|
|
* * `false` - Enables any type of visual selection. This is default value.
|
|
* * `current` - Disables the selection of a currently selected cell, the area selection is still present.
|
|
* * `area` - Disables the area selection, the currently selected cell selection is still present.
|
|
*
|
|
* @type {Boolean|String|Array}
|
|
* @default false
|
|
* @since 0.13.2
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* disableVisualSelection: true,
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as string ('current' or 'area')
|
|
* disableVisualSelection: 'current',
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as array
|
|
* disableVisualSelection: ['current', 'area'],
|
|
* ...
|
|
* ```
|
|
*/
|
|
disableVisualSelection: false,
|
|
|
|
/**
|
|
* @description
|
|
* Set whether to display the current sorting order indicator (a triangle icon in the column header, specifying the sorting order).
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
* @since 0.15.0-beta3
|
|
*/
|
|
sortIndicator: void 0,
|
|
|
|
/**
|
|
* Disable or enable ManualColumnFreeze plugin.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
manualColumnFreeze: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Defines whether Handsontable should trim the whitespace at the beginning and the end of the cell contents.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
trimWhitespace: true,
|
|
|
|
settings: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Defines data source for Autocomplete or Dropdown cell types.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // source as a array
|
|
* columns: [{
|
|
* type: 'autocomplete',
|
|
* source: ['A', 'B', 'C', 'D']
|
|
* }]
|
|
* ...
|
|
* // source as a function
|
|
* columns: [{
|
|
* type: 'autocomplete',
|
|
* source: function(query, callback) {
|
|
* fetch('http://example.com/query?q=' + query, function(response) {
|
|
* callback(response.items);
|
|
* })
|
|
* }
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Array|Function}
|
|
* @default undefined
|
|
*/
|
|
source: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Defines the column header name.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* title: 'First name',
|
|
* type: 'text',
|
|
* },
|
|
* {
|
|
* title: 'Last name',
|
|
* type: 'text',
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String}
|
|
* @default undefined
|
|
*/
|
|
title: void 0,
|
|
|
|
/**
|
|
* Data template for `'checkbox'` type when checkbox is checked.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* checkedTemplate: 'good'
|
|
*
|
|
* // if a checkbox-typed cell is checked, then getDataAtCell(x,y), where x and y are the coordinates of the cell
|
|
* // will return 'good'.
|
|
* ```
|
|
* @type {Boolean|String}
|
|
* @default true
|
|
*/
|
|
checkedTemplate: void 0,
|
|
|
|
/**
|
|
* Data template for `'checkbox'` type when checkbox is unchecked.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* uncheckedTemplate: 'bad'
|
|
*
|
|
* // if a checkbox-typed cell is not checked, then getDataAtCell(x,y), where x and y are the coordinates of the cell
|
|
* // will return 'bad'.
|
|
* ```
|
|
* @type {Boolean|String}
|
|
* @default false
|
|
*/
|
|
uncheckedTemplate: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Object which describes if renderer should create checkbox element with label element as a parent. Option desired for
|
|
* [checkbox](http://docs.handsontable.com/demo-checkbox.html)-typed cells.
|
|
*
|
|
* By default the [checkbox](http://docs.handsontable.com/demo-checkbox.html) renderer renders the checkbox without a label.
|
|
*
|
|
* Possible object properties:
|
|
* * `property` - Defines the property name of the data object, which will to be used as a label.
|
|
* (eg. `label: {property: 'name.last'}`). This option works only if data was passed as an array of objects.
|
|
* * `position` - String which describes where to place the label text (before or after checkbox element).
|
|
* Valid values are `'before'` and '`after`' (defaults to `'after'`).
|
|
* * `value` - String or a Function which will be used as label text.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'checkbox',
|
|
* label: {position: 'after', value: 'My label: '}
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @since 0.19.0
|
|
* @type {Object}
|
|
* @default undefined
|
|
*/
|
|
label: void 0,
|
|
|
|
/**
|
|
* Display format. See [numbrojs](http://numbrojs.com). This option is desired for
|
|
* [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells.
|
|
*
|
|
* Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'numeric',
|
|
* format: '0,00'
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String}
|
|
* @default '0'
|
|
*/
|
|
format: void 0,
|
|
|
|
/**
|
|
* Language display format. See [numbrojs](http://numbrojs.com/languages.html#supported-languages). This option is desired for
|
|
* [numeric](http://docs.handsontable.com/demo-numeric.html)-typed cells.
|
|
*
|
|
* Since 0.26.0 Handsontable uses [numbro](http://numbrojs.com/) as a main library for numbers formatting.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'numeric',
|
|
* language: 'en-US'
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String}
|
|
* @default 'en-US'
|
|
*/
|
|
language: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Data source for [select](http://docs.handsontable.com/demo-select.html)-typed cells.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* editor: 'select',
|
|
* selectOptions: ['A', 'B', 'C'],
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
selectOptions: void 0,
|
|
|
|
/**
|
|
* Enables or disables the autoColumnSize plugin. Default value is `undefined`, which has the same effect as `true`.
|
|
* Disabling this plugin can increase performance, as no size-related calculations would be done.
|
|
*
|
|
* Column width calculations are divided into sync and async part. Each of this parts has their own advantages and
|
|
* disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't
|
|
* block the browser UI.
|
|
*
|
|
* To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value.
|
|
* `syncLimit` option is available since 0.16.0.
|
|
*
|
|
* You can also use the `useHeaders` option to take the column headers with into calculation.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as a number (300 columns in sync, rest async)
|
|
* autoColumnSize: {syncLimit: 300},
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as a string (percent)
|
|
* autoColumnSize: {syncLimit: '40%'},
|
|
* ...
|
|
*
|
|
* ...
|
|
* // use headers width while calculation the column width
|
|
* autoColumnSize: {useHeaders: true},
|
|
* ...
|
|
*
|
|
* ```
|
|
*
|
|
* @type {Object|Boolean}
|
|
* @default {syncLimit: 50}
|
|
*/
|
|
autoColumnSize: void 0,
|
|
|
|
/**
|
|
* Enables or disables autoRowSize plugin. Default value is `undefined`, which has the same effect as `false` (disabled).
|
|
* Enabling this plugin can decrease performance, as size-related calculations would be performed.
|
|
*
|
|
* Row height calculations are divided into sync and async stages. Each of these stages has their own advantages and
|
|
* disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't
|
|
* block the browser UI.
|
|
*
|
|
* To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value.
|
|
* `syncLimit` options is available since 0.16.0.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as number (300 columns in sync, rest async)
|
|
* autoRowSize: {syncLimit: 300},
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as string (percent)
|
|
* autoRowSize: {syncLimit: '40%'},
|
|
* ...
|
|
* ```
|
|
* @type {Object|Boolean}
|
|
* @default {syncLimit: 1000}
|
|
*/
|
|
autoRowSize: void 0,
|
|
|
|
/**
|
|
* Date validation format.
|
|
*
|
|
* Option desired for `'date'` - typed cells.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'date',
|
|
* dateFormat: 'MM/DD/YYYY'
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String}
|
|
* @default 'DD/MM/YYYY'
|
|
*/
|
|
dateFormat: void 0,
|
|
|
|
/**
|
|
* If `true` then dates will be automatically formatted to match the desired format.
|
|
*
|
|
* Option desired for `'date'`-typed typed cells.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'date',
|
|
* dateFormat: 'YYYY-MM-DD',
|
|
* correctFormat: true
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
correctFormat: false,
|
|
|
|
/**
|
|
* Definition of default value which will fill the empty cells.
|
|
*
|
|
* Option desired for `'date'`-typed cells.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'date',
|
|
* defaultData: '2015-02-02'
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String}
|
|
*/
|
|
defaultDate: void 0,
|
|
|
|
/**
|
|
* If set to `true`, the value entered into the cell must match (case-sensitive) the autocomplete source. Otherwise, cell won't pass the validation.
|
|
* When filtering the autocomplete source list, the editor will be working in case-insensitive mode.
|
|
*
|
|
* Option desired for `autocomplete`-typed cells.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'autocomplete',
|
|
* source: ['A', 'B', 'C'],
|
|
* strict: true
|
|
* }]
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
strict: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* If typed `true`, data defined in `source` of the autocomplete or dropdown cell will be treated as HTML.
|
|
*
|
|
* __Warning:__ Enabling this option can cause serious XSS vulnerabilities.
|
|
*
|
|
* Option desired for `'autocomplete'`-typed cells.
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* columns: [{
|
|
* type: 'autocomplete',
|
|
* allowHtml: true,
|
|
* source: ['<b>foo</b>', '<b>bar</b>']
|
|
* }]
|
|
* ...
|
|
* ```
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
allowHtml: false,
|
|
|
|
/**
|
|
* If typed `true` then virtual rendering mechanism for handsontable will be disabled.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
renderAllRows: void 0,
|
|
|
|
/**
|
|
* Prevents table to overlap outside the parent element. If `'horizontal'` option is chosen then table will appear horizontal
|
|
* scrollbar in case where parent's width is narrower then table's width.
|
|
*
|
|
* Possible values:
|
|
* * `false` - Disables functionality (Default option).
|
|
* * `horizontal` - Prevents horizontal overflow table.
|
|
* * `vertical` - Prevents vertical overflow table (Not implemented yet).
|
|
*
|
|
* @since 0.20.3
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* preventOverflow: 'horizontal'
|
|
* ...
|
|
* ```
|
|
*
|
|
* @type {String|Boolean}
|
|
*/
|
|
preventOverflow: false,
|
|
|
|
/**
|
|
* @description
|
|
* Plugin allowing 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.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean|String}
|
|
* @example
|
|
*
|
|
* ```js
|
|
* ...
|
|
* var hot = new Handsontable(document.getElementById('example'), {
|
|
* date: getData(),
|
|
* bindRowsWithHeaders: true
|
|
* });
|
|
* ...
|
|
* ```
|
|
*
|
|
*/
|
|
bindRowsWithHeaders: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* The 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 `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.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean|Array}
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* collapsibleColumns: [
|
|
* {row: -4, col: 1, collapsible: true},
|
|
* {row: -3, col: 5, collapsible: true}
|
|
* ]
|
|
* ...
|
|
* // or
|
|
* ...
|
|
* collapsibleColumns: true
|
|
* ...
|
|
* ```
|
|
*/
|
|
collapsibleColumns: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Allows making pre-defined calculations on the cell values and display the results within Handsontable.
|
|
* See the demo for more information.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Object}
|
|
*/
|
|
columnSummary: void 0,
|
|
|
|
/**
|
|
* This plugin allows adding a configurable dropdown menu to the table's column headers.
|
|
* The dropdown menu acts like the Context Menu, but is triggered by clicking the button in the header.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean|Object|Array}
|
|
*/
|
|
dropdownMenu: void 0,
|
|
|
|
/**
|
|
* The filters plugin.
|
|
* It allows filtering the table data either by the built-in component or with the API.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean}
|
|
*/
|
|
filters: void 0,
|
|
|
|
/**
|
|
* It allows Handsontable to process formula expressions defined in the provided data.
|
|
*
|
|
* @pro
|
|
* @since 1.7.0
|
|
* @type {Boolean}
|
|
*/
|
|
formulas: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* GanttChart plugin enables a possibility to create a Gantt chart using a Handsontable instance.
|
|
* In this case, the whole table becomes read-only.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Object}
|
|
*/
|
|
ganttChart: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Allows adding 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).
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean|Object}
|
|
*/
|
|
headerTooltips: void 0,
|
|
|
|
/**
|
|
* Plugin allowing hiding of certain columns.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean|Object}
|
|
*/
|
|
hiddenColumns: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Plugin allowing hiding of certain rows.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean|Object}
|
|
*/
|
|
hiddenRows: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Allows creating a nested header structure, using the HTML's colspan attribute.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Array}
|
|
*/
|
|
nestedHeaders: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Plugin allowing hiding of certain rows.
|
|
*
|
|
* @pro
|
|
* @since 1.0.0-beta1
|
|
* @type {Boolean|Array}
|
|
*/
|
|
trimRows: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Allows setting a custom width of the row headers. You can provide a number or an array of widths, if many row header levels are defined.
|
|
*
|
|
* @since 0.22.0
|
|
* @type {Number|Array}
|
|
*/
|
|
rowHeaderWidth: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Allows setting a custom height of the column headers. You can provide a number or an array of heights, if many column header levels are defined.
|
|
*
|
|
* @since 0.22.0
|
|
* @type {Number|Array}
|
|
*/
|
|
columnHeaderHeight: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* Enabling this plugin switches table into one-way data binding where changes are applied into data source (from outside table)
|
|
* will be automatically reflected in the table.
|
|
*
|
|
* For every data change [afterChangesObserved](Hooks.html#event:afterChangesObserved) hook will be fired.
|
|
*
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
observeChanges: void 0,
|
|
|
|
/**
|
|
* @description
|
|
* When passed to the `column` property, allows specifying a custom sorting function for the desired column.
|
|
*
|
|
* @since 0.24.0
|
|
* @type {Function}
|
|
* @example
|
|
* ```js
|
|
* columns: [
|
|
* {
|
|
* sortFunction: function(sortOrder) {
|
|
* return function(a, b) {
|
|
* // sorting function body.
|
|
* //
|
|
* // Function parameters:
|
|
* // sortOrder: If true, the order is ascending, if false - descending. undefined = original order
|
|
* // a, b: Two compared elements. These are 2-element arrays, with the first element being the row index, the second - cell value.
|
|
* }
|
|
* }
|
|
* }
|
|
* ]
|
|
* ```
|
|
*/
|
|
sortFunction: void 0,
|
|
|
|
/**
|
|
* If defined as 'true', the Autocomplete's suggestion list would be sorted by relevance (the closer to the left the match is, the higher the suggestion).
|
|
*
|
|
* Option desired for cells of the `'autocomplete'` type.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
sortByRelevance: true,
|
|
|
|
/**
|
|
* If defined as 'true', when the user types into the input area the Autocomplete's suggestion list is updated to only
|
|
* include those choices starting with what has been typed; if defined as 'false' all suggestions remain shown, with
|
|
* those matching what has been typed marked in bold.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
filter: true,
|
|
|
|
/**
|
|
* If defined as 'true', filtering in the Autocomplete Editor will be case-sensitive.
|
|
*
|
|
* @type {Boolean}
|
|
* @default: false
|
|
*/
|
|
filteringCaseSensitive: false
|
|
};
|
|
|
|
exports.default = DefaultSettings;
|
|
|
|
/***/ }),
|
|
/* 89 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.getNormalizedDate = getNormalizedDate;
|
|
/* eslint-disable import/prefer-default-export */
|
|
|
|
/**
|
|
* Get normalized Date object for the ISO formatted date strings.
|
|
* Natively, the date object parsed from a ISO 8601 string will be offsetted by the timezone difference, which may result in returning a wrong date.
|
|
* See: Github issue #3338.
|
|
*
|
|
* @param {String} dateString String representing the date.
|
|
* @returns {Date} The proper Date object.
|
|
*/
|
|
function getNormalizedDate(dateString) {
|
|
var nativeDate = new Date(dateString);
|
|
|
|
// NaN if dateString is not in ISO format
|
|
if (!isNaN(new Date(dateString + "T00:00").getDate())) {
|
|
|
|
// Compensate timezone offset
|
|
return new Date(nativeDate.getTime() + nativeDate.getTimezoneOffset() * 60000);
|
|
}
|
|
|
|
return nativeDate;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 90 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.P, 'Array', {copyWithin: __webpack_require__(392)});
|
|
|
|
__webpack_require__(38)('copyWithin');
|
|
|
|
/***/ }),
|
|
/* 91 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.P, 'Array', {fill: __webpack_require__(393)});
|
|
|
|
__webpack_require__(38)('fill');
|
|
|
|
/***/ }),
|
|
/* 92 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
|
|
var $export = __webpack_require__(3)
|
|
, $find = __webpack_require__(54)(6)
|
|
, KEY = 'findIndex'
|
|
, forced = true;
|
|
// Shouldn't skip holes
|
|
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
|
|
$export($export.P + $export.F * forced, 'Array', {
|
|
findIndex: function findIndex(callbackfn/*, that = undefined */){
|
|
return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
|
|
}
|
|
});
|
|
__webpack_require__(38)(KEY);
|
|
|
|
/***/ }),
|
|
/* 93 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
|
|
var $export = __webpack_require__(3)
|
|
, $find = __webpack_require__(54)(5)
|
|
, KEY = 'find'
|
|
, forced = true;
|
|
// Shouldn't skip holes
|
|
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
|
|
$export($export.P + $export.F * forced, 'Array', {
|
|
find: function find(callbackfn/*, that = undefined */){
|
|
return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
|
|
}
|
|
});
|
|
__webpack_require__(38)(KEY);
|
|
|
|
/***/ }),
|
|
/* 94 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var ctx = __webpack_require__(29)
|
|
, $export = __webpack_require__(3)
|
|
, toObject = __webpack_require__(42)
|
|
, call = __webpack_require__(280)
|
|
, isArrayIter = __webpack_require__(276)
|
|
, toLength = __webpack_require__(24)
|
|
, createProperty = __webpack_require__(74)
|
|
, getIterFn = __webpack_require__(291);
|
|
|
|
$export($export.S + $export.F * !__webpack_require__(79)(function(iter){ Array.from(iter); }), 'Array', {
|
|
// 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
|
|
from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){
|
|
var O = toObject(arrayLike)
|
|
, C = typeof this == 'function' ? this : Array
|
|
, aLen = arguments.length
|
|
, mapfn = aLen > 1 ? arguments[1] : undefined
|
|
, mapping = mapfn !== undefined
|
|
, index = 0
|
|
, iterFn = getIterFn(O)
|
|
, length, result, step, iterator;
|
|
if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
|
|
// if object isn't iterable or it's array with default iterator - use simple case
|
|
if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){
|
|
for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){
|
|
createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);
|
|
}
|
|
} else {
|
|
length = toLength(O.length);
|
|
for(result = new C(length); length > index; index++){
|
|
createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
|
|
}
|
|
}
|
|
result.length = index;
|
|
return result;
|
|
}
|
|
});
|
|
|
|
|
|
/***/ }),
|
|
/* 95 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var $export = __webpack_require__(3)
|
|
, createProperty = __webpack_require__(74);
|
|
|
|
// WebKit Array.of isn't generic
|
|
$export($export.S + $export.F * __webpack_require__(31)(function(){
|
|
function F(){}
|
|
return !(Array.of.call(F) instanceof F);
|
|
}), 'Array', {
|
|
// 22.1.2.3 Array.of( ...items)
|
|
of: function of(/* ...args */){
|
|
var index = 0
|
|
, aLen = arguments.length
|
|
, result = new (typeof this == 'function' ? this : Array)(aLen);
|
|
while(aLen > index)createProperty(result, index, arguments[index++]);
|
|
result.length = aLen;
|
|
return result;
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 96 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var dP = __webpack_require__(19).f
|
|
, createDesc = __webpack_require__(41)
|
|
, has = __webpack_require__(22)
|
|
, FProto = Function.prototype
|
|
, nameRE = /^\s*function ([^ (]*)/
|
|
, NAME = 'name';
|
|
|
|
var isExtensible = Object.isExtensible || function(){
|
|
return true;
|
|
};
|
|
|
|
// 19.2.4.2 name
|
|
NAME in FProto || __webpack_require__(21) && dP(FProto, NAME, {
|
|
configurable: true,
|
|
get: function(){
|
|
try {
|
|
var that = this
|
|
, name = ('' + that).match(nameRE)[1];
|
|
has(that, NAME) || !isExtensible(that) || dP(that, NAME, createDesc(5, name));
|
|
return name;
|
|
} catch(e){
|
|
return '';
|
|
}
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 97 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var strong = __webpack_require__(272);
|
|
|
|
// 23.1 Map Objects
|
|
module.exports = __webpack_require__(55)('Map', function(get){
|
|
return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
|
|
}, {
|
|
// 23.1.3.6 Map.prototype.get(key)
|
|
get: function get(key){
|
|
var entry = strong.getEntry(this, key);
|
|
return entry && entry.v;
|
|
},
|
|
// 23.1.3.9 Map.prototype.set(key, value)
|
|
set: function set(key, value){
|
|
return strong.def(this, key === 0 ? 0 : key, value);
|
|
}
|
|
}, strong, true);
|
|
|
|
/***/ }),
|
|
/* 98 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.1 Number.EPSILON
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.S, 'Number', {EPSILON: Math.pow(2, -52)});
|
|
|
|
/***/ }),
|
|
/* 99 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.2 Number.isFinite(number)
|
|
var $export = __webpack_require__(3)
|
|
, _isFinite = __webpack_require__(13).isFinite;
|
|
|
|
$export($export.S, 'Number', {
|
|
isFinite: function isFinite(it){
|
|
return typeof it == 'number' && _isFinite(it);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 100 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.3 Number.isInteger(number)
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.S, 'Number', {isInteger: __webpack_require__(278)});
|
|
|
|
/***/ }),
|
|
/* 101 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.4 Number.isNaN(number)
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.S, 'Number', {
|
|
isNaN: function isNaN(number){
|
|
return number != number;
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 102 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.5 Number.isSafeInteger(number)
|
|
var $export = __webpack_require__(3)
|
|
, isInteger = __webpack_require__(278)
|
|
, abs = Math.abs;
|
|
|
|
$export($export.S, 'Number', {
|
|
isSafeInteger: function isSafeInteger(number){
|
|
return isInteger(number) && abs(number) <= 0x1fffffffffffff;
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 103 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.6 Number.MAX_SAFE_INTEGER
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.S, 'Number', {MAX_SAFE_INTEGER: 0x1fffffffffffff});
|
|
|
|
/***/ }),
|
|
/* 104 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.10 Number.MIN_SAFE_INTEGER
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.S, 'Number', {MIN_SAFE_INTEGER: -0x1fffffffffffff});
|
|
|
|
/***/ }),
|
|
/* 105 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 19.1.3.1 Object.assign(target, source)
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.S + $export.F, 'Object', {assign: __webpack_require__(283)});
|
|
|
|
/***/ }),
|
|
/* 106 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 19.1.3.10 Object.is(value1, value2)
|
|
var $export = __webpack_require__(3);
|
|
$export($export.S, 'Object', {is: __webpack_require__(407)});
|
|
|
|
/***/ }),
|
|
/* 107 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 19.1.3.19 Object.setPrototypeOf(O, proto)
|
|
var $export = __webpack_require__(3);
|
|
$export($export.S, 'Object', {setPrototypeOf: __webpack_require__(286).set});
|
|
|
|
/***/ }),
|
|
/* 108 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var LIBRARY = __webpack_require__(58)
|
|
, global = __webpack_require__(13)
|
|
, ctx = __webpack_require__(29)
|
|
, classof = __webpack_require__(271)
|
|
, $export = __webpack_require__(3)
|
|
, isObject = __webpack_require__(15)
|
|
, aFunction = __webpack_require__(73)
|
|
, anInstance = __webpack_require__(53)
|
|
, forOf = __webpack_require__(57)
|
|
, speciesConstructor = __webpack_require__(408)
|
|
, task = __webpack_require__(86).set
|
|
, microtask = __webpack_require__(402)()
|
|
, PROMISE = 'Promise'
|
|
, TypeError = global.TypeError
|
|
, process = global.process
|
|
, $Promise = global[PROMISE]
|
|
, process = global.process
|
|
, isNode = classof(process) == 'process'
|
|
, empty = function(){ /* empty */ }
|
|
, Internal, GenericPromiseCapability, Wrapper;
|
|
|
|
var USE_NATIVE = !!function(){
|
|
try {
|
|
// correct subclassing with @@species support
|
|
var promise = $Promise.resolve(1)
|
|
, FakePromise = (promise.constructor = {})[__webpack_require__(10)('species')] = function(exec){ exec(empty, empty); };
|
|
// unhandled rejections tracking support, NodeJS Promise without it fails @@species test
|
|
return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
|
|
} catch(e){ /* empty */ }
|
|
}();
|
|
|
|
// helpers
|
|
var sameConstructor = function(a, b){
|
|
// with library wrapper special case
|
|
return a === b || a === $Promise && b === Wrapper;
|
|
};
|
|
var isThenable = function(it){
|
|
var then;
|
|
return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
|
|
};
|
|
var newPromiseCapability = function(C){
|
|
return sameConstructor($Promise, C)
|
|
? new PromiseCapability(C)
|
|
: new GenericPromiseCapability(C);
|
|
};
|
|
var PromiseCapability = GenericPromiseCapability = function(C){
|
|
var resolve, reject;
|
|
this.promise = new C(function($$resolve, $$reject){
|
|
if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');
|
|
resolve = $$resolve;
|
|
reject = $$reject;
|
|
});
|
|
this.resolve = aFunction(resolve);
|
|
this.reject = aFunction(reject);
|
|
};
|
|
var perform = function(exec){
|
|
try {
|
|
exec();
|
|
} catch(e){
|
|
return {error: e};
|
|
}
|
|
};
|
|
var notify = function(promise, isReject){
|
|
if(promise._n)return;
|
|
promise._n = true;
|
|
var chain = promise._c;
|
|
microtask(function(){
|
|
var value = promise._v
|
|
, ok = promise._s == 1
|
|
, i = 0;
|
|
var run = function(reaction){
|
|
var handler = ok ? reaction.ok : reaction.fail
|
|
, resolve = reaction.resolve
|
|
, reject = reaction.reject
|
|
, domain = reaction.domain
|
|
, result, then;
|
|
try {
|
|
if(handler){
|
|
if(!ok){
|
|
if(promise._h == 2)onHandleUnhandled(promise);
|
|
promise._h = 1;
|
|
}
|
|
if(handler === true)result = value;
|
|
else {
|
|
if(domain)domain.enter();
|
|
result = handler(value);
|
|
if(domain)domain.exit();
|
|
}
|
|
if(result === reaction.promise){
|
|
reject(TypeError('Promise-chain cycle'));
|
|
} else if(then = isThenable(result)){
|
|
then.call(result, resolve, reject);
|
|
} else resolve(result);
|
|
} else reject(value);
|
|
} catch(e){
|
|
reject(e);
|
|
}
|
|
};
|
|
while(chain.length > i)run(chain[i++]); // variable length - can't use forEach
|
|
promise._c = [];
|
|
promise._n = false;
|
|
if(isReject && !promise._h)onUnhandled(promise);
|
|
});
|
|
};
|
|
var onUnhandled = function(promise){
|
|
task.call(global, function(){
|
|
var value = promise._v
|
|
, abrupt, handler, console;
|
|
if(isUnhandled(promise)){
|
|
abrupt = perform(function(){
|
|
if(isNode){
|
|
process.emit('unhandledRejection', value, promise);
|
|
} else if(handler = global.onunhandledrejection){
|
|
handler({promise: promise, reason: value});
|
|
} else if((console = global.console) && console.error){
|
|
console.error('Unhandled promise rejection', value);
|
|
}
|
|
});
|
|
// Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
|
|
promise._h = isNode || isUnhandled(promise) ? 2 : 1;
|
|
} promise._a = undefined;
|
|
if(abrupt)throw abrupt.error;
|
|
});
|
|
};
|
|
var isUnhandled = function(promise){
|
|
if(promise._h == 1)return false;
|
|
var chain = promise._a || promise._c
|
|
, i = 0
|
|
, reaction;
|
|
while(chain.length > i){
|
|
reaction = chain[i++];
|
|
if(reaction.fail || !isUnhandled(reaction.promise))return false;
|
|
} return true;
|
|
};
|
|
var onHandleUnhandled = function(promise){
|
|
task.call(global, function(){
|
|
var handler;
|
|
if(isNode){
|
|
process.emit('rejectionHandled', promise);
|
|
} else if(handler = global.onrejectionhandled){
|
|
handler({promise: promise, reason: promise._v});
|
|
}
|
|
});
|
|
};
|
|
var $reject = function(value){
|
|
var promise = this;
|
|
if(promise._d)return;
|
|
promise._d = true;
|
|
promise = promise._w || promise; // unwrap
|
|
promise._v = value;
|
|
promise._s = 2;
|
|
if(!promise._a)promise._a = promise._c.slice();
|
|
notify(promise, true);
|
|
};
|
|
var $resolve = function(value){
|
|
var promise = this
|
|
, then;
|
|
if(promise._d)return;
|
|
promise._d = true;
|
|
promise = promise._w || promise; // unwrap
|
|
try {
|
|
if(promise === value)throw TypeError("Promise can't be resolved itself");
|
|
if(then = isThenable(value)){
|
|
microtask(function(){
|
|
var wrapper = {_w: promise, _d: false}; // wrap
|
|
try {
|
|
then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
|
|
} catch(e){
|
|
$reject.call(wrapper, e);
|
|
}
|
|
});
|
|
} else {
|
|
promise._v = value;
|
|
promise._s = 1;
|
|
notify(promise, false);
|
|
}
|
|
} catch(e){
|
|
$reject.call({_w: promise, _d: false}, e); // wrap
|
|
}
|
|
};
|
|
|
|
// constructor polyfill
|
|
if(!USE_NATIVE){
|
|
// 25.4.3.1 Promise(executor)
|
|
$Promise = function Promise(executor){
|
|
anInstance(this, $Promise, PROMISE, '_h');
|
|
aFunction(executor);
|
|
Internal.call(this);
|
|
try {
|
|
executor(ctx($resolve, this, 1), ctx($reject, this, 1));
|
|
} catch(err){
|
|
$reject.call(this, err);
|
|
}
|
|
};
|
|
Internal = function Promise(executor){
|
|
this._c = []; // <- awaiting reactions
|
|
this._a = undefined; // <- checked in isUnhandled reactions
|
|
this._s = 0; // <- state
|
|
this._d = false; // <- done
|
|
this._v = undefined; // <- value
|
|
this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
|
|
this._n = false; // <- notify
|
|
};
|
|
Internal.prototype = __webpack_require__(60)($Promise.prototype, {
|
|
// 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
|
|
then: function then(onFulfilled, onRejected){
|
|
var reaction = newPromiseCapability(speciesConstructor(this, $Promise));
|
|
reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
|
|
reaction.fail = typeof onRejected == 'function' && onRejected;
|
|
reaction.domain = isNode ? process.domain : undefined;
|
|
this._c.push(reaction);
|
|
if(this._a)this._a.push(reaction);
|
|
if(this._s)notify(this, false);
|
|
return reaction.promise;
|
|
},
|
|
// 25.4.5.1 Promise.prototype.catch(onRejected)
|
|
'catch': function(onRejected){
|
|
return this.then(undefined, onRejected);
|
|
}
|
|
});
|
|
PromiseCapability = function(){
|
|
var promise = new Internal;
|
|
this.promise = promise;
|
|
this.resolve = ctx($resolve, promise, 1);
|
|
this.reject = ctx($reject, promise, 1);
|
|
};
|
|
}
|
|
|
|
$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise});
|
|
__webpack_require__(49)($Promise, PROMISE);
|
|
__webpack_require__(287)(PROMISE);
|
|
Wrapper = __webpack_require__(45)[PROMISE];
|
|
|
|
// statics
|
|
$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
|
|
// 25.4.4.5 Promise.reject(r)
|
|
reject: function reject(r){
|
|
var capability = newPromiseCapability(this)
|
|
, $$reject = capability.reject;
|
|
$$reject(r);
|
|
return capability.promise;
|
|
}
|
|
});
|
|
$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
|
|
// 25.4.4.6 Promise.resolve(x)
|
|
resolve: function resolve(x){
|
|
// instanceof instead of internal slot check because we should fix it without replacement native Promise core
|
|
if(x instanceof $Promise && sameConstructor(x.constructor, this))return x;
|
|
var capability = newPromiseCapability(this)
|
|
, $$resolve = capability.resolve;
|
|
$$resolve(x);
|
|
return capability.promise;
|
|
}
|
|
});
|
|
$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(79)(function(iter){
|
|
$Promise.all(iter)['catch'](empty);
|
|
})), PROMISE, {
|
|
// 25.4.4.1 Promise.all(iterable)
|
|
all: function all(iterable){
|
|
var C = this
|
|
, capability = newPromiseCapability(C)
|
|
, resolve = capability.resolve
|
|
, reject = capability.reject;
|
|
var abrupt = perform(function(){
|
|
var values = []
|
|
, index = 0
|
|
, remaining = 1;
|
|
forOf(iterable, false, function(promise){
|
|
var $index = index++
|
|
, alreadyCalled = false;
|
|
values.push(undefined);
|
|
remaining++;
|
|
C.resolve(promise).then(function(value){
|
|
if(alreadyCalled)return;
|
|
alreadyCalled = true;
|
|
values[$index] = value;
|
|
--remaining || resolve(values);
|
|
}, reject);
|
|
});
|
|
--remaining || resolve(values);
|
|
});
|
|
if(abrupt)reject(abrupt.error);
|
|
return capability.promise;
|
|
},
|
|
// 25.4.4.4 Promise.race(iterable)
|
|
race: function race(iterable){
|
|
var C = this
|
|
, capability = newPromiseCapability(C)
|
|
, reject = capability.reject;
|
|
var abrupt = perform(function(){
|
|
forOf(iterable, false, function(promise){
|
|
C.resolve(promise).then(capability.resolve, reject);
|
|
});
|
|
});
|
|
if(abrupt)reject(abrupt.error);
|
|
return capability.promise;
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 109 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 21.2.5.3 get RegExp.prototype.flags()
|
|
if(__webpack_require__(21) && /./g.flags != 'g')__webpack_require__(19).f(RegExp.prototype, 'flags', {
|
|
configurable: true,
|
|
get: __webpack_require__(397)
|
|
});
|
|
|
|
/***/ }),
|
|
/* 110 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// @@match logic
|
|
__webpack_require__(56)('match', 1, function(defined, MATCH, $match){
|
|
// 21.1.3.11 String.prototype.match(regexp)
|
|
return [function match(regexp){
|
|
'use strict';
|
|
var O = defined(this)
|
|
, fn = regexp == undefined ? undefined : regexp[MATCH];
|
|
return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
|
|
}, $match];
|
|
});
|
|
|
|
/***/ }),
|
|
/* 111 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// @@replace logic
|
|
__webpack_require__(56)('replace', 2, function(defined, REPLACE, $replace){
|
|
// 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
|
|
return [function replace(searchValue, replaceValue){
|
|
'use strict';
|
|
var O = defined(this)
|
|
, fn = searchValue == undefined ? undefined : searchValue[REPLACE];
|
|
return fn !== undefined
|
|
? fn.call(searchValue, O, replaceValue)
|
|
: $replace.call(String(O), searchValue, replaceValue);
|
|
}, $replace];
|
|
});
|
|
|
|
/***/ }),
|
|
/* 112 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// @@search logic
|
|
__webpack_require__(56)('search', 1, function(defined, SEARCH, $search){
|
|
// 21.1.3.15 String.prototype.search(regexp)
|
|
return [function search(regexp){
|
|
'use strict';
|
|
var O = defined(this)
|
|
, fn = regexp == undefined ? undefined : regexp[SEARCH];
|
|
return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
|
|
}, $search];
|
|
});
|
|
|
|
/***/ }),
|
|
/* 113 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// @@split logic
|
|
__webpack_require__(56)('split', 2, function(defined, SPLIT, $split){
|
|
'use strict';
|
|
var isRegExp = __webpack_require__(279)
|
|
, _split = $split
|
|
, $push = [].push
|
|
, $SPLIT = 'split'
|
|
, LENGTH = 'length'
|
|
, LAST_INDEX = 'lastIndex';
|
|
if(
|
|
'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||
|
|
'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||
|
|
'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||
|
|
'.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||
|
|
'.'[$SPLIT](/()()/)[LENGTH] > 1 ||
|
|
''[$SPLIT](/.?/)[LENGTH]
|
|
){
|
|
var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group
|
|
// based on es5-shim implementation, need to rework it
|
|
$split = function(separator, limit){
|
|
var string = String(this);
|
|
if(separator === undefined && limit === 0)return [];
|
|
// If `separator` is not a regex, use native split
|
|
if(!isRegExp(separator))return _split.call(string, separator, limit);
|
|
var output = [];
|
|
var flags = (separator.ignoreCase ? 'i' : '') +
|
|
(separator.multiline ? 'm' : '') +
|
|
(separator.unicode ? 'u' : '') +
|
|
(separator.sticky ? 'y' : '');
|
|
var lastLastIndex = 0;
|
|
var splitLimit = limit === undefined ? 4294967295 : limit >>> 0;
|
|
// Make `global` and avoid `lastIndex` issues by working with a copy
|
|
var separatorCopy = new RegExp(separator.source, flags + 'g');
|
|
var separator2, match, lastIndex, lastLength, i;
|
|
// Doesn't need flags gy, but they don't hurt
|
|
if(!NPCG)separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
|
|
while(match = separatorCopy.exec(string)){
|
|
// `separatorCopy.lastIndex` is not reliable cross-browser
|
|
lastIndex = match.index + match[0][LENGTH];
|
|
if(lastIndex > lastLastIndex){
|
|
output.push(string.slice(lastLastIndex, match.index));
|
|
// Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG
|
|
if(!NPCG && match[LENGTH] > 1)match[0].replace(separator2, function(){
|
|
for(i = 1; i < arguments[LENGTH] - 2; i++)if(arguments[i] === undefined)match[i] = undefined;
|
|
});
|
|
if(match[LENGTH] > 1 && match.index < string[LENGTH])$push.apply(output, match.slice(1));
|
|
lastLength = match[0][LENGTH];
|
|
lastLastIndex = lastIndex;
|
|
if(output[LENGTH] >= splitLimit)break;
|
|
}
|
|
if(separatorCopy[LAST_INDEX] === match.index)separatorCopy[LAST_INDEX]++; // Avoid an infinite loop
|
|
}
|
|
if(lastLastIndex === string[LENGTH]){
|
|
if(lastLength || !separatorCopy.test(''))output.push('');
|
|
} else output.push(string.slice(lastLastIndex));
|
|
return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
|
|
};
|
|
// Chakra, V8
|
|
} else if('0'[$SPLIT](undefined, 0)[LENGTH]){
|
|
$split = function(separator, limit){
|
|
return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit);
|
|
};
|
|
}
|
|
// 21.1.3.17 String.prototype.split(separator, limit)
|
|
return [function split(separator, limit){
|
|
var O = defined(this)
|
|
, fn = separator == undefined ? undefined : separator[SPLIT];
|
|
return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit);
|
|
}, $split];
|
|
});
|
|
|
|
/***/ }),
|
|
/* 114 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var strong = __webpack_require__(272);
|
|
|
|
// 23.2 Set Objects
|
|
module.exports = __webpack_require__(55)('Set', function(get){
|
|
return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
|
|
}, {
|
|
// 23.2.3.1 Set.prototype.add(value)
|
|
add: function add(value){
|
|
return strong.def(this, value = value === 0 ? 0 : value, value);
|
|
}
|
|
}, strong);
|
|
|
|
/***/ }),
|
|
/* 115 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var $export = __webpack_require__(3)
|
|
, $at = __webpack_require__(409)(false);
|
|
$export($export.P, 'String', {
|
|
// 21.1.3.3 String.prototype.codePointAt(pos)
|
|
codePointAt: function codePointAt(pos){
|
|
return $at(this, pos);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 116 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])
|
|
|
|
var $export = __webpack_require__(3)
|
|
, toLength = __webpack_require__(24)
|
|
, context = __webpack_require__(85)
|
|
, ENDS_WITH = 'endsWith'
|
|
, $endsWith = ''[ENDS_WITH];
|
|
|
|
$export($export.P + $export.F * __webpack_require__(77)(ENDS_WITH), 'String', {
|
|
endsWith: function endsWith(searchString /*, endPosition = @length */){
|
|
var that = context(this, searchString, ENDS_WITH)
|
|
, endPosition = arguments.length > 1 ? arguments[1] : undefined
|
|
, len = toLength(that.length)
|
|
, end = endPosition === undefined ? len : Math.min(toLength(endPosition), len)
|
|
, search = String(searchString);
|
|
return $endsWith
|
|
? $endsWith.call(that, search, end)
|
|
: that.slice(end - search.length, end) === search;
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 117 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var $export = __webpack_require__(3)
|
|
, toIndex = __webpack_require__(61)
|
|
, fromCharCode = String.fromCharCode
|
|
, $fromCodePoint = String.fromCodePoint;
|
|
|
|
// length should be 1, old FF problem
|
|
$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
|
|
// 21.1.2.2 String.fromCodePoint(...codePoints)
|
|
fromCodePoint: function fromCodePoint(x){ // eslint-disable-line no-unused-vars
|
|
var res = []
|
|
, aLen = arguments.length
|
|
, i = 0
|
|
, code;
|
|
while(aLen > i){
|
|
code = +arguments[i++];
|
|
if(toIndex(code, 0x10ffff) !== code)throw RangeError(code + ' is not a valid code point');
|
|
res.push(code < 0x10000
|
|
? fromCharCode(code)
|
|
: fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
|
|
);
|
|
} return res.join('');
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 118 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// 21.1.3.7 String.prototype.includes(searchString, position = 0)
|
|
|
|
var $export = __webpack_require__(3)
|
|
, context = __webpack_require__(85)
|
|
, INCLUDES = 'includes';
|
|
|
|
$export($export.P + $export.F * __webpack_require__(77)(INCLUDES), 'String', {
|
|
includes: function includes(searchString /*, position = 0 */){
|
|
return !!~context(this, searchString, INCLUDES)
|
|
.indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 119 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var $export = __webpack_require__(3)
|
|
, toIObject = __webpack_require__(23)
|
|
, toLength = __webpack_require__(24);
|
|
|
|
$export($export.S, 'String', {
|
|
// 21.1.2.4 String.raw(callSite, ...substitutions)
|
|
raw: function raw(callSite){
|
|
var tpl = toIObject(callSite.raw)
|
|
, len = toLength(tpl.length)
|
|
, aLen = arguments.length
|
|
, res = []
|
|
, i = 0;
|
|
while(len > i){
|
|
res.push(String(tpl[i++]));
|
|
if(i < aLen)res.push(String(arguments[i]));
|
|
} return res.join('');
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 120 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var $export = __webpack_require__(3);
|
|
|
|
$export($export.P, 'String', {
|
|
// 21.1.3.13 String.prototype.repeat(count)
|
|
repeat: __webpack_require__(289)
|
|
});
|
|
|
|
/***/ }),
|
|
/* 121 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// 21.1.3.18 String.prototype.startsWith(searchString [, position ])
|
|
|
|
var $export = __webpack_require__(3)
|
|
, toLength = __webpack_require__(24)
|
|
, context = __webpack_require__(85)
|
|
, STARTS_WITH = 'startsWith'
|
|
, $startsWith = ''[STARTS_WITH];
|
|
|
|
$export($export.P + $export.F * __webpack_require__(77)(STARTS_WITH), 'String', {
|
|
startsWith: function startsWith(searchString /*, position = 0 */){
|
|
var that = context(this, searchString, STARTS_WITH)
|
|
, index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length))
|
|
, search = String(searchString);
|
|
return $startsWith
|
|
? $startsWith.call(that, search, index)
|
|
: that.slice(index, index + search.length) === search;
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 122 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// ECMAScript 6 symbols shim
|
|
var global = __webpack_require__(13)
|
|
, has = __webpack_require__(22)
|
|
, DESCRIPTORS = __webpack_require__(21)
|
|
, $export = __webpack_require__(3)
|
|
, redefine = __webpack_require__(33)
|
|
, META = __webpack_require__(47).KEY
|
|
, $fails = __webpack_require__(31)
|
|
, shared = __webpack_require__(84)
|
|
, setToStringTag = __webpack_require__(49)
|
|
, uid = __webpack_require__(50)
|
|
, wks = __webpack_require__(10)
|
|
, wksExt = __webpack_require__(290)
|
|
, wksDefine = __webpack_require__(410)
|
|
, keyOf = __webpack_require__(401)
|
|
, enumKeys = __webpack_require__(396)
|
|
, isArray = __webpack_require__(277)
|
|
, anObject = __webpack_require__(18)
|
|
, toIObject = __webpack_require__(23)
|
|
, toPrimitive = __webpack_require__(87)
|
|
, createDesc = __webpack_require__(41)
|
|
, _create = __webpack_require__(80)
|
|
, gOPNExt = __webpack_require__(404)
|
|
, $GOPD = __webpack_require__(81)
|
|
, $DP = __webpack_require__(19)
|
|
, $keys = __webpack_require__(40)
|
|
, gOPD = $GOPD.f
|
|
, dP = $DP.f
|
|
, gOPN = gOPNExt.f
|
|
, $Symbol = global.Symbol
|
|
, $JSON = global.JSON
|
|
, _stringify = $JSON && $JSON.stringify
|
|
, PROTOTYPE = 'prototype'
|
|
, HIDDEN = wks('_hidden')
|
|
, TO_PRIMITIVE = wks('toPrimitive')
|
|
, isEnum = {}.propertyIsEnumerable
|
|
, SymbolRegistry = shared('symbol-registry')
|
|
, AllSymbols = shared('symbols')
|
|
, OPSymbols = shared('op-symbols')
|
|
, ObjectProto = Object[PROTOTYPE]
|
|
, USE_NATIVE = typeof $Symbol == 'function'
|
|
, QObject = global.QObject;
|
|
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
|
|
var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;
|
|
|
|
// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
|
|
var setSymbolDesc = DESCRIPTORS && $fails(function(){
|
|
return _create(dP({}, 'a', {
|
|
get: function(){ return dP(this, 'a', {value: 7}).a; }
|
|
})).a != 7;
|
|
}) ? function(it, key, D){
|
|
var protoDesc = gOPD(ObjectProto, key);
|
|
if(protoDesc)delete ObjectProto[key];
|
|
dP(it, key, D);
|
|
if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc);
|
|
} : dP;
|
|
|
|
var wrap = function(tag){
|
|
var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);
|
|
sym._k = tag;
|
|
return sym;
|
|
};
|
|
|
|
var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){
|
|
return typeof it == 'symbol';
|
|
} : function(it){
|
|
return it instanceof $Symbol;
|
|
};
|
|
|
|
var $defineProperty = function defineProperty(it, key, D){
|
|
if(it === ObjectProto)$defineProperty(OPSymbols, key, D);
|
|
anObject(it);
|
|
key = toPrimitive(key, true);
|
|
anObject(D);
|
|
if(has(AllSymbols, key)){
|
|
if(!D.enumerable){
|
|
if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {}));
|
|
it[HIDDEN][key] = true;
|
|
} else {
|
|
if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;
|
|
D = _create(D, {enumerable: createDesc(0, false)});
|
|
} return setSymbolDesc(it, key, D);
|
|
} return dP(it, key, D);
|
|
};
|
|
var $defineProperties = function defineProperties(it, P){
|
|
anObject(it);
|
|
var keys = enumKeys(P = toIObject(P))
|
|
, i = 0
|
|
, l = keys.length
|
|
, key;
|
|
while(l > i)$defineProperty(it, key = keys[i++], P[key]);
|
|
return it;
|
|
};
|
|
var $create = function create(it, P){
|
|
return P === undefined ? _create(it) : $defineProperties(_create(it), P);
|
|
};
|
|
var $propertyIsEnumerable = function propertyIsEnumerable(key){
|
|
var E = isEnum.call(this, key = toPrimitive(key, true));
|
|
if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false;
|
|
return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
|
|
};
|
|
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
|
|
it = toIObject(it);
|
|
key = toPrimitive(key, true);
|
|
if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return;
|
|
var D = gOPD(it, key);
|
|
if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;
|
|
return D;
|
|
};
|
|
var $getOwnPropertyNames = function getOwnPropertyNames(it){
|
|
var names = gOPN(toIObject(it))
|
|
, result = []
|
|
, i = 0
|
|
, key;
|
|
while(names.length > i){
|
|
if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key);
|
|
} return result;
|
|
};
|
|
var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
|
|
var IS_OP = it === ObjectProto
|
|
, names = gOPN(IS_OP ? OPSymbols : toIObject(it))
|
|
, result = []
|
|
, i = 0
|
|
, key;
|
|
while(names.length > i){
|
|
if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]);
|
|
} return result;
|
|
};
|
|
|
|
// 19.4.1.1 Symbol([description])
|
|
if(!USE_NATIVE){
|
|
$Symbol = function Symbol(){
|
|
if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!');
|
|
var tag = uid(arguments.length > 0 ? arguments[0] : undefined);
|
|
var $set = function(value){
|
|
if(this === ObjectProto)$set.call(OPSymbols, value);
|
|
if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
|
|
setSymbolDesc(this, tag, createDesc(1, value));
|
|
};
|
|
if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set});
|
|
return wrap(tag);
|
|
};
|
|
redefine($Symbol[PROTOTYPE], 'toString', function toString(){
|
|
return this._k;
|
|
});
|
|
|
|
$GOPD.f = $getOwnPropertyDescriptor;
|
|
$DP.f = $defineProperty;
|
|
__webpack_require__(82).f = gOPNExt.f = $getOwnPropertyNames;
|
|
__webpack_require__(48).f = $propertyIsEnumerable;
|
|
__webpack_require__(59).f = $getOwnPropertySymbols;
|
|
|
|
if(DESCRIPTORS && !__webpack_require__(58)){
|
|
redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
|
|
}
|
|
|
|
wksExt.f = function(name){
|
|
return wrap(wks(name));
|
|
}
|
|
}
|
|
|
|
$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol});
|
|
|
|
for(var symbols = (
|
|
// 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
|
|
'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
|
|
).split(','), i = 0; symbols.length > i; )wks(symbols[i++]);
|
|
|
|
for(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]);
|
|
|
|
$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {
|
|
// 19.4.2.1 Symbol.for(key)
|
|
'for': function(key){
|
|
return has(SymbolRegistry, key += '')
|
|
? SymbolRegistry[key]
|
|
: SymbolRegistry[key] = $Symbol(key);
|
|
},
|
|
// 19.4.2.5 Symbol.keyFor(sym)
|
|
keyFor: function keyFor(key){
|
|
if(isSymbol(key))return keyOf(SymbolRegistry, key);
|
|
throw TypeError(key + ' is not a symbol!');
|
|
},
|
|
useSetter: function(){ setter = true; },
|
|
useSimple: function(){ setter = false; }
|
|
});
|
|
|
|
$export($export.S + $export.F * !USE_NATIVE, 'Object', {
|
|
// 19.1.2.2 Object.create(O [, Properties])
|
|
create: $create,
|
|
// 19.1.2.4 Object.defineProperty(O, P, Attributes)
|
|
defineProperty: $defineProperty,
|
|
// 19.1.2.3 Object.defineProperties(O, Properties)
|
|
defineProperties: $defineProperties,
|
|
// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
|
|
getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
|
|
// 19.1.2.7 Object.getOwnPropertyNames(O)
|
|
getOwnPropertyNames: $getOwnPropertyNames,
|
|
// 19.1.2.8 Object.getOwnPropertySymbols(O)
|
|
getOwnPropertySymbols: $getOwnPropertySymbols
|
|
});
|
|
|
|
// 24.3.2 JSON.stringify(value [, replacer [, space]])
|
|
$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){
|
|
var S = $Symbol();
|
|
// MS Edge converts symbol values to JSON as {}
|
|
// WebKit converts symbol values to JSON as null
|
|
// V8 throws on boxed symbols
|
|
return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';
|
|
})), 'JSON', {
|
|
stringify: function stringify(it){
|
|
if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
|
|
var args = [it]
|
|
, i = 1
|
|
, replacer, $replacer;
|
|
while(arguments.length > i)args.push(arguments[i++]);
|
|
replacer = args[1];
|
|
if(typeof replacer == 'function')$replacer = replacer;
|
|
if($replacer || !isArray(replacer))replacer = function(key, value){
|
|
if($replacer)value = $replacer.call(this, key, value);
|
|
if(!isSymbol(value))return value;
|
|
};
|
|
args[1] = replacer;
|
|
return _stringify.apply($JSON, args);
|
|
}
|
|
});
|
|
|
|
// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
|
|
$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(32)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
|
|
// 19.4.3.5 Symbol.prototype[@@toStringTag]
|
|
setToStringTag($Symbol, 'Symbol');
|
|
// 20.2.1.9 Math[@@toStringTag]
|
|
setToStringTag(Math, 'Math', true);
|
|
// 24.3.3 JSON[@@toStringTag]
|
|
setToStringTag(global.JSON, 'JSON', true);
|
|
|
|
/***/ }),
|
|
/* 123 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var each = __webpack_require__(54)(0)
|
|
, redefine = __webpack_require__(33)
|
|
, meta = __webpack_require__(47)
|
|
, assign = __webpack_require__(283)
|
|
, weak = __webpack_require__(273)
|
|
, isObject = __webpack_require__(15)
|
|
, getWeak = meta.getWeak
|
|
, isExtensible = Object.isExtensible
|
|
, uncaughtFrozenStore = weak.ufstore
|
|
, tmp = {}
|
|
, InternalMap;
|
|
|
|
var wrapper = function(get){
|
|
return function WeakMap(){
|
|
return get(this, arguments.length > 0 ? arguments[0] : undefined);
|
|
};
|
|
};
|
|
|
|
var methods = {
|
|
// 23.3.3.3 WeakMap.prototype.get(key)
|
|
get: function get(key){
|
|
if(isObject(key)){
|
|
var data = getWeak(key);
|
|
if(data === true)return uncaughtFrozenStore(this).get(key);
|
|
return data ? data[this._i] : undefined;
|
|
}
|
|
},
|
|
// 23.3.3.5 WeakMap.prototype.set(key, value)
|
|
set: function set(key, value){
|
|
return weak.def(this, key, value);
|
|
}
|
|
};
|
|
|
|
// 23.3 WeakMap Objects
|
|
var $WeakMap = module.exports = __webpack_require__(55)('WeakMap', wrapper, methods, weak, true, true);
|
|
|
|
// IE11 WeakMap frozen keys fix
|
|
if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){
|
|
InternalMap = weak.getConstructor(wrapper);
|
|
assign(InternalMap.prototype, methods);
|
|
meta.NEED = true;
|
|
each(['delete', 'has', 'get', 'set'], function(key){
|
|
var proto = $WeakMap.prototype
|
|
, method = proto[key];
|
|
redefine(proto, key, function(a, b){
|
|
// store frozen objects on internal weakmap shim
|
|
if(isObject(a) && !isExtensible(a)){
|
|
if(!this._f)this._f = new InternalMap;
|
|
var result = this._f[key](a, b);
|
|
return key == 'set' ? this : result;
|
|
// store all the rest on native weakmap
|
|
} return method.call(this, a, b);
|
|
});
|
|
});
|
|
}
|
|
|
|
/***/ }),
|
|
/* 124 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var weak = __webpack_require__(273);
|
|
|
|
// 23.4 WeakSet Objects
|
|
__webpack_require__(55)('WeakSet', function(get){
|
|
return function WeakSet(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
|
|
}, {
|
|
// 23.4.3.1 WeakSet.prototype.add(value)
|
|
add: function add(value){
|
|
return weak.def(this, value, true);
|
|
}
|
|
}, weak, false, true);
|
|
|
|
/***/ }),
|
|
/* 125 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// https://github.com/tc39/Array.prototype.includes
|
|
var $export = __webpack_require__(3)
|
|
, $includes = __webpack_require__(270)(true);
|
|
|
|
$export($export.P, 'Array', {
|
|
includes: function includes(el /*, fromIndex = 0 */){
|
|
return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
|
|
}
|
|
});
|
|
|
|
__webpack_require__(38)('includes');
|
|
|
|
/***/ }),
|
|
/* 126 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// https://github.com/tc39/proposal-object-values-entries
|
|
var $export = __webpack_require__(3)
|
|
, $entries = __webpack_require__(285)(true);
|
|
|
|
$export($export.S, 'Object', {
|
|
entries: function entries(it){
|
|
return $entries(it);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 127 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// https://github.com/tc39/proposal-object-getownpropertydescriptors
|
|
var $export = __webpack_require__(3)
|
|
, ownKeys = __webpack_require__(406)
|
|
, toIObject = __webpack_require__(23)
|
|
, gOPD = __webpack_require__(81)
|
|
, createProperty = __webpack_require__(74);
|
|
|
|
$export($export.S, 'Object', {
|
|
getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object){
|
|
var O = toIObject(object)
|
|
, getDesc = gOPD.f
|
|
, keys = ownKeys(O)
|
|
, result = {}
|
|
, i = 0
|
|
, key;
|
|
while(keys.length > i)createProperty(result, key = keys[i++], getDesc(O, key));
|
|
return result;
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 128 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// https://github.com/tc39/proposal-object-values-entries
|
|
var $export = __webpack_require__(3)
|
|
, $values = __webpack_require__(285)(false);
|
|
|
|
$export($export.S, 'Object', {
|
|
values: function values(it){
|
|
return $values(it);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 129 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// https://github.com/tc39/proposal-string-pad-start-end
|
|
var $export = __webpack_require__(3)
|
|
, $pad = __webpack_require__(288);
|
|
|
|
$export($export.P, 'String', {
|
|
padEnd: function padEnd(maxLength /*, fillString = ' ' */){
|
|
return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 130 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// https://github.com/tc39/proposal-string-pad-start-end
|
|
var $export = __webpack_require__(3)
|
|
, $pad = __webpack_require__(288);
|
|
|
|
$export($export.P, 'String', {
|
|
padStart: function padStart(maxLength /*, fillString = ' ' */){
|
|
return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 131 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var $iterators = __webpack_require__(68)
|
|
, redefine = __webpack_require__(33)
|
|
, global = __webpack_require__(13)
|
|
, hide = __webpack_require__(32)
|
|
, Iterators = __webpack_require__(46)
|
|
, wks = __webpack_require__(10)
|
|
, ITERATOR = wks('iterator')
|
|
, TO_STRING_TAG = wks('toStringTag')
|
|
, ArrayValues = Iterators.Array;
|
|
|
|
for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){
|
|
var NAME = collections[i]
|
|
, Collection = global[NAME]
|
|
, proto = Collection && Collection.prototype
|
|
, key;
|
|
if(proto){
|
|
if(!proto[ITERATOR])hide(proto, ITERATOR, ArrayValues);
|
|
if(!proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME);
|
|
Iterators[NAME] = ArrayValues;
|
|
for(key in $iterators)if(!proto[key])redefine(proto, key, $iterators[key], true);
|
|
}
|
|
}
|
|
|
|
/***/ }),
|
|
/* 132 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var $export = __webpack_require__(3)
|
|
, $task = __webpack_require__(86);
|
|
$export($export.G + $export.B, {
|
|
setImmediate: $task.set,
|
|
clearImmediate: $task.clear
|
|
});
|
|
|
|
/***/ }),
|
|
/* 133 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 134 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 135 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 136 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 137 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 138 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 139 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 140 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 141 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 142 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 143 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 144 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 145 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 146 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 147 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 148 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 149 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 150 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 151 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 152 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 153 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 154 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 155 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 156 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 157 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 158 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 159 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 160 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 161 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 162 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 163 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 164 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 165 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 166 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 167 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 168 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 169 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 170 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 171 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 172 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 173 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 174 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 175 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 176 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 177 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 178 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 179 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 180 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 181 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 182 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 183 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 184 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 185 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 186 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 187 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 188 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 189 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 190 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 191 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 192 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 193 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 194 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 195 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 196 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 197 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 198 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 199 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 200 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 201 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 202 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 203 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 204 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 205 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 206 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 207 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 208 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 209 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 210 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 211 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 212 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 213 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 214 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 215 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 216 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 217 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 218 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 219 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 220 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 221 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 222 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 223 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 224 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 225 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 226 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 227 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 228 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 229 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 230 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 231 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 232 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 233 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 234 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 235 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 236 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 237 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 238 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 239 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 240 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 241 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 242 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 243 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 244 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 245 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 246 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 247 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 248 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* SheetClip - Spreadsheet Clipboard Parser
|
|
* version 0.2
|
|
*
|
|
* This tiny library transforms JavaScript arrays to strings that are pasteable by LibreOffice, OpenOffice,
|
|
* Google Docs and Microsoft Excel.
|
|
*
|
|
* Copyright 2012, Marcin Warpechowski
|
|
* Licensed under the MIT license.
|
|
* http://github.com/warpech/sheetclip/
|
|
*/
|
|
/*jslint white: true*/
|
|
(function (global) {
|
|
"use strict";
|
|
|
|
function countQuotes(str) {
|
|
return str.split('"').length - 1;
|
|
}
|
|
|
|
var SheetClip = {
|
|
/**
|
|
* Decode spreadsheet string into array
|
|
*
|
|
* @param {String} str
|
|
* @returns {Array}
|
|
*/
|
|
parse: function parse(str) {
|
|
var r,
|
|
rLen,
|
|
rows,
|
|
arr = [],
|
|
a = 0,
|
|
c,
|
|
cLen,
|
|
multiline,
|
|
last;
|
|
|
|
rows = str.split('\n');
|
|
|
|
if (rows.length > 1 && rows[rows.length - 1] === '') {
|
|
rows.pop();
|
|
}
|
|
for (r = 0, rLen = rows.length; r < rLen; r += 1) {
|
|
rows[r] = rows[r].split('\t');
|
|
|
|
for (c = 0, cLen = rows[r].length; c < cLen; c += 1) {
|
|
if (!arr[a]) {
|
|
arr[a] = [];
|
|
}
|
|
if (multiline && c === 0) {
|
|
last = arr[a].length - 1;
|
|
arr[a][last] = arr[a][last] + '\n' + rows[r][0];
|
|
|
|
if (multiline && countQuotes(rows[r][0]) & 1) {
|
|
//& 1 is a bitwise way of performing mod 2
|
|
multiline = false;
|
|
arr[a][last] = arr[a][last].substring(0, arr[a][last].length - 1).replace(/""/g, '"');
|
|
}
|
|
} else {
|
|
if (c === cLen - 1 && rows[r][c].indexOf('"') === 0 && countQuotes(rows[r][c]) & 1) {
|
|
arr[a].push(rows[r][c].substring(1).replace(/""/g, '"'));
|
|
multiline = true;
|
|
} else {
|
|
arr[a].push(rows[r][c].replace(/""/g, '"'));
|
|
multiline = false;
|
|
}
|
|
}
|
|
}
|
|
if (!multiline) {
|
|
a += 1;
|
|
}
|
|
}
|
|
|
|
return arr;
|
|
},
|
|
|
|
/**
|
|
* Encode array into valid spreadsheet string
|
|
*
|
|
* @param arr
|
|
* @returns {String}
|
|
*/
|
|
stringify: function stringify(arr) {
|
|
var r,
|
|
rLen,
|
|
c,
|
|
cLen,
|
|
str = '',
|
|
val;
|
|
|
|
for (r = 0, rLen = arr.length; r < rLen; r += 1) {
|
|
cLen = arr[r].length;
|
|
|
|
for (c = 0; c < cLen; c += 1) {
|
|
if (c > 0) {
|
|
str += '\t';
|
|
}
|
|
val = arr[r][c];
|
|
|
|
if (typeof val === 'string') {
|
|
if (val.indexOf('\n') > -1) {
|
|
str += '"' + val.replace(/"/g, '""') + '"';
|
|
} else {
|
|
str += val;
|
|
}
|
|
} else if (val === null || val === void 0) {
|
|
// void 0 resolves to undefined
|
|
str += '';
|
|
} else {
|
|
str += val;
|
|
}
|
|
}
|
|
|
|
if (r !== rLen - 1) {
|
|
str += '\n';
|
|
}
|
|
}
|
|
|
|
return str;
|
|
}
|
|
};
|
|
|
|
if (true) {
|
|
exports.parse = SheetClip.parse;
|
|
exports.stringify = SheetClip.stringify;
|
|
} else {
|
|
global.SheetClip = SheetClip;
|
|
}
|
|
})(window);
|
|
|
|
/***/ }),
|
|
/* 249 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
/*!
|
|
* https://github.com/Starcounter-Jack/JSON-Patch
|
|
* json-patch-duplex.js version: 0.5.7
|
|
* (c) 2013 Joachim Wester
|
|
* MIT license
|
|
*/
|
|
var __extends = undefined && undefined.__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 (typeof a === 'undefined' ? 'undefined' : _typeof(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 (_typeof(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 ((typeof obj === 'undefined' ? 'undefined' : _typeof(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 (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 ((typeof oldVal === 'undefined' ? 'undefined' : _typeof(oldVal)) == "object" && oldVal != null && (typeof newVal === 'undefined' ? 'undefined' : _typeof(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" || (typeof obj === 'undefined' ? 'undefined' : _typeof(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 ((typeof operation === 'undefined' ? 'undefined' : _typeof(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;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 250 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _coords = __webpack_require__(43);
|
|
|
|
var _coords2 = _interopRequireDefault(_coords);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
*
|
|
*/
|
|
var Border = function () {
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
* @param {Object} settings
|
|
*/
|
|
function Border(wotInstance, settings) {
|
|
_classCallCheck(this, Border);
|
|
|
|
if (!settings) {
|
|
return;
|
|
}
|
|
this.eventManager = new _eventManager2.default(wotInstance);
|
|
this.instance = wotInstance;
|
|
this.wot = wotInstance;
|
|
this.settings = settings;
|
|
this.mouseDown = false;
|
|
this.main = null;
|
|
|
|
this.top = null;
|
|
this.left = null;
|
|
this.bottom = null;
|
|
this.right = null;
|
|
|
|
this.topStyle = null;
|
|
this.leftStyle = null;
|
|
this.bottomStyle = null;
|
|
this.rightStyle = null;
|
|
|
|
this.cornerDefaultStyle = {
|
|
width: '5px',
|
|
height: '5px',
|
|
borderWidth: '2px',
|
|
borderStyle: 'solid',
|
|
borderColor: '#FFF'
|
|
};
|
|
this.corner = null;
|
|
this.cornerStyle = null;
|
|
|
|
this.createBorders(settings);
|
|
this.registerListeners();
|
|
}
|
|
|
|
/**
|
|
* Register all necessary events
|
|
*/
|
|
|
|
|
|
_createClass(Border, [{
|
|
key: 'registerListeners',
|
|
value: function registerListeners() {
|
|
var _this2 = this;
|
|
|
|
this.eventManager.addEventListener(document.body, 'mousedown', function () {
|
|
return _this2.onMouseDown();
|
|
});
|
|
this.eventManager.addEventListener(document.body, 'mouseup', function () {
|
|
return _this2.onMouseUp();
|
|
});
|
|
|
|
var _loop = function _loop(c, len) {
|
|
_this2.eventManager.addEventListener(_this2.main.childNodes[c], 'mouseenter', function (event) {
|
|
return _this2.onMouseEnter(event, _this2.main.childNodes[c]);
|
|
});
|
|
};
|
|
|
|
for (var c = 0, len = this.main.childNodes.length; c < len; c++) {
|
|
_loop(c, len);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mouse down listener
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseDown',
|
|
value: function onMouseDown() {
|
|
this.mouseDown = true;
|
|
}
|
|
|
|
/**
|
|
* Mouse up listener
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseUp',
|
|
value: function onMouseUp() {
|
|
this.mouseDown = false;
|
|
}
|
|
|
|
/**
|
|
* Mouse enter listener for fragment selection functionality.
|
|
*
|
|
* @private
|
|
* @param {Event} event Dom event
|
|
* @param {HTMLElement} parentElement Part of border element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseEnter',
|
|
value: function onMouseEnter(event, parentElement) {
|
|
if (!this.mouseDown || !this.wot.getSetting('hideBorderOnMouseDownOver')) {
|
|
return;
|
|
}
|
|
event.preventDefault();
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
|
|
var _this = this;
|
|
var bounds = parentElement.getBoundingClientRect();
|
|
// Hide border to prevents selection jumping when fragmentSelection is enabled.
|
|
parentElement.style.display = 'none';
|
|
|
|
function isOutside(event) {
|
|
if (event.clientY < Math.floor(bounds.top)) {
|
|
return true;
|
|
}
|
|
if (event.clientY > Math.ceil(bounds.top + bounds.height)) {
|
|
return true;
|
|
}
|
|
if (event.clientX < Math.floor(bounds.left)) {
|
|
return true;
|
|
}
|
|
if (event.clientX > Math.ceil(bounds.left + bounds.width)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function handler(event) {
|
|
if (isOutside(event)) {
|
|
_this.eventManager.removeEventListener(document.body, 'mousemove', handler);
|
|
parentElement.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
this.eventManager.addEventListener(document.body, 'mousemove', handler);
|
|
}
|
|
|
|
/**
|
|
* Create border elements
|
|
*
|
|
* @param {Object} settings
|
|
*/
|
|
|
|
}, {
|
|
key: 'createBorders',
|
|
value: function createBorders(settings) {
|
|
this.main = document.createElement('div');
|
|
|
|
var borderDivs = ['top', 'left', 'bottom', 'right', 'corner'];
|
|
var style = this.main.style;
|
|
style.position = 'absolute';
|
|
style.top = 0;
|
|
style.left = 0;
|
|
|
|
for (var i = 0; i < 5; i++) {
|
|
var position = borderDivs[i];
|
|
var div = document.createElement('div');
|
|
div.className = 'wtBorder ' + (this.settings.className || ''); // + borderDivs[i];
|
|
|
|
if (this.settings[position] && this.settings[position].hide) {
|
|
div.className += ' hidden';
|
|
}
|
|
style = div.style;
|
|
style.backgroundColor = this.settings[position] && this.settings[position].color ? this.settings[position].color : settings.border.color;
|
|
style.height = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px';
|
|
style.width = this.settings[position] && this.settings[position].width ? this.settings[position].width + 'px' : settings.border.width + 'px';
|
|
|
|
this.main.appendChild(div);
|
|
}
|
|
this.top = this.main.childNodes[0];
|
|
this.left = this.main.childNodes[1];
|
|
this.bottom = this.main.childNodes[2];
|
|
this.right = this.main.childNodes[3];
|
|
|
|
this.topStyle = this.top.style;
|
|
this.leftStyle = this.left.style;
|
|
this.bottomStyle = this.bottom.style;
|
|
this.rightStyle = this.right.style;
|
|
|
|
this.corner = this.main.childNodes[4];
|
|
this.corner.className += ' corner';
|
|
this.cornerStyle = this.corner.style;
|
|
this.cornerStyle.width = this.cornerDefaultStyle.width;
|
|
this.cornerStyle.height = this.cornerDefaultStyle.height;
|
|
this.cornerStyle.border = [this.cornerDefaultStyle.borderWidth, this.cornerDefaultStyle.borderStyle, this.cornerDefaultStyle.borderColor].join(' ');
|
|
|
|
if ((0, _browser.isMobileBrowser)()) {
|
|
this.createMultipleSelectorHandles();
|
|
}
|
|
this.disappear();
|
|
|
|
if (!this.wot.wtTable.bordersHolder) {
|
|
this.wot.wtTable.bordersHolder = document.createElement('div');
|
|
this.wot.wtTable.bordersHolder.className = 'htBorders';
|
|
this.wot.wtTable.spreader.appendChild(this.wot.wtTable.bordersHolder);
|
|
}
|
|
this.wot.wtTable.bordersHolder.insertBefore(this.main, this.wot.wtTable.bordersHolder.firstChild);
|
|
}
|
|
|
|
/**
|
|
* Create multiple selector handler for mobile devices
|
|
*/
|
|
|
|
}, {
|
|
key: 'createMultipleSelectorHandles',
|
|
value: function createMultipleSelectorHandles() {
|
|
this.selectionHandles = {
|
|
topLeft: document.createElement('DIV'),
|
|
topLeftHitArea: document.createElement('DIV'),
|
|
bottomRight: document.createElement('DIV'),
|
|
bottomRightHitArea: document.createElement('DIV')
|
|
};
|
|
var width = 10;
|
|
var hitAreaWidth = 40;
|
|
|
|
this.selectionHandles.topLeft.className = 'topLeftSelectionHandle';
|
|
this.selectionHandles.topLeftHitArea.className = 'topLeftSelectionHandle-HitArea';
|
|
this.selectionHandles.bottomRight.className = 'bottomRightSelectionHandle';
|
|
this.selectionHandles.bottomRightHitArea.className = 'bottomRightSelectionHandle-HitArea';
|
|
|
|
this.selectionHandles.styles = {
|
|
topLeft: this.selectionHandles.topLeft.style,
|
|
topLeftHitArea: this.selectionHandles.topLeftHitArea.style,
|
|
bottomRight: this.selectionHandles.bottomRight.style,
|
|
bottomRightHitArea: this.selectionHandles.bottomRightHitArea.style
|
|
};
|
|
|
|
var hitAreaStyle = {
|
|
position: 'absolute',
|
|
height: hitAreaWidth + 'px',
|
|
width: hitAreaWidth + 'px',
|
|
'border-radius': parseInt(hitAreaWidth / 1.5, 10) + 'px'
|
|
};
|
|
|
|
for (var prop in hitAreaStyle) {
|
|
if ((0, _object.hasOwnProperty)(hitAreaStyle, prop)) {
|
|
this.selectionHandles.styles.bottomRightHitArea[prop] = hitAreaStyle[prop];
|
|
this.selectionHandles.styles.topLeftHitArea[prop] = hitAreaStyle[prop];
|
|
}
|
|
}
|
|
|
|
var handleStyle = {
|
|
position: 'absolute',
|
|
height: width + 'px',
|
|
width: width + 'px',
|
|
'border-radius': parseInt(width / 1.5, 10) + 'px',
|
|
background: '#F5F5FF',
|
|
border: '1px solid #4285c8'
|
|
};
|
|
|
|
for (var _prop in handleStyle) {
|
|
if ((0, _object.hasOwnProperty)(handleStyle, _prop)) {
|
|
this.selectionHandles.styles.bottomRight[_prop] = handleStyle[_prop];
|
|
this.selectionHandles.styles.topLeft[_prop] = handleStyle[_prop];
|
|
}
|
|
}
|
|
this.main.appendChild(this.selectionHandles.topLeft);
|
|
this.main.appendChild(this.selectionHandles.bottomRight);
|
|
this.main.appendChild(this.selectionHandles.topLeftHitArea);
|
|
this.main.appendChild(this.selectionHandles.bottomRightHitArea);
|
|
}
|
|
}, {
|
|
key: 'isPartRange',
|
|
value: function isPartRange(row, col) {
|
|
if (this.wot.selections.area.cellRange) {
|
|
if (row != this.wot.selections.area.cellRange.to.row || col != this.wot.selections.area.cellRange.to.col) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}, {
|
|
key: 'updateMultipleSelectionHandlesPosition',
|
|
value: function updateMultipleSelectionHandlesPosition(row, col, top, left, width, height) {
|
|
var handleWidth = parseInt(this.selectionHandles.styles.topLeft.width, 10);
|
|
var hitAreaWidth = parseInt(this.selectionHandles.styles.topLeftHitArea.width, 10);
|
|
|
|
this.selectionHandles.styles.topLeft.top = parseInt(top - handleWidth, 10) + 'px';
|
|
this.selectionHandles.styles.topLeft.left = parseInt(left - handleWidth, 10) + 'px';
|
|
|
|
this.selectionHandles.styles.topLeftHitArea.top = parseInt(top - hitAreaWidth / 4 * 3, 10) + 'px';
|
|
this.selectionHandles.styles.topLeftHitArea.left = parseInt(left - hitAreaWidth / 4 * 3, 10) + 'px';
|
|
|
|
this.selectionHandles.styles.bottomRight.top = parseInt(top + height, 10) + 'px';
|
|
this.selectionHandles.styles.bottomRight.left = parseInt(left + width, 10) + 'px';
|
|
|
|
this.selectionHandles.styles.bottomRightHitArea.top = parseInt(top + height - hitAreaWidth / 4, 10) + 'px';
|
|
this.selectionHandles.styles.bottomRightHitArea.left = parseInt(left + width - hitAreaWidth / 4, 10) + 'px';
|
|
|
|
if (this.settings.border.multipleSelectionHandlesVisible && this.settings.border.multipleSelectionHandlesVisible()) {
|
|
this.selectionHandles.styles.topLeft.display = 'block';
|
|
this.selectionHandles.styles.topLeftHitArea.display = 'block';
|
|
|
|
if (this.isPartRange(row, col)) {
|
|
this.selectionHandles.styles.bottomRight.display = 'none';
|
|
this.selectionHandles.styles.bottomRightHitArea.display = 'none';
|
|
} else {
|
|
this.selectionHandles.styles.bottomRight.display = 'block';
|
|
this.selectionHandles.styles.bottomRightHitArea.display = 'block';
|
|
}
|
|
} else {
|
|
this.selectionHandles.styles.topLeft.display = 'none';
|
|
this.selectionHandles.styles.bottomRight.display = 'none';
|
|
this.selectionHandles.styles.topLeftHitArea.display = 'none';
|
|
this.selectionHandles.styles.bottomRightHitArea.display = 'none';
|
|
}
|
|
|
|
if (row == this.wot.wtSettings.getSetting('fixedRowsTop') || col == this.wot.wtSettings.getSetting('fixedColumnsLeft')) {
|
|
this.selectionHandles.styles.topLeft.zIndex = '9999';
|
|
this.selectionHandles.styles.topLeftHitArea.zIndex = '9999';
|
|
} else {
|
|
this.selectionHandles.styles.topLeft.zIndex = '';
|
|
this.selectionHandles.styles.topLeftHitArea.zIndex = '';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show border around one or many cells
|
|
*
|
|
* @param {Array} corners
|
|
*/
|
|
|
|
}, {
|
|
key: 'appear',
|
|
value: function appear(corners) {
|
|
if (this.disabled) {
|
|
return;
|
|
}
|
|
var isMultiple, fromTD, toTD, fromOffset, toOffset, containerOffset, top, minTop, left, minLeft, height, width, fromRow, fromColumn, toRow, toColumn, trimmingContainer, cornerOverlappingContainer, ilen;
|
|
|
|
ilen = this.wot.wtTable.getRenderedRowsCount();
|
|
|
|
for (var i = 0; i < ilen; i++) {
|
|
var s = this.wot.wtTable.rowFilter.renderedToSource(i);
|
|
|
|
if (s >= corners[0] && s <= corners[2]) {
|
|
fromRow = s;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (var _i = ilen - 1; _i >= 0; _i--) {
|
|
var _s = this.wot.wtTable.rowFilter.renderedToSource(_i);
|
|
|
|
if (_s >= corners[0] && _s <= corners[2]) {
|
|
toRow = _s;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ilen = this.wot.wtTable.getRenderedColumnsCount();
|
|
|
|
for (var _i2 = 0; _i2 < ilen; _i2++) {
|
|
var _s2 = this.wot.wtTable.columnFilter.renderedToSource(_i2);
|
|
|
|
if (_s2 >= corners[1] && _s2 <= corners[3]) {
|
|
fromColumn = _s2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (var _i3 = ilen - 1; _i3 >= 0; _i3--) {
|
|
var _s3 = this.wot.wtTable.columnFilter.renderedToSource(_i3);
|
|
|
|
if (_s3 >= corners[1] && _s3 <= corners[3]) {
|
|
toColumn = _s3;
|
|
break;
|
|
}
|
|
}
|
|
if (fromRow === void 0 || fromColumn === void 0) {
|
|
this.disappear();
|
|
|
|
return;
|
|
}
|
|
isMultiple = fromRow !== toRow || fromColumn !== toColumn;
|
|
fromTD = this.wot.wtTable.getCell(new _coords2.default(fromRow, fromColumn));
|
|
toTD = isMultiple ? this.wot.wtTable.getCell(new _coords2.default(toRow, toColumn)) : fromTD;
|
|
fromOffset = (0, _element.offset)(fromTD);
|
|
toOffset = isMultiple ? (0, _element.offset)(toTD) : fromOffset;
|
|
containerOffset = (0, _element.offset)(this.wot.wtTable.TABLE);
|
|
|
|
minTop = fromOffset.top;
|
|
height = toOffset.top + (0, _element.outerHeight)(toTD) - minTop;
|
|
minLeft = fromOffset.left;
|
|
width = toOffset.left + (0, _element.outerWidth)(toTD) - minLeft;
|
|
|
|
top = minTop - containerOffset.top - 1;
|
|
left = minLeft - containerOffset.left - 1;
|
|
var style = (0, _element.getComputedStyle)(fromTD);
|
|
|
|
if (parseInt(style.borderTopWidth, 10) > 0) {
|
|
top += 1;
|
|
height = height > 0 ? height - 1 : 0;
|
|
}
|
|
if (parseInt(style.borderLeftWidth, 10) > 0) {
|
|
left += 1;
|
|
width = width > 0 ? width - 1 : 0;
|
|
}
|
|
|
|
this.topStyle.top = top + 'px';
|
|
this.topStyle.left = left + 'px';
|
|
this.topStyle.width = width + 'px';
|
|
this.topStyle.display = 'block';
|
|
|
|
this.leftStyle.top = top + 'px';
|
|
this.leftStyle.left = left + 'px';
|
|
this.leftStyle.height = height + 'px';
|
|
this.leftStyle.display = 'block';
|
|
|
|
var delta = Math.floor(this.settings.border.width / 2);
|
|
|
|
this.bottomStyle.top = top + height - delta + 'px';
|
|
this.bottomStyle.left = left + 'px';
|
|
this.bottomStyle.width = width + 'px';
|
|
this.bottomStyle.display = 'block';
|
|
|
|
this.rightStyle.top = top + 'px';
|
|
this.rightStyle.left = left + width - delta + 'px';
|
|
this.rightStyle.height = height + 1 + 'px';
|
|
this.rightStyle.display = 'block';
|
|
|
|
if ((0, _browser.isMobileBrowser)() || !this.hasSetting(this.settings.border.cornerVisible) || this.isPartRange(toRow, toColumn)) {
|
|
this.cornerStyle.display = 'none';
|
|
} else {
|
|
this.cornerStyle.top = top + height - 4 + 'px';
|
|
this.cornerStyle.left = left + width - 4 + 'px';
|
|
this.cornerStyle.borderRightWidth = this.cornerDefaultStyle.borderWidth;
|
|
this.cornerStyle.width = this.cornerDefaultStyle.width;
|
|
|
|
// Hide the fill handle, so the possible further adjustments won't force unneeded scrollbars.
|
|
this.cornerStyle.display = 'none';
|
|
|
|
trimmingContainer = (0, _element.getTrimmingContainer)(this.wot.wtTable.TABLE);
|
|
|
|
if (toColumn === this.wot.getSetting('totalColumns') - 1) {
|
|
cornerOverlappingContainer = toTD.offsetLeft + (0, _element.outerWidth)(toTD) + parseInt(this.cornerDefaultStyle.width, 10) / 2 >= (0, _element.innerWidth)(trimmingContainer);
|
|
|
|
if (cornerOverlappingContainer) {
|
|
this.cornerStyle.left = Math.floor(left + width - 3 - parseInt(this.cornerDefaultStyle.width, 10) / 2) + 'px';
|
|
this.cornerStyle.borderRightWidth = 0;
|
|
}
|
|
}
|
|
|
|
if (toRow === this.wot.getSetting('totalRows') - 1) {
|
|
cornerOverlappingContainer = toTD.offsetTop + (0, _element.outerHeight)(toTD) + parseInt(this.cornerDefaultStyle.height, 10) / 2 >= (0, _element.innerHeight)(trimmingContainer);
|
|
|
|
if (cornerOverlappingContainer) {
|
|
this.cornerStyle.top = Math.floor(top + height - 3 - parseInt(this.cornerDefaultStyle.height, 10) / 2) + 'px';
|
|
this.cornerStyle.borderBottomWidth = 0;
|
|
}
|
|
}
|
|
|
|
this.cornerStyle.display = 'block';
|
|
}
|
|
|
|
if ((0, _browser.isMobileBrowser)()) {
|
|
this.updateMultipleSelectionHandlesPosition(fromRow, fromColumn, top, left, width, height);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hide border
|
|
*/
|
|
|
|
}, {
|
|
key: 'disappear',
|
|
value: function disappear() {
|
|
this.topStyle.display = 'none';
|
|
this.leftStyle.display = 'none';
|
|
this.bottomStyle.display = 'none';
|
|
this.rightStyle.display = 'none';
|
|
this.cornerStyle.display = 'none';
|
|
|
|
if ((0, _browser.isMobileBrowser)()) {
|
|
this.selectionHandles.styles.topLeft.display = 'none';
|
|
this.selectionHandles.styles.bottomRight.display = 'none';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Function} setting
|
|
* @returns {*}
|
|
*/
|
|
|
|
}, {
|
|
key: 'hasSetting',
|
|
value: function hasSetting(setting) {
|
|
if (typeof setting === 'function') {
|
|
return setting();
|
|
}
|
|
|
|
return !!setting;
|
|
}
|
|
}]);
|
|
|
|
return Border;
|
|
}();
|
|
|
|
exports.default = Border;
|
|
|
|
/***/ }),
|
|
/* 251 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var privatePool = new WeakMap();
|
|
|
|
/**
|
|
* Calculates indexes of columns to render OR columns that are visible.
|
|
* To redo the calculation, you need to create a new calculator.
|
|
*
|
|
* @class ViewportColumnsCalculator
|
|
*/
|
|
|
|
var ViewportColumnsCalculator = function () {
|
|
_createClass(ViewportColumnsCalculator, null, [{
|
|
key: 'DEFAULT_WIDTH',
|
|
|
|
/**
|
|
* Default column width
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
get: function get() {
|
|
return 50;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} viewportWidth Width of the viewport
|
|
* @param {Number} scrollOffset Current horizontal scroll position of the viewport
|
|
* @param {Number} totalColumns Total number of rows
|
|
* @param {Function} columnWidthFn Function that returns the width of the column at a given index (in px)
|
|
* @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin)
|
|
* @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport
|
|
* @param {Boolean} stretchH
|
|
* @param {Function} [stretchingColumnWidthFn] Function that returns the new width of the stretched column.
|
|
*/
|
|
|
|
}]);
|
|
|
|
function ViewportColumnsCalculator(viewportWidth, scrollOffset, totalColumns, columnWidthFn, overrideFn, onlyFullyVisible, stretchH) {
|
|
var stretchingColumnWidthFn = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : function (width) {
|
|
return width;
|
|
};
|
|
|
|
_classCallCheck(this, ViewportColumnsCalculator);
|
|
|
|
privatePool.set(this, {
|
|
viewportWidth: viewportWidth,
|
|
scrollOffset: scrollOffset,
|
|
totalColumns: totalColumns,
|
|
columnWidthFn: columnWidthFn,
|
|
overrideFn: overrideFn,
|
|
onlyFullyVisible: onlyFullyVisible,
|
|
stretchingColumnWidthFn: stretchingColumnWidthFn
|
|
});
|
|
|
|
/**
|
|
* Number of rendered/visible columns
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
this.count = 0;
|
|
|
|
/**
|
|
* Index of the first rendered/visible column (can be overwritten using overrideFn)
|
|
*
|
|
* @type {Number|null}
|
|
*/
|
|
this.startColumn = null;
|
|
|
|
/**
|
|
* Index of the last rendered/visible column (can be overwritten using overrideFn)
|
|
*
|
|
* @type {null}
|
|
*/
|
|
this.endColumn = null;
|
|
|
|
/**
|
|
* Position of the first rendered/visible column (in px)
|
|
*
|
|
* @type {Number|null}
|
|
*/
|
|
this.startPosition = null;
|
|
|
|
this.stretchAllRatio = 0;
|
|
this.stretchLastWidth = 0;
|
|
this.stretch = stretchH;
|
|
this.totalTargetWidth = 0;
|
|
this.needVerifyLastColumnWidth = true;
|
|
this.stretchAllColumnsWidth = [];
|
|
|
|
this.calculate();
|
|
}
|
|
|
|
/**
|
|
* Calculates viewport
|
|
*/
|
|
|
|
|
|
_createClass(ViewportColumnsCalculator, [{
|
|
key: 'calculate',
|
|
value: function calculate() {
|
|
var sum = 0;
|
|
var needReverse = true;
|
|
var startPositions = [];
|
|
var columnWidth = void 0;
|
|
|
|
var priv = privatePool.get(this);
|
|
var onlyFullyVisible = priv.onlyFullyVisible;
|
|
var overrideFn = priv.overrideFn;
|
|
var scrollOffset = priv.scrollOffset;
|
|
var totalColumns = priv.totalColumns;
|
|
var viewportWidth = priv.viewportWidth;
|
|
|
|
for (var i = 0; i < totalColumns; i++) {
|
|
columnWidth = this._getColumnWidth(i);
|
|
|
|
if (sum <= scrollOffset && !onlyFullyVisible) {
|
|
this.startColumn = i;
|
|
}
|
|
|
|
// +1 pixel for row header width compensation for horizontal scroll > 0
|
|
var compensatedViewportWidth = scrollOffset > 0 ? viewportWidth + 1 : viewportWidth;
|
|
|
|
if (sum >= scrollOffset && sum + columnWidth <= scrollOffset + compensatedViewportWidth) {
|
|
if (this.startColumn == null) {
|
|
this.startColumn = i;
|
|
}
|
|
this.endColumn = i;
|
|
}
|
|
startPositions.push(sum);
|
|
sum += columnWidth;
|
|
|
|
if (!onlyFullyVisible) {
|
|
this.endColumn = i;
|
|
}
|
|
if (sum >= scrollOffset + viewportWidth) {
|
|
needReverse = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (this.endColumn === totalColumns - 1 && needReverse) {
|
|
this.startColumn = this.endColumn;
|
|
|
|
while (this.startColumn > 0) {
|
|
var viewportSum = startPositions[this.endColumn] + columnWidth - startPositions[this.startColumn - 1];
|
|
|
|
if (viewportSum <= viewportWidth || !onlyFullyVisible) {
|
|
this.startColumn--;
|
|
}
|
|
if (viewportSum > viewportWidth) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.startColumn !== null && overrideFn) {
|
|
overrideFn(this);
|
|
}
|
|
this.startPosition = startPositions[this.startColumn];
|
|
|
|
if (this.startPosition == void 0) {
|
|
this.startPosition = null;
|
|
}
|
|
if (this.startColumn !== null) {
|
|
this.count = this.endColumn - this.startColumn + 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Recalculate columns stretching.
|
|
*
|
|
* @param {Number} totalWidth
|
|
*/
|
|
|
|
}, {
|
|
key: 'refreshStretching',
|
|
value: function refreshStretching(totalWidth) {
|
|
if (this.stretch === 'none') {
|
|
return;
|
|
}
|
|
this.totalTargetWidth = totalWidth;
|
|
|
|
var priv = privatePool.get(this);
|
|
var totalColumns = priv.totalColumns;
|
|
var sumAll = 0;
|
|
|
|
for (var i = 0; i < totalColumns; i++) {
|
|
var columnWidth = this._getColumnWidth(i);
|
|
var permanentColumnWidth = priv.stretchingColumnWidthFn(void 0, i);
|
|
|
|
if (typeof permanentColumnWidth === 'number') {
|
|
totalWidth -= permanentColumnWidth;
|
|
} else {
|
|
sumAll += columnWidth;
|
|
}
|
|
}
|
|
var remainingSize = totalWidth - sumAll;
|
|
|
|
if (this.stretch === 'all' && remainingSize > 0) {
|
|
this.stretchAllRatio = totalWidth / sumAll;
|
|
this.stretchAllColumnsWidth = [];
|
|
this.needVerifyLastColumnWidth = true;
|
|
} else if (this.stretch === 'last' && totalWidth !== Infinity) {
|
|
var _columnWidth = this._getColumnWidth(totalColumns - 1);
|
|
var lastColumnWidth = remainingSize + _columnWidth;
|
|
|
|
this.stretchLastWidth = lastColumnWidth >= 0 ? lastColumnWidth : _columnWidth;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get stretched column width based on stretchH (all or last) setting passed in handsontable instance.
|
|
*
|
|
* @param {Number} column
|
|
* @param {Number} baseWidth
|
|
* @returns {Number|null}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getStretchedColumnWidth',
|
|
value: function getStretchedColumnWidth(column, baseWidth) {
|
|
var result = null;
|
|
|
|
if (this.stretch === 'all' && this.stretchAllRatio !== 0) {
|
|
result = this._getStretchedAllColumnWidth(column, baseWidth);
|
|
} else if (this.stretch === 'last' && this.stretchLastWidth !== 0) {
|
|
result = this._getStretchedLastColumnWidth(column);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} column
|
|
* @param {Number} baseWidth
|
|
* @returns {Number}
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: '_getStretchedAllColumnWidth',
|
|
value: function _getStretchedAllColumnWidth(column, baseWidth) {
|
|
var sumRatioWidth = 0;
|
|
var priv = privatePool.get(this);
|
|
var totalColumns = priv.totalColumns;
|
|
|
|
if (!this.stretchAllColumnsWidth[column]) {
|
|
var stretchedWidth = Math.round(baseWidth * this.stretchAllRatio);
|
|
var newStretchedWidth = priv.stretchingColumnWidthFn(stretchedWidth, column);
|
|
|
|
if (newStretchedWidth === void 0) {
|
|
this.stretchAllColumnsWidth[column] = stretchedWidth;
|
|
} else {
|
|
this.stretchAllColumnsWidth[column] = isNaN(newStretchedWidth) ? this._getColumnWidth(column) : newStretchedWidth;
|
|
}
|
|
}
|
|
|
|
if (this.stretchAllColumnsWidth.length === totalColumns && this.needVerifyLastColumnWidth) {
|
|
this.needVerifyLastColumnWidth = false;
|
|
|
|
for (var i = 0; i < this.stretchAllColumnsWidth.length; i++) {
|
|
sumRatioWidth += this.stretchAllColumnsWidth[i];
|
|
}
|
|
if (sumRatioWidth !== this.totalTargetWidth) {
|
|
this.stretchAllColumnsWidth[this.stretchAllColumnsWidth.length - 1] += this.totalTargetWidth - sumRatioWidth;
|
|
}
|
|
}
|
|
|
|
return this.stretchAllColumnsWidth[column];
|
|
}
|
|
|
|
/**
|
|
* @param {Number} column
|
|
* @returns {Number|null}
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: '_getStretchedLastColumnWidth',
|
|
value: function _getStretchedLastColumnWidth(column) {
|
|
var priv = privatePool.get(this);
|
|
var totalColumns = priv.totalColumns;
|
|
|
|
if (column === totalColumns - 1) {
|
|
return this.stretchLastWidth;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} column Column index.
|
|
* @returns {Number}
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: '_getColumnWidth',
|
|
value: function _getColumnWidth(column) {
|
|
var width = privatePool.get(this).columnWidthFn(column);
|
|
|
|
if (width === void 0) {
|
|
width = ViewportColumnsCalculator.DEFAULT_WIDTH;
|
|
}
|
|
|
|
return width;
|
|
}
|
|
}]);
|
|
|
|
return ViewportColumnsCalculator;
|
|
}();
|
|
|
|
exports.default = ViewportColumnsCalculator;
|
|
|
|
/***/ }),
|
|
/* 252 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var privatePool = new WeakMap();
|
|
|
|
/**
|
|
* Calculates indexes of rows to render OR rows that are visible.
|
|
* To redo the calculation, you need to create a new calculator.
|
|
*
|
|
* @class ViewportRowsCalculator
|
|
*/
|
|
|
|
var ViewportRowsCalculator = function () {
|
|
_createClass(ViewportRowsCalculator, null, [{
|
|
key: "DEFAULT_HEIGHT",
|
|
|
|
/**
|
|
* Default row height
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
get: function get() {
|
|
return 23;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} viewportHeight Height of the viewport
|
|
* @param {Number} scrollOffset Current vertical scroll position of the viewport
|
|
* @param {Number} totalRows Total number of rows
|
|
* @param {Function} rowHeightFn Function that returns the height of the row at a given index (in px)
|
|
* @param {Function} overrideFn Function that changes calculated this.startRow, this.endRow (used by MergeCells plugin)
|
|
* @param {Boolean} onlyFullyVisible if `true`, only startRow and endRow will be indexes of rows that are fully in viewport
|
|
* @param {Number} horizontalScrollbarHeight
|
|
*/
|
|
|
|
}]);
|
|
|
|
function ViewportRowsCalculator(viewportHeight, scrollOffset, totalRows, rowHeightFn, overrideFn, onlyFullyVisible, horizontalScrollbarHeight) {
|
|
_classCallCheck(this, ViewportRowsCalculator);
|
|
|
|
privatePool.set(this, {
|
|
viewportHeight: viewportHeight,
|
|
scrollOffset: scrollOffset,
|
|
totalRows: totalRows,
|
|
rowHeightFn: rowHeightFn,
|
|
overrideFn: overrideFn,
|
|
onlyFullyVisible: onlyFullyVisible,
|
|
horizontalScrollbarHeight: horizontalScrollbarHeight
|
|
});
|
|
|
|
/**
|
|
* Number of rendered/visible rows
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
this.count = 0;
|
|
|
|
/**
|
|
* Index of the first rendered/visible row (can be overwritten using overrideFn)
|
|
*
|
|
* @type {Number|null}
|
|
*/
|
|
this.startRow = null;
|
|
|
|
/**
|
|
* Index of the last rendered/visible row (can be overwritten using overrideFn)
|
|
*
|
|
* @type {null}
|
|
*/
|
|
this.endRow = null;
|
|
|
|
/**
|
|
* Position of the first rendered/visible row (in px)
|
|
*
|
|
* @type {Number|null}
|
|
*/
|
|
this.startPosition = null;
|
|
|
|
this.calculate();
|
|
}
|
|
|
|
/**
|
|
* Calculates viewport
|
|
*/
|
|
|
|
|
|
_createClass(ViewportRowsCalculator, [{
|
|
key: "calculate",
|
|
value: function calculate() {
|
|
var sum = 0;
|
|
var needReverse = true;
|
|
var startPositions = [];
|
|
|
|
var priv = privatePool.get(this);
|
|
var onlyFullyVisible = priv.onlyFullyVisible;
|
|
var overrideFn = priv.overrideFn;
|
|
var rowHeightFn = priv.rowHeightFn;
|
|
var scrollOffset = priv.scrollOffset;
|
|
var totalRows = priv.totalRows;
|
|
var viewportHeight = priv.viewportHeight;
|
|
var horizontalScrollbarHeight = priv.horizontalScrollbarHeight || 0;
|
|
var rowHeight = void 0;
|
|
|
|
// Calculate the number (start and end index) of rows needed
|
|
for (var i = 0; i < totalRows; i++) {
|
|
rowHeight = rowHeightFn(i);
|
|
|
|
if (rowHeight === undefined) {
|
|
rowHeight = ViewportRowsCalculator.DEFAULT_HEIGHT;
|
|
}
|
|
if (sum <= scrollOffset && !onlyFullyVisible) {
|
|
this.startRow = i;
|
|
}
|
|
|
|
// the row is within the "visible range"
|
|
if (sum >= scrollOffset && sum + rowHeight <= scrollOffset + viewportHeight - horizontalScrollbarHeight) {
|
|
if (this.startRow === null) {
|
|
this.startRow = i;
|
|
}
|
|
this.endRow = i;
|
|
}
|
|
startPositions.push(sum);
|
|
sum += rowHeight;
|
|
|
|
if (!onlyFullyVisible) {
|
|
this.endRow = i;
|
|
}
|
|
if (sum >= scrollOffset + viewportHeight - horizontalScrollbarHeight) {
|
|
needReverse = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If the estimation has reached the last row and there is still some space available in the viewport,
|
|
// we need to render in reverse in order to fill the whole viewport with rows
|
|
if (this.endRow === totalRows - 1 && needReverse) {
|
|
this.startRow = this.endRow;
|
|
|
|
while (this.startRow > 0) {
|
|
// rowHeight is the height of the last row
|
|
var viewportSum = startPositions[this.endRow] + rowHeight - startPositions[this.startRow - 1];
|
|
|
|
if (viewportSum <= viewportHeight - horizontalScrollbarHeight || !onlyFullyVisible) {
|
|
this.startRow--;
|
|
}
|
|
if (viewportSum >= viewportHeight - horizontalScrollbarHeight) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.startRow !== null && overrideFn) {
|
|
overrideFn(this);
|
|
}
|
|
this.startPosition = startPositions[this.startRow];
|
|
|
|
if (this.startPosition == void 0) {
|
|
this.startPosition = null;
|
|
}
|
|
if (this.startRow !== null) {
|
|
this.count = this.endRow - this.startRow + 1;
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return ViewportRowsCalculator;
|
|
}();
|
|
|
|
exports.default = ViewportRowsCalculator;
|
|
|
|
/***/ }),
|
|
/* 253 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
var _event = __webpack_require__(254);
|
|
|
|
var _event2 = _interopRequireDefault(_event);
|
|
|
|
var _overlays = __webpack_require__(257);
|
|
|
|
var _overlays2 = _interopRequireDefault(_overlays);
|
|
|
|
var _scroll = __webpack_require__(258);
|
|
|
|
var _scroll2 = _interopRequireDefault(_scroll);
|
|
|
|
var _settings = __webpack_require__(259);
|
|
|
|
var _settings2 = _interopRequireDefault(_settings);
|
|
|
|
var _table = __webpack_require__(260);
|
|
|
|
var _table2 = _interopRequireDefault(_table);
|
|
|
|
var _viewport = __webpack_require__(262);
|
|
|
|
var _viewport2 = _interopRequireDefault(_viewport);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Walkontable
|
|
*/
|
|
var Walkontable = function () {
|
|
/**
|
|
* @param {Object} settings
|
|
*/
|
|
function Walkontable(settings) {
|
|
_classCallCheck(this, Walkontable);
|
|
|
|
var originalHeaders = [];
|
|
|
|
// this is the namespace for global events
|
|
this.guid = 'wt_' + (0, _string.randomString)();
|
|
|
|
// bootstrap from settings
|
|
if (settings.cloneSource) {
|
|
this.cloneSource = settings.cloneSource;
|
|
this.cloneOverlay = settings.cloneOverlay;
|
|
this.wtSettings = settings.cloneSource.wtSettings;
|
|
this.wtTable = new _table2.default(this, settings.table, settings.wtRootElement);
|
|
this.wtScroll = new _scroll2.default(this);
|
|
this.wtViewport = settings.cloneSource.wtViewport;
|
|
this.wtEvent = new _event2.default(this);
|
|
this.selections = this.cloneSource.selections;
|
|
} else {
|
|
this.wtSettings = new _settings2.default(this, settings);
|
|
this.wtTable = new _table2.default(this, settings.table);
|
|
this.wtScroll = new _scroll2.default(this);
|
|
this.wtViewport = new _viewport2.default(this);
|
|
this.wtEvent = new _event2.default(this);
|
|
this.selections = this.getSetting('selections');
|
|
this.wtOverlays = new _overlays2.default(this);
|
|
this.exportSettingsAsClassNames();
|
|
}
|
|
|
|
// find original headers
|
|
if (this.wtTable.THEAD.childNodes.length && this.wtTable.THEAD.childNodes[0].childNodes.length) {
|
|
for (var c = 0, clen = this.wtTable.THEAD.childNodes[0].childNodes.length; c < clen; c++) {
|
|
originalHeaders.push(this.wtTable.THEAD.childNodes[0].childNodes[c].innerHTML);
|
|
}
|
|
if (!this.getSetting('columnHeaders').length) {
|
|
this.update('columnHeaders', [function (column, TH) {
|
|
(0, _element.fastInnerText)(TH, originalHeaders[column]);
|
|
}]);
|
|
}
|
|
}
|
|
this.drawn = false;
|
|
this.drawInterrupted = false;
|
|
}
|
|
|
|
/**
|
|
* Force rerender of Walkontable
|
|
*
|
|
* @param {Boolean} [fastDraw=false] When `true`, try to refresh only the positions of borders without rerendering
|
|
* the data. It will only work if Table.draw() does not force
|
|
* rendering anyway
|
|
* @returns {Walkontable}
|
|
*/
|
|
|
|
|
|
_createClass(Walkontable, [{
|
|
key: 'draw',
|
|
value: function draw() {
|
|
var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
this.drawInterrupted = false;
|
|
|
|
if (!fastDraw && !(0, _element.isVisible)(this.wtTable.TABLE)) {
|
|
// draw interrupted because TABLE is not visible
|
|
this.drawInterrupted = true;
|
|
} else {
|
|
this.wtTable.draw(fastDraw);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Returns the TD at coords. If topmost is set to true, returns TD from the topmost overlay layer,
|
|
* if not set or set to false, returns TD from the master table.
|
|
*
|
|
* @param {CellCoords} coords
|
|
* @param {Boolean} [topmost=false]
|
|
* @returns {Object}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCell',
|
|
value: function getCell(coords) {
|
|
var topmost = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
|
|
if (!topmost) {
|
|
return this.wtTable.getCell(coords);
|
|
}
|
|
|
|
var totalRows = this.wtSettings.getSetting('totalRows');
|
|
var fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop');
|
|
var fixedRowsBottom = this.wtSettings.getSetting('fixedRowsBottom');
|
|
var fixedColumns = this.wtSettings.getSetting('fixedColumnsLeft');
|
|
|
|
if (coords.row < fixedRowsTop && coords.col < fixedColumns) {
|
|
return this.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell(coords);
|
|
} else if (coords.row < fixedRowsTop) {
|
|
return this.wtOverlays.topOverlay.clone.wtTable.getCell(coords);
|
|
} else if (coords.col < fixedColumns && coords.row >= totalRows - fixedRowsBottom) {
|
|
if (this.wtOverlays.bottomLeftCornerOverlay && this.wtOverlays.bottomLeftCornerOverlay.clone) {
|
|
return this.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.getCell(coords);
|
|
}
|
|
} else if (coords.col < fixedColumns) {
|
|
return this.wtOverlays.leftOverlay.clone.wtTable.getCell(coords);
|
|
} else if (coords.row < totalRows && coords.row > totalRows - fixedRowsBottom) {
|
|
if (this.wtOverlays.bottomOverlay && this.wtOverlays.bottomOverlay.clone) {
|
|
return this.wtOverlays.bottomOverlay.clone.wtTable.getCell(coords);
|
|
}
|
|
}
|
|
|
|
return this.wtTable.getCell(coords);
|
|
}
|
|
|
|
/**
|
|
* @param {Object} settings
|
|
* @param {*} value
|
|
* @returns {Walkontable}
|
|
*/
|
|
|
|
}, {
|
|
key: 'update',
|
|
value: function update(settings, value) {
|
|
return this.wtSettings.update(settings, value);
|
|
}
|
|
|
|
/**
|
|
* Scroll the viewport to a row at the given index in the data source
|
|
*
|
|
* @param {Number} row
|
|
* @returns {Walkontable}
|
|
*/
|
|
|
|
}, {
|
|
key: 'scrollVertical',
|
|
value: function scrollVertical(row) {
|
|
this.wtOverlays.topOverlay.scrollTo(row);
|
|
this.getSetting('onScrollVertically');
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Scroll the viewport to a column at the given index in the data source
|
|
*
|
|
* @param {Number} column
|
|
* @returns {Walkontable}
|
|
*/
|
|
|
|
}, {
|
|
key: 'scrollHorizontal',
|
|
value: function scrollHorizontal(column) {
|
|
this.wtOverlays.leftOverlay.scrollTo(column);
|
|
this.getSetting('onScrollHorizontally');
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Scrolls the viewport to a cell (rerenders if needed)
|
|
*
|
|
* @param {CellCoords} coords
|
|
* @returns {Walkontable}
|
|
*/
|
|
|
|
}, {
|
|
key: 'scrollViewport',
|
|
value: function scrollViewport(coords) {
|
|
this.wtScroll.scrollViewport(coords);
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getViewport',
|
|
value: function getViewport() {
|
|
return [this.wtTable.getFirstVisibleRow(), this.wtTable.getFirstVisibleColumn(), this.wtTable.getLastVisibleRow(), this.wtTable.getLastVisibleColumn()];
|
|
}
|
|
|
|
/**
|
|
* Get overlay name
|
|
*
|
|
* @returns {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getOverlayName',
|
|
value: function getOverlayName() {
|
|
return this.cloneOverlay ? this.cloneOverlay.type : 'master';
|
|
}
|
|
|
|
/**
|
|
* Check overlay type of this Walkontable instance.
|
|
*
|
|
* @param {String} name Clone type @see {Overlay.CLONE_TYPES}.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isOverlayName',
|
|
value: function isOverlayName(name) {
|
|
if (this.cloneOverlay) {
|
|
return this.cloneOverlay.type === name;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Export settings as class names added to the parent element of the table.
|
|
*/
|
|
|
|
}, {
|
|
key: 'exportSettingsAsClassNames',
|
|
value: function exportSettingsAsClassNames() {
|
|
var _this = this;
|
|
|
|
var toExport = {
|
|
rowHeaders: ['array'],
|
|
columnHeaders: ['array']
|
|
};
|
|
var allClassNames = [];
|
|
var newClassNames = [];
|
|
|
|
(0, _object.objectEach)(toExport, function (optionType, key) {
|
|
if (optionType.indexOf('array') > -1 && _this.getSetting(key).length) {
|
|
newClassNames.push('ht' + (0, _string.toUpperCaseFirst)(key));
|
|
}
|
|
allClassNames.push('ht' + (0, _string.toUpperCaseFirst)(key));
|
|
});
|
|
(0, _element.removeClass)(this.wtTable.wtRootElement.parentNode, allClassNames);
|
|
(0, _element.addClass)(this.wtTable.wtRootElement.parentNode, newClassNames);
|
|
}
|
|
|
|
/**
|
|
* Get/Set Walkontable instance setting
|
|
*
|
|
* @param {String} key
|
|
* @param {*} [param1]
|
|
* @param {*} [param2]
|
|
* @param {*} [param3]
|
|
* @param {*} [param4]
|
|
* @returns {*}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSetting',
|
|
value: function getSetting(key, param1, param2, param3, param4) {
|
|
// this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
|
|
return this.wtSettings.getSetting(key, param1, param2, param3, param4);
|
|
}
|
|
|
|
/**
|
|
* Checks if setting exists
|
|
*
|
|
* @param {String} key
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'hasSetting',
|
|
value: function hasSetting(key) {
|
|
return this.wtSettings.has(key);
|
|
}
|
|
|
|
/**
|
|
* Destroy instance
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.wtOverlays.destroy();
|
|
this.wtEvent.destroy();
|
|
}
|
|
}]);
|
|
|
|
return Walkontable;
|
|
}();
|
|
|
|
exports.default = Walkontable;
|
|
|
|
/***/ }),
|
|
/* 254 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _function = __webpack_require__(35);
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
*
|
|
*/
|
|
function Event(instance) {
|
|
var that = this;
|
|
var eventManager = new _eventManager2.default(instance);
|
|
|
|
this.instance = instance;
|
|
|
|
var dblClickOrigin = [null, null];
|
|
this.dblClickTimeout = [null, null];
|
|
|
|
var onMouseDown = function onMouseDown(event) {
|
|
var activeElement = document.activeElement;
|
|
var getParentNode = (0, _function.partial)(_element.getParent, event.realTarget);
|
|
var realTarget = event.realTarget;
|
|
|
|
// ignore focusable element from mouse down processing (https://github.com/handsontable/handsontable/issues/3555)
|
|
if (realTarget === activeElement || getParentNode(0) === activeElement || getParentNode(1) === activeElement) {
|
|
return;
|
|
}
|
|
|
|
var cell = that.parentCell(realTarget);
|
|
|
|
if ((0, _element.hasClass)(realTarget, 'corner')) {
|
|
that.instance.getSetting('onCellCornerMouseDown', event, realTarget);
|
|
} else if (cell.TD) {
|
|
if (that.instance.hasSetting('onCellMouseDown')) {
|
|
that.instance.getSetting('onCellMouseDown', event, cell.coords, cell.TD, that.instance);
|
|
}
|
|
}
|
|
|
|
if (event.button !== 2) {
|
|
// if not right mouse button
|
|
if (cell.TD) {
|
|
dblClickOrigin[0] = cell.TD;
|
|
clearTimeout(that.dblClickTimeout[0]);
|
|
that.dblClickTimeout[0] = setTimeout(function () {
|
|
dblClickOrigin[0] = null;
|
|
}, 1000);
|
|
}
|
|
}
|
|
};
|
|
|
|
var onTouchMove = function onTouchMove(event) {
|
|
that.instance.touchMoving = true;
|
|
};
|
|
|
|
var longTouchTimeout;
|
|
|
|
var onTouchStart = function onTouchStart(event) {
|
|
var container = this;
|
|
|
|
eventManager.addEventListener(this, 'touchmove', onTouchMove);
|
|
|
|
// Prevent cell selection when scrolling with touch event - not the best solution performance-wise
|
|
that.checkIfTouchMove = setTimeout(function () {
|
|
if (that.instance.touchMoving === true) {
|
|
that.instance.touchMoving = void 0;
|
|
|
|
eventManager.removeEventListener('touchmove', onTouchMove, false);
|
|
}
|
|
|
|
onMouseDown(event);
|
|
}, 30);
|
|
};
|
|
|
|
var onMouseOver = function onMouseOver(event) {
|
|
var table, td, mainWOT;
|
|
|
|
if (that.instance.hasSetting('onCellMouseOver')) {
|
|
table = that.instance.wtTable.TABLE;
|
|
td = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table);
|
|
mainWOT = that.instance.cloneSource || that.instance;
|
|
|
|
if (td && td !== mainWOT.lastMouseOver && (0, _element.isChildOf)(td, table)) {
|
|
mainWOT.lastMouseOver = td;
|
|
|
|
that.instance.getSetting('onCellMouseOver', event, that.instance.wtTable.getCoords(td), td, that.instance);
|
|
}
|
|
}
|
|
};
|
|
|
|
var onMouseOut = function onMouseOut(event) {
|
|
var table = void 0;
|
|
var lastTD = void 0;
|
|
var nextTD = void 0;
|
|
|
|
if (that.instance.hasSetting('onCellMouseOut')) {
|
|
table = that.instance.wtTable.TABLE;
|
|
lastTD = (0, _element.closestDown)(event.realTarget, ['TD', 'TH'], table);
|
|
nextTD = (0, _element.closestDown)(event.relatedTarget, ['TD', 'TH'], table);
|
|
|
|
if (lastTD && lastTD !== nextTD && (0, _element.isChildOf)(lastTD, table)) {
|
|
that.instance.getSetting('onCellMouseOut', event, that.instance.wtTable.getCoords(lastTD), lastTD, that.instance);
|
|
}
|
|
}
|
|
};
|
|
|
|
var onMouseUp = function onMouseUp(event) {
|
|
if (event.button !== 2) {
|
|
// if not right mouse button
|
|
var cell = that.parentCell(event.realTarget);
|
|
|
|
if (cell.TD === dblClickOrigin[0] && cell.TD === dblClickOrigin[1]) {
|
|
if ((0, _element.hasClass)(event.realTarget, 'corner')) {
|
|
that.instance.getSetting('onCellCornerDblClick', event, cell.coords, cell.TD, that.instance);
|
|
} else {
|
|
that.instance.getSetting('onCellDblClick', event, cell.coords, cell.TD, that.instance);
|
|
}
|
|
|
|
dblClickOrigin[0] = null;
|
|
dblClickOrigin[1] = null;
|
|
} else if (cell.TD === dblClickOrigin[0]) {
|
|
that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance);
|
|
|
|
dblClickOrigin[1] = cell.TD;
|
|
clearTimeout(that.dblClickTimeout[1]);
|
|
that.dblClickTimeout[1] = setTimeout(function () {
|
|
dblClickOrigin[1] = null;
|
|
}, 500);
|
|
} else if (cell.TD && that.instance.hasSetting('onCellMouseUp')) {
|
|
that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance);
|
|
}
|
|
}
|
|
};
|
|
|
|
var onTouchEnd = function onTouchEnd(event) {
|
|
clearTimeout(longTouchTimeout);
|
|
// that.instance.longTouch == void 0;
|
|
|
|
event.preventDefault();
|
|
onMouseUp(event);
|
|
|
|
// eventManager.removeEventListener(that.instance.wtTable.holder, "mouseup", onMouseUp);
|
|
};
|
|
|
|
eventManager.addEventListener(this.instance.wtTable.holder, 'mousedown', onMouseDown);
|
|
eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseover', onMouseOver);
|
|
eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseout', onMouseOut);
|
|
eventManager.addEventListener(this.instance.wtTable.holder, 'mouseup', onMouseUp);
|
|
|
|
// check if full HOT instance, or detached WOT AND run on mobile device
|
|
if (this.instance.wtTable.holder.parentNode.parentNode && (0, _browser.isMobileBrowser)() && !that.instance.wtTable.isWorkingOnClone()) {
|
|
var classSelector = '.' + this.instance.wtTable.holder.parentNode.className.split(' ').join('.');
|
|
|
|
eventManager.addEventListener(this.instance.wtTable.holder, 'touchstart', function (event) {
|
|
that.instance.touchApplied = true;
|
|
if ((0, _element.isChildOf)(event.target, classSelector)) {
|
|
onTouchStart.call(event.target, event);
|
|
}
|
|
});
|
|
eventManager.addEventListener(this.instance.wtTable.holder, 'touchend', function (event) {
|
|
that.instance.touchApplied = false;
|
|
if ((0, _element.isChildOf)(event.target, classSelector)) {
|
|
onTouchEnd.call(event.target, event);
|
|
}
|
|
});
|
|
|
|
if (!that.instance.momentumScrolling) {
|
|
that.instance.momentumScrolling = {};
|
|
}
|
|
eventManager.addEventListener(this.instance.wtTable.holder, 'scroll', function (event) {
|
|
clearTimeout(that.instance.momentumScrolling._timeout);
|
|
|
|
if (!that.instance.momentumScrolling.ongoing) {
|
|
that.instance.getSetting('onBeforeTouchScroll');
|
|
}
|
|
that.instance.momentumScrolling.ongoing = true;
|
|
|
|
that.instance.momentumScrolling._timeout = setTimeout(function () {
|
|
if (!that.instance.touchApplied) {
|
|
that.instance.momentumScrolling.ongoing = false;
|
|
|
|
that.instance.getSetting('onAfterMomentumScroll');
|
|
}
|
|
}, 200);
|
|
});
|
|
}
|
|
|
|
eventManager.addEventListener(window, 'resize', function () {
|
|
if (that.instance.getSetting('stretchH') !== 'none') {
|
|
that.instance.draw();
|
|
}
|
|
});
|
|
|
|
this.destroy = function () {
|
|
clearTimeout(this.dblClickTimeout[0]);
|
|
clearTimeout(this.dblClickTimeout[1]);
|
|
|
|
eventManager.destroy();
|
|
};
|
|
}
|
|
|
|
Event.prototype.parentCell = function (elem) {
|
|
var cell = {};
|
|
var TABLE = this.instance.wtTable.TABLE;
|
|
var TD = (0, _element.closestDown)(elem, ['TD', 'TH'], TABLE);
|
|
|
|
if (TD) {
|
|
cell.coords = this.instance.wtTable.getCoords(TD);
|
|
cell.TD = TD;
|
|
} else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'current')) {
|
|
cell.coords = this.instance.selections.current.cellRange.highlight; // selections.current is current selected cell
|
|
cell.TD = this.instance.wtTable.getCell(cell.coords);
|
|
} else if ((0, _element.hasClass)(elem, 'wtBorder') && (0, _element.hasClass)(elem, 'area')) {
|
|
if (this.instance.selections.area.cellRange) {
|
|
cell.coords = this.instance.selections.area.cellRange.to; // selections.area is area selected cells
|
|
cell.TD = this.instance.wtTable.getCell(cell.coords);
|
|
}
|
|
}
|
|
|
|
return cell;
|
|
};
|
|
|
|
exports.default = Event;
|
|
|
|
/***/ }),
|
|
/* 255 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class ColumnFilter
|
|
*/
|
|
var ColumnFilter = function () {
|
|
/**
|
|
* @param {Number} offset
|
|
* @param {Number} total
|
|
* @param {Number} countTH
|
|
*/
|
|
function ColumnFilter(offset, total, countTH) {
|
|
_classCallCheck(this, ColumnFilter);
|
|
|
|
this.offset = offset;
|
|
this.total = total;
|
|
this.countTH = countTH;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
|
|
_createClass(ColumnFilter, [{
|
|
key: "offsetted",
|
|
value: function offsetted(index) {
|
|
return index + this.offset;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "unOffsetted",
|
|
value: function unOffsetted(index) {
|
|
return index - this.offset;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "renderedToSource",
|
|
value: function renderedToSource(index) {
|
|
return this.offsetted(index);
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "sourceToRendered",
|
|
value: function sourceToRendered(index) {
|
|
return this.unOffsetted(index);
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "offsettedTH",
|
|
value: function offsettedTH(index) {
|
|
return index - this.countTH;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "unOffsettedTH",
|
|
value: function unOffsettedTH(index) {
|
|
return index + this.countTH;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "visibleRowHeadedColumnToSourceColumn",
|
|
value: function visibleRowHeadedColumnToSourceColumn(index) {
|
|
return this.renderedToSource(this.offsettedTH(index));
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "sourceColumnToVisibleRowHeadedColumn",
|
|
value: function sourceColumnToVisibleRowHeadedColumn(index) {
|
|
return this.unOffsettedTH(this.sourceToRendered(index));
|
|
}
|
|
}]);
|
|
|
|
return ColumnFilter;
|
|
}();
|
|
|
|
exports.default = ColumnFilter;
|
|
|
|
/***/ }),
|
|
/* 256 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class RowFilter
|
|
*/
|
|
var RowFilter = function () {
|
|
/**
|
|
* @param {Number} offset
|
|
* @param {Number} total
|
|
* @param {Number} countTH
|
|
*/
|
|
function RowFilter(offset, total, countTH) {
|
|
_classCallCheck(this, RowFilter);
|
|
|
|
this.offset = offset;
|
|
this.total = total;
|
|
this.countTH = countTH;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
|
|
_createClass(RowFilter, [{
|
|
key: "offsetted",
|
|
value: function offsetted(index) {
|
|
return index + this.offset;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "unOffsetted",
|
|
value: function unOffsetted(index) {
|
|
return index - this.offset;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "renderedToSource",
|
|
value: function renderedToSource(index) {
|
|
return this.offsetted(index);
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "sourceToRendered",
|
|
value: function sourceToRendered(index) {
|
|
return this.unOffsetted(index);
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "offsettedTH",
|
|
value: function offsettedTH(index) {
|
|
return index - this.countTH;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "unOffsettedTH",
|
|
value: function unOffsettedTH(index) {
|
|
return index + this.countTH;
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "visibleColHeadedRowToSourceRow",
|
|
value: function visibleColHeadedRowToSourceRow(index) {
|
|
return this.renderedToSource(this.offsettedTH(index));
|
|
}
|
|
|
|
/**
|
|
* @param index
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: "sourceRowToVisibleColHeadedRow",
|
|
value: function sourceRowToVisibleColHeadedRow(index) {
|
|
return this.unOffsettedTH(this.sourceToRendered(index));
|
|
}
|
|
}]);
|
|
|
|
return RowFilter;
|
|
}();
|
|
|
|
exports.default = RowFilter;
|
|
|
|
/***/ }),
|
|
/* 257 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Overlays
|
|
*/
|
|
var Overlays = function () {
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
*/
|
|
function Overlays(wotInstance) {
|
|
_classCallCheck(this, Overlays);
|
|
|
|
this.wot = wotInstance;
|
|
|
|
// legacy support
|
|
this.instance = this.wot;
|
|
this.eventManager = new _eventManager2.default(this.wot);
|
|
|
|
this.wot.update('scrollbarWidth', (0, _element.getScrollbarWidth)());
|
|
this.wot.update('scrollbarHeight', (0, _element.getScrollbarWidth)());
|
|
|
|
this.scrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE);
|
|
|
|
this.prepareOverlays();
|
|
|
|
this.destroyed = false;
|
|
this.keyPressed = false;
|
|
this.spreaderLastSize = {
|
|
width: null,
|
|
height: null
|
|
};
|
|
this.overlayScrollPositions = {
|
|
master: {
|
|
top: 0,
|
|
left: 0
|
|
},
|
|
top: {
|
|
top: null,
|
|
left: 0
|
|
},
|
|
bottom: {
|
|
top: null,
|
|
left: 0
|
|
},
|
|
left: {
|
|
top: 0,
|
|
left: null
|
|
}
|
|
};
|
|
|
|
this.pendingScrollCallbacks = {
|
|
master: {
|
|
top: 0,
|
|
left: 0
|
|
},
|
|
top: {
|
|
left: 0
|
|
},
|
|
bottom: {
|
|
left: 0
|
|
},
|
|
left: {
|
|
top: 0
|
|
}
|
|
};
|
|
|
|
this.verticalScrolling = false;
|
|
this.horizontalScrolling = false;
|
|
this.delegatedScrollCallback = false;
|
|
|
|
this.registeredListeners = [];
|
|
|
|
this.registerListeners();
|
|
}
|
|
|
|
/**
|
|
* Prepare overlays based on user settings.
|
|
*
|
|
* @returns {Boolean} Returns `true` if changes applied to overlay needs scroll synchronization.
|
|
*/
|
|
|
|
|
|
_createClass(Overlays, [{
|
|
key: 'prepareOverlays',
|
|
value: function prepareOverlays() {
|
|
var syncScroll = false;
|
|
|
|
if (this.topOverlay) {
|
|
syncScroll = this.topOverlay.updateStateOfRendering() || syncScroll;
|
|
} else {
|
|
this.topOverlay = _base2.default.createOverlay(_base2.default.CLONE_TOP, this.wot);
|
|
}
|
|
|
|
if (!_base2.default.hasOverlay(_base2.default.CLONE_BOTTOM)) {
|
|
this.bottomOverlay = {
|
|
needFullRender: false,
|
|
updateStateOfRendering: function updateStateOfRendering() {
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
if (!_base2.default.hasOverlay(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
|
|
this.bottomLeftCornerOverlay = {
|
|
needFullRender: false,
|
|
updateStateOfRendering: function updateStateOfRendering() {
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
|
|
if (this.bottomOverlay) {
|
|
syncScroll = this.bottomOverlay.updateStateOfRendering() || syncScroll;
|
|
} else {
|
|
this.bottomOverlay = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM, this.wot);
|
|
}
|
|
|
|
if (this.leftOverlay) {
|
|
syncScroll = this.leftOverlay.updateStateOfRendering() || syncScroll;
|
|
} else {
|
|
this.leftOverlay = _base2.default.createOverlay(_base2.default.CLONE_LEFT, this.wot);
|
|
}
|
|
|
|
if (this.topOverlay.needFullRender && this.leftOverlay.needFullRender) {
|
|
if (this.topLeftCornerOverlay) {
|
|
syncScroll = this.topLeftCornerOverlay.updateStateOfRendering() || syncScroll;
|
|
} else {
|
|
this.topLeftCornerOverlay = _base2.default.createOverlay(_base2.default.CLONE_TOP_LEFT_CORNER, this.wot);
|
|
}
|
|
}
|
|
|
|
if (this.bottomOverlay.needFullRender && this.leftOverlay.needFullRender) {
|
|
if (this.bottomLeftCornerOverlay) {
|
|
syncScroll = this.bottomLeftCornerOverlay.updateStateOfRendering() || syncScroll;
|
|
} else {
|
|
this.bottomLeftCornerOverlay = _base2.default.createOverlay(_base2.default.CLONE_BOTTOM_LEFT_CORNER, this.wot);
|
|
}
|
|
}
|
|
|
|
if (this.wot.getSetting('debug') && !this.debug) {
|
|
this.debug = _base2.default.createOverlay(_base2.default.CLONE_DEBUG, this.wot);
|
|
}
|
|
|
|
return syncScroll;
|
|
}
|
|
|
|
/**
|
|
* Refresh and redraw table
|
|
*/
|
|
|
|
}, {
|
|
key: 'refreshAll',
|
|
value: function refreshAll() {
|
|
if (!this.wot.drawn) {
|
|
return;
|
|
}
|
|
if (!this.wot.wtTable.holder.parentNode) {
|
|
// Walkontable was detached from DOM, but this handler was not removed
|
|
this.destroy();
|
|
|
|
return;
|
|
}
|
|
this.wot.draw(true);
|
|
|
|
if (this.verticalScrolling) {
|
|
this.leftOverlay.onScroll();
|
|
}
|
|
|
|
if (this.horizontalScrolling) {
|
|
this.topOverlay.onScroll();
|
|
}
|
|
|
|
this.verticalScrolling = false;
|
|
this.horizontalScrolling = false;
|
|
}
|
|
|
|
/**
|
|
* Register all necessary event listeners.
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerListeners',
|
|
value: function registerListeners() {
|
|
var _this = this;
|
|
|
|
var topOverlayScrollable = this.topOverlay.mainTableScrollableElement;
|
|
var leftOverlayScrollable = this.leftOverlay.mainTableScrollableElement;
|
|
|
|
var listenersToRegister = [];
|
|
listenersToRegister.push([document.documentElement, 'keydown', function (event) {
|
|
return _this.onKeyDown(event);
|
|
}]);
|
|
listenersToRegister.push([document.documentElement, 'keyup', function () {
|
|
return _this.onKeyUp();
|
|
}]);
|
|
listenersToRegister.push([document, 'visibilitychange', function () {
|
|
return _this.onKeyUp();
|
|
}]);
|
|
listenersToRegister.push([topOverlayScrollable, 'scroll', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
|
|
if (topOverlayScrollable !== leftOverlayScrollable) {
|
|
listenersToRegister.push([leftOverlayScrollable, 'scroll', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
}
|
|
|
|
if (this.topOverlay.needFullRender) {
|
|
listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'scroll', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'wheel', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
}
|
|
|
|
if (this.bottomOverlay.needFullRender) {
|
|
listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'scroll', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'wheel', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
}
|
|
|
|
if (this.leftOverlay.needFullRender) {
|
|
listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'scroll', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'wheel', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
}
|
|
|
|
if (this.topLeftCornerOverlay && this.topLeftCornerOverlay.needFullRender) {
|
|
listenersToRegister.push([this.topLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
}
|
|
|
|
if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.needFullRender) {
|
|
listenersToRegister.push([this.bottomLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
|
|
return _this.onTableScroll(event);
|
|
}]);
|
|
}
|
|
|
|
if (this.topOverlay.trimmingContainer !== window && this.leftOverlay.trimmingContainer !== window) {
|
|
// This is necessary?
|
|
// eventManager.addEventListener(window, 'scroll', (event) => this.refreshAll(event));
|
|
listenersToRegister.push([window, 'wheel', function (event) {
|
|
var overlay = void 0;
|
|
var deltaY = event.wheelDeltaY || event.deltaY;
|
|
var deltaX = event.wheelDeltaX || event.deltaX;
|
|
|
|
if (_this.topOverlay.clone.wtTable.holder.contains(event.realTarget)) {
|
|
overlay = 'top';
|
|
} else if (_this.bottomOverlay.clone && _this.bottomOverlay.clone.wtTable.holder.contains(event.realTarget)) {
|
|
overlay = 'bottom';
|
|
} else if (_this.leftOverlay.clone.wtTable.holder.contains(event.realTarget)) {
|
|
overlay = 'left';
|
|
} else if (_this.topLeftCornerOverlay && _this.topLeftCornerOverlay.clone && _this.topLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) {
|
|
overlay = 'topLeft';
|
|
} else if (_this.bottomLeftCornerOverlay && _this.bottomLeftCornerOverlay.clone && _this.bottomLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) {
|
|
overlay = 'bottomLeft';
|
|
}
|
|
|
|
if (overlay == 'top' && deltaY !== 0 || overlay == 'left' && deltaX !== 0 || overlay == 'bottom' && deltaY !== 0 || (overlay === 'topLeft' || overlay === 'bottomLeft') && (deltaY !== 0 || deltaX !== 0)) {
|
|
|
|
event.preventDefault();
|
|
}
|
|
}]);
|
|
}
|
|
|
|
while (listenersToRegister.length) {
|
|
var listener = listenersToRegister.pop();
|
|
this.eventManager.addEventListener(listener[0], listener[1], listener[2]);
|
|
|
|
this.registeredListeners.push(listener);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deregister all previously registered listeners.
|
|
*/
|
|
|
|
}, {
|
|
key: 'deregisterListeners',
|
|
value: function deregisterListeners() {
|
|
while (this.registeredListeners.length) {
|
|
var listener = this.registeredListeners.pop();
|
|
this.eventManager.removeEventListener(listener[0], listener[1], listener[2]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scroll listener
|
|
*
|
|
* @param {Event} event
|
|
*/
|
|
|
|
}, {
|
|
key: 'onTableScroll',
|
|
value: function onTableScroll(event) {
|
|
// if mobile browser, do not update scroll positions, as the overlays are hidden during the scroll
|
|
if ((0, _browser.isMobileBrowser)()) {
|
|
return;
|
|
}
|
|
var masterHorizontal = this.leftOverlay.mainTableScrollableElement;
|
|
var masterVertical = this.topOverlay.mainTableScrollableElement;
|
|
var target = event.target;
|
|
|
|
// For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
|
|
// by hot.refreshBorder
|
|
if (this.keyPressed) {
|
|
if (masterVertical !== window && target !== window && !event.target.contains(masterVertical) || masterHorizontal !== window && target !== window && !event.target.contains(masterHorizontal)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (event.type === 'scroll') {
|
|
this.syncScrollPositions(event);
|
|
} else {
|
|
this.translateMouseWheelToScroll(event);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Key down listener
|
|
*/
|
|
|
|
}, {
|
|
key: 'onKeyDown',
|
|
value: function onKeyDown(event) {
|
|
this.keyPressed = (0, _unicode.isKey)(event.keyCode, 'ARROW_UP|ARROW_RIGHT|ARROW_DOWN|ARROW_LEFT');
|
|
}
|
|
|
|
/**
|
|
* Key up listener
|
|
*/
|
|
|
|
}, {
|
|
key: 'onKeyUp',
|
|
value: function onKeyUp() {
|
|
this.keyPressed = false;
|
|
}
|
|
|
|
/**
|
|
* Translate wheel event into scroll event and sync scroll overlays position
|
|
*
|
|
* @private
|
|
* @param {Event} event
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'translateMouseWheelToScroll',
|
|
value: function translateMouseWheelToScroll(event) {
|
|
var topOverlay = this.topOverlay.clone.wtTable.holder;
|
|
var bottomOverlay = this.bottomOverlay.clone ? this.bottomOverlay.clone.wtTable.holder : null;
|
|
var leftOverlay = this.leftOverlay.clone.wtTable.holder;
|
|
var topLeftCornerOverlay = this.topLeftCornerOverlay && this.topLeftCornerOverlay.clone ? this.topLeftCornerOverlay.clone.wtTable.holder : null;
|
|
var bottomLeftCornerOverlay = this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone ? this.bottomLeftCornerOverlay.clone.wtTable.holder : null;
|
|
var mouseWheelSpeedRatio = -0.2;
|
|
var deltaY = event.wheelDeltaY || -1 * event.deltaY;
|
|
var deltaX = event.wheelDeltaX || -1 * event.deltaX;
|
|
var parentHolder = null;
|
|
var eventMockup = { type: 'wheel' };
|
|
var tempElem = event.target;
|
|
var delta = null;
|
|
|
|
// Fix for extremely slow header scrolling with a mousewheel on Firefox
|
|
if (event.deltaMode === 1) {
|
|
deltaY *= 120;
|
|
deltaX *= 120;
|
|
}
|
|
|
|
while (tempElem != document && tempElem != null) {
|
|
if (tempElem.className.indexOf('wtHolder') > -1) {
|
|
parentHolder = tempElem;
|
|
break;
|
|
}
|
|
tempElem = tempElem.parentNode;
|
|
}
|
|
eventMockup.target = parentHolder;
|
|
|
|
if (parentHolder === topLeftCornerOverlay || parentHolder === bottomLeftCornerOverlay) {
|
|
this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaX, 'x');
|
|
this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaY, 'y');
|
|
} else {
|
|
if (parentHolder === topOverlay || parentHolder === bottomOverlay) {
|
|
delta = deltaY;
|
|
} else if (parentHolder === leftOverlay) {
|
|
delta = deltaX;
|
|
}
|
|
|
|
this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * delta);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Synchronize scroll position between master table and overlay table.
|
|
*
|
|
* @private
|
|
* @param {Event|Object} event
|
|
* @param {Number} [fakeScrollValue=null]
|
|
* @param {String} [fakeScrollDirection=null] `x` or `y`.
|
|
*/
|
|
|
|
}, {
|
|
key: 'syncScrollPositions',
|
|
value: function syncScrollPositions(event) {
|
|
var fakeScrollValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
var fakeScrollDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
|
|
if (this.destroyed) {
|
|
return;
|
|
}
|
|
if (arguments.length === 0) {
|
|
this.syncScrollWithMaster();
|
|
|
|
return;
|
|
}
|
|
var masterHorizontal = this.leftOverlay.mainTableScrollableElement;
|
|
var masterVertical = this.topOverlay.mainTableScrollableElement;
|
|
var target = event.target;
|
|
var tempScrollValue = 0;
|
|
var scrollValueChanged = false;
|
|
var topOverlay = void 0;
|
|
var leftOverlay = void 0;
|
|
var topLeftCornerOverlay = void 0;
|
|
var bottomLeftCornerOverlay = void 0;
|
|
var bottomOverlay = void 0;
|
|
var delegatedScroll = false;
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
|
|
if (this.topOverlay.needFullRender) {
|
|
topOverlay = this.topOverlay.clone.wtTable.holder;
|
|
}
|
|
|
|
if (this.bottomOverlay.needFullRender) {
|
|
bottomOverlay = this.bottomOverlay.clone.wtTable.holder;
|
|
}
|
|
|
|
if (this.leftOverlay.needFullRender) {
|
|
leftOverlay = this.leftOverlay.clone.wtTable.holder;
|
|
}
|
|
|
|
if (this.leftOverlay.needFullRender && this.topOverlay.needFullRender) {
|
|
topLeftCornerOverlay = this.topLeftCornerOverlay.clone.wtTable.holder;
|
|
}
|
|
|
|
if (this.leftOverlay.needFullRender && this.bottomOverlay.needFullRender) {
|
|
bottomLeftCornerOverlay = this.bottomLeftCornerOverlay.clone.wtTable.holder;
|
|
}
|
|
|
|
if (target === document) {
|
|
target = window;
|
|
}
|
|
|
|
if (target === masterHorizontal || target === masterVertical) {
|
|
if (preventOverflow) {
|
|
tempScrollValue = (0, _element.getScrollLeft)(this.scrollableElement);
|
|
} else {
|
|
tempScrollValue = (0, _element.getScrollLeft)(target);
|
|
}
|
|
|
|
// if scrolling the master table - populate the scroll values to both top and left overlays
|
|
this.horizontalScrolling = true;
|
|
this.overlayScrollPositions.master.left = tempScrollValue;
|
|
scrollValueChanged = true;
|
|
|
|
if (this.pendingScrollCallbacks.master.left > 0) {
|
|
this.pendingScrollCallbacks.master.left--;
|
|
} else {
|
|
if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) {
|
|
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.top.left++;
|
|
}
|
|
|
|
topOverlay.scrollLeft = tempScrollValue;
|
|
delegatedScroll = masterHorizontal !== window;
|
|
}
|
|
|
|
if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) {
|
|
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.bottom.left++;
|
|
}
|
|
|
|
bottomOverlay.scrollLeft = tempScrollValue;
|
|
delegatedScroll = masterHorizontal !== window;
|
|
}
|
|
}
|
|
|
|
tempScrollValue = (0, _element.getScrollTop)(target);
|
|
|
|
this.verticalScrolling = true;
|
|
this.overlayScrollPositions.master.top = tempScrollValue;
|
|
scrollValueChanged = true;
|
|
|
|
if (this.pendingScrollCallbacks.master.top > 0) {
|
|
this.pendingScrollCallbacks.master.top--;
|
|
} else if (leftOverlay && leftOverlay.scrollTop !== tempScrollValue) {
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.left.top++;
|
|
}
|
|
|
|
leftOverlay.scrollTop = tempScrollValue;
|
|
delegatedScroll = masterVertical !== window;
|
|
}
|
|
} else if (target === bottomOverlay) {
|
|
tempScrollValue = (0, _element.getScrollLeft)(target);
|
|
|
|
// if scrolling the bottom overlay - populate the horizontal scroll to the master table
|
|
this.horizontalScrolling = true;
|
|
this.overlayScrollPositions.bottom.left = tempScrollValue;
|
|
scrollValueChanged = true;
|
|
|
|
if (this.pendingScrollCallbacks.bottom.left > 0) {
|
|
this.pendingScrollCallbacks.bottom.left--;
|
|
} else {
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.master.left++;
|
|
}
|
|
|
|
masterHorizontal.scrollLeft = tempScrollValue;
|
|
|
|
if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) {
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.top.left++;
|
|
}
|
|
|
|
topOverlay.scrollLeft = tempScrollValue;
|
|
delegatedScroll = masterVertical !== window;
|
|
}
|
|
}
|
|
|
|
// "fake" scroll value calculated from the mousewheel event
|
|
if (fakeScrollValue !== null) {
|
|
scrollValueChanged = true;
|
|
masterVertical.scrollTop += fakeScrollValue;
|
|
}
|
|
} else if (target === topOverlay) {
|
|
tempScrollValue = (0, _element.getScrollLeft)(target);
|
|
|
|
// if scrolling the top overlay - populate the horizontal scroll to the master table
|
|
this.horizontalScrolling = true;
|
|
this.overlayScrollPositions.top.left = tempScrollValue;
|
|
scrollValueChanged = true;
|
|
|
|
if (this.pendingScrollCallbacks.top.left > 0) {
|
|
this.pendingScrollCallbacks.top.left--;
|
|
} else {
|
|
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.master.left++;
|
|
}
|
|
|
|
masterHorizontal.scrollLeft = tempScrollValue;
|
|
}
|
|
|
|
// "fake" scroll value calculated from the mousewheel event
|
|
if (fakeScrollValue !== null) {
|
|
scrollValueChanged = true;
|
|
masterVertical.scrollTop += fakeScrollValue;
|
|
}
|
|
|
|
if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) {
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.bottom.left++;
|
|
}
|
|
|
|
bottomOverlay.scrollLeft = tempScrollValue;
|
|
delegatedScroll = masterVertical !== window;
|
|
}
|
|
} else if (target === leftOverlay) {
|
|
tempScrollValue = (0, _element.getScrollTop)(target);
|
|
|
|
// if scrolling the left overlay - populate the vertical scroll to the master table
|
|
if (this.overlayScrollPositions.left.top !== tempScrollValue) {
|
|
this.verticalScrolling = true;
|
|
this.overlayScrollPositions.left.top = tempScrollValue;
|
|
scrollValueChanged = true;
|
|
|
|
if (this.pendingScrollCallbacks.left.top > 0) {
|
|
this.pendingScrollCallbacks.left.top--;
|
|
} else {
|
|
if (fakeScrollValue == null) {
|
|
this.pendingScrollCallbacks.master.top++;
|
|
}
|
|
|
|
masterVertical.scrollTop = tempScrollValue;
|
|
}
|
|
}
|
|
|
|
// "fake" scroll value calculated from the mousewheel event
|
|
if (fakeScrollValue !== null) {
|
|
scrollValueChanged = true;
|
|
masterVertical.scrollLeft += fakeScrollValue;
|
|
}
|
|
} else if (target === topLeftCornerOverlay || target === bottomLeftCornerOverlay) {
|
|
if (fakeScrollValue !== null) {
|
|
scrollValueChanged = true;
|
|
|
|
if (fakeScrollDirection === 'x') {
|
|
masterVertical.scrollLeft += fakeScrollValue;
|
|
} else if (fakeScrollDirection === 'y') {
|
|
masterVertical.scrollTop += fakeScrollValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!this.keyPressed && scrollValueChanged && event.type === 'scroll') {
|
|
if (this.delegatedScrollCallback) {
|
|
this.delegatedScrollCallback = false;
|
|
} else {
|
|
this.refreshAll();
|
|
}
|
|
|
|
if (delegatedScroll) {
|
|
this.delegatedScrollCallback = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Synchronize overlay scrollbars with the master scrollbar
|
|
*/
|
|
|
|
}, {
|
|
key: 'syncScrollWithMaster',
|
|
value: function syncScrollWithMaster() {
|
|
var master = this.topOverlay.mainTableScrollableElement;
|
|
var scrollLeft = master.scrollLeft,
|
|
scrollTop = master.scrollTop;
|
|
|
|
|
|
if (this.topOverlay.needFullRender) {
|
|
this.topOverlay.clone.wtTable.holder.scrollLeft = scrollLeft;
|
|
}
|
|
if (this.bottomOverlay.needFullRender) {
|
|
this.bottomOverlay.clone.wtTable.holder.scrollLeft = scrollLeft;
|
|
}
|
|
if (this.leftOverlay.needFullRender) {
|
|
this.leftOverlay.clone.wtTable.holder.scrollTop = scrollTop;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the main scrollable elements for all the overlays.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updateMainScrollableElements',
|
|
value: function updateMainScrollableElements() {
|
|
this.deregisterListeners();
|
|
|
|
this.leftOverlay.updateMainScrollableElement();
|
|
this.topOverlay.updateMainScrollableElement();
|
|
|
|
if (this.bottomOverlay.needFullRender) {
|
|
this.bottomOverlay.updateMainScrollableElement();
|
|
}
|
|
|
|
this.scrollableElement = (0, _element.getScrollableElement)(this.wot.wtTable.TABLE);
|
|
|
|
this.registerListeners();
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.eventManager.destroy();
|
|
this.topOverlay.destroy();
|
|
|
|
if (this.bottomOverlay.clone) {
|
|
this.bottomOverlay.destroy();
|
|
}
|
|
this.leftOverlay.destroy();
|
|
|
|
if (this.topLeftCornerOverlay) {
|
|
this.topLeftCornerOverlay.destroy();
|
|
}
|
|
|
|
if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) {
|
|
this.bottomLeftCornerOverlay.destroy();
|
|
}
|
|
|
|
if (this.debug) {
|
|
this.debug.destroy();
|
|
}
|
|
this.destroyed = true;
|
|
}
|
|
|
|
/**
|
|
* @param {Boolean} [fastDraw=false]
|
|
*/
|
|
|
|
}, {
|
|
key: 'refresh',
|
|
value: function refresh() {
|
|
var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
if (this.topOverlay.areElementSizesAdjusted && this.leftOverlay.areElementSizesAdjusted) {
|
|
var container = this.wot.wtTable.wtRootElement.parentNode || this.wot.wtTable.wtRootElement;
|
|
var width = container.clientWidth;
|
|
var height = container.clientHeight;
|
|
|
|
if (width !== this.spreaderLastSize.width || height !== this.spreaderLastSize.height) {
|
|
this.spreaderLastSize.width = width;
|
|
this.spreaderLastSize.height = height;
|
|
this.adjustElementsSize();
|
|
}
|
|
}
|
|
|
|
if (this.bottomOverlay.clone) {
|
|
this.bottomOverlay.refresh(fastDraw);
|
|
}
|
|
|
|
this.leftOverlay.refresh(fastDraw);
|
|
this.topOverlay.refresh(fastDraw);
|
|
|
|
if (this.topLeftCornerOverlay) {
|
|
this.topLeftCornerOverlay.refresh(fastDraw);
|
|
}
|
|
|
|
if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) {
|
|
this.bottomLeftCornerOverlay.refresh(fastDraw);
|
|
}
|
|
|
|
if (this.debug) {
|
|
this.debug.refresh(fastDraw);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adjust overlays elements size and master table size
|
|
*
|
|
* @param {Boolean} [force=false]
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustElementsSize',
|
|
value: function adjustElementsSize() {
|
|
var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
var totalColumns = this.wot.getSetting('totalColumns');
|
|
var totalRows = this.wot.getSetting('totalRows');
|
|
var headerRowSize = this.wot.wtViewport.getRowHeaderWidth();
|
|
var headerColumnSize = this.wot.wtViewport.getColumnHeaderHeight();
|
|
var hiderStyle = this.wot.wtTable.hider.style;
|
|
|
|
hiderStyle.width = headerRowSize + this.leftOverlay.sumCellSizes(0, totalColumns) + 'px';
|
|
hiderStyle.height = headerColumnSize + this.topOverlay.sumCellSizes(0, totalRows) + 1 + 'px';
|
|
|
|
this.topOverlay.adjustElementsSize(force);
|
|
this.leftOverlay.adjustElementsSize(force);
|
|
|
|
if (this.bottomOverlay.clone) {
|
|
this.bottomOverlay.adjustElementsSize(force);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
}, {
|
|
key: 'applyToDOM',
|
|
value: function applyToDOM() {
|
|
if (!this.topOverlay.areElementSizesAdjusted || !this.leftOverlay.areElementSizesAdjusted) {
|
|
this.adjustElementsSize();
|
|
}
|
|
this.topOverlay.applyToDOM();
|
|
|
|
if (this.bottomOverlay.clone) {
|
|
this.bottomOverlay.applyToDOM();
|
|
}
|
|
|
|
this.leftOverlay.applyToDOM();
|
|
}
|
|
|
|
/**
|
|
* Get the parent overlay of the provided element.
|
|
*
|
|
* @param {HTMLElement} element
|
|
* @returns {Object|null}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getParentOverlay',
|
|
value: function getParentOverlay(element) {
|
|
if (!element) {
|
|
return null;
|
|
}
|
|
|
|
var overlays = [this.topOverlay, this.leftOverlay, this.bottomOverlay, this.topLeftCornerOverlay, this.bottomLeftCornerOverlay];
|
|
var result = null;
|
|
|
|
(0, _array.arrayEach)(overlays, function (elem, i) {
|
|
if (!elem) {
|
|
return;
|
|
}
|
|
|
|
if (elem.clone && elem.clone.wtTable.TABLE.contains(element)) {
|
|
result = elem.clone;
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
}]);
|
|
|
|
return Overlays;
|
|
}();
|
|
|
|
exports.default = Overlays;
|
|
|
|
/***/ }),
|
|
/* 258 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Scroll
|
|
*/
|
|
var Scroll = function () {
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
*/
|
|
function Scroll(wotInstance) {
|
|
_classCallCheck(this, Scroll);
|
|
|
|
this.wot = wotInstance;
|
|
|
|
// legacy support
|
|
this.instance = wotInstance;
|
|
}
|
|
|
|
/**
|
|
* Scrolls viewport to a cell by minimum number of cells
|
|
*
|
|
* @param {CellCoords} coords
|
|
*/
|
|
|
|
|
|
_createClass(Scroll, [{
|
|
key: 'scrollViewport',
|
|
value: function scrollViewport(coords) {
|
|
if (!this.wot.drawn) {
|
|
return;
|
|
}
|
|
|
|
var _getVariables2 = this._getVariables(),
|
|
topOverlay = _getVariables2.topOverlay,
|
|
leftOverlay = _getVariables2.leftOverlay,
|
|
totalRows = _getVariables2.totalRows,
|
|
totalColumns = _getVariables2.totalColumns,
|
|
fixedRowsTop = _getVariables2.fixedRowsTop,
|
|
fixedRowsBottom = _getVariables2.fixedRowsBottom,
|
|
fixedColumnsLeft = _getVariables2.fixedColumnsLeft;
|
|
|
|
if (coords.row < 0 || coords.row > Math.max(totalRows - 1, 0)) {
|
|
throw new Error('row ' + coords.row + ' does not exist');
|
|
}
|
|
|
|
if (coords.col < 0 || coords.col > Math.max(totalColumns - 1, 0)) {
|
|
throw new Error('column ' + coords.col + ' does not exist');
|
|
}
|
|
|
|
if (coords.row >= fixedRowsTop && coords.row < this.getFirstVisibleRow()) {
|
|
topOverlay.scrollTo(coords.row);
|
|
} else if (coords.row > this.getLastVisibleRow() && coords.row < totalRows - fixedRowsBottom) {
|
|
topOverlay.scrollTo(coords.row, true);
|
|
}
|
|
|
|
if (coords.col >= fixedColumnsLeft && coords.col < this.getFirstVisibleColumn()) {
|
|
leftOverlay.scrollTo(coords.col);
|
|
} else if (coords.col > this.getLastVisibleColumn()) {
|
|
leftOverlay.scrollTo(coords.col, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get first visible row based on virtual dom and how table is visible in browser window viewport.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getFirstVisibleRow',
|
|
value: function getFirstVisibleRow() {
|
|
var _getVariables3 = this._getVariables(),
|
|
topOverlay = _getVariables3.topOverlay,
|
|
wtTable = _getVariables3.wtTable,
|
|
wtViewport = _getVariables3.wtViewport,
|
|
totalRows = _getVariables3.totalRows,
|
|
fixedRowsTop = _getVariables3.fixedRowsTop;
|
|
|
|
var firstVisibleRow = wtTable.getFirstVisibleRow();
|
|
|
|
if (topOverlay.mainTableScrollableElement === window) {
|
|
var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
|
|
var totalTableHeight = (0, _element.innerHeight)(wtTable.hider);
|
|
var windowHeight = (0, _element.innerHeight)(window);
|
|
var windowScrollTop = (0, _element.getScrollTop)(window);
|
|
|
|
// Only calculate firstVisibleRow when table didn't filled (from up) whole viewport space
|
|
if (rootElementOffset.top + totalTableHeight - windowHeight <= windowScrollTop) {
|
|
var rowsHeight = wtViewport.getColumnHeaderHeight();
|
|
|
|
rowsHeight += topOverlay.sumCellSizes(0, fixedRowsTop);
|
|
|
|
(0, _number.rangeEachReverse)(totalRows, 1, function (row) {
|
|
rowsHeight += topOverlay.sumCellSizes(row - 1, row);
|
|
|
|
if (rootElementOffset.top + totalTableHeight - rowsHeight <= windowScrollTop) {
|
|
// Return physical row + 1
|
|
firstVisibleRow = row;
|
|
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return firstVisibleRow;
|
|
}
|
|
|
|
/**
|
|
* Get last visible row based on virtual dom and how table is visible in browser window viewport.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getLastVisibleRow',
|
|
value: function getLastVisibleRow() {
|
|
var _getVariables4 = this._getVariables(),
|
|
topOverlay = _getVariables4.topOverlay,
|
|
wtTable = _getVariables4.wtTable,
|
|
wtViewport = _getVariables4.wtViewport,
|
|
totalRows = _getVariables4.totalRows;
|
|
|
|
var lastVisibleRow = wtTable.getLastVisibleRow();
|
|
|
|
if (topOverlay.mainTableScrollableElement === window) {
|
|
var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
|
|
var windowHeight = (0, _element.innerHeight)(window);
|
|
var windowScrollTop = (0, _element.getScrollTop)(window);
|
|
|
|
// Only calculate lastVisibleRow when table didn't filled (from bottom) whole viewport space
|
|
if (rootElementOffset.top > windowScrollTop) {
|
|
var rowsHeight = wtViewport.getColumnHeaderHeight();
|
|
|
|
(0, _number.rangeEach)(1, totalRows, function (row) {
|
|
rowsHeight += topOverlay.sumCellSizes(row - 1, row);
|
|
|
|
if (rootElementOffset.top + rowsHeight - windowScrollTop >= windowHeight) {
|
|
// Return physical row - 1 (-2 because rangeEach gives row index + 1 - sumCellSizes requirements)
|
|
lastVisibleRow = row - 2;
|
|
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return lastVisibleRow;
|
|
}
|
|
|
|
/**
|
|
* Get first visible column based on virtual dom and how table is visible in browser window viewport.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getFirstVisibleColumn',
|
|
value: function getFirstVisibleColumn() {
|
|
var _getVariables5 = this._getVariables(),
|
|
leftOverlay = _getVariables5.leftOverlay,
|
|
wtTable = _getVariables5.wtTable,
|
|
wtViewport = _getVariables5.wtViewport,
|
|
totalColumns = _getVariables5.totalColumns,
|
|
fixedColumnsLeft = _getVariables5.fixedColumnsLeft;
|
|
|
|
var firstVisibleColumn = wtTable.getFirstVisibleColumn();
|
|
|
|
if (leftOverlay.mainTableScrollableElement === window) {
|
|
var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
|
|
var totalTableWidth = (0, _element.innerWidth)(wtTable.hider);
|
|
var windowWidth = (0, _element.innerWidth)(window);
|
|
var windowScrollLeft = (0, _element.getScrollLeft)(window);
|
|
|
|
// Only calculate firstVisibleColumn when table didn't filled (from left) whole viewport space
|
|
if (rootElementOffset.left + totalTableWidth - windowWidth <= windowScrollLeft) {
|
|
var columnsWidth = wtViewport.getRowHeaderWidth();
|
|
|
|
(0, _number.rangeEachReverse)(totalColumns, 1, function (column) {
|
|
columnsWidth += leftOverlay.sumCellSizes(column - 1, column);
|
|
|
|
if (rootElementOffset.left + totalTableWidth - columnsWidth <= windowScrollLeft) {
|
|
// Return physical column + 1
|
|
firstVisibleColumn = column;
|
|
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return firstVisibleColumn;
|
|
}
|
|
|
|
/**
|
|
* Get last visible column based on virtual dom and how table is visible in browser window viewport.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getLastVisibleColumn',
|
|
value: function getLastVisibleColumn() {
|
|
var _getVariables6 = this._getVariables(),
|
|
leftOverlay = _getVariables6.leftOverlay,
|
|
wtTable = _getVariables6.wtTable,
|
|
wtViewport = _getVariables6.wtViewport,
|
|
totalColumns = _getVariables6.totalColumns;
|
|
|
|
var lastVisibleColumn = wtTable.getLastVisibleColumn();
|
|
|
|
if (leftOverlay.mainTableScrollableElement === window) {
|
|
var rootElementOffset = (0, _element.offset)(wtTable.wtRootElement);
|
|
var windowWidth = (0, _element.innerWidth)(window);
|
|
var windowScrollLeft = (0, _element.getScrollLeft)(window);
|
|
|
|
// Only calculate lastVisibleColumn when table didn't filled (from right) whole viewport space
|
|
if (rootElementOffset.left > windowScrollLeft) {
|
|
var columnsWidth = wtViewport.getRowHeaderWidth();
|
|
|
|
(0, _number.rangeEach)(1, totalColumns, function (column) {
|
|
columnsWidth += leftOverlay.sumCellSizes(column - 1, column);
|
|
|
|
if (rootElementOffset.left + columnsWidth - windowScrollLeft >= windowWidth) {
|
|
// Return physical column - 1 (-2 because rangeEach gives column index + 1 - sumCellSizes requirements)
|
|
lastVisibleColumn = column - 2;
|
|
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return lastVisibleColumn;
|
|
}
|
|
|
|
/**
|
|
* Returns collection of variables used to rows and columns visibility calculations.
|
|
*
|
|
* @returns {Object}
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: '_getVariables',
|
|
value: function _getVariables() {
|
|
var wot = this.wot;
|
|
var topOverlay = wot.wtOverlays.topOverlay;
|
|
var leftOverlay = wot.wtOverlays.leftOverlay;
|
|
var wtTable = wot.wtTable;
|
|
var wtViewport = wot.wtViewport;
|
|
var totalRows = wot.getSetting('totalRows');
|
|
var totalColumns = wot.getSetting('totalColumns');
|
|
var fixedRowsTop = wot.getSetting('fixedRowsTop');
|
|
var fixedRowsBottom = wot.getSetting('fixedRowsBottom');
|
|
var fixedColumnsLeft = wot.getSetting('fixedColumnsLeft');
|
|
|
|
return {
|
|
topOverlay: topOverlay,
|
|
leftOverlay: leftOverlay,
|
|
wtTable: wtTable,
|
|
wtViewport: wtViewport,
|
|
totalRows: totalRows,
|
|
totalColumns: totalColumns,
|
|
fixedRowsTop: fixedRowsTop,
|
|
fixedRowsBottom: fixedRowsBottom,
|
|
fixedColumnsLeft: fixedColumnsLeft
|
|
};
|
|
}
|
|
}]);
|
|
|
|
return Scroll;
|
|
}();
|
|
|
|
exports.default = Scroll;
|
|
|
|
/***/ }),
|
|
/* 259 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Settings
|
|
*/
|
|
var Settings = function () {
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
* @param {Object} settings
|
|
*/
|
|
function Settings(wotInstance, settings) {
|
|
var _this = this;
|
|
|
|
_classCallCheck(this, Settings);
|
|
|
|
this.wot = wotInstance;
|
|
|
|
// legacy support
|
|
this.instance = wotInstance;
|
|
|
|
// default settings. void 0 means it is required, null means it can be empty
|
|
this.defaults = {
|
|
table: void 0,
|
|
debug: false, // shows WalkontableDebugOverlay
|
|
|
|
// presentation mode
|
|
externalRowCalculator: false,
|
|
stretchH: 'none', // values: all, last, none
|
|
currentRowClassName: null,
|
|
currentColumnClassName: null,
|
|
preventOverflow: function preventOverflow() {
|
|
return false;
|
|
},
|
|
|
|
|
|
// data source
|
|
data: void 0,
|
|
freezeOverlays: false,
|
|
fixedColumnsLeft: 0,
|
|
fixedRowsTop: 0,
|
|
fixedRowsBottom: 0,
|
|
minSpareRows: 0,
|
|
|
|
// this must be array of functions: [function (row, TH) {}]
|
|
rowHeaders: function rowHeaders() {
|
|
return [];
|
|
},
|
|
|
|
|
|
// this must be array of functions: [function (column, TH) {}]
|
|
columnHeaders: function columnHeaders() {
|
|
return [];
|
|
},
|
|
|
|
totalRows: void 0,
|
|
totalColumns: void 0,
|
|
cellRenderer: function cellRenderer(row, column, TD) {
|
|
var cellData = _this.getSetting('data', row, column);
|
|
|
|
(0, _element.fastInnerText)(TD, cellData === void 0 || cellData === null ? '' : cellData);
|
|
},
|
|
|
|
// columnWidth: 50,
|
|
columnWidth: function columnWidth(col) {
|
|
// return undefined means use default size for the rendered cell content
|
|
},
|
|
rowHeight: function rowHeight(row) {
|
|
// return undefined means use default size for the rendered cell content
|
|
},
|
|
|
|
defaultRowHeight: 23,
|
|
defaultColumnWidth: 50,
|
|
selections: null,
|
|
hideBorderOnMouseDownOver: false,
|
|
viewportRowCalculatorOverride: null,
|
|
viewportColumnCalculatorOverride: null,
|
|
|
|
// callbacks
|
|
onCellMouseDown: null,
|
|
onCellMouseOver: null,
|
|
onCellMouseOut: null,
|
|
onCellMouseUp: null,
|
|
|
|
// onCellMouseOut: null,
|
|
onCellDblClick: null,
|
|
onCellCornerMouseDown: null,
|
|
onCellCornerDblClick: null,
|
|
beforeDraw: null,
|
|
onDraw: null,
|
|
onBeforeDrawBorders: null,
|
|
onScrollVertically: null,
|
|
onScrollHorizontally: null,
|
|
onBeforeTouchScroll: null,
|
|
onAfterMomentumScroll: null,
|
|
onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(width) {
|
|
return width;
|
|
},
|
|
onModifyRowHeaderWidth: null,
|
|
|
|
// constants
|
|
scrollbarWidth: 10,
|
|
scrollbarHeight: 10,
|
|
|
|
renderAllRows: false,
|
|
groups: false,
|
|
rowHeaderWidth: null,
|
|
columnHeaderHeight: null,
|
|
headerClassName: null
|
|
};
|
|
|
|
// reference to settings
|
|
this.settings = {};
|
|
|
|
for (var i in this.defaults) {
|
|
if ((0, _object.hasOwnProperty)(this.defaults, i)) {
|
|
if (settings[i] !== void 0) {
|
|
this.settings[i] = settings[i];
|
|
} else if (this.defaults[i] === void 0) {
|
|
throw new Error('A required setting "' + i + '" was not provided');
|
|
} else {
|
|
this.settings[i] = this.defaults[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update settings
|
|
*
|
|
* @param {Object} settings
|
|
* @param {*} value
|
|
* @returns {Walkontable}
|
|
*/
|
|
|
|
|
|
_createClass(Settings, [{
|
|
key: 'update',
|
|
value: function update(settings, value) {
|
|
if (value === void 0) {
|
|
// settings is object
|
|
for (var i in settings) {
|
|
if ((0, _object.hasOwnProperty)(settings, i)) {
|
|
this.settings[i] = settings[i];
|
|
}
|
|
}
|
|
} else {
|
|
// if value is defined then settings is the key
|
|
this.settings[settings] = value;
|
|
}
|
|
return this.wot;
|
|
}
|
|
|
|
/**
|
|
* Get setting by name
|
|
*
|
|
* @param {String} key
|
|
* @param {*} param1
|
|
* @param {*} param2
|
|
* @param {*} param3
|
|
* @param {*} param4
|
|
* @returns {*}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSetting',
|
|
value: function getSetting(key, param1, param2, param3, param4) {
|
|
if (typeof this.settings[key] === 'function') {
|
|
// this is faster than .apply - https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
|
|
return this.settings[key](param1, param2, param3, param4);
|
|
} else if (param1 !== void 0 && Array.isArray(this.settings[key])) {
|
|
// perhaps this can be removed, it is only used in tests
|
|
return this.settings[key][param1];
|
|
}
|
|
|
|
return this.settings[key];
|
|
}
|
|
|
|
/**
|
|
* Checks if setting exists
|
|
*
|
|
* @param {Boolean} key
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'has',
|
|
value: function has(key) {
|
|
return !!this.settings[key];
|
|
}
|
|
}]);
|
|
|
|
return Settings;
|
|
}();
|
|
|
|
exports.default = Settings;
|
|
|
|
/***/ }),
|
|
/* 260 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _function = __webpack_require__(35);
|
|
|
|
var _coords = __webpack_require__(43);
|
|
|
|
var _coords2 = _interopRequireDefault(_coords);
|
|
|
|
var _range = __webpack_require__(69);
|
|
|
|
var _range2 = _interopRequireDefault(_range);
|
|
|
|
var _column = __webpack_require__(255);
|
|
|
|
var _column2 = _interopRequireDefault(_column);
|
|
|
|
var _row = __webpack_require__(256);
|
|
|
|
var _row2 = _interopRequireDefault(_row);
|
|
|
|
var _tableRenderer = __webpack_require__(261);
|
|
|
|
var _tableRenderer2 = _interopRequireDefault(_tableRenderer);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
*
|
|
*/
|
|
var Table = function () {
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
* @param {HTMLTableElement} table
|
|
*/
|
|
function Table(wotInstance, table) {
|
|
var _this = this;
|
|
|
|
_classCallCheck(this, Table);
|
|
|
|
this.wot = wotInstance;
|
|
|
|
// legacy support
|
|
this.instance = this.wot;
|
|
this.TABLE = table;
|
|
this.TBODY = null;
|
|
this.THEAD = null;
|
|
this.COLGROUP = null;
|
|
this.tableOffset = 0;
|
|
this.holderOffset = 0;
|
|
|
|
(0, _element.removeTextNodes)(this.TABLE);
|
|
|
|
this.spreader = this.createSpreader(this.TABLE);
|
|
this.hider = this.createHider(this.spreader);
|
|
this.holder = this.createHolder(this.hider);
|
|
|
|
this.wtRootElement = this.holder.parentNode;
|
|
this.alignOverlaysWithTrimmingContainer();
|
|
this.fixTableDomTree();
|
|
|
|
this.colgroupChildrenLength = this.COLGROUP.childNodes.length;
|
|
this.theadChildrenLength = this.THEAD.firstChild ? this.THEAD.firstChild.childNodes.length : 0;
|
|
this.tbodyChildrenLength = this.TBODY.childNodes.length;
|
|
|
|
this.rowFilter = null;
|
|
this.columnFilter = null;
|
|
this.correctHeaderWidth = false;
|
|
|
|
var origRowHeaderWidth = this.wot.wtSettings.settings.rowHeaderWidth;
|
|
|
|
// Fix for jumping row headers (https://github.com/handsontable/handsontable/issues/3850)
|
|
this.wot.wtSettings.settings.rowHeaderWidth = function () {
|
|
return _this._modifyRowHeaderWidth(origRowHeaderWidth);
|
|
};
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
|
|
_createClass(Table, [{
|
|
key: 'fixTableDomTree',
|
|
value: function fixTableDomTree() {
|
|
this.TBODY = this.TABLE.querySelector('tbody');
|
|
|
|
if (!this.TBODY) {
|
|
this.TBODY = document.createElement('tbody');
|
|
this.TABLE.appendChild(this.TBODY);
|
|
}
|
|
this.THEAD = this.TABLE.querySelector('thead');
|
|
|
|
if (!this.THEAD) {
|
|
this.THEAD = document.createElement('thead');
|
|
this.TABLE.insertBefore(this.THEAD, this.TBODY);
|
|
}
|
|
this.COLGROUP = this.TABLE.querySelector('colgroup');
|
|
|
|
if (!this.COLGROUP) {
|
|
this.COLGROUP = document.createElement('colgroup');
|
|
this.TABLE.insertBefore(this.COLGROUP, this.THEAD);
|
|
}
|
|
|
|
if (this.wot.getSetting('columnHeaders').length && !this.THEAD.childNodes.length) {
|
|
this.THEAD.appendChild(document.createElement('TR'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param table
|
|
* @returns {HTMLElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createSpreader',
|
|
value: function createSpreader(table) {
|
|
var parent = table.parentNode;
|
|
var spreader = void 0;
|
|
|
|
if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
|
|
spreader = document.createElement('div');
|
|
spreader.className = 'wtSpreader';
|
|
|
|
if (parent) {
|
|
// if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it
|
|
parent.insertBefore(spreader, table);
|
|
}
|
|
spreader.appendChild(table);
|
|
}
|
|
spreader.style.position = 'relative';
|
|
|
|
return spreader;
|
|
}
|
|
|
|
/**
|
|
* @param spreader
|
|
* @returns {HTMLElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createHider',
|
|
value: function createHider(spreader) {
|
|
var parent = spreader.parentNode;
|
|
var hider = void 0;
|
|
|
|
if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
|
|
hider = document.createElement('div');
|
|
hider.className = 'wtHider';
|
|
|
|
if (parent) {
|
|
// if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it
|
|
parent.insertBefore(hider, spreader);
|
|
}
|
|
hider.appendChild(spreader);
|
|
}
|
|
|
|
return hider;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param hider
|
|
* @returns {HTMLElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createHolder',
|
|
value: function createHolder(hider) {
|
|
var parent = hider.parentNode;
|
|
var holder = void 0;
|
|
|
|
if (!parent || parent.nodeType !== 1 || !(0, _element.hasClass)(parent, 'wtHolder')) {
|
|
holder = document.createElement('div');
|
|
holder.style.position = 'relative';
|
|
holder.className = 'wtHolder';
|
|
|
|
if (parent) {
|
|
// if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it
|
|
parent.insertBefore(holder, hider);
|
|
}
|
|
if (!this.isWorkingOnClone()) {
|
|
holder.parentNode.className += 'ht_master handsontable';
|
|
}
|
|
holder.appendChild(hider);
|
|
}
|
|
|
|
return holder;
|
|
}
|
|
}, {
|
|
key: 'alignOverlaysWithTrimmingContainer',
|
|
value: function alignOverlaysWithTrimmingContainer() {
|
|
var trimmingElement = (0, _element.getTrimmingContainer)(this.wtRootElement);
|
|
|
|
if (!this.isWorkingOnClone()) {
|
|
this.holder.parentNode.style.position = 'relative';
|
|
|
|
if (trimmingElement === window) {
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
|
|
if (!preventOverflow) {
|
|
this.holder.style.overflow = 'visible';
|
|
this.wtRootElement.style.overflow = 'visible';
|
|
}
|
|
} else {
|
|
this.holder.style.width = (0, _element.getStyle)(trimmingElement, 'width');
|
|
this.holder.style.height = (0, _element.getStyle)(trimmingElement, 'height');
|
|
this.holder.style.overflow = '';
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: 'isWorkingOnClone',
|
|
value: function isWorkingOnClone() {
|
|
return !!this.wot.cloneSource;
|
|
}
|
|
|
|
/**
|
|
* Redraws the table
|
|
*
|
|
* @param {Boolean} fastDraw If TRUE, will try to avoid full redraw and only update the border positions. If FALSE or UNDEFINED, will perform a full redraw
|
|
* @returns {Table}
|
|
*/
|
|
|
|
}, {
|
|
key: 'draw',
|
|
value: function draw(fastDraw) {
|
|
var _wot = this.wot,
|
|
wtOverlays = _wot.wtOverlays,
|
|
wtViewport = _wot.wtViewport;
|
|
|
|
var totalRows = this.instance.getSetting('totalRows');
|
|
var rowHeaders = this.wot.getSetting('rowHeaders').length;
|
|
var columnHeaders = this.wot.getSetting('columnHeaders').length;
|
|
var syncScroll = false;
|
|
|
|
if (!this.isWorkingOnClone()) {
|
|
this.holderOffset = (0, _element.offset)(this.holder);
|
|
fastDraw = wtViewport.createRenderCalculators(fastDraw);
|
|
|
|
if (rowHeaders && !this.wot.getSetting('fixedColumnsLeft')) {
|
|
var leftScrollPos = wtOverlays.leftOverlay.getScrollPosition();
|
|
var previousState = this.correctHeaderWidth;
|
|
|
|
this.correctHeaderWidth = leftScrollPos > 0;
|
|
|
|
if (previousState !== this.correctHeaderWidth) {
|
|
fastDraw = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!this.isWorkingOnClone()) {
|
|
syncScroll = wtOverlays.prepareOverlays();
|
|
}
|
|
|
|
if (fastDraw) {
|
|
if (!this.isWorkingOnClone()) {
|
|
// in case we only scrolled without redraw, update visible rows information in oldRowsCalculator
|
|
wtViewport.createVisibleCalculators();
|
|
}
|
|
if (wtOverlays) {
|
|
wtOverlays.refresh(true);
|
|
}
|
|
} else {
|
|
if (this.isWorkingOnClone()) {
|
|
this.tableOffset = this.wot.cloneSource.wtTable.tableOffset;
|
|
} else {
|
|
this.tableOffset = (0, _element.offset)(this.TABLE);
|
|
}
|
|
var startRow = void 0;
|
|
|
|
if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER)) {
|
|
startRow = 0;
|
|
} else if (_base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.instance.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
|
|
startRow = Math.max(totalRows - this.wot.getSetting('fixedRowsBottom'), 0);
|
|
} else {
|
|
startRow = wtViewport.rowsRenderCalculator.startRow;
|
|
}
|
|
var startColumn = void 0;
|
|
|
|
if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_DEBUG) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_LEFT) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_TOP_LEFT_CORNER) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
|
|
startColumn = 0;
|
|
} else {
|
|
startColumn = wtViewport.columnsRenderCalculator.startColumn;
|
|
}
|
|
this.rowFilter = new _row2.default(startRow, totalRows, columnHeaders);
|
|
this.columnFilter = new _column2.default(startColumn, this.wot.getSetting('totalColumns'), rowHeaders);
|
|
|
|
this.alignOverlaysWithTrimmingContainer();
|
|
this._doDraw(); // creates calculator after draw
|
|
}
|
|
this.refreshSelections(fastDraw);
|
|
|
|
if (!this.isWorkingOnClone()) {
|
|
wtOverlays.topOverlay.resetFixedPosition();
|
|
|
|
if (wtOverlays.bottomOverlay.clone) {
|
|
wtOverlays.bottomOverlay.resetFixedPosition();
|
|
}
|
|
|
|
wtOverlays.leftOverlay.resetFixedPosition();
|
|
|
|
if (wtOverlays.topLeftCornerOverlay) {
|
|
wtOverlays.topLeftCornerOverlay.resetFixedPosition();
|
|
}
|
|
|
|
if (wtOverlays.bottomLeftCornerOverlay && wtOverlays.bottomLeftCornerOverlay.clone) {
|
|
wtOverlays.bottomLeftCornerOverlay.resetFixedPosition();
|
|
}
|
|
}
|
|
if (syncScroll) {
|
|
wtOverlays.syncScrollWithMaster();
|
|
}
|
|
this.wot.drawn = true;
|
|
|
|
return this;
|
|
}
|
|
}, {
|
|
key: '_doDraw',
|
|
value: function _doDraw() {
|
|
var wtRenderer = new _tableRenderer2.default(this);
|
|
|
|
wtRenderer.render();
|
|
}
|
|
}, {
|
|
key: 'removeClassFromCells',
|
|
value: function removeClassFromCells(className) {
|
|
var nodes = this.TABLE.querySelectorAll('.' + className);
|
|
|
|
for (var i = 0, len = nodes.length; i < len; i++) {
|
|
(0, _element.removeClass)(nodes[i], className);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'refreshSelections',
|
|
value: function refreshSelections(fastDraw) {
|
|
if (!this.wot.selections) {
|
|
return;
|
|
}
|
|
var len = this.wot.selections.length;
|
|
|
|
if (fastDraw) {
|
|
for (var i = 0; i < len; i++) {
|
|
// there was no rerender, so we need to remove classNames by ourselves
|
|
if (this.wot.selections[i].settings.className) {
|
|
this.removeClassFromCells(this.wot.selections[i].settings.className);
|
|
}
|
|
if (this.wot.selections[i].settings.highlightHeaderClassName) {
|
|
this.removeClassFromCells(this.wot.selections[i].settings.highlightHeaderClassName);
|
|
}
|
|
if (this.wot.selections[i].settings.highlightRowClassName) {
|
|
this.removeClassFromCells(this.wot.selections[i].settings.highlightRowClassName);
|
|
}
|
|
if (this.wot.selections[i].settings.highlightColumnClassName) {
|
|
this.removeClassFromCells(this.wot.selections[i].settings.highlightColumnClassName);
|
|
}
|
|
}
|
|
}
|
|
for (var _i = 0; _i < len; _i++) {
|
|
this.wot.selections[_i].draw(this.wot, fastDraw);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get cell element at coords.
|
|
*
|
|
* @param {CellCoords} coords
|
|
* @returns {HTMLElement|Number} HTMLElement on success or Number one of the exit codes on error:
|
|
* -1 row before viewport
|
|
* -2 row after viewport
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCell',
|
|
value: function getCell(coords) {
|
|
if (this.isRowBeforeRenderedRows(coords.row)) {
|
|
// row before rendered rows
|
|
return -1;
|
|
} else if (this.isRowAfterRenderedRows(coords.row)) {
|
|
// row after rendered rows
|
|
return -2;
|
|
}
|
|
|
|
var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(coords.row)];
|
|
|
|
if (TR) {
|
|
return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(coords.col)];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* getColumnHeader
|
|
*
|
|
* @param {Number} col Column index
|
|
* @param {Number} [level=0] Header level (0 = most distant to the table)
|
|
* @returns {Object} HTMLElement on success or undefined on error
|
|
*/
|
|
|
|
}, {
|
|
key: 'getColumnHeader',
|
|
value: function getColumnHeader(col) {
|
|
var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
|
|
var TR = this.THEAD.childNodes[level];
|
|
|
|
if (TR) {
|
|
return TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(col)];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* getRowHeader
|
|
*
|
|
* @param {Number} row Row index
|
|
* @returns {HTMLElement} HTMLElement on success or Number one of the exit codes on error: `null table doesn't have row headers`
|
|
*/
|
|
|
|
}, {
|
|
key: 'getRowHeader',
|
|
value: function getRowHeader(row) {
|
|
if (this.columnFilter.sourceColumnToVisibleRowHeadedColumn(0) === 0) {
|
|
return null;
|
|
}
|
|
var TR = this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)];
|
|
|
|
if (TR) {
|
|
return TR.childNodes[0];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns cell coords object for a given TD (or a child element of a TD element).
|
|
*
|
|
* @param {HTMLTableCellElement} TD A cell DOM element (or a child of one).
|
|
* @returns {CellCoords|null} The coordinates of the provided TD element (or the closest TD element) or null, if the provided element is not applicable.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCoords',
|
|
value: function getCoords(TD) {
|
|
if (TD.nodeName !== 'TD' && TD.nodeName !== 'TH') {
|
|
TD = (0, _element.closest)(TD, ['TD', 'TH']);
|
|
}
|
|
|
|
if (TD === null) {
|
|
return null;
|
|
}
|
|
|
|
var TR = TD.parentNode;
|
|
var CONTAINER = TR.parentNode;
|
|
var row = (0, _element.index)(TR);
|
|
var col = TD.cellIndex;
|
|
|
|
if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_TOP, TD)) {
|
|
if (CONTAINER.nodeName === 'THEAD') {
|
|
row -= CONTAINER.childNodes.length;
|
|
}
|
|
} else if (CONTAINER === this.THEAD) {
|
|
row = this.rowFilter.visibleColHeadedRowToSourceRow(row);
|
|
} else {
|
|
row = this.rowFilter.renderedToSource(row);
|
|
}
|
|
|
|
if ((0, _element.overlayContainsElement)(_base2.default.CLONE_TOP_LEFT_CORNER, TD) || (0, _element.overlayContainsElement)(_base2.default.CLONE_LEFT, TD)) {
|
|
col = this.columnFilter.offsettedTH(col);
|
|
} else {
|
|
col = this.columnFilter.visibleRowHeadedColumnToSourceColumn(col);
|
|
}
|
|
|
|
return new _coords2.default(row, col);
|
|
}
|
|
}, {
|
|
key: 'getTrForRow',
|
|
value: function getTrForRow(row) {
|
|
return this.TBODY.childNodes[this.rowFilter.sourceToRendered(row)];
|
|
}
|
|
}, {
|
|
key: 'getFirstRenderedRow',
|
|
value: function getFirstRenderedRow() {
|
|
return this.wot.wtViewport.rowsRenderCalculator.startRow;
|
|
}
|
|
}, {
|
|
key: 'getFirstVisibleRow',
|
|
value: function getFirstVisibleRow() {
|
|
return this.wot.wtViewport.rowsVisibleCalculator.startRow;
|
|
}
|
|
}, {
|
|
key: 'getFirstRenderedColumn',
|
|
value: function getFirstRenderedColumn() {
|
|
return this.wot.wtViewport.columnsRenderCalculator.startColumn;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number} Returns -1 if no row is visible
|
|
*/
|
|
|
|
}, {
|
|
key: 'getFirstVisibleColumn',
|
|
value: function getFirstVisibleColumn() {
|
|
return this.wot.wtViewport.columnsVisibleCalculator.startColumn;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number} Returns -1 if no row is visible
|
|
*/
|
|
|
|
}, {
|
|
key: 'getLastRenderedRow',
|
|
value: function getLastRenderedRow() {
|
|
return this.wot.wtViewport.rowsRenderCalculator.endRow;
|
|
}
|
|
}, {
|
|
key: 'getLastVisibleRow',
|
|
value: function getLastVisibleRow() {
|
|
return this.wot.wtViewport.rowsVisibleCalculator.endRow;
|
|
}
|
|
}, {
|
|
key: 'getLastRenderedColumn',
|
|
value: function getLastRenderedColumn() {
|
|
return this.wot.wtViewport.columnsRenderCalculator.endColumn;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number} Returns -1 if no column is visible
|
|
*/
|
|
|
|
}, {
|
|
key: 'getLastVisibleColumn',
|
|
value: function getLastVisibleColumn() {
|
|
return this.wot.wtViewport.columnsVisibleCalculator.endColumn;
|
|
}
|
|
}, {
|
|
key: 'isRowBeforeRenderedRows',
|
|
value: function isRowBeforeRenderedRows(row) {
|
|
return this.rowFilter && this.rowFilter.sourceToRendered(row) < 0 && row >= 0;
|
|
}
|
|
}, {
|
|
key: 'isRowAfterViewport',
|
|
value: function isRowAfterViewport(row) {
|
|
return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastVisibleRow();
|
|
}
|
|
}, {
|
|
key: 'isRowAfterRenderedRows',
|
|
value: function isRowAfterRenderedRows(row) {
|
|
return this.rowFilter && this.rowFilter.sourceToRendered(row) > this.getLastRenderedRow();
|
|
}
|
|
}, {
|
|
key: 'isColumnBeforeViewport',
|
|
value: function isColumnBeforeViewport(column) {
|
|
return this.columnFilter && this.columnFilter.sourceToRendered(column) < 0 && column >= 0;
|
|
}
|
|
}, {
|
|
key: 'isColumnAfterViewport',
|
|
value: function isColumnAfterViewport(column) {
|
|
return this.columnFilter && this.columnFilter.sourceToRendered(column) > this.getLastVisibleColumn();
|
|
}
|
|
}, {
|
|
key: 'isLastRowFullyVisible',
|
|
value: function isLastRowFullyVisible() {
|
|
return this.getLastVisibleRow() === this.getLastRenderedRow();
|
|
}
|
|
}, {
|
|
key: 'isLastColumnFullyVisible',
|
|
value: function isLastColumnFullyVisible() {
|
|
return this.getLastVisibleColumn() === this.getLastRenderedColumn();
|
|
}
|
|
}, {
|
|
key: 'getRenderedColumnsCount',
|
|
value: function getRenderedColumnsCount() {
|
|
var columnsCount = this.wot.wtViewport.columnsRenderCalculator.count;
|
|
var totalColumns = this.wot.getSetting('totalColumns');
|
|
|
|
if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) {
|
|
columnsCount = totalColumns;
|
|
} else if (this.wot.isOverlayName(_base2.default.CLONE_LEFT) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
|
|
return Math.min(this.wot.getSetting('fixedColumnsLeft'), totalColumns);
|
|
}
|
|
|
|
return columnsCount;
|
|
}
|
|
}, {
|
|
key: 'getRenderedRowsCount',
|
|
value: function getRenderedRowsCount() {
|
|
var rowsCount = this.wot.wtViewport.rowsRenderCalculator.count;
|
|
var totalRows = this.wot.getSetting('totalRows');
|
|
|
|
if (this.wot.isOverlayName(_base2.default.CLONE_DEBUG)) {
|
|
rowsCount = totalRows;
|
|
} else if (this.wot.isOverlayName(_base2.default.CLONE_TOP) || this.wot.isOverlayName(_base2.default.CLONE_TOP_LEFT_CORNER)) {
|
|
rowsCount = Math.min(this.wot.getSetting('fixedRowsTop'), totalRows);
|
|
} else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM) || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
|
|
rowsCount = Math.min(this.wot.getSetting('fixedRowsBottom'), totalRows);
|
|
}
|
|
|
|
return rowsCount;
|
|
}
|
|
}, {
|
|
key: 'getVisibleRowsCount',
|
|
value: function getVisibleRowsCount() {
|
|
return this.wot.wtViewport.rowsVisibleCalculator.count;
|
|
}
|
|
}, {
|
|
key: 'allRowsInViewport',
|
|
value: function allRowsInViewport() {
|
|
return this.wot.getSetting('totalRows') == this.getVisibleRowsCount();
|
|
}
|
|
|
|
/**
|
|
* Checks if any of the row's cells content exceeds its initial height, and if so, returns the oversized height
|
|
*
|
|
* @param {Number} sourceRow
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getRowHeight',
|
|
value: function getRowHeight(sourceRow) {
|
|
var height = this.wot.wtSettings.settings.rowHeight(sourceRow);
|
|
var oversizedHeight = this.wot.wtViewport.oversizedRows[sourceRow];
|
|
|
|
if (oversizedHeight !== void 0) {
|
|
height = height === void 0 ? oversizedHeight : Math.max(height, oversizedHeight);
|
|
}
|
|
|
|
return height;
|
|
}
|
|
}, {
|
|
key: 'getColumnHeaderHeight',
|
|
value: function getColumnHeaderHeight(level) {
|
|
var height = this.wot.wtSettings.settings.defaultRowHeight;
|
|
var oversizedHeight = this.wot.wtViewport.oversizedColumnHeaders[level];
|
|
|
|
if (oversizedHeight !== void 0) {
|
|
height = height ? Math.max(height, oversizedHeight) : oversizedHeight;
|
|
}
|
|
|
|
return height;
|
|
}
|
|
}, {
|
|
key: 'getVisibleColumnsCount',
|
|
value: function getVisibleColumnsCount() {
|
|
return this.wot.wtViewport.columnsVisibleCalculator.count;
|
|
}
|
|
}, {
|
|
key: 'allColumnsInViewport',
|
|
value: function allColumnsInViewport() {
|
|
return this.wot.getSetting('totalColumns') == this.getVisibleColumnsCount();
|
|
}
|
|
}, {
|
|
key: 'getColumnWidth',
|
|
value: function getColumnWidth(sourceColumn) {
|
|
var width = this.wot.wtSettings.settings.columnWidth;
|
|
|
|
if (typeof width === 'function') {
|
|
width = width(sourceColumn);
|
|
} else if ((typeof width === 'undefined' ? 'undefined' : _typeof(width)) === 'object') {
|
|
width = width[sourceColumn];
|
|
}
|
|
|
|
return width || this.wot.wtSettings.settings.defaultColumnWidth;
|
|
}
|
|
}, {
|
|
key: 'getStretchedColumnWidth',
|
|
value: function getStretchedColumnWidth(sourceColumn) {
|
|
var columnWidth = this.getColumnWidth(sourceColumn);
|
|
var width = columnWidth == null ? this.instance.wtSettings.settings.defaultColumnWidth : columnWidth;
|
|
var calculator = this.wot.wtViewport.columnsRenderCalculator;
|
|
|
|
if (calculator) {
|
|
var stretchedWidth = calculator.getStretchedColumnWidth(sourceColumn, width);
|
|
|
|
if (stretchedWidth) {
|
|
width = stretchedWidth;
|
|
}
|
|
}
|
|
|
|
return width;
|
|
}
|
|
|
|
/**
|
|
* Modify row header widths provided by user in class contructor.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: '_modifyRowHeaderWidth',
|
|
value: function _modifyRowHeaderWidth(rowHeaderWidthFactory) {
|
|
var widths = (0, _function.isFunction)(rowHeaderWidthFactory) ? rowHeaderWidthFactory() : null;
|
|
|
|
if (Array.isArray(widths)) {
|
|
widths = [].concat(_toConsumableArray(widths));
|
|
widths[widths.length - 1] = this._correctRowHeaderWidth(widths[widths.length - 1]);
|
|
} else {
|
|
widths = this._correctRowHeaderWidth(widths);
|
|
}
|
|
|
|
return widths;
|
|
}
|
|
|
|
/**
|
|
* Correct row header width if necessary.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: '_correctRowHeaderWidth',
|
|
value: function _correctRowHeaderWidth(width) {
|
|
if (typeof width !== 'number') {
|
|
width = this.wot.getSetting('defaultColumnWidth');
|
|
}
|
|
if (this.correctHeaderWidth) {
|
|
width++;
|
|
}
|
|
|
|
return width;
|
|
}
|
|
}]);
|
|
|
|
return Table;
|
|
}();
|
|
|
|
exports.default = Table;
|
|
|
|
/***/ }),
|
|
/* 261 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var performanceWarningAppeared = false;
|
|
|
|
/**
|
|
* @class TableRenderer
|
|
*/
|
|
|
|
var TableRenderer = function () {
|
|
/**
|
|
* @param {WalkontableTable} wtTable
|
|
*/
|
|
function TableRenderer(wtTable) {
|
|
_classCallCheck(this, TableRenderer);
|
|
|
|
this.wtTable = wtTable;
|
|
this.wot = wtTable.instance;
|
|
|
|
// legacy support
|
|
this.instance = wtTable.instance;
|
|
|
|
this.rowFilter = wtTable.rowFilter;
|
|
this.columnFilter = wtTable.columnFilter;
|
|
|
|
this.TABLE = wtTable.TABLE;
|
|
this.THEAD = wtTable.THEAD;
|
|
this.TBODY = wtTable.TBODY;
|
|
this.COLGROUP = wtTable.COLGROUP;
|
|
|
|
this.rowHeaders = [];
|
|
this.rowHeaderCount = 0;
|
|
this.columnHeaders = [];
|
|
this.columnHeaderCount = 0;
|
|
this.fixedRowsTop = 0;
|
|
this.fixedRowsBottom = 0;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
|
|
_createClass(TableRenderer, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
if (!this.wtTable.isWorkingOnClone()) {
|
|
var skipRender = {};
|
|
this.wot.getSetting('beforeDraw', true, skipRender);
|
|
|
|
if (skipRender.skipRender === true) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.rowHeaders = this.wot.getSetting('rowHeaders');
|
|
this.rowHeaderCount = this.rowHeaders.length;
|
|
this.fixedRowsTop = this.wot.getSetting('fixedRowsTop');
|
|
this.fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
|
|
this.columnHeaders = this.wot.getSetting('columnHeaders');
|
|
this.columnHeaderCount = this.columnHeaders.length;
|
|
|
|
var columnsToRender = this.wtTable.getRenderedColumnsCount();
|
|
var rowsToRender = this.wtTable.getRenderedRowsCount();
|
|
var totalColumns = this.wot.getSetting('totalColumns');
|
|
var totalRows = this.wot.getSetting('totalRows');
|
|
var workspaceWidth = void 0;
|
|
var adjusted = false;
|
|
|
|
if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
|
|
|
|
// do NOT render headers on the bottom or bottom-left corner overlay
|
|
this.columnHeaders = [];
|
|
this.columnHeaderCount = 0;
|
|
}
|
|
|
|
if (totalColumns >= 0) {
|
|
// prepare COL and TH elements for rendering
|
|
this.adjustAvailableNodes();
|
|
adjusted = true;
|
|
|
|
// adjust column widths according to user widths settings
|
|
this.renderColumnHeaders();
|
|
|
|
// Render table rows
|
|
this.renderRows(totalRows, rowsToRender, columnsToRender);
|
|
|
|
if (!this.wtTable.isWorkingOnClone()) {
|
|
workspaceWidth = this.wot.wtViewport.getWorkspaceWidth();
|
|
this.wot.wtViewport.containerWidth = null;
|
|
}
|
|
|
|
this.adjustColumnWidths(columnsToRender);
|
|
this.markOversizedColumnHeaders();
|
|
this.adjustColumnHeaderHeights();
|
|
}
|
|
|
|
if (!adjusted) {
|
|
this.adjustAvailableNodes();
|
|
}
|
|
this.removeRedundantRows(rowsToRender);
|
|
|
|
if (!this.wtTable.isWorkingOnClone() || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) {
|
|
this.markOversizedRows();
|
|
}
|
|
if (!this.wtTable.isWorkingOnClone()) {
|
|
this.wot.wtViewport.createVisibleCalculators();
|
|
this.wot.wtOverlays.refresh(false);
|
|
|
|
this.wot.wtOverlays.applyToDOM();
|
|
|
|
var hiderWidth = (0, _element.outerWidth)(this.wtTable.hider);
|
|
var tableWidth = (0, _element.outerWidth)(this.wtTable.TABLE);
|
|
|
|
if (hiderWidth !== 0 && tableWidth !== hiderWidth) {
|
|
// Recalculate the column widths, if width changes made in the overlays removed the scrollbar, thus changing the viewport width.
|
|
this.adjustColumnWidths(columnsToRender);
|
|
}
|
|
|
|
if (workspaceWidth !== this.wot.wtViewport.getWorkspaceWidth()) {
|
|
// workspace width changed though to shown/hidden vertical scrollbar. Let's reapply stretching
|
|
this.wot.wtViewport.containerWidth = null;
|
|
|
|
var firstRendered = this.wtTable.getFirstRenderedColumn();
|
|
var lastRendered = this.wtTable.getLastRenderedColumn();
|
|
var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth');
|
|
var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth');
|
|
|
|
rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);
|
|
|
|
if (rowHeaderWidthSetting != null) {
|
|
for (var i = 0; i < this.rowHeaderCount; i++) {
|
|
var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
|
|
|
|
width = width == null ? defaultColumnWidth : width;
|
|
|
|
this.COLGROUP.childNodes[i].style.width = width + 'px';
|
|
}
|
|
}
|
|
|
|
for (var _i = firstRendered; _i < lastRendered; _i++) {
|
|
var _width = this.wtTable.getStretchedColumnWidth(_i);
|
|
var renderedIndex = this.columnFilter.sourceToRendered(_i);
|
|
|
|
this.COLGROUP.childNodes[renderedIndex + this.rowHeaderCount].style.width = _width + 'px';
|
|
}
|
|
}
|
|
|
|
this.wot.getSetting('onDraw', true);
|
|
} else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) {
|
|
this.wot.cloneSource.wtOverlays.adjustElementsSize();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Number} renderedRowsCount
|
|
*/
|
|
|
|
}, {
|
|
key: 'removeRedundantRows',
|
|
value: function removeRedundantRows(renderedRowsCount) {
|
|
while (this.wtTable.tbodyChildrenLength > renderedRowsCount) {
|
|
this.TBODY.removeChild(this.TBODY.lastChild);
|
|
this.wtTable.tbodyChildrenLength--;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Number} totalRows
|
|
* @param {Number} rowsToRender
|
|
* @param {Number} columnsToRender
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderRows',
|
|
value: function renderRows(totalRows, rowsToRender, columnsToRender) {
|
|
var lastTD = void 0,
|
|
TR = void 0;
|
|
var visibleRowIndex = 0;
|
|
var sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex);
|
|
var isWorkingOnClone = this.wtTable.isWorkingOnClone();
|
|
|
|
while (sourceRowIndex < totalRows && sourceRowIndex >= 0) {
|
|
if (!performanceWarningAppeared && visibleRowIndex > 1000) {
|
|
performanceWarningAppeared = true;
|
|
console.warn('Performance tip: Handsontable rendered more than 1000 visible rows. Consider limiting the number ' + 'of rendered rows by specifying the table height and/or turning off the "renderAllRows" option.');
|
|
}
|
|
if (rowsToRender !== void 0 && visibleRowIndex === rowsToRender) {
|
|
// We have as much rows as needed for this clone
|
|
break;
|
|
}
|
|
TR = this.getOrCreateTrForRow(visibleRowIndex, TR);
|
|
|
|
// Render row headers
|
|
this.renderRowHeaders(sourceRowIndex, TR);
|
|
// Add and/or remove TDs to TR to match the desired number
|
|
this.adjustColumns(TR, columnsToRender + this.rowHeaderCount);
|
|
|
|
lastTD = this.renderCells(sourceRowIndex, TR, columnsToRender);
|
|
|
|
if (!isWorkingOnClone ||
|
|
// Necessary to refresh oversized row heights after editing cell in overlays
|
|
this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) {
|
|
// Reset the oversized row cache for this row
|
|
this.resetOversizedRow(sourceRowIndex);
|
|
}
|
|
|
|
if (TR.firstChild) {
|
|
// if I have 2 fixed columns with one-line content and the 3rd column has a multiline content, this is
|
|
// the way to make sure that the overlay will has same row height
|
|
var height = this.wot.wtTable.getRowHeight(sourceRowIndex);
|
|
|
|
if (height) {
|
|
// Decrease height. 1 pixel will be "replaced" by 1px border top
|
|
height--;
|
|
TR.firstChild.style.height = height + 'px';
|
|
} else {
|
|
TR.firstChild.style.height = '';
|
|
}
|
|
}
|
|
visibleRowIndex++;
|
|
sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reset the oversized row cache for the provided index
|
|
*
|
|
* @param {Number} sourceRow Row index
|
|
*/
|
|
|
|
}, {
|
|
key: 'resetOversizedRow',
|
|
value: function resetOversizedRow(sourceRow) {
|
|
if (this.wot.getSetting('externalRowCalculator')) {
|
|
return;
|
|
}
|
|
if (this.wot.wtViewport.oversizedRows && this.wot.wtViewport.oversizedRows[sourceRow]) {
|
|
this.wot.wtViewport.oversizedRows[sourceRow] = void 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if any of the rendered rows is higher than expected, and if so, cache them
|
|
*/
|
|
|
|
}, {
|
|
key: 'markOversizedRows',
|
|
value: function markOversizedRows() {
|
|
if (this.wot.getSetting('externalRowCalculator')) {
|
|
return;
|
|
}
|
|
var rowCount = this.instance.wtTable.TBODY.childNodes.length;
|
|
var expectedTableHeight = rowCount * this.instance.wtSettings.settings.defaultRowHeight;
|
|
var actualTableHeight = (0, _element.innerHeight)(this.instance.wtTable.TBODY) - 1;
|
|
var previousRowHeight = void 0;
|
|
var rowInnerHeight = void 0;
|
|
var sourceRowIndex = void 0;
|
|
var currentTr = void 0;
|
|
var rowHeader = void 0;
|
|
var totalRows = this.instance.getSetting('totalRows');
|
|
|
|
if (expectedTableHeight === actualTableHeight && !this.instance.getSetting('fixedRowsBottom')) {
|
|
// If the actual table height equals rowCount * default single row height, no row is oversized -> no need to iterate over them
|
|
return;
|
|
}
|
|
|
|
while (rowCount) {
|
|
rowCount--;
|
|
sourceRowIndex = this.instance.wtTable.rowFilter.renderedToSource(rowCount);
|
|
previousRowHeight = this.instance.wtTable.getRowHeight(sourceRowIndex);
|
|
currentTr = this.instance.wtTable.getTrForRow(sourceRowIndex);
|
|
rowHeader = currentTr.querySelector('th');
|
|
|
|
if (rowHeader) {
|
|
rowInnerHeight = (0, _element.innerHeight)(rowHeader);
|
|
} else {
|
|
rowInnerHeight = (0, _element.innerHeight)(currentTr) - 1;
|
|
}
|
|
|
|
if (!previousRowHeight && this.instance.wtSettings.settings.defaultRowHeight < rowInnerHeight || previousRowHeight < rowInnerHeight) {
|
|
this.instance.wtViewport.oversizedRows[sourceRowIndex] = ++rowInnerHeight;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if any of the rendered columns is higher than expected, and if so, cache them.
|
|
*/
|
|
|
|
}, {
|
|
key: 'markOversizedColumnHeaders',
|
|
value: function markOversizedColumnHeaders() {
|
|
var overlayName = this.wot.getOverlayName();
|
|
|
|
if (!this.columnHeaderCount || this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] || this.wtTable.isWorkingOnClone()) {
|
|
return;
|
|
}
|
|
var columnCount = this.wtTable.getRenderedColumnsCount();
|
|
|
|
for (var i = 0; i < this.columnHeaderCount; i++) {
|
|
for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) {
|
|
this.markIfOversizedColumnHeader(renderedColumnIndex);
|
|
}
|
|
}
|
|
this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] = true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustColumnHeaderHeights',
|
|
value: function adjustColumnHeaderHeights() {
|
|
var columnHeaders = this.wot.getSetting('columnHeaders');
|
|
var children = this.wot.wtTable.THEAD.childNodes;
|
|
var oversizedColumnHeaders = this.wot.wtViewport.oversizedColumnHeaders;
|
|
|
|
for (var i = 0, len = columnHeaders.length; i < len; i++) {
|
|
if (oversizedColumnHeaders[i]) {
|
|
if (!children[i] || children[i].childNodes.length === 0) {
|
|
return;
|
|
}
|
|
children[i].childNodes[0].style.height = oversizedColumnHeaders[i] + 'px';
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if column header for the specified column is higher than expected, and if so, cache it
|
|
*
|
|
* @param {Number} col Index of column
|
|
*/
|
|
|
|
}, {
|
|
key: 'markIfOversizedColumnHeader',
|
|
value: function markIfOversizedColumnHeader(col) {
|
|
var sourceColIndex = this.wot.wtTable.columnFilter.renderedToSource(col);
|
|
var level = this.columnHeaderCount;
|
|
var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight;
|
|
var previousColHeaderHeight = void 0;
|
|
var currentHeader = void 0;
|
|
var currentHeaderHeight = void 0;
|
|
var columnHeaderHeightSetting = this.wot.getSetting('columnHeaderHeight') || [];
|
|
|
|
while (level) {
|
|
level--;
|
|
|
|
previousColHeaderHeight = this.wot.wtTable.getColumnHeaderHeight(level);
|
|
currentHeader = this.wot.wtTable.getColumnHeader(sourceColIndex, level);
|
|
|
|
if (!currentHeader) {
|
|
/* eslint-disable no-continue */
|
|
continue;
|
|
}
|
|
currentHeaderHeight = (0, _element.innerHeight)(currentHeader);
|
|
|
|
if (!previousColHeaderHeight && defaultRowHeight < currentHeaderHeight || previousColHeaderHeight < currentHeaderHeight) {
|
|
this.wot.wtViewport.oversizedColumnHeaders[level] = currentHeaderHeight;
|
|
}
|
|
|
|
if (Array.isArray(columnHeaderHeightSetting)) {
|
|
if (columnHeaderHeightSetting[level] != null) {
|
|
this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level];
|
|
}
|
|
} else if (!isNaN(columnHeaderHeightSetting)) {
|
|
this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting;
|
|
}
|
|
|
|
if (this.wot.wtViewport.oversizedColumnHeaders[level] < (columnHeaderHeightSetting[level] || columnHeaderHeightSetting)) {
|
|
this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level] || columnHeaderHeightSetting;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Number} sourceRowIndex
|
|
* @param {HTMLTableRowElement} TR
|
|
* @param {Number} columnsToRender
|
|
* @returns {HTMLTableCellElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderCells',
|
|
value: function renderCells(sourceRowIndex, TR, columnsToRender) {
|
|
var TD = void 0;
|
|
var sourceColIndex = void 0;
|
|
|
|
for (var visibleColIndex = 0; visibleColIndex < columnsToRender; visibleColIndex++) {
|
|
sourceColIndex = this.columnFilter.renderedToSource(visibleColIndex);
|
|
|
|
if (visibleColIndex === 0) {
|
|
TD = TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(sourceColIndex)];
|
|
} else {
|
|
TD = TD.nextSibling; // http://jsperf.com/nextsibling-vs-indexed-childnodes
|
|
}
|
|
// If the number of headers has been reduced, we need to replace excess TH with TD
|
|
if (TD.nodeName == 'TH') {
|
|
TD = replaceThWithTd(TD, TR);
|
|
}
|
|
if (!(0, _element.hasClass)(TD, 'hide')) {
|
|
TD.className = '';
|
|
}
|
|
TD.removeAttribute('style');
|
|
this.wot.wtSettings.settings.cellRenderer(sourceRowIndex, sourceColIndex, TD);
|
|
}
|
|
|
|
return TD;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} columnsToRender Number of columns to render.
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustColumnWidths',
|
|
value: function adjustColumnWidths(columnsToRender) {
|
|
var scrollbarCompensation = 0;
|
|
var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
|
|
var mainHolder = sourceInstance.wtTable.holder;
|
|
var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth');
|
|
var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth');
|
|
|
|
if (mainHolder.offsetHeight < mainHolder.scrollHeight) {
|
|
scrollbarCompensation = (0, _element.getScrollbarWidth)();
|
|
}
|
|
this.wot.wtViewport.columnsRenderCalculator.refreshStretching(this.wot.wtViewport.getViewportWidth() - scrollbarCompensation);
|
|
|
|
rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);
|
|
|
|
if (rowHeaderWidthSetting != null) {
|
|
for (var i = 0; i < this.rowHeaderCount; i++) {
|
|
var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
|
|
|
|
width = width == null ? defaultColumnWidth : width;
|
|
|
|
this.COLGROUP.childNodes[i].style.width = width + 'px';
|
|
}
|
|
}
|
|
|
|
for (var renderedColIndex = 0; renderedColIndex < columnsToRender; renderedColIndex++) {
|
|
var _width2 = this.wtTable.getStretchedColumnWidth(this.columnFilter.renderedToSource(renderedColIndex));
|
|
|
|
this.COLGROUP.childNodes[renderedColIndex + this.rowHeaderCount].style.width = _width2 + 'px';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {HTMLTableCellElement} TR
|
|
*/
|
|
|
|
}, {
|
|
key: 'appendToTbody',
|
|
value: function appendToTbody(TR) {
|
|
this.TBODY.appendChild(TR);
|
|
this.wtTable.tbodyChildrenLength++;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} rowIndex
|
|
* @param {HTMLTableRowElement} currentTr
|
|
* @returns {HTMLTableCellElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getOrCreateTrForRow',
|
|
value: function getOrCreateTrForRow(rowIndex, currentTr) {
|
|
var TR = void 0;
|
|
|
|
if (rowIndex >= this.wtTable.tbodyChildrenLength) {
|
|
TR = this.createRow();
|
|
this.appendToTbody(TR);
|
|
} else if (rowIndex === 0) {
|
|
TR = this.TBODY.firstChild;
|
|
} else {
|
|
// http://jsperf.com/nextsibling-vs-indexed-childnodes
|
|
TR = currentTr.nextSibling;
|
|
}
|
|
if (TR.className) {
|
|
TR.removeAttribute('class');
|
|
}
|
|
|
|
return TR;
|
|
}
|
|
|
|
/**
|
|
* @returns {HTMLTableCellElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createRow',
|
|
value: function createRow() {
|
|
var TR = document.createElement('TR');
|
|
|
|
for (var visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) {
|
|
TR.appendChild(document.createElement('TH'));
|
|
}
|
|
|
|
return TR;
|
|
}
|
|
|
|
/**
|
|
* @param {Number} row
|
|
* @param {Number} col
|
|
* @param {HTMLTableCellElement} TH
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderRowHeader',
|
|
value: function renderRowHeader(row, col, TH) {
|
|
TH.className = '';
|
|
TH.removeAttribute('style');
|
|
this.rowHeaders[col](row, TH, col);
|
|
}
|
|
|
|
/**
|
|
* @param {Number} row
|
|
* @param {HTMLTableCellElement} TR
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderRowHeaders',
|
|
value: function renderRowHeaders(row, TR) {
|
|
for (var TH = TR.firstChild, visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) {
|
|
// If the number of row headers increased we need to create TH or replace an existing TD node with TH
|
|
if (!TH) {
|
|
TH = document.createElement('TH');
|
|
TR.appendChild(TH);
|
|
} else if (TH.nodeName == 'TD') {
|
|
TH = replaceTdWithTh(TH, TR);
|
|
}
|
|
this.renderRowHeader(row, visibleColIndex, TH);
|
|
// http://jsperf.com/nextsibling-vs-indexed-childnodes
|
|
TH = TH.nextSibling;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adjust the number of COL and TH elements to match the number of columns and headers that need to be rendered
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustAvailableNodes',
|
|
value: function adjustAvailableNodes() {
|
|
this.adjustColGroups();
|
|
this.adjustThead();
|
|
}
|
|
|
|
/**
|
|
* Renders the column headers
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderColumnHeaders',
|
|
value: function renderColumnHeaders() {
|
|
if (!this.columnHeaderCount) {
|
|
return;
|
|
}
|
|
var columnCount = this.wtTable.getRenderedColumnsCount();
|
|
|
|
for (var i = 0; i < this.columnHeaderCount; i++) {
|
|
var TR = this.getTrForColumnHeaders(i);
|
|
|
|
for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) {
|
|
var sourceCol = this.columnFilter.renderedToSource(renderedColumnIndex);
|
|
|
|
this.renderColumnHeader(i, sourceCol, TR.childNodes[renderedColumnIndex + this.rowHeaderCount]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adjusts the number of COL elements to match the number of columns that need to be rendered
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustColGroups',
|
|
value: function adjustColGroups() {
|
|
var columnCount = this.wtTable.getRenderedColumnsCount();
|
|
|
|
while (this.wtTable.colgroupChildrenLength < columnCount + this.rowHeaderCount) {
|
|
this.COLGROUP.appendChild(document.createElement('COL'));
|
|
this.wtTable.colgroupChildrenLength++;
|
|
}
|
|
while (this.wtTable.colgroupChildrenLength > columnCount + this.rowHeaderCount) {
|
|
this.COLGROUP.removeChild(this.COLGROUP.lastChild);
|
|
this.wtTable.colgroupChildrenLength--;
|
|
}
|
|
if (this.rowHeaderCount) {
|
|
(0, _element.addClass)(this.COLGROUP.childNodes[0], 'rowHeader');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adjusts the number of TH elements in THEAD to match the number of headers and columns that need to be rendered
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustThead',
|
|
value: function adjustThead() {
|
|
var columnCount = this.wtTable.getRenderedColumnsCount();
|
|
var TR = this.THEAD.firstChild;
|
|
|
|
if (this.columnHeaders.length) {
|
|
for (var i = 0, len = this.columnHeaders.length; i < len; i++) {
|
|
TR = this.THEAD.childNodes[i];
|
|
|
|
if (!TR) {
|
|
TR = document.createElement('TR');
|
|
this.THEAD.appendChild(TR);
|
|
}
|
|
this.theadChildrenLength = TR.childNodes.length;
|
|
|
|
while (this.theadChildrenLength < columnCount + this.rowHeaderCount) {
|
|
TR.appendChild(document.createElement('TH'));
|
|
this.theadChildrenLength++;
|
|
}
|
|
while (this.theadChildrenLength > columnCount + this.rowHeaderCount) {
|
|
TR.removeChild(TR.lastChild);
|
|
this.theadChildrenLength--;
|
|
}
|
|
}
|
|
var theadChildrenLength = this.THEAD.childNodes.length;
|
|
|
|
if (theadChildrenLength > this.columnHeaders.length) {
|
|
for (var _i2 = this.columnHeaders.length; _i2 < theadChildrenLength; _i2++) {
|
|
this.THEAD.removeChild(this.THEAD.lastChild);
|
|
}
|
|
}
|
|
} else if (TR) {
|
|
(0, _element.empty)(TR);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Number} index
|
|
* @returns {HTMLTableCellElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getTrForColumnHeaders',
|
|
value: function getTrForColumnHeaders(index) {
|
|
return this.THEAD.childNodes[index];
|
|
}
|
|
|
|
/**
|
|
* @param {Number} row
|
|
* @param {Number} col
|
|
* @param {HTMLTableCellElement} TH
|
|
* @returns {*}
|
|
*/
|
|
|
|
}, {
|
|
key: 'renderColumnHeader',
|
|
value: function renderColumnHeader(row, col, TH) {
|
|
TH.className = '';
|
|
TH.removeAttribute('style');
|
|
|
|
return this.columnHeaders[row](col, TH, row);
|
|
}
|
|
|
|
/**
|
|
* Add and/or remove the TDs to match the desired number
|
|
*
|
|
* @param {HTMLTableCellElement} TR Table row in question
|
|
* @param {Number} desiredCount The desired number of TDs in the TR
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustColumns',
|
|
value: function adjustColumns(TR, desiredCount) {
|
|
var count = TR.childNodes.length;
|
|
|
|
while (count < desiredCount) {
|
|
var TD = document.createElement('TD');
|
|
|
|
TR.appendChild(TD);
|
|
count++;
|
|
}
|
|
while (count > desiredCount) {
|
|
TR.removeChild(TR.lastChild);
|
|
count--;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Number} columnsToRender
|
|
*/
|
|
|
|
}, {
|
|
key: 'removeRedundantColumns',
|
|
value: function removeRedundantColumns(columnsToRender) {
|
|
while (this.wtTable.tbodyChildrenLength > columnsToRender) {
|
|
this.TBODY.removeChild(this.TBODY.lastChild);
|
|
this.wtTable.tbodyChildrenLength--;
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return TableRenderer;
|
|
}();
|
|
|
|
function replaceTdWithTh(TD, TR) {
|
|
var TH = document.createElement('TH');
|
|
|
|
TR.insertBefore(TH, TD);
|
|
TR.removeChild(TD);
|
|
|
|
return TH;
|
|
}
|
|
|
|
function replaceThWithTd(TH, TR) {
|
|
var TD = document.createElement('TD');
|
|
|
|
TR.insertBefore(TD, TH);
|
|
TR.removeChild(TH);
|
|
|
|
return TD;
|
|
}
|
|
|
|
exports.default = TableRenderer;
|
|
|
|
/***/ }),
|
|
/* 262 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _viewportColumns = __webpack_require__(251);
|
|
|
|
var _viewportColumns2 = _interopRequireDefault(_viewportColumns);
|
|
|
|
var _viewportRows = __webpack_require__(252);
|
|
|
|
var _viewportRows2 = _interopRequireDefault(_viewportRows);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Viewport
|
|
*/
|
|
var Viewport = function () {
|
|
/**
|
|
* @param wotInstance
|
|
*/
|
|
function Viewport(wotInstance) {
|
|
var _this = this;
|
|
|
|
_classCallCheck(this, Viewport);
|
|
|
|
this.wot = wotInstance;
|
|
// legacy support
|
|
this.instance = this.wot;
|
|
|
|
this.oversizedRows = [];
|
|
this.oversizedColumnHeaders = [];
|
|
this.hasOversizedColumnHeadersMarked = {};
|
|
this.clientHeight = 0;
|
|
this.containerWidth = NaN;
|
|
this.rowHeaderWidth = NaN;
|
|
this.rowsVisibleCalculator = null;
|
|
this.columnsVisibleCalculator = null;
|
|
|
|
this.eventManager = new _eventManager2.default(this.wot);
|
|
this.eventManager.addEventListener(window, 'resize', function () {
|
|
_this.clientHeight = _this.getWorkspaceHeight();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @returns {number}
|
|
*/
|
|
|
|
|
|
_createClass(Viewport, [{
|
|
key: 'getWorkspaceHeight',
|
|
value: function getWorkspaceHeight() {
|
|
var trimmingContainer = this.instance.wtOverlays.topOverlay.trimmingContainer;
|
|
var elemHeight = void 0;
|
|
var height = 0;
|
|
|
|
if (trimmingContainer === window) {
|
|
height = document.documentElement.clientHeight;
|
|
} else {
|
|
elemHeight = (0, _element.outerHeight)(trimmingContainer);
|
|
// returns height without DIV scrollbar
|
|
height = elemHeight > 0 && trimmingContainer.clientHeight > 0 ? trimmingContainer.clientHeight : Infinity;
|
|
}
|
|
|
|
return height;
|
|
}
|
|
}, {
|
|
key: 'getWorkspaceWidth',
|
|
value: function getWorkspaceWidth() {
|
|
var width = void 0;
|
|
var totalColumns = this.wot.getSetting('totalColumns');
|
|
var trimmingContainer = this.instance.wtOverlays.leftOverlay.trimmingContainer;
|
|
var overflow = void 0;
|
|
var stretchSetting = this.wot.getSetting('stretchH');
|
|
var docOffsetWidth = document.documentElement.offsetWidth;
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
|
|
if (preventOverflow) {
|
|
return (0, _element.outerWidth)(this.instance.wtTable.wtRootElement);
|
|
}
|
|
|
|
if (this.wot.getSetting('freezeOverlays')) {
|
|
width = Math.min(docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth);
|
|
} else {
|
|
width = Math.min(this.getContainerFillWidth(), docOffsetWidth - this.getWorkspaceOffset().left, docOffsetWidth);
|
|
}
|
|
|
|
if (trimmingContainer === window && totalColumns > 0 && this.sumColumnWidths(0, totalColumns - 1) > width) {
|
|
// in case sum of column widths is higher than available stylesheet width, let's assume using the whole window
|
|
// otherwise continue below, which will allow stretching
|
|
// this is used in `scroll_window.html`
|
|
// TODO test me
|
|
return document.documentElement.clientWidth;
|
|
}
|
|
|
|
if (trimmingContainer !== window) {
|
|
overflow = (0, _element.getStyle)(this.instance.wtOverlays.leftOverlay.trimmingContainer, 'overflow');
|
|
|
|
if (overflow == 'scroll' || overflow == 'hidden' || overflow == 'auto') {
|
|
// this is used in `scroll.html`
|
|
// TODO test me
|
|
return Math.max(width, trimmingContainer.clientWidth);
|
|
}
|
|
}
|
|
|
|
if (stretchSetting === 'none' || !stretchSetting) {
|
|
// if no stretching is used, return the maximum used workspace width
|
|
return Math.max(width, (0, _element.outerWidth)(this.instance.wtTable.TABLE));
|
|
}
|
|
|
|
// if stretching is used, return the actual container width, so the columns can fit inside it
|
|
return width;
|
|
}
|
|
|
|
/**
|
|
* Checks if viewport has vertical scroll
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'hasVerticalScroll',
|
|
value: function hasVerticalScroll() {
|
|
return this.getWorkspaceActualHeight() > this.getWorkspaceHeight();
|
|
}
|
|
|
|
/**
|
|
* Checks if viewport has horizontal scroll
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'hasHorizontalScroll',
|
|
value: function hasHorizontalScroll() {
|
|
return this.getWorkspaceActualWidth() > this.getWorkspaceWidth();
|
|
}
|
|
|
|
/**
|
|
* @param from
|
|
* @param length
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'sumColumnWidths',
|
|
value: function sumColumnWidths(from, length) {
|
|
var sum = 0;
|
|
|
|
while (from < length) {
|
|
sum += this.wot.wtTable.getColumnWidth(from);
|
|
from++;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getContainerFillWidth',
|
|
value: function getContainerFillWidth() {
|
|
if (this.containerWidth) {
|
|
return this.containerWidth;
|
|
}
|
|
var mainContainer = this.instance.wtTable.holder;
|
|
var fillWidth = void 0;
|
|
var dummyElement = void 0;
|
|
|
|
dummyElement = document.createElement('div');
|
|
dummyElement.style.width = '100%';
|
|
dummyElement.style.height = '1px';
|
|
mainContainer.appendChild(dummyElement);
|
|
fillWidth = dummyElement.offsetWidth;
|
|
|
|
this.containerWidth = fillWidth;
|
|
mainContainer.removeChild(dummyElement);
|
|
|
|
return fillWidth;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getWorkspaceOffset',
|
|
value: function getWorkspaceOffset() {
|
|
return (0, _element.offset)(this.wot.wtTable.TABLE);
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getWorkspaceActualHeight',
|
|
value: function getWorkspaceActualHeight() {
|
|
return (0, _element.outerHeight)(this.wot.wtTable.TABLE);
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getWorkspaceActualWidth',
|
|
value: function getWorkspaceActualWidth() {
|
|
return (0, _element.outerWidth)(this.wot.wtTable.TABLE) || (0, _element.outerWidth)(this.wot.wtTable.TBODY) || (0, _element.outerWidth)(this.wot.wtTable.THEAD); // IE8 reports 0 as <table> offsetWidth;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getColumnHeaderHeight',
|
|
value: function getColumnHeaderHeight() {
|
|
if (isNaN(this.columnHeaderHeight)) {
|
|
this.columnHeaderHeight = (0, _element.outerHeight)(this.wot.wtTable.THEAD);
|
|
}
|
|
|
|
return this.columnHeaderHeight;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getViewportHeight',
|
|
value: function getViewportHeight() {
|
|
var containerHeight = this.getWorkspaceHeight();
|
|
var columnHeaderHeight = void 0;
|
|
|
|
if (containerHeight === Infinity) {
|
|
return containerHeight;
|
|
}
|
|
columnHeaderHeight = this.getColumnHeaderHeight();
|
|
|
|
if (columnHeaderHeight > 0) {
|
|
containerHeight -= columnHeaderHeight;
|
|
}
|
|
|
|
return containerHeight;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getRowHeaderWidth',
|
|
value: function getRowHeaderWidth() {
|
|
var rowHeadersHeightSetting = this.instance.getSetting('rowHeaderWidth');
|
|
var rowHeaders = this.instance.getSetting('rowHeaders');
|
|
|
|
if (rowHeadersHeightSetting) {
|
|
this.rowHeaderWidth = 0;
|
|
|
|
for (var i = 0, len = rowHeaders.length; i < len; i++) {
|
|
this.rowHeaderWidth += rowHeadersHeightSetting[i] || rowHeadersHeightSetting;
|
|
}
|
|
}
|
|
|
|
if (this.wot.cloneSource) {
|
|
return this.wot.cloneSource.wtViewport.getRowHeaderWidth();
|
|
}
|
|
|
|
if (isNaN(this.rowHeaderWidth)) {
|
|
|
|
if (rowHeaders.length) {
|
|
var TH = this.instance.wtTable.TABLE.querySelector('TH');
|
|
this.rowHeaderWidth = 0;
|
|
|
|
for (var _i = 0, _len = rowHeaders.length; _i < _len; _i++) {
|
|
if (TH) {
|
|
this.rowHeaderWidth += (0, _element.outerWidth)(TH);
|
|
TH = TH.nextSibling;
|
|
} else {
|
|
// yes this is a cheat but it worked like that before, just taking assumption from CSS instead of measuring.
|
|
// TODO: proper fix
|
|
this.rowHeaderWidth += 50;
|
|
}
|
|
}
|
|
} else {
|
|
this.rowHeaderWidth = 0;
|
|
}
|
|
}
|
|
|
|
this.rowHeaderWidth = this.instance.getSetting('onModifyRowHeaderWidth', this.rowHeaderWidth) || this.rowHeaderWidth;
|
|
|
|
return this.rowHeaderWidth;
|
|
}
|
|
|
|
/**
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getViewportWidth',
|
|
value: function getViewportWidth() {
|
|
var containerWidth = this.getWorkspaceWidth();
|
|
var rowHeaderWidth = void 0;
|
|
|
|
if (containerWidth === Infinity) {
|
|
return containerWidth;
|
|
}
|
|
rowHeaderWidth = this.getRowHeaderWidth();
|
|
|
|
if (rowHeaderWidth > 0) {
|
|
return containerWidth - rowHeaderWidth;
|
|
}
|
|
|
|
return containerWidth;
|
|
}
|
|
|
|
/**
|
|
* Creates:
|
|
* - rowsRenderCalculator (before draw, to qualify rows for rendering)
|
|
* - rowsVisibleCalculator (after draw, to measure which rows are actually visible)
|
|
*
|
|
* @returns {ViewportRowsCalculator}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createRowsCalculator',
|
|
value: function createRowsCalculator() {
|
|
var _this2 = this;
|
|
|
|
var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
var height = void 0;
|
|
var pos = void 0;
|
|
var fixedRowsTop = void 0;
|
|
var scrollbarHeight = void 0;
|
|
var fixedRowsBottom = void 0;
|
|
var fixedRowsHeight = void 0;
|
|
var totalRows = void 0;
|
|
|
|
this.rowHeaderWidth = NaN;
|
|
|
|
if (this.wot.wtSettings.settings.renderAllRows) {
|
|
height = Infinity;
|
|
} else {
|
|
height = this.getViewportHeight();
|
|
}
|
|
pos = this.wot.wtOverlays.topOverlay.getScrollPosition() - this.wot.wtOverlays.topOverlay.getTableParentOffset();
|
|
|
|
if (pos < 0) {
|
|
pos = 0;
|
|
}
|
|
fixedRowsTop = this.wot.getSetting('fixedRowsTop');
|
|
fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
|
|
totalRows = this.wot.getSetting('totalRows');
|
|
|
|
if (fixedRowsTop) {
|
|
fixedRowsHeight = this.wot.wtOverlays.topOverlay.sumCellSizes(0, fixedRowsTop);
|
|
pos += fixedRowsHeight;
|
|
height -= fixedRowsHeight;
|
|
}
|
|
|
|
if (fixedRowsBottom && this.wot.wtOverlays.bottomOverlay.clone) {
|
|
fixedRowsHeight = this.wot.wtOverlays.bottomOverlay.sumCellSizes(totalRows - fixedRowsBottom, totalRows);
|
|
|
|
height -= fixedRowsHeight;
|
|
}
|
|
|
|
if (this.wot.wtTable.holder.clientHeight === this.wot.wtTable.holder.offsetHeight) {
|
|
scrollbarHeight = 0;
|
|
} else {
|
|
scrollbarHeight = (0, _element.getScrollbarWidth)();
|
|
}
|
|
|
|
return new _viewportRows2.default(height, pos, this.wot.getSetting('totalRows'), function (sourceRow) {
|
|
return _this2.wot.wtTable.getRowHeight(sourceRow);
|
|
}, visible ? null : this.wot.wtSettings.settings.viewportRowCalculatorOverride, visible, scrollbarHeight);
|
|
}
|
|
|
|
/**
|
|
* Creates:
|
|
* - columnsRenderCalculator (before draw, to qualify columns for rendering)
|
|
* - columnsVisibleCalculator (after draw, to measure which columns are actually visible)
|
|
*
|
|
* @returns {ViewportRowsCalculator}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createColumnsCalculator',
|
|
value: function createColumnsCalculator() {
|
|
var _this3 = this;
|
|
|
|
var visible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
var width = this.getViewportWidth();
|
|
var pos = void 0;
|
|
var fixedColumnsLeft = void 0;
|
|
|
|
this.columnHeaderHeight = NaN;
|
|
|
|
pos = this.wot.wtOverlays.leftOverlay.getScrollPosition() - this.wot.wtOverlays.leftOverlay.getTableParentOffset();
|
|
|
|
if (pos < 0) {
|
|
pos = 0;
|
|
}
|
|
fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft');
|
|
|
|
if (fixedColumnsLeft) {
|
|
var fixedColumnsWidth = this.wot.wtOverlays.leftOverlay.sumCellSizes(0, fixedColumnsLeft);
|
|
pos += fixedColumnsWidth;
|
|
width -= fixedColumnsWidth;
|
|
}
|
|
if (this.wot.wtTable.holder.clientWidth !== this.wot.wtTable.holder.offsetWidth) {
|
|
width -= (0, _element.getScrollbarWidth)();
|
|
}
|
|
|
|
return new _viewportColumns2.default(width, pos, this.wot.getSetting('totalColumns'), function (sourceCol) {
|
|
return _this3.wot.wtTable.getColumnWidth(sourceCol);
|
|
}, visible ? null : this.wot.wtSettings.settings.viewportColumnCalculatorOverride, visible, this.wot.getSetting('stretchH'), function (stretchedWidth, column) {
|
|
return _this3.wot.getSetting('onBeforeStretchingColumnWidth', stretchedWidth, column);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates rowsRenderCalculator and columnsRenderCalculator (before draw, to determine what rows and
|
|
* cols should be rendered)
|
|
*
|
|
* @param fastDraw {Boolean} If `true`, will try to avoid full redraw and only update the border positions.
|
|
* If `false` or `undefined`, will perform a full redraw
|
|
* @returns fastDraw {Boolean} The fastDraw value, possibly modified
|
|
*/
|
|
|
|
}, {
|
|
key: 'createRenderCalculators',
|
|
value: function createRenderCalculators() {
|
|
var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
if (fastDraw) {
|
|
var proposedRowsVisibleCalculator = this.createRowsCalculator(true);
|
|
var proposedColumnsVisibleCalculator = this.createColumnsCalculator(true);
|
|
|
|
if (!(this.areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) && this.areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator))) {
|
|
fastDraw = false;
|
|
}
|
|
}
|
|
|
|
if (!fastDraw) {
|
|
this.rowsRenderCalculator = this.createRowsCalculator();
|
|
this.columnsRenderCalculator = this.createColumnsCalculator();
|
|
}
|
|
// delete temporarily to make sure that renderers always use rowsRenderCalculator, not rowsVisibleCalculator
|
|
this.rowsVisibleCalculator = null;
|
|
this.columnsVisibleCalculator = null;
|
|
|
|
return fastDraw;
|
|
}
|
|
|
|
/**
|
|
* Creates rowsVisibleCalculator and columnsVisibleCalculator (after draw, to determine what are
|
|
* the actually visible rows and columns)
|
|
*/
|
|
|
|
}, {
|
|
key: 'createVisibleCalculators',
|
|
value: function createVisibleCalculators() {
|
|
this.rowsVisibleCalculator = this.createRowsCalculator(true);
|
|
this.columnsVisibleCalculator = this.createColumnsCalculator(true);
|
|
}
|
|
|
|
/**
|
|
* Returns information whether proposedRowsVisibleCalculator viewport
|
|
* is contained inside rows rendered in previous draw (cached in rowsRenderCalculator)
|
|
*
|
|
* @param {Object} proposedRowsVisibleCalculator
|
|
* @returns {Boolean} Returns `true` if all proposed visible rows are already rendered (meaning: redraw is not needed).
|
|
* Returns `false` if at least one proposed visible row is not already rendered (meaning: redraw is needed)
|
|
*/
|
|
|
|
}, {
|
|
key: 'areAllProposedVisibleRowsAlreadyRendered',
|
|
value: function areAllProposedVisibleRowsAlreadyRendered(proposedRowsVisibleCalculator) {
|
|
if (this.rowsVisibleCalculator) {
|
|
if (proposedRowsVisibleCalculator.startRow < this.rowsRenderCalculator.startRow || proposedRowsVisibleCalculator.startRow === this.rowsRenderCalculator.startRow && proposedRowsVisibleCalculator.startRow > 0) {
|
|
return false;
|
|
} else if (proposedRowsVisibleCalculator.endRow > this.rowsRenderCalculator.endRow || proposedRowsVisibleCalculator.endRow === this.rowsRenderCalculator.endRow && proposedRowsVisibleCalculator.endRow < this.wot.getSetting('totalRows') - 1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns information whether proposedColumnsVisibleCalculator viewport
|
|
* is contained inside column rendered in previous draw (cached in columnsRenderCalculator)
|
|
*
|
|
* @param {Object} proposedColumnsVisibleCalculator
|
|
* @returns {Boolean} Returns `true` if all proposed visible columns are already rendered (meaning: redraw is not needed).
|
|
* Returns `false` if at least one proposed visible column is not already rendered (meaning: redraw is needed)
|
|
*/
|
|
|
|
}, {
|
|
key: 'areAllProposedVisibleColumnsAlreadyRendered',
|
|
value: function areAllProposedVisibleColumnsAlreadyRendered(proposedColumnsVisibleCalculator) {
|
|
if (this.columnsVisibleCalculator) {
|
|
if (proposedColumnsVisibleCalculator.startColumn < this.columnsRenderCalculator.startColumn || proposedColumnsVisibleCalculator.startColumn === this.columnsRenderCalculator.startColumn && proposedColumnsVisibleCalculator.startColumn > 0) {
|
|
return false;
|
|
} else if (proposedColumnsVisibleCalculator.endColumn > this.columnsRenderCalculator.endColumn || proposedColumnsVisibleCalculator.endColumn === this.columnsRenderCalculator.endColumn && proposedColumnsVisibleCalculator.endColumn < this.wot.getSetting('totalColumns') - 1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Resets values in keys of the hasOversizedColumnHeadersMarked object after updateSettings.
|
|
*/
|
|
|
|
}, {
|
|
key: 'resetHasOversizedColumnHeadersMarked',
|
|
value: function resetHasOversizedColumnHeadersMarked() {
|
|
(0, _object.objectEach)(this.hasOversizedColumnHeadersMarked, function (value, key, object) {
|
|
object[key] = void 0;
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return Viewport;
|
|
}();
|
|
|
|
exports.default = Viewport;
|
|
|
|
/***/ }),
|
|
/* 263 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _handsontableEditor = __webpack_require__(264);
|
|
|
|
var _handsontableEditor2 = _interopRequireDefault(_handsontableEditor);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var AutocompleteEditor = _handsontableEditor2.default.prototype.extend();
|
|
|
|
/**
|
|
* @private
|
|
* @editor AutocompleteEditor
|
|
* @class AutocompleteEditor
|
|
* @dependencies HandsontableEditor
|
|
*/
|
|
AutocompleteEditor.prototype.init = function () {
|
|
_handsontableEditor2.default.prototype.init.apply(this, arguments);
|
|
this.query = null;
|
|
this.strippedChoices = [];
|
|
this.rawChoices = [];
|
|
};
|
|
|
|
AutocompleteEditor.prototype.getValue = function () {
|
|
var _this2 = this;
|
|
|
|
var selectedValue = this.rawChoices.find(function (value) {
|
|
var strippedValue = _this2.stripValueIfNeeded(value);
|
|
|
|
return strippedValue === _this2.TEXTAREA.value;
|
|
});
|
|
|
|
if ((0, _mixed.isDefined)(selectedValue)) {
|
|
return selectedValue;
|
|
}
|
|
|
|
return this.TEXTAREA.value;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.createElements = function () {
|
|
_handsontableEditor2.default.prototype.createElements.apply(this, arguments);
|
|
|
|
(0, _element.addClass)(this.htContainer, 'autocompleteEditor');
|
|
(0, _element.addClass)(this.htContainer, window.navigator.platform.indexOf('Mac') === -1 ? '' : 'htMacScroll');
|
|
};
|
|
|
|
var skipOne = false;
|
|
function onBeforeKeyDown(event) {
|
|
skipOne = false;
|
|
var editor = this.getActiveEditor();
|
|
|
|
if ((0, _unicode.isPrintableChar)(event.keyCode) || event.keyCode === _unicode.KEY_CODES.BACKSPACE || event.keyCode === _unicode.KEY_CODES.DELETE || event.keyCode === _unicode.KEY_CODES.INSERT) {
|
|
var timeOffset = 0;
|
|
|
|
// on ctl+c / cmd+c don't update suggestion list
|
|
if (event.keyCode === _unicode.KEY_CODES.C && (event.ctrlKey || event.metaKey)) {
|
|
return;
|
|
}
|
|
if (!editor.isOpened()) {
|
|
timeOffset += 10;
|
|
}
|
|
|
|
if (editor.htEditor) {
|
|
editor.instance._registerTimeout(setTimeout(function () {
|
|
editor.queryChoices(editor.TEXTAREA.value);
|
|
skipOne = true;
|
|
}, timeOffset));
|
|
}
|
|
}
|
|
}
|
|
|
|
AutocompleteEditor.prototype.prepare = function () {
|
|
this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
|
|
_handsontableEditor2.default.prototype.prepare.apply(this, arguments);
|
|
};
|
|
|
|
AutocompleteEditor.prototype.open = function () {
|
|
// Ugly fix for handsontable which grab window object for autocomplete scroll listener instead table element.
|
|
this.TEXTAREA_PARENT.style.overflow = 'auto';
|
|
_handsontableEditor2.default.prototype.open.apply(this, arguments);
|
|
this.TEXTAREA_PARENT.style.overflow = '';
|
|
|
|
var choicesListHot = this.htEditor.getInstance();
|
|
var _this = this;
|
|
var trimDropdown = this.cellProperties.trimDropdown === void 0 ? true : this.cellProperties.trimDropdown;
|
|
|
|
this.TEXTAREA.style.visibility = 'visible';
|
|
this.focus();
|
|
|
|
choicesListHot.updateSettings({
|
|
colWidths: trimDropdown ? [(0, _element.outerWidth)(this.TEXTAREA) - 2] : void 0,
|
|
width: trimDropdown ? (0, _element.outerWidth)(this.TEXTAREA) + (0, _element.getScrollbarWidth)() + 2 : void 0,
|
|
afterRenderer: function afterRenderer(TD, row, col, prop, value, cellProperties) {
|
|
var _this$cellProperties = _this.cellProperties,
|
|
filteringCaseSensitive = _this$cellProperties.filteringCaseSensitive,
|
|
allowHtml = _this$cellProperties.allowHtml;
|
|
|
|
var indexOfMatch = void 0;
|
|
var match = void 0;
|
|
|
|
value = (0, _mixed.stringify)(value);
|
|
|
|
if (value && !allowHtml) {
|
|
indexOfMatch = filteringCaseSensitive === true ? value.indexOf(this.query) : value.toLowerCase().indexOf(_this.query.toLowerCase());
|
|
|
|
if (indexOfMatch !== -1) {
|
|
match = value.substr(indexOfMatch, _this.query.length);
|
|
value = value.replace(match, '<strong>' + match + '</strong>');
|
|
}
|
|
}
|
|
TD.innerHTML = value;
|
|
},
|
|
|
|
autoColumnSize: true,
|
|
modifyColWidth: function modifyColWidth(width, col) {
|
|
// workaround for <strong> text overlapping the dropdown, not really accurate
|
|
var autoWidths = this.getPlugin('autoColumnSize').widths;
|
|
|
|
if (autoWidths[col]) {
|
|
width = autoWidths[col];
|
|
}
|
|
|
|
return trimDropdown ? width : width + 15;
|
|
}
|
|
});
|
|
|
|
// Add additional space for autocomplete holder
|
|
this.htEditor.view.wt.wtTable.holder.parentNode.style['padding-right'] = (0, _element.getScrollbarWidth)() + 2 + 'px';
|
|
|
|
if (skipOne) {
|
|
skipOne = false;
|
|
}
|
|
|
|
_this.instance._registerTimeout(setTimeout(function () {
|
|
_this.queryChoices(_this.TEXTAREA.value);
|
|
}, 0));
|
|
};
|
|
|
|
AutocompleteEditor.prototype.close = function () {
|
|
_handsontableEditor2.default.prototype.close.apply(this, arguments);
|
|
};
|
|
AutocompleteEditor.prototype.queryChoices = function (query) {
|
|
var _this3 = this;
|
|
|
|
this.query = query;
|
|
var source = this.cellProperties.source;
|
|
|
|
if (typeof source == 'function') {
|
|
source.call(this.cellProperties, query, function (choices) {
|
|
_this3.rawChoices = choices;
|
|
_this3.updateChoicesList(_this3.stripValuesIfNeeded(choices));
|
|
});
|
|
} else if (Array.isArray(source)) {
|
|
this.rawChoices = source;
|
|
this.updateChoicesList(this.stripValuesIfNeeded(source));
|
|
} else {
|
|
this.updateChoicesList([]);
|
|
}
|
|
};
|
|
|
|
AutocompleteEditor.prototype.updateChoicesList = function (choices) {
|
|
var pos = (0, _element.getCaretPosition)(this.TEXTAREA);
|
|
var endPos = (0, _element.getSelectionEndPosition)(this.TEXTAREA);
|
|
var sortByRelevanceSetting = this.cellProperties.sortByRelevance;
|
|
var filterSetting = this.cellProperties.filter;
|
|
var orderByRelevance = null;
|
|
var highlightIndex = null;
|
|
|
|
if (sortByRelevanceSetting) {
|
|
orderByRelevance = AutocompleteEditor.sortByRelevance(this.stripValueIfNeeded(this.getValue()), choices, this.cellProperties.filteringCaseSensitive);
|
|
}
|
|
var orderByRelevanceLength = Array.isArray(orderByRelevance) ? orderByRelevance.length : 0;
|
|
|
|
if (filterSetting === false) {
|
|
if (orderByRelevanceLength) {
|
|
highlightIndex = orderByRelevance[0];
|
|
}
|
|
} else {
|
|
var sorted = [];
|
|
|
|
for (var i = 0, choicesCount = choices.length; i < choicesCount; i++) {
|
|
if (sortByRelevanceSetting && orderByRelevanceLength <= i) {
|
|
break;
|
|
}
|
|
if (orderByRelevanceLength) {
|
|
sorted.push(choices[orderByRelevance[i]]);
|
|
} else {
|
|
sorted.push(choices[i]);
|
|
}
|
|
}
|
|
|
|
highlightIndex = 0;
|
|
choices = sorted;
|
|
}
|
|
|
|
this.strippedChoices = choices;
|
|
this.htEditor.loadData((0, _array.pivot)([choices]));
|
|
|
|
this.updateDropdownHeight();
|
|
|
|
this.flipDropdownIfNeeded();
|
|
|
|
if (this.cellProperties.strict === true) {
|
|
this.highlightBestMatchingChoice(highlightIndex);
|
|
}
|
|
|
|
this.instance.listen();
|
|
this.TEXTAREA.focus();
|
|
(0, _element.setCaretPosition)(this.TEXTAREA, pos, pos === endPos ? void 0 : endPos);
|
|
};
|
|
|
|
AutocompleteEditor.prototype.flipDropdownIfNeeded = function () {
|
|
var textareaOffset = (0, _element.offset)(this.TEXTAREA);
|
|
var textareaHeight = (0, _element.outerHeight)(this.TEXTAREA);
|
|
var dropdownHeight = this.getDropdownHeight();
|
|
var trimmingContainer = (0, _element.getTrimmingContainer)(this.instance.view.wt.wtTable.TABLE);
|
|
var trimmingContainerScrollTop = trimmingContainer.scrollTop;
|
|
var headersHeight = (0, _element.outerHeight)(this.instance.view.wt.wtTable.THEAD);
|
|
var containerOffset = {
|
|
row: 0,
|
|
col: 0
|
|
};
|
|
|
|
if (trimmingContainer !== window) {
|
|
containerOffset = (0, _element.offset)(trimmingContainer);
|
|
}
|
|
|
|
var spaceAbove = textareaOffset.top - containerOffset.top - headersHeight + trimmingContainerScrollTop;
|
|
var spaceBelow = trimmingContainer.scrollHeight - spaceAbove - headersHeight - textareaHeight;
|
|
var flipNeeded = dropdownHeight > spaceBelow && spaceAbove > spaceBelow;
|
|
|
|
if (flipNeeded) {
|
|
this.flipDropdown(dropdownHeight);
|
|
} else {
|
|
this.unflipDropdown();
|
|
}
|
|
|
|
this.limitDropdownIfNeeded(flipNeeded ? spaceAbove : spaceBelow, dropdownHeight);
|
|
|
|
return flipNeeded;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.limitDropdownIfNeeded = function (spaceAvailable, dropdownHeight) {
|
|
if (dropdownHeight > spaceAvailable) {
|
|
var tempHeight = 0;
|
|
var i = 0;
|
|
var lastRowHeight = 0;
|
|
var height = null;
|
|
|
|
do {
|
|
lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view.wt.wtSettings.settings.defaultRowHeight;
|
|
tempHeight += lastRowHeight;
|
|
i++;
|
|
} while (tempHeight < spaceAvailable);
|
|
|
|
height = tempHeight - lastRowHeight;
|
|
|
|
if (this.htEditor.flipped) {
|
|
this.htEditor.rootElement.style.top = parseInt(this.htEditor.rootElement.style.top, 10) + dropdownHeight - height + 'px';
|
|
}
|
|
|
|
this.setDropdownHeight(tempHeight - lastRowHeight);
|
|
}
|
|
};
|
|
|
|
AutocompleteEditor.prototype.flipDropdown = function (dropdownHeight) {
|
|
var dropdownStyle = this.htEditor.rootElement.style;
|
|
|
|
dropdownStyle.position = 'absolute';
|
|
dropdownStyle.top = -dropdownHeight + 'px';
|
|
|
|
this.htEditor.flipped = true;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.unflipDropdown = function () {
|
|
var dropdownStyle = this.htEditor.rootElement.style;
|
|
|
|
if (dropdownStyle.position === 'absolute') {
|
|
dropdownStyle.position = '';
|
|
dropdownStyle.top = '';
|
|
}
|
|
|
|
this.htEditor.flipped = void 0;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.updateDropdownHeight = function () {
|
|
var currentDropdownWidth = this.htEditor.getColWidth(0) + (0, _element.getScrollbarWidth)() + 2;
|
|
var trimDropdown = this.cellProperties.trimDropdown;
|
|
|
|
this.htEditor.updateSettings({
|
|
height: this.getDropdownHeight(),
|
|
width: trimDropdown ? void 0 : currentDropdownWidth
|
|
});
|
|
|
|
this.htEditor.view.wt.wtTable.alignOverlaysWithTrimmingContainer();
|
|
};
|
|
|
|
AutocompleteEditor.prototype.setDropdownHeight = function (height) {
|
|
this.htEditor.updateSettings({
|
|
height: height
|
|
});
|
|
};
|
|
|
|
AutocompleteEditor.prototype.finishEditing = function (restoreOriginalValue) {
|
|
if (!restoreOriginalValue) {
|
|
this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
|
|
}
|
|
_handsontableEditor2.default.prototype.finishEditing.apply(this, arguments);
|
|
};
|
|
|
|
AutocompleteEditor.prototype.highlightBestMatchingChoice = function (index) {
|
|
if (typeof index === 'number') {
|
|
this.htEditor.selectCell(index, 0);
|
|
} else {
|
|
this.htEditor.deselectCell();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Filters and sorts by relevance
|
|
* @param value
|
|
* @param choices
|
|
* @param caseSensitive
|
|
* @returns {Array} array of indexes in original choices array
|
|
*/
|
|
AutocompleteEditor.sortByRelevance = function (value, choices, caseSensitive) {
|
|
var choicesRelevance = [];
|
|
var currentItem = void 0;
|
|
var valueLength = value.length;
|
|
var valueIndex = void 0;
|
|
var charsLeft = void 0;
|
|
var result = [];
|
|
var i = void 0;
|
|
var choicesCount = choices.length;
|
|
|
|
if (valueLength === 0) {
|
|
for (i = 0; i < choicesCount; i++) {
|
|
result.push(i);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
for (i = 0; i < choicesCount; i++) {
|
|
currentItem = (0, _string.stripTags)((0, _mixed.stringify)(choices[i]));
|
|
|
|
if (caseSensitive) {
|
|
valueIndex = currentItem.indexOf(value);
|
|
} else {
|
|
valueIndex = currentItem.toLowerCase().indexOf(value.toLowerCase());
|
|
}
|
|
|
|
if (valueIndex !== -1) {
|
|
charsLeft = currentItem.length - valueIndex - valueLength;
|
|
|
|
choicesRelevance.push({
|
|
baseIndex: i,
|
|
index: valueIndex,
|
|
charsLeft: charsLeft,
|
|
value: currentItem
|
|
});
|
|
}
|
|
}
|
|
|
|
choicesRelevance.sort(function (a, b) {
|
|
|
|
if (b.index === -1) {
|
|
return -1;
|
|
}
|
|
if (a.index === -1) {
|
|
return 1;
|
|
}
|
|
|
|
if (a.index < b.index) {
|
|
return -1;
|
|
} else if (b.index < a.index) {
|
|
return 1;
|
|
} else if (a.index === b.index) {
|
|
if (a.charsLeft < b.charsLeft) {
|
|
return -1;
|
|
} else if (a.charsLeft > b.charsLeft) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
});
|
|
|
|
for (i = 0, choicesCount = choicesRelevance.length; i < choicesCount; i++) {
|
|
result.push(choicesRelevance[i].baseIndex);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.getDropdownHeight = function () {
|
|
var firstRowHeight = this.htEditor.getInstance().getRowHeight(0) || 23;
|
|
var visibleRows = this.cellProperties.visibleRows;
|
|
|
|
return this.strippedChoices.length >= visibleRows ? visibleRows * firstRowHeight : this.strippedChoices.length * firstRowHeight + 8;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.stripValueIfNeeded = function (value) {
|
|
return this.stripValuesIfNeeded([value])[0];
|
|
};
|
|
|
|
AutocompleteEditor.prototype.stripValuesIfNeeded = function (values) {
|
|
var allowHtml = this.cellProperties.allowHtml;
|
|
|
|
|
|
var stringifiedValues = (0, _array.arrayMap)(values, function (value) {
|
|
return (0, _mixed.stringify)(value);
|
|
});
|
|
var strippedValues = (0, _array.arrayMap)(stringifiedValues, function (value) {
|
|
return allowHtml ? value : (0, _string.stripTags)(value);
|
|
});
|
|
|
|
return strippedValues;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.allowKeyEventPropagation = function (keyCode) {
|
|
var selected = { row: this.htEditor.getSelectedRange() ? this.htEditor.getSelectedRange().from.row : -1 };
|
|
var allowed = false;
|
|
|
|
if (keyCode === _unicode.KEY_CODES.ARROW_DOWN && selected.row > 0 && selected.row < this.htEditor.countRows() - 1) {
|
|
allowed = true;
|
|
}
|
|
if (keyCode === _unicode.KEY_CODES.ARROW_UP && selected.row > -1) {
|
|
allowed = true;
|
|
}
|
|
|
|
return allowed;
|
|
};
|
|
|
|
AutocompleteEditor.prototype.discardEditor = function (result) {
|
|
_handsontableEditor2.default.prototype.discardEditor.apply(this, arguments);
|
|
|
|
this.instance.view.render();
|
|
};
|
|
|
|
exports.default = AutocompleteEditor;
|
|
|
|
/***/ }),
|
|
/* 264 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _textEditor = __webpack_require__(44);
|
|
|
|
var _textEditor2 = _interopRequireDefault(_textEditor);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var HandsontableEditor = _textEditor2.default.prototype.extend();
|
|
|
|
/**
|
|
* @private
|
|
* @editor HandsontableEditor
|
|
* @class HandsontableEditor
|
|
* @dependencies TextEditor
|
|
*/
|
|
HandsontableEditor.prototype.createElements = function () {
|
|
_textEditor2.default.prototype.createElements.apply(this, arguments);
|
|
|
|
var DIV = document.createElement('DIV');
|
|
DIV.className = 'handsontableEditor';
|
|
this.TEXTAREA_PARENT.appendChild(DIV);
|
|
|
|
this.htContainer = DIV;
|
|
this.assignHooks();
|
|
};
|
|
|
|
HandsontableEditor.prototype.prepare = function (td, row, col, prop, value, cellProperties) {
|
|
_textEditor2.default.prototype.prepare.apply(this, arguments);
|
|
|
|
var parent = this;
|
|
var options = {
|
|
startRows: 0,
|
|
startCols: 0,
|
|
minRows: 0,
|
|
minCols: 0,
|
|
className: 'listbox',
|
|
copyPaste: false,
|
|
autoColumnSize: false,
|
|
autoRowSize: false,
|
|
readOnly: true,
|
|
fillHandle: false,
|
|
afterOnCellMouseDown: function afterOnCellMouseDown(_, coords) {
|
|
var value = this.getSourceData(coords.row, coords.col);
|
|
|
|
// if the value is undefined then it means we don't want to set the value
|
|
if (value !== void 0) {
|
|
parent.setValue(value);
|
|
}
|
|
parent.instance.destroyEditor();
|
|
}
|
|
};
|
|
|
|
if (this.cellProperties.handsontable) {
|
|
(0, _object.extend)(options, cellProperties.handsontable);
|
|
}
|
|
this.htOptions = options;
|
|
};
|
|
|
|
var onBeforeKeyDown = function onBeforeKeyDown(event) {
|
|
if ((0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
var editor = this.getActiveEditor();
|
|
|
|
var innerHOT = editor.htEditor.getInstance();
|
|
|
|
var rowToSelect;
|
|
var selectedRow;
|
|
|
|
if (event.keyCode == _unicode.KEY_CODES.ARROW_DOWN) {
|
|
if (!innerHOT.getSelected() && !innerHOT.flipped) {
|
|
rowToSelect = 0;
|
|
} else if (innerHOT.getSelected()) {
|
|
if (innerHOT.flipped) {
|
|
rowToSelect = innerHOT.getSelected()[0] + 1;
|
|
} else if (!innerHOT.flipped) {
|
|
selectedRow = innerHOT.getSelected()[0];
|
|
var lastRow = innerHOT.countRows() - 1;
|
|
rowToSelect = Math.min(lastRow, selectedRow + 1);
|
|
}
|
|
}
|
|
} else if (event.keyCode == _unicode.KEY_CODES.ARROW_UP) {
|
|
if (!innerHOT.getSelected() && innerHOT.flipped) {
|
|
rowToSelect = innerHOT.countRows() - 1;
|
|
} else if (innerHOT.getSelected()) {
|
|
if (innerHOT.flipped) {
|
|
selectedRow = innerHOT.getSelected()[0];
|
|
rowToSelect = Math.max(0, selectedRow - 1);
|
|
} else {
|
|
selectedRow = innerHOT.getSelected()[0];
|
|
rowToSelect = selectedRow - 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rowToSelect !== void 0) {
|
|
if (rowToSelect < 0 || innerHOT.flipped && rowToSelect > innerHOT.countRows() - 1) {
|
|
innerHOT.deselectCell();
|
|
} else {
|
|
innerHOT.selectCell(rowToSelect, 0);
|
|
}
|
|
if (innerHOT.getData().length) {
|
|
event.preventDefault();
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
|
|
editor.instance.listen();
|
|
editor.TEXTAREA.focus();
|
|
}
|
|
}
|
|
};
|
|
|
|
HandsontableEditor.prototype.open = function () {
|
|
this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
|
|
|
|
_textEditor2.default.prototype.open.apply(this, arguments);
|
|
|
|
if (this.htEditor) {
|
|
this.htEditor.destroy();
|
|
}
|
|
// Construct and initialise a new Handsontable
|
|
this.htEditor = new this.instance.constructor(this.htContainer, this.htOptions);
|
|
this.htEditor.init();
|
|
|
|
if (this.cellProperties.strict) {
|
|
this.htEditor.selectCell(0, 0);
|
|
this.TEXTAREA.style.visibility = 'hidden';
|
|
} else {
|
|
this.htEditor.deselectCell();
|
|
this.TEXTAREA.style.visibility = 'visible';
|
|
}
|
|
|
|
(0, _element.setCaretPosition)(this.TEXTAREA, 0, this.TEXTAREA.value.length);
|
|
};
|
|
|
|
HandsontableEditor.prototype.close = function () {
|
|
this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
|
|
this.instance.listen();
|
|
|
|
_textEditor2.default.prototype.close.apply(this, arguments);
|
|
};
|
|
|
|
HandsontableEditor.prototype.focus = function () {
|
|
this.instance.listen();
|
|
_textEditor2.default.prototype.focus.apply(this, arguments);
|
|
};
|
|
|
|
HandsontableEditor.prototype.beginEditing = function (initialValue) {
|
|
var onBeginEditing = this.instance.getSettings().onBeginEditing;
|
|
|
|
if (onBeginEditing && onBeginEditing() === false) {
|
|
return;
|
|
}
|
|
_textEditor2.default.prototype.beginEditing.apply(this, arguments);
|
|
};
|
|
|
|
HandsontableEditor.prototype.finishEditing = function (isCancelled, ctrlDown) {
|
|
if (this.htEditor && this.htEditor.isListening()) {
|
|
// if focus is still in the HOT editor
|
|
|
|
this.instance.listen(); // return the focus to the parent HOT instance
|
|
}
|
|
|
|
if (this.htEditor && this.htEditor.getSelected()) {
|
|
var value = this.htEditor.getInstance().getValue();
|
|
|
|
if (value !== void 0) {
|
|
// if the value is undefined then it means we don't want to set the value
|
|
this.setValue(value);
|
|
}
|
|
}
|
|
|
|
return _textEditor2.default.prototype.finishEditing.apply(this, arguments);
|
|
};
|
|
|
|
HandsontableEditor.prototype.assignHooks = function () {
|
|
var _this = this;
|
|
|
|
this.instance.addHook('afterDestroy', function () {
|
|
if (_this.htEditor) {
|
|
_this.htEditor.destroy();
|
|
}
|
|
});
|
|
};
|
|
|
|
exports.default = HandsontableEditor;
|
|
|
|
/***/ }),
|
|
/* 265 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var MIXIN_NAME = 'arrayMapper';
|
|
|
|
/**
|
|
* @type {Object}
|
|
*/
|
|
var arrayMapper = {
|
|
_arrayMap: [],
|
|
|
|
/**
|
|
* Get value by map index.
|
|
*
|
|
* @param {Number} index Array index.
|
|
* @return {*} Returns value mapped to passed index.
|
|
*/
|
|
getValueByIndex: function getValueByIndex(index) {
|
|
var value = void 0;
|
|
|
|
/* eslint-disable no-cond-assign */
|
|
return (value = this._arrayMap[index]) === void 0 ? null : value;
|
|
},
|
|
|
|
|
|
/**
|
|
* Get map index by its value.
|
|
*
|
|
* @param {*} value Value to search.
|
|
* @returns {Number} Returns array index.
|
|
*/
|
|
getIndexByValue: function getIndexByValue(value) {
|
|
var index = void 0;
|
|
|
|
/* eslint-disable no-cond-assign */
|
|
return (index = this._arrayMap.indexOf(value)) === -1 ? null : index;
|
|
},
|
|
|
|
|
|
/**
|
|
* Insert new items to array mapper starting at passed index. New entries will be a continuation of last value in the array.
|
|
*
|
|
* @param {Number} index Array index.
|
|
* @param {Number} [amount=1] Defines how many items will be created to an array.
|
|
* @returns {Array} Returns added items.
|
|
*/
|
|
insertItems: function insertItems(index) {
|
|
var _this = this;
|
|
|
|
var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
|
|
var newIndex = (0, _array.arrayMax)(this._arrayMap) + 1;
|
|
var addedItems = [];
|
|
|
|
(0, _number.rangeEach)(amount - 1, function (count) {
|
|
addedItems.push(_this._arrayMap.splice(index + count, 0, newIndex + count));
|
|
});
|
|
|
|
return addedItems;
|
|
},
|
|
|
|
|
|
/**
|
|
* Remove items from array mapper.
|
|
*
|
|
* @param {Number} index Array index.
|
|
* @param {Number} [amount=1] Defines how many items will be created to an array.
|
|
* @returns {Array} Returns removed items.
|
|
*/
|
|
removeItems: function removeItems(index) {
|
|
var _this2 = this;
|
|
|
|
var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
|
|
var removedItems = [];
|
|
|
|
if (Array.isArray(index)) {
|
|
var mapCopy = [].concat(this._arrayMap);
|
|
|
|
// Sort descending
|
|
index.sort(function (a, b) {
|
|
return b - a;
|
|
});
|
|
|
|
removedItems = (0, _array.arrayReduce)(index, function (acc, item) {
|
|
_this2._arrayMap.splice(item, 1);
|
|
|
|
return acc.concat(mapCopy.slice(item, item + 1));
|
|
}, []);
|
|
} else {
|
|
removedItems = this._arrayMap.splice(index, amount);
|
|
}
|
|
|
|
return removedItems;
|
|
},
|
|
|
|
|
|
/**
|
|
* Unshift items (remove and shift chunk of array to the left).
|
|
*
|
|
* @param {Number|Array} index Array index or Array of indexes to unshift.
|
|
* @param {Number} [amount=1] Defines how many items will be removed from an array (when index is passed as number).
|
|
*/
|
|
unshiftItems: function unshiftItems(index) {
|
|
var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
|
|
var removedItems = this.removeItems(index, amount);
|
|
|
|
function countRowShift(logicalRow) {
|
|
// Todo: compare perf between reduce vs sort->each->brake
|
|
return (0, _array.arrayReduce)(removedItems, function (count, removedLogicalRow) {
|
|
if (logicalRow > removedLogicalRow) {
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}, 0);
|
|
}
|
|
|
|
this._arrayMap = (0, _array.arrayMap)(this._arrayMap, function (logicalRow, physicalRow) {
|
|
var rowShift = countRowShift(logicalRow);
|
|
|
|
if (rowShift) {
|
|
logicalRow -= rowShift;
|
|
}
|
|
|
|
return logicalRow;
|
|
});
|
|
},
|
|
|
|
|
|
/**
|
|
* Shift (right shifting) items starting at passed index.
|
|
*
|
|
* @param {Number} index Array index.
|
|
* @param {Number} [amount=1] Defines how many items will be created to an array.
|
|
*/
|
|
shiftItems: function shiftItems(index) {
|
|
var _this3 = this;
|
|
|
|
var amount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
|
|
this._arrayMap = (0, _array.arrayMap)(this._arrayMap, function (row) {
|
|
if (row >= index) {
|
|
row += amount;
|
|
}
|
|
|
|
return row;
|
|
});
|
|
|
|
(0, _number.rangeEach)(amount - 1, function (count) {
|
|
_this3._arrayMap.splice(index + count, 0, index + count);
|
|
});
|
|
},
|
|
|
|
|
|
/**
|
|
* Clear all stored index<->value information from an array.
|
|
*/
|
|
clearMap: function clearMap() {
|
|
this._arrayMap.length = 0;
|
|
}
|
|
};
|
|
|
|
(0, _object.defineGetter)(arrayMapper, 'MIXIN_NAME', MIXIN_NAME, {
|
|
writable: false,
|
|
enumerable: false
|
|
});
|
|
|
|
exports.default = arrayMapper;
|
|
|
|
/***/ }),
|
|
/* 266 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var STATE_INITIALIZED = 0;
|
|
var STATE_BUILT = 1;
|
|
var STATE_APPENDED = 2;
|
|
var UNIT = 'px';
|
|
|
|
/**
|
|
* @class
|
|
* @private
|
|
*/
|
|
|
|
var BaseUI = function () {
|
|
function BaseUI(hotInstance) {
|
|
_classCallCheck(this, BaseUI);
|
|
|
|
/**
|
|
* Instance of Handsontable.
|
|
*
|
|
* @type {Core}
|
|
*/
|
|
this.hot = hotInstance;
|
|
/**
|
|
* DOM element representing the ui element.
|
|
*
|
|
* @type {HTMLElement}
|
|
* @private
|
|
*/
|
|
this._element = null;
|
|
/**
|
|
* Flag which determines build state of element.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
this.state = STATE_INITIALIZED;
|
|
}
|
|
|
|
/**
|
|
* Add created UI elements to table.
|
|
*
|
|
* @param {HTMLElement} wrapper Element which are parent for our UI element.
|
|
*/
|
|
|
|
|
|
_createClass(BaseUI, [{
|
|
key: 'appendTo',
|
|
value: function appendTo(wrapper) {
|
|
wrapper.appendChild(this._element);
|
|
|
|
this.state = STATE_APPENDED;
|
|
}
|
|
|
|
/**
|
|
* Method for create UI element. Only create, without append to table.
|
|
*/
|
|
|
|
}, {
|
|
key: 'build',
|
|
value: function build() {
|
|
this._element = document.createElement('div');
|
|
this.state = STATE_BUILT;
|
|
}
|
|
|
|
/**
|
|
* Method for remove UI element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
if (this.isAppended()) {
|
|
this._element.parentElement.removeChild(this._element);
|
|
}
|
|
|
|
this._element = null;
|
|
this.state = STATE_INITIALIZED;
|
|
}
|
|
|
|
/**
|
|
* Check if UI element are appended.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isAppended',
|
|
value: function isAppended() {
|
|
return this.state === STATE_APPENDED;
|
|
}
|
|
|
|
/**
|
|
* Check if UI element are built.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isBuilt',
|
|
value: function isBuilt() {
|
|
return this.state >= STATE_BUILT;
|
|
}
|
|
|
|
/**
|
|
* Setter for position.
|
|
*
|
|
* @param {Number} top New top position of the element.
|
|
* @param {Number} left New left position of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPosition',
|
|
value: function setPosition(top, left) {
|
|
if ((0, _number.isNumeric)(top)) {
|
|
this._element.style.top = top + UNIT;
|
|
}
|
|
if ((0, _number.isNumeric)(left)) {
|
|
this._element.style.left = left + UNIT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the element position.
|
|
*
|
|
* @returns {Object} Object contains left and top position of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getPosition',
|
|
value: function getPosition() {
|
|
return {
|
|
top: this._element.style.top ? parseInt(this._element.style.top, 10) : 0,
|
|
left: this._element.style.left ? parseInt(this._element.style.left, 10) : 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Setter for the element size.
|
|
*
|
|
* @param {Number} width New width of the element.
|
|
* @param {Number} height New height of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSize',
|
|
value: function setSize(width, height) {
|
|
if ((0, _number.isNumeric)(width)) {
|
|
this._element.style.width = width + UNIT;
|
|
}
|
|
if ((0, _number.isNumeric)(height)) {
|
|
this._element.style.height = height + UNIT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the element position.
|
|
*
|
|
* @returns {Object} Object contains height and width of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSize',
|
|
value: function getSize() {
|
|
return {
|
|
width: this._element.style.width ? parseInt(this._element.style.width, 10) : 0,
|
|
height: this._element.style.height ? parseInt(this._element.style.height, 10) : 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Setter for the element offset. Offset means marginTop and marginLeft of the element.
|
|
*
|
|
* @param {Number} top New margin top of the element.
|
|
* @param {Number} left New margin left of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setOffset',
|
|
value: function setOffset(top, left) {
|
|
if ((0, _number.isNumeric)(top)) {
|
|
this._element.style.marginTop = top + UNIT;
|
|
}
|
|
if ((0, _number.isNumeric)(left)) {
|
|
this._element.style.marginLeft = left + UNIT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the element offset.
|
|
*
|
|
* @returns {Object} Object contains top and left offset of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getOffset',
|
|
value: function getOffset() {
|
|
return {
|
|
top: this._element.style.marginTop ? parseInt(this._element.style.marginTop, 10) : 0,
|
|
left: this._element.style.marginLeft ? parseInt(this._element.style.marginLeft, 10) : 0
|
|
};
|
|
}
|
|
}]);
|
|
|
|
return BaseUI;
|
|
}();
|
|
|
|
exports.default = BaseUI;
|
|
|
|
/***/ }),
|
|
/* 267 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var STATE_INITIALIZED = 0;
|
|
var STATE_BUILT = 1;
|
|
var STATE_APPENDED = 2;
|
|
var UNIT = 'px';
|
|
|
|
/**
|
|
* @class
|
|
* @private
|
|
*/
|
|
|
|
var BaseUI = function () {
|
|
function BaseUI(hotInstance) {
|
|
_classCallCheck(this, BaseUI);
|
|
|
|
/**
|
|
* Instance of Handsontable.
|
|
*
|
|
* @type {Core}
|
|
*/
|
|
this.hot = hotInstance;
|
|
/**
|
|
* DOM element representing the ui element.
|
|
*
|
|
* @type {HTMLElement}
|
|
* @private
|
|
*/
|
|
this._element = null;
|
|
/**
|
|
* Flag which determines build state of element.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
this.state = STATE_INITIALIZED;
|
|
}
|
|
|
|
/**
|
|
* Add created UI elements to table.
|
|
*
|
|
* @param {HTMLElement} wrapper Element which are parent for our UI element.
|
|
*/
|
|
|
|
|
|
_createClass(BaseUI, [{
|
|
key: 'appendTo',
|
|
value: function appendTo(wrapper) {
|
|
wrapper.appendChild(this._element);
|
|
|
|
this.state = STATE_APPENDED;
|
|
}
|
|
|
|
/**
|
|
* Method for create UI element. Only create, without append to table.
|
|
*/
|
|
|
|
}, {
|
|
key: 'build',
|
|
value: function build() {
|
|
this._element = document.createElement('div');
|
|
this.state = STATE_BUILT;
|
|
}
|
|
|
|
/**
|
|
* Method for remove UI element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
if (this.isAppended()) {
|
|
this._element.parentElement.removeChild(this._element);
|
|
}
|
|
|
|
this._element = null;
|
|
this.state = STATE_INITIALIZED;
|
|
}
|
|
|
|
/**
|
|
* Check if UI element are appended.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isAppended',
|
|
value: function isAppended() {
|
|
return this.state === STATE_APPENDED;
|
|
}
|
|
|
|
/**
|
|
* Check if UI element are built.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isBuilt',
|
|
value: function isBuilt() {
|
|
return this.state >= STATE_BUILT;
|
|
}
|
|
|
|
/**
|
|
* Setter for position.
|
|
*
|
|
* @param {Number} top New top position of the element.
|
|
* @param {Number} left New left position of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPosition',
|
|
value: function setPosition(top, left) {
|
|
if (top) {
|
|
this._element.style.top = top + UNIT;
|
|
}
|
|
if (left) {
|
|
this._element.style.left = left + UNIT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the element position.
|
|
*
|
|
* @returns {Object} Object contains left and top position of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getPosition',
|
|
value: function getPosition() {
|
|
return {
|
|
top: this._element.style.top ? parseInt(this._element.style.top, 10) : 0,
|
|
left: this._element.style.left ? parseInt(this._element.style.left, 10) : 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Setter for the element size.
|
|
*
|
|
* @param {Number} width New width of the element.
|
|
* @param {Number} height New height of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSize',
|
|
value: function setSize(width, height) {
|
|
if (width) {
|
|
this._element.style.width = width + UNIT;
|
|
}
|
|
if (height) {
|
|
this._element.style.height = height + UNIT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the element position.
|
|
*
|
|
* @returns {Object} Object contains height and width of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSize',
|
|
value: function getSize() {
|
|
return {
|
|
width: this._element.style.width ? parseInt(this._element.style.width, 10) : 0,
|
|
height: this._element.style.height ? parseInt(this._element.style.height, 10) : 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Setter for the element offset. Offset means marginTop and marginLeft of the element.
|
|
*
|
|
* @param {Number} top New margin top of the element.
|
|
* @param {Number} left New margin left of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setOffset',
|
|
value: function setOffset(top, left) {
|
|
if (top) {
|
|
this._element.style.marginTop = top + UNIT;
|
|
}
|
|
if (left) {
|
|
this._element.style.marginLeft = left + UNIT;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the element offset.
|
|
*
|
|
* @returns {Object} Object contains top and left offset of the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getOffset',
|
|
value: function getOffset() {
|
|
return {
|
|
top: this._element.style.marginTop ? parseInt(this._element.style.marginTop, 10) : 0,
|
|
left: this._element.style.marginLeft ? parseInt(this._element.style.marginLeft, 10) : 0
|
|
};
|
|
}
|
|
}]);
|
|
|
|
return BaseUI;
|
|
}();
|
|
|
|
exports.default = BaseUI;
|
|
|
|
/***/ }),
|
|
/* 268 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.RecordTranslator = undefined;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
exports.registerIdentity = registerIdentity;
|
|
exports.getTranslator = getTranslator;
|
|
|
|
var _core = __webpack_require__(64);
|
|
|
|
var _core2 = _interopRequireDefault(_core);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class RecordTranslator
|
|
* @util
|
|
*/
|
|
var RecordTranslator = function () {
|
|
function RecordTranslator(hot) {
|
|
_classCallCheck(this, RecordTranslator);
|
|
|
|
this.hot = hot;
|
|
}
|
|
|
|
/**
|
|
* Translate physical row index into visual.
|
|
*
|
|
* @param {Number} row Physical row index.
|
|
* @returns {Number} Returns visual row index.
|
|
*/
|
|
|
|
|
|
_createClass(RecordTranslator, [{
|
|
key: 'toVisualRow',
|
|
value: function toVisualRow(row) {
|
|
return this.hot.runHooks('unmodifyRow', row);
|
|
}
|
|
|
|
/**
|
|
* Translate physical column index into visual.
|
|
*
|
|
* @param {Number} column Physical column index.
|
|
* @returns {Number} Returns visual column index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'toVisualColumn',
|
|
value: function toVisualColumn(column) {
|
|
return this.hot.runHooks('unmodifyCol', column);
|
|
}
|
|
|
|
/**
|
|
* Translate physical coordinates into visual. Can be passed as separate 2 arguments (row, column) or as an object in first
|
|
* argument with `row` and `column` keys.
|
|
*
|
|
* @param {Number|Object} row Physical coordinates or row index.
|
|
* @param {Number} [column] Physical column index.
|
|
* @returns {Object|Array} Returns an object with visual records or an array if coordinates passed as separate arguments.
|
|
*/
|
|
|
|
}, {
|
|
key: 'toVisual',
|
|
value: function toVisual(row, column) {
|
|
var result = void 0;
|
|
|
|
if ((0, _object.isObject)(row)) {
|
|
result = {
|
|
row: this.toVisualRow(row.row),
|
|
column: this.toVisualColumn(row.column)
|
|
};
|
|
} else {
|
|
result = [this.toVisualRow(row), this.toVisualColumn(column)];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Translate visual row index into physical.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @returns {Number} Returns physical row index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'toPhysicalRow',
|
|
value: function toPhysicalRow(row) {
|
|
return this.hot.runHooks('modifyRow', row);
|
|
}
|
|
|
|
/**
|
|
* Translate visual column index into physical.
|
|
*
|
|
* @param {Number} column Visual column index.
|
|
* @returns {Number} Returns physical column index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'toPhysicalColumn',
|
|
value: function toPhysicalColumn(column) {
|
|
return this.hot.runHooks('modifyCol', column);
|
|
}
|
|
|
|
/**
|
|
* Translate visual coordinates into physical. Can be passed as separate 2 arguments (row, column) or as an object in first
|
|
* argument with `row` and `column` keys.
|
|
*
|
|
* @param {Number|Object} row Visual coordinates or row index.
|
|
* @param {Number} [column] Visual column index.
|
|
* @returns {Object|Array} Returns an object with physical records or an array if coordinates passed as separate arguments.
|
|
*/
|
|
|
|
}, {
|
|
key: 'toPhysical',
|
|
value: function toPhysical(row, column) {
|
|
var result = void 0;
|
|
|
|
if ((0, _object.isObject)(row)) {
|
|
result = {
|
|
row: this.toPhysicalRow(row.row),
|
|
column: this.toPhysicalColumn(row.column)
|
|
};
|
|
} else {
|
|
result = [this.toPhysicalRow(row), this.toPhysicalColumn(column)];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}]);
|
|
|
|
return RecordTranslator;
|
|
}();
|
|
|
|
exports.RecordTranslator = RecordTranslator;
|
|
|
|
|
|
var identities = new WeakMap();
|
|
var translatorSingletons = new WeakMap();
|
|
|
|
function registerIdentity(identity, hot) {
|
|
identities.set(identity, hot);
|
|
}
|
|
|
|
function getTranslator(identity) {
|
|
var singleton = void 0;
|
|
|
|
if (!(identity instanceof _core2.default)) {
|
|
if (!identities.has(identity)) {
|
|
throw Error('Record translator was not registered for this object identity');
|
|
}
|
|
identity = identities.get(identity);
|
|
}
|
|
if (translatorSingletons.has(identity)) {
|
|
singleton = translatorSingletons.get(identity);
|
|
} else {
|
|
singleton = new RecordTranslator(identity);
|
|
translatorSingletons.set(identity, singleton);
|
|
}
|
|
|
|
return singleton;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 269 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
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; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class SamplesGenerator
|
|
* @util
|
|
*/
|
|
var SamplesGenerator = function () {
|
|
_createClass(SamplesGenerator, null, [{
|
|
key: 'SAMPLE_COUNT',
|
|
|
|
/**
|
|
* Number of samples to take of each value length.
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
get: function get() {
|
|
return 3;
|
|
}
|
|
}]);
|
|
|
|
function SamplesGenerator(dataFactory) {
|
|
_classCallCheck(this, SamplesGenerator);
|
|
|
|
/**
|
|
* Samples prepared for calculations.
|
|
*
|
|
* @type {Map}
|
|
* @default {null}
|
|
*/
|
|
this.samples = null;
|
|
/**
|
|
* Function which give the data to collect samples.
|
|
*
|
|
* @type {Function}
|
|
*/
|
|
this.dataFactory = dataFactory;
|
|
/**
|
|
* Custom number of samples to take of each value length.
|
|
*
|
|
* @type {Number}
|
|
* @default {null}
|
|
*/
|
|
this.customSampleCount = null;
|
|
/**
|
|
* `true` if duplicate samples collection should be allowed, `false` otherwise.
|
|
*
|
|
* @type {Boolean}
|
|
* @default {false}
|
|
*/
|
|
this.allowDuplicates = false;
|
|
}
|
|
|
|
/**
|
|
* Get the sample count for this instance.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
|
|
_createClass(SamplesGenerator, [{
|
|
key: 'getSampleCount',
|
|
value: function getSampleCount() {
|
|
if (this.customSampleCount) {
|
|
return this.customSampleCount;
|
|
}
|
|
return SamplesGenerator.SAMPLE_COUNT;
|
|
}
|
|
}, {
|
|
key: 'setSampleCount',
|
|
|
|
|
|
/**
|
|
* Set the sample count.
|
|
*
|
|
* @param {Number} sampleCount Number of samples to be collected.
|
|
*/
|
|
value: function setSampleCount(sampleCount) {
|
|
this.customSampleCount = sampleCount;
|
|
}
|
|
|
|
/**
|
|
* Set if the generator should accept duplicate values.
|
|
*
|
|
* @param {Boolean} allowDuplicates `true` to allow duplicate values.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setAllowDuplicates',
|
|
value: function setAllowDuplicates(allowDuplicates) {
|
|
this.allowDuplicates = allowDuplicates;
|
|
}
|
|
|
|
/**
|
|
* Generate samples for row. You can control which area should be sampled by passing `rowRange` object and `colRange` object.
|
|
*
|
|
* @param {Object|Number} rowRange
|
|
* @param {Object} colRange
|
|
* @returns {Object}
|
|
*/
|
|
|
|
}, {
|
|
key: 'generateRowSamples',
|
|
value: function generateRowSamples(rowRange, colRange) {
|
|
return this.generateSamples('row', colRange, rowRange);
|
|
}
|
|
|
|
/**
|
|
* Generate samples for column. You can control which area should be sampled by passing `colRange` object and `rowRange` object.
|
|
*
|
|
* @param {Object} colRange Column index.
|
|
* @param {Object} rowRange Column index.
|
|
* @returns {Object}
|
|
*/
|
|
|
|
}, {
|
|
key: 'generateColumnSamples',
|
|
value: function generateColumnSamples(colRange, rowRange) {
|
|
return this.generateSamples('col', rowRange, colRange);
|
|
}
|
|
|
|
/**
|
|
* Generate collection of samples.
|
|
*
|
|
* @param {String} type Type to generate. Can be `col` or `row`.
|
|
* @param {Object} range
|
|
* @param {Object|Number} specifierRange
|
|
* @returns {Map}
|
|
*/
|
|
|
|
}, {
|
|
key: 'generateSamples',
|
|
value: function generateSamples(type, range, specifierRange) {
|
|
var _this = this;
|
|
|
|
var samples = new Map();
|
|
|
|
if (typeof specifierRange === 'number') {
|
|
specifierRange = { from: specifierRange, to: specifierRange };
|
|
}
|
|
(0, _number.rangeEach)(specifierRange.from, specifierRange.to, function (index) {
|
|
var sample = _this.generateSample(type, range, index);
|
|
|
|
samples.set(index, sample);
|
|
});
|
|
|
|
return samples;
|
|
}
|
|
|
|
/**
|
|
* Generate sample for specified type (`row` or `col`).
|
|
*
|
|
* @param {String} type Samples type `row` or `col`.
|
|
* @param {Object} range
|
|
* @param {Number} specifierValue
|
|
* @returns {Map}
|
|
*/
|
|
|
|
}, {
|
|
key: 'generateSample',
|
|
value: function generateSample(type, range, specifierValue) {
|
|
var _this2 = this;
|
|
|
|
var samples = new Map();
|
|
var sampledValues = [];
|
|
var length = void 0;
|
|
|
|
(0, _number.rangeEach)(range.from, range.to, function (index) {
|
|
var value = void 0;
|
|
|
|
if (type === 'row') {
|
|
value = _this2.dataFactory(specifierValue, index);
|
|
} else if (type === 'col') {
|
|
value = _this2.dataFactory(index, specifierValue);
|
|
} else {
|
|
throw new Error('Unsupported sample type');
|
|
}
|
|
|
|
if ((0, _object.isObject)(value)) {
|
|
length = Object.keys(value).length;
|
|
} else if (Array.isArray(value)) {
|
|
length = value.length;
|
|
} else {
|
|
length = (0, _mixed.stringify)(value).length;
|
|
}
|
|
|
|
if (!samples.has(length)) {
|
|
samples.set(length, {
|
|
needed: _this2.getSampleCount(),
|
|
strings: []
|
|
});
|
|
}
|
|
var sample = samples.get(length);
|
|
|
|
if (sample.needed) {
|
|
var duplicate = sampledValues.indexOf(value) > -1;
|
|
|
|
if (!duplicate || _this2.allowDuplicates) {
|
|
var computedKey = type === 'row' ? 'col' : 'row';
|
|
|
|
sample.strings.push(_defineProperty({ value: value }, computedKey, index));
|
|
sampledValues.push(value);
|
|
sample.needed--;
|
|
}
|
|
}
|
|
});
|
|
|
|
return samples;
|
|
}
|
|
}]);
|
|
|
|
return SamplesGenerator;
|
|
}();
|
|
|
|
exports.default = SamplesGenerator;
|
|
|
|
/***/ }),
|
|
/* 270 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// false -> Array#indexOf
|
|
// true -> Array#includes
|
|
var toIObject = __webpack_require__(23)
|
|
, toLength = __webpack_require__(24)
|
|
, toIndex = __webpack_require__(61);
|
|
module.exports = function(IS_INCLUDES){
|
|
return function($this, el, fromIndex){
|
|
var O = toIObject($this)
|
|
, length = toLength(O.length)
|
|
, index = toIndex(fromIndex, length)
|
|
, value;
|
|
// Array#includes uses SameValueZero equality algorithm
|
|
if(IS_INCLUDES && el != el)while(length > index){
|
|
value = O[index++];
|
|
if(value != value)return true;
|
|
// Array#toIndex ignores holes, Array#includes - not
|
|
} else for(;length > index; index++)if(IS_INCLUDES || index in O){
|
|
if(O[index] === el)return IS_INCLUDES || index || 0;
|
|
} return !IS_INCLUDES && -1;
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 271 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// getting tag from 19.1.3.6 Object.prototype.toString()
|
|
var cof = __webpack_require__(39)
|
|
, TAG = __webpack_require__(10)('toStringTag')
|
|
// ES3 wrong here
|
|
, ARG = cof(function(){ return arguments; }()) == 'Arguments';
|
|
|
|
// fallback for IE11 Script Access Denied error
|
|
var tryGet = function(it, key){
|
|
try {
|
|
return it[key];
|
|
} catch(e){ /* empty */ }
|
|
};
|
|
|
|
module.exports = function(it){
|
|
var O, T, B;
|
|
return it === undefined ? 'Undefined' : it === null ? 'Null'
|
|
// @@toStringTag case
|
|
: typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
|
|
// builtinTag case
|
|
: ARG ? cof(O)
|
|
// ES3 arguments fallback
|
|
: (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 272 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var dP = __webpack_require__(19).f
|
|
, create = __webpack_require__(80)
|
|
, redefineAll = __webpack_require__(60)
|
|
, ctx = __webpack_require__(29)
|
|
, anInstance = __webpack_require__(53)
|
|
, defined = __webpack_require__(30)
|
|
, forOf = __webpack_require__(57)
|
|
, $iterDefine = __webpack_require__(281)
|
|
, step = __webpack_require__(282)
|
|
, setSpecies = __webpack_require__(287)
|
|
, DESCRIPTORS = __webpack_require__(21)
|
|
, fastKey = __webpack_require__(47).fastKey
|
|
, SIZE = DESCRIPTORS ? '_s' : 'size';
|
|
|
|
var getEntry = function(that, key){
|
|
// fast case
|
|
var index = fastKey(key), entry;
|
|
if(index !== 'F')return that._i[index];
|
|
// frozen object case
|
|
for(entry = that._f; entry; entry = entry.n){
|
|
if(entry.k == key)return entry;
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
|
|
var C = wrapper(function(that, iterable){
|
|
anInstance(that, C, NAME, '_i');
|
|
that._i = create(null); // index
|
|
that._f = undefined; // first entry
|
|
that._l = undefined; // last entry
|
|
that[SIZE] = 0; // size
|
|
if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
|
|
});
|
|
redefineAll(C.prototype, {
|
|
// 23.1.3.1 Map.prototype.clear()
|
|
// 23.2.3.2 Set.prototype.clear()
|
|
clear: function clear(){
|
|
for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){
|
|
entry.r = true;
|
|
if(entry.p)entry.p = entry.p.n = undefined;
|
|
delete data[entry.i];
|
|
}
|
|
that._f = that._l = undefined;
|
|
that[SIZE] = 0;
|
|
},
|
|
// 23.1.3.3 Map.prototype.delete(key)
|
|
// 23.2.3.4 Set.prototype.delete(value)
|
|
'delete': function(key){
|
|
var that = this
|
|
, entry = getEntry(that, key);
|
|
if(entry){
|
|
var next = entry.n
|
|
, prev = entry.p;
|
|
delete that._i[entry.i];
|
|
entry.r = true;
|
|
if(prev)prev.n = next;
|
|
if(next)next.p = prev;
|
|
if(that._f == entry)that._f = next;
|
|
if(that._l == entry)that._l = prev;
|
|
that[SIZE]--;
|
|
} return !!entry;
|
|
},
|
|
// 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
|
|
// 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
|
|
forEach: function forEach(callbackfn /*, that = undefined */){
|
|
anInstance(this, C, 'forEach');
|
|
var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)
|
|
, entry;
|
|
while(entry = entry ? entry.n : this._f){
|
|
f(entry.v, entry.k, this);
|
|
// revert to the last existing entry
|
|
while(entry && entry.r)entry = entry.p;
|
|
}
|
|
},
|
|
// 23.1.3.7 Map.prototype.has(key)
|
|
// 23.2.3.7 Set.prototype.has(value)
|
|
has: function has(key){
|
|
return !!getEntry(this, key);
|
|
}
|
|
});
|
|
if(DESCRIPTORS)dP(C.prototype, 'size', {
|
|
get: function(){
|
|
return defined(this[SIZE]);
|
|
}
|
|
});
|
|
return C;
|
|
},
|
|
def: function(that, key, value){
|
|
var entry = getEntry(that, key)
|
|
, prev, index;
|
|
// change existing entry
|
|
if(entry){
|
|
entry.v = value;
|
|
// create new entry
|
|
} else {
|
|
that._l = entry = {
|
|
i: index = fastKey(key, true), // <- index
|
|
k: key, // <- key
|
|
v: value, // <- value
|
|
p: prev = that._l, // <- previous entry
|
|
n: undefined, // <- next entry
|
|
r: false // <- removed
|
|
};
|
|
if(!that._f)that._f = entry;
|
|
if(prev)prev.n = entry;
|
|
that[SIZE]++;
|
|
// add to index
|
|
if(index !== 'F')that._i[index] = entry;
|
|
} return that;
|
|
},
|
|
getEntry: getEntry,
|
|
setStrong: function(C, NAME, IS_MAP){
|
|
// add .keys, .values, .entries, [@@iterator]
|
|
// 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
|
|
$iterDefine(C, NAME, function(iterated, kind){
|
|
this._t = iterated; // target
|
|
this._k = kind; // kind
|
|
this._l = undefined; // previous
|
|
}, function(){
|
|
var that = this
|
|
, kind = that._k
|
|
, entry = that._l;
|
|
// revert to the last existing entry
|
|
while(entry && entry.r)entry = entry.p;
|
|
// get next entry
|
|
if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){
|
|
// or finish the iteration
|
|
that._t = undefined;
|
|
return step(1);
|
|
}
|
|
// return step by kind
|
|
if(kind == 'keys' )return step(0, entry.k);
|
|
if(kind == 'values')return step(0, entry.v);
|
|
return step(0, [entry.k, entry.v]);
|
|
}, IS_MAP ? 'entries' : 'values' , !IS_MAP, true);
|
|
|
|
// add [@@species], 23.1.2.2, 23.2.2.2
|
|
setSpecies(NAME);
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 273 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var redefineAll = __webpack_require__(60)
|
|
, getWeak = __webpack_require__(47).getWeak
|
|
, anObject = __webpack_require__(18)
|
|
, isObject = __webpack_require__(15)
|
|
, anInstance = __webpack_require__(53)
|
|
, forOf = __webpack_require__(57)
|
|
, createArrayMethod = __webpack_require__(54)
|
|
, $has = __webpack_require__(22)
|
|
, arrayFind = createArrayMethod(5)
|
|
, arrayFindIndex = createArrayMethod(6)
|
|
, id = 0;
|
|
|
|
// fallback for uncaught frozen keys
|
|
var uncaughtFrozenStore = function(that){
|
|
return that._l || (that._l = new UncaughtFrozenStore);
|
|
};
|
|
var UncaughtFrozenStore = function(){
|
|
this.a = [];
|
|
};
|
|
var findUncaughtFrozen = function(store, key){
|
|
return arrayFind(store.a, function(it){
|
|
return it[0] === key;
|
|
});
|
|
};
|
|
UncaughtFrozenStore.prototype = {
|
|
get: function(key){
|
|
var entry = findUncaughtFrozen(this, key);
|
|
if(entry)return entry[1];
|
|
},
|
|
has: function(key){
|
|
return !!findUncaughtFrozen(this, key);
|
|
},
|
|
set: function(key, value){
|
|
var entry = findUncaughtFrozen(this, key);
|
|
if(entry)entry[1] = value;
|
|
else this.a.push([key, value]);
|
|
},
|
|
'delete': function(key){
|
|
var index = arrayFindIndex(this.a, function(it){
|
|
return it[0] === key;
|
|
});
|
|
if(~index)this.a.splice(index, 1);
|
|
return !!~index;
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
|
|
var C = wrapper(function(that, iterable){
|
|
anInstance(that, C, NAME, '_i');
|
|
that._i = id++; // collection id
|
|
that._l = undefined; // leak store for uncaught frozen objects
|
|
if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
|
|
});
|
|
redefineAll(C.prototype, {
|
|
// 23.3.3.2 WeakMap.prototype.delete(key)
|
|
// 23.4.3.3 WeakSet.prototype.delete(value)
|
|
'delete': function(key){
|
|
if(!isObject(key))return false;
|
|
var data = getWeak(key);
|
|
if(data === true)return uncaughtFrozenStore(this)['delete'](key);
|
|
return data && $has(data, this._i) && delete data[this._i];
|
|
},
|
|
// 23.3.3.4 WeakMap.prototype.has(key)
|
|
// 23.4.3.4 WeakSet.prototype.has(value)
|
|
has: function has(key){
|
|
if(!isObject(key))return false;
|
|
var data = getWeak(key);
|
|
if(data === true)return uncaughtFrozenStore(this).has(key);
|
|
return data && $has(data, this._i);
|
|
}
|
|
});
|
|
return C;
|
|
},
|
|
def: function(that, key, value){
|
|
var data = getWeak(anObject(key), true);
|
|
if(data === true)uncaughtFrozenStore(that).set(key, value);
|
|
else data[that._i] = value;
|
|
return that;
|
|
},
|
|
ufstore: uncaughtFrozenStore
|
|
};
|
|
|
|
/***/ }),
|
|
/* 274 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = __webpack_require__(13).document && document.documentElement;
|
|
|
|
/***/ }),
|
|
/* 275 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = !__webpack_require__(21) && !__webpack_require__(31)(function(){
|
|
return Object.defineProperty(__webpack_require__(75)('div'), 'a', {get: function(){ return 7; }}).a != 7;
|
|
});
|
|
|
|
/***/ }),
|
|
/* 276 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// check on default Array iterator
|
|
var Iterators = __webpack_require__(46)
|
|
, ITERATOR = __webpack_require__(10)('iterator')
|
|
, ArrayProto = Array.prototype;
|
|
|
|
module.exports = function(it){
|
|
return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 277 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 7.2.2 IsArray(argument)
|
|
var cof = __webpack_require__(39);
|
|
module.exports = Array.isArray || function isArray(arg){
|
|
return cof(arg) == 'Array';
|
|
};
|
|
|
|
/***/ }),
|
|
/* 278 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 20.1.2.3 Number.isInteger(number)
|
|
var isObject = __webpack_require__(15)
|
|
, floor = Math.floor;
|
|
module.exports = function isInteger(it){
|
|
return !isObject(it) && isFinite(it) && floor(it) === it;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 279 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 7.2.8 IsRegExp(argument)
|
|
var isObject = __webpack_require__(15)
|
|
, cof = __webpack_require__(39)
|
|
, MATCH = __webpack_require__(10)('match');
|
|
module.exports = function(it){
|
|
var isRegExp;
|
|
return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
|
|
};
|
|
|
|
/***/ }),
|
|
/* 280 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// call something on iterator step with safe closing on error
|
|
var anObject = __webpack_require__(18);
|
|
module.exports = function(iterator, fn, value, entries){
|
|
try {
|
|
return entries ? fn(anObject(value)[0], value[1]) : fn(value);
|
|
// 7.4.6 IteratorClose(iterator, completion)
|
|
} catch(e){
|
|
var ret = iterator['return'];
|
|
if(ret !== undefined)anObject(ret.call(iterator));
|
|
throw e;
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 281 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var LIBRARY = __webpack_require__(58)
|
|
, $export = __webpack_require__(3)
|
|
, redefine = __webpack_require__(33)
|
|
, hide = __webpack_require__(32)
|
|
, has = __webpack_require__(22)
|
|
, Iterators = __webpack_require__(46)
|
|
, $iterCreate = __webpack_require__(400)
|
|
, setToStringTag = __webpack_require__(49)
|
|
, getPrototypeOf = __webpack_require__(405)
|
|
, ITERATOR = __webpack_require__(10)('iterator')
|
|
, BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
|
|
, FF_ITERATOR = '@@iterator'
|
|
, KEYS = 'keys'
|
|
, VALUES = 'values';
|
|
|
|
var returnThis = function(){ return this; };
|
|
|
|
module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){
|
|
$iterCreate(Constructor, NAME, next);
|
|
var getMethod = function(kind){
|
|
if(!BUGGY && kind in proto)return proto[kind];
|
|
switch(kind){
|
|
case KEYS: return function keys(){ return new Constructor(this, kind); };
|
|
case VALUES: return function values(){ return new Constructor(this, kind); };
|
|
} return function entries(){ return new Constructor(this, kind); };
|
|
};
|
|
var TAG = NAME + ' Iterator'
|
|
, DEF_VALUES = DEFAULT == VALUES
|
|
, VALUES_BUG = false
|
|
, proto = Base.prototype
|
|
, $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
|
|
, $default = $native || getMethod(DEFAULT)
|
|
, $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined
|
|
, $anyNative = NAME == 'Array' ? proto.entries || $native : $native
|
|
, methods, key, IteratorPrototype;
|
|
// Fix native
|
|
if($anyNative){
|
|
IteratorPrototype = getPrototypeOf($anyNative.call(new Base));
|
|
if(IteratorPrototype !== Object.prototype){
|
|
// Set @@toStringTag to native iterators
|
|
setToStringTag(IteratorPrototype, TAG, true);
|
|
// fix for some old engines
|
|
if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);
|
|
}
|
|
}
|
|
// fix Array#{values, @@iterator}.name in V8 / FF
|
|
if(DEF_VALUES && $native && $native.name !== VALUES){
|
|
VALUES_BUG = true;
|
|
$default = function values(){ return $native.call(this); };
|
|
}
|
|
// Define iterator
|
|
if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){
|
|
hide(proto, ITERATOR, $default);
|
|
}
|
|
// Plug for library
|
|
Iterators[NAME] = $default;
|
|
Iterators[TAG] = returnThis;
|
|
if(DEFAULT){
|
|
methods = {
|
|
values: DEF_VALUES ? $default : getMethod(VALUES),
|
|
keys: IS_SET ? $default : getMethod(KEYS),
|
|
entries: $entries
|
|
};
|
|
if(FORCED)for(key in methods){
|
|
if(!(key in proto))redefine(proto, key, methods[key]);
|
|
} else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
|
|
}
|
|
return methods;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 282 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function(done, value){
|
|
return {value: value, done: !!done};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 283 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// 19.1.2.1 Object.assign(target, source, ...)
|
|
var getKeys = __webpack_require__(40)
|
|
, gOPS = __webpack_require__(59)
|
|
, pIE = __webpack_require__(48)
|
|
, toObject = __webpack_require__(42)
|
|
, IObject = __webpack_require__(78)
|
|
, $assign = Object.assign;
|
|
|
|
// should work with symbols and should have deterministic property order (V8 bug)
|
|
module.exports = !$assign || __webpack_require__(31)(function(){
|
|
var A = {}
|
|
, B = {}
|
|
, S = Symbol()
|
|
, K = 'abcdefghijklmnopqrst';
|
|
A[S] = 7;
|
|
K.split('').forEach(function(k){ B[k] = k; });
|
|
return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
|
|
}) ? function assign(target, source){ // eslint-disable-line no-unused-vars
|
|
var T = toObject(target)
|
|
, aLen = arguments.length
|
|
, index = 1
|
|
, getSymbols = gOPS.f
|
|
, isEnum = pIE.f;
|
|
while(aLen > index){
|
|
var S = IObject(arguments[index++])
|
|
, keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)
|
|
, length = keys.length
|
|
, j = 0
|
|
, key;
|
|
while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];
|
|
} return T;
|
|
} : $assign;
|
|
|
|
/***/ }),
|
|
/* 284 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var has = __webpack_require__(22)
|
|
, toIObject = __webpack_require__(23)
|
|
, arrayIndexOf = __webpack_require__(270)(false)
|
|
, IE_PROTO = __webpack_require__(83)('IE_PROTO');
|
|
|
|
module.exports = function(object, names){
|
|
var O = toIObject(object)
|
|
, i = 0
|
|
, result = []
|
|
, key;
|
|
for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);
|
|
// Don't enum bug & hidden keys
|
|
while(names.length > i)if(has(O, key = names[i++])){
|
|
~arrayIndexOf(result, key) || result.push(key);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 285 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var getKeys = __webpack_require__(40)
|
|
, toIObject = __webpack_require__(23)
|
|
, isEnum = __webpack_require__(48).f;
|
|
module.exports = function(isEntries){
|
|
return function(it){
|
|
var O = toIObject(it)
|
|
, keys = getKeys(O)
|
|
, length = keys.length
|
|
, i = 0
|
|
, result = []
|
|
, key;
|
|
while(length > i)if(isEnum.call(O, key = keys[i++])){
|
|
result.push(isEntries ? [key, O[key]] : O[key]);
|
|
} return result;
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 286 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// Works with __proto__ only. Old v8 can't work with null proto objects.
|
|
/* eslint-disable no-proto */
|
|
var isObject = __webpack_require__(15)
|
|
, anObject = __webpack_require__(18);
|
|
var check = function(O, proto){
|
|
anObject(O);
|
|
if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!");
|
|
};
|
|
module.exports = {
|
|
set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
|
|
function(test, buggy, set){
|
|
try {
|
|
set = __webpack_require__(29)(Function.call, __webpack_require__(81).f(Object.prototype, '__proto__').set, 2);
|
|
set(test, []);
|
|
buggy = !(test instanceof Array);
|
|
} catch(e){ buggy = true; }
|
|
return function setPrototypeOf(O, proto){
|
|
check(O, proto);
|
|
if(buggy)O.__proto__ = proto;
|
|
else set(O, proto);
|
|
return O;
|
|
};
|
|
}({}, false) : undefined),
|
|
check: check
|
|
};
|
|
|
|
/***/ }),
|
|
/* 287 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var global = __webpack_require__(13)
|
|
, dP = __webpack_require__(19)
|
|
, DESCRIPTORS = __webpack_require__(21)
|
|
, SPECIES = __webpack_require__(10)('species');
|
|
|
|
module.exports = function(KEY){
|
|
var C = global[KEY];
|
|
if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {
|
|
configurable: true,
|
|
get: function(){ return this; }
|
|
});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 288 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// https://github.com/tc39/proposal-string-pad-start-end
|
|
var toLength = __webpack_require__(24)
|
|
, repeat = __webpack_require__(289)
|
|
, defined = __webpack_require__(30);
|
|
|
|
module.exports = function(that, maxLength, fillString, left){
|
|
var S = String(defined(that))
|
|
, stringLength = S.length
|
|
, fillStr = fillString === undefined ? ' ' : String(fillString)
|
|
, intMaxLength = toLength(maxLength);
|
|
if(intMaxLength <= stringLength || fillStr == '')return S;
|
|
var fillLen = intMaxLength - stringLength
|
|
, stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
|
|
if(stringFiller.length > fillLen)stringFiller = stringFiller.slice(0, fillLen);
|
|
return left ? stringFiller + S : S + stringFiller;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 289 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var toInteger = __webpack_require__(62)
|
|
, defined = __webpack_require__(30);
|
|
|
|
module.exports = function repeat(count){
|
|
var str = String(defined(this))
|
|
, res = ''
|
|
, n = toInteger(count);
|
|
if(n < 0 || n == Infinity)throw RangeError("Count can't be negative");
|
|
for(;n > 0; (n >>>= 1) && (str += str))if(n & 1)res += str;
|
|
return res;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 290 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
exports.f = __webpack_require__(10);
|
|
|
|
/***/ }),
|
|
/* 291 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var classof = __webpack_require__(271)
|
|
, ITERATOR = __webpack_require__(10)('iterator')
|
|
, Iterators = __webpack_require__(46);
|
|
module.exports = __webpack_require__(45).getIteratorMethod = function(it){
|
|
if(it != undefined)return it[ITERATOR]
|
|
|| it['@@iterator']
|
|
|| Iterators[classof(it)];
|
|
};
|
|
|
|
/***/ }),
|
|
/* 292 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = jQueryWrapper;
|
|
function jQueryWrapper(Handsontable) {
|
|
var jQuery = typeof window === 'undefined' ? false : window.jQuery;
|
|
|
|
if (!jQuery) {
|
|
return;
|
|
}
|
|
|
|
jQuery.fn.handsontable = function (action) {
|
|
var $this = this.first(); // Use only first element from list
|
|
var instance = $this.data('handsontable');
|
|
|
|
// Init case
|
|
if (typeof action !== 'string') {
|
|
var userSettings = action || {};
|
|
|
|
if (instance) {
|
|
instance.updateSettings(userSettings);
|
|
} else {
|
|
instance = new Handsontable.Core($this[0], userSettings);
|
|
$this.data('handsontable', instance);
|
|
instance.init();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
// Action case
|
|
var args = [];
|
|
var output = void 0;
|
|
|
|
if (arguments.length > 1) {
|
|
for (var i = 1, ilen = arguments.length; i < ilen; i++) {
|
|
args.push(arguments[i]);
|
|
}
|
|
}
|
|
|
|
if (instance) {
|
|
if (typeof instance[action] !== 'undefined') {
|
|
output = instance[action].apply(instance, args);
|
|
|
|
if (action === 'destroy') {
|
|
$this.removeData();
|
|
}
|
|
} else {
|
|
throw new Error('Handsontable do not provide action: ' + action);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 293 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.Base = exports.UndoRedo = exports.TouchScroll = exports.Search = exports.PersistentState = exports.ObserveChanges = exports.MultipleSelectionHandles = exports.MergeCells = exports.ManualRowResize = exports.ManualRowMove = exports.ManualColumnResize = exports.ManualColumnMove = exports.ManualColumnFreeze = exports.DragToScroll = exports.CustomBorders = exports.CopyPaste = exports.ContextMenu = exports.Comments = exports.ColumnSorting = exports.AutoRowSize = exports.AutoFill = exports.AutoColumnSize = undefined;
|
|
|
|
var _autoColumnSize = __webpack_require__(325);
|
|
|
|
var _autoColumnSize2 = _interopRequireDefault(_autoColumnSize);
|
|
|
|
var _autofill = __webpack_require__(327);
|
|
|
|
var _autofill2 = _interopRequireDefault(_autofill);
|
|
|
|
var _autoRowSize = __webpack_require__(326);
|
|
|
|
var _autoRowSize2 = _interopRequireDefault(_autoRowSize);
|
|
|
|
var _columnSorting = __webpack_require__(329);
|
|
|
|
var _columnSorting2 = _interopRequireDefault(_columnSorting);
|
|
|
|
var _comments = __webpack_require__(331);
|
|
|
|
var _comments2 = _interopRequireDefault(_comments);
|
|
|
|
var _contextMenu = __webpack_require__(334);
|
|
|
|
var _contextMenu2 = _interopRequireDefault(_contextMenu);
|
|
|
|
var _copyPaste = __webpack_require__(351);
|
|
|
|
var _copyPaste2 = _interopRequireDefault(_copyPaste);
|
|
|
|
var _customBorders = __webpack_require__(353);
|
|
|
|
var _customBorders2 = _interopRequireDefault(_customBorders);
|
|
|
|
var _dragToScroll = __webpack_require__(354);
|
|
|
|
var _dragToScroll2 = _interopRequireDefault(_dragToScroll);
|
|
|
|
var _manualColumnFreeze = __webpack_require__(357);
|
|
|
|
var _manualColumnFreeze2 = _interopRequireDefault(_manualColumnFreeze);
|
|
|
|
var _manualColumnMove = __webpack_require__(359);
|
|
|
|
var _manualColumnMove2 = _interopRequireDefault(_manualColumnMove);
|
|
|
|
var _manualColumnResize = __webpack_require__(362);
|
|
|
|
var _manualColumnResize2 = _interopRequireDefault(_manualColumnResize);
|
|
|
|
var _manualRowMove = __webpack_require__(363);
|
|
|
|
var _manualRowMove2 = _interopRequireDefault(_manualRowMove);
|
|
|
|
var _manualRowResize = __webpack_require__(367);
|
|
|
|
var _manualRowResize2 = _interopRequireDefault(_manualRowResize);
|
|
|
|
var _mergeCells = __webpack_require__(368);
|
|
|
|
var _mergeCells2 = _interopRequireDefault(_mergeCells);
|
|
|
|
var _multipleSelectionHandles = __webpack_require__(369);
|
|
|
|
var _multipleSelectionHandles2 = _interopRequireDefault(_multipleSelectionHandles);
|
|
|
|
var _observeChanges = __webpack_require__(371);
|
|
|
|
var _observeChanges2 = _interopRequireDefault(_observeChanges);
|
|
|
|
var _persistentState = __webpack_require__(373);
|
|
|
|
var _persistentState2 = _interopRequireDefault(_persistentState);
|
|
|
|
var _search = __webpack_require__(374);
|
|
|
|
var _search2 = _interopRequireDefault(_search);
|
|
|
|
var _touchScroll = __webpack_require__(375);
|
|
|
|
var _touchScroll2 = _interopRequireDefault(_touchScroll);
|
|
|
|
var _undoRedo = __webpack_require__(376);
|
|
|
|
var _undoRedo2 = _interopRequireDefault(_undoRedo);
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
exports.AutoColumnSize = _autoColumnSize2.default;
|
|
exports.AutoFill = _autofill2.default;
|
|
exports.AutoRowSize = _autoRowSize2.default;
|
|
exports.ColumnSorting = _columnSorting2.default;
|
|
exports.Comments = _comments2.default;
|
|
exports.ContextMenu = _contextMenu2.default;
|
|
exports.CopyPaste = _copyPaste2.default;
|
|
exports.CustomBorders = _customBorders2.default;
|
|
exports.DragToScroll = _dragToScroll2.default;
|
|
exports.ManualColumnFreeze = _manualColumnFreeze2.default;
|
|
exports.ManualColumnMove = _manualColumnMove2.default;
|
|
exports.ManualColumnResize = _manualColumnResize2.default;
|
|
exports.ManualRowMove = _manualRowMove2.default;
|
|
exports.ManualRowResize = _manualRowResize2.default;
|
|
exports.MergeCells = _mergeCells2.default;
|
|
exports.MultipleSelectionHandles = _multipleSelectionHandles2.default;
|
|
exports.ObserveChanges = _observeChanges2.default;
|
|
exports.PersistentState = _persistentState2.default;
|
|
exports.Search = _search2.default;
|
|
exports.TouchScroll = _touchScroll2.default;
|
|
exports.UndoRedo = _undoRedo2.default;
|
|
exports.Base = _base2.default;
|
|
|
|
/***/ }),
|
|
/* 294 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 295 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 296 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 297 */
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
/***/ }),
|
|
/* 298 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* autoResize - resizes a DOM element to the width and height of another DOM element
|
|
*
|
|
* Copyright 2014, Marcin Warpechowski
|
|
* Licensed under the MIT license
|
|
*/
|
|
|
|
function autoResize() {
|
|
var defaults = {
|
|
minHeight: 200,
|
|
maxHeight: 300,
|
|
minWidth: 100,
|
|
maxWidth: 300
|
|
},
|
|
el,
|
|
body = document.body,
|
|
text = document.createTextNode(''),
|
|
span = document.createElement('SPAN'),
|
|
observe = function observe(element, event, handler) {
|
|
if (window.attachEvent) {
|
|
element.attachEvent('on' + event, handler);
|
|
} else {
|
|
element.addEventListener(event, handler, false);
|
|
}
|
|
},
|
|
_unObserve = function _unObserve(element, event, handler) {
|
|
if (window.removeEventListener) {
|
|
element.removeEventListener(event, handler, false);
|
|
} else {
|
|
element.detachEvent('on' + event, handler);
|
|
}
|
|
},
|
|
resize = function resize(newChar) {
|
|
var width, scrollHeight;
|
|
|
|
if (!newChar) {
|
|
newChar = "";
|
|
} else if (!/^[a-zA-Z \.,\\\/\|0-9]$/.test(newChar)) {
|
|
newChar = ".";
|
|
}
|
|
|
|
if (text.textContent !== void 0) {
|
|
text.textContent = el.value + newChar;
|
|
} else {
|
|
text.data = el.value + newChar; //IE8
|
|
}
|
|
span.style.fontSize = getComputedStyle(el).fontSize;
|
|
span.style.fontFamily = getComputedStyle(el).fontFamily;
|
|
span.style.whiteSpace = "pre";
|
|
|
|
body.appendChild(span);
|
|
width = span.clientWidth + 2;
|
|
body.removeChild(span);
|
|
|
|
el.style.height = defaults.minHeight + 'px';
|
|
|
|
if (defaults.minWidth > width) {
|
|
el.style.width = defaults.minWidth + 'px';
|
|
} else if (width > defaults.maxWidth) {
|
|
el.style.width = defaults.maxWidth + 'px';
|
|
} else {
|
|
el.style.width = width + 'px';
|
|
}
|
|
scrollHeight = el.scrollHeight ? el.scrollHeight - 1 : 0;
|
|
|
|
if (defaults.minHeight > scrollHeight) {
|
|
el.style.height = defaults.minHeight + 'px';
|
|
} else if (defaults.maxHeight < scrollHeight) {
|
|
el.style.height = defaults.maxHeight + 'px';
|
|
el.style.overflowY = 'visible';
|
|
} else {
|
|
el.style.height = scrollHeight + 'px';
|
|
}
|
|
},
|
|
delayedResize = function delayedResize() {
|
|
window.setTimeout(resize, 0);
|
|
},
|
|
extendDefaults = function extendDefaults(config) {
|
|
|
|
if (config && config.minHeight) {
|
|
if (config.minHeight == 'inherit') {
|
|
defaults.minHeight = el.clientHeight;
|
|
} else {
|
|
var minHeight = parseInt(config.minHeight);
|
|
if (!isNaN(minHeight)) {
|
|
defaults.minHeight = minHeight;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config && config.maxHeight) {
|
|
if (config.maxHeight == 'inherit') {
|
|
defaults.maxHeight = el.clientHeight;
|
|
} else {
|
|
var maxHeight = parseInt(config.maxHeight);
|
|
if (!isNaN(maxHeight)) {
|
|
defaults.maxHeight = maxHeight;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config && config.minWidth) {
|
|
if (config.minWidth == 'inherit') {
|
|
defaults.minWidth = el.clientWidth;
|
|
} else {
|
|
var minWidth = parseInt(config.minWidth);
|
|
if (!isNaN(minWidth)) {
|
|
defaults.minWidth = minWidth;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config && config.maxWidth) {
|
|
if (config.maxWidth == 'inherit') {
|
|
defaults.maxWidth = el.clientWidth;
|
|
} else {
|
|
var maxWidth = parseInt(config.maxWidth);
|
|
if (!isNaN(maxWidth)) {
|
|
defaults.maxWidth = maxWidth;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!span.firstChild) {
|
|
span.className = "autoResize";
|
|
span.style.display = 'inline-block';
|
|
span.appendChild(text);
|
|
}
|
|
},
|
|
_init = function _init(el_, config, doObserve) {
|
|
el = el_;
|
|
extendDefaults(config);
|
|
|
|
if (el.nodeName == 'TEXTAREA') {
|
|
|
|
el.style.resize = 'none';
|
|
el.style.overflowY = '';
|
|
el.style.height = defaults.minHeight + 'px';
|
|
el.style.minWidth = defaults.minWidth + 'px';
|
|
el.style.maxWidth = defaults.maxWidth + 'px';
|
|
el.style.overflowY = 'hidden';
|
|
}
|
|
|
|
if (doObserve) {
|
|
observe(el, 'change', resize);
|
|
observe(el, 'cut', delayedResize);
|
|
observe(el, 'paste', delayedResize);
|
|
observe(el, 'drop', delayedResize);
|
|
observe(el, 'keydown', delayedResize);
|
|
observe(el, 'focus', resize);
|
|
}
|
|
|
|
resize();
|
|
};
|
|
|
|
function getComputedStyle(element) {
|
|
return element.currentStyle || document.defaultView.getComputedStyle(element);
|
|
}
|
|
|
|
return {
|
|
init: function init(el_, config, doObserve) {
|
|
_init(el_, config, doObserve);
|
|
},
|
|
unObserve: function unObserve() {
|
|
_unObserve(el, 'change', resize);
|
|
_unObserve(el, 'cut', delayedResize);
|
|
_unObserve(el, 'paste', delayedResize);
|
|
_unObserve(el, 'drop', delayedResize);
|
|
_unObserve(el, 'keydown', delayedResize);
|
|
_unObserve(el, 'focus', resize);
|
|
},
|
|
resize: resize
|
|
};
|
|
}
|
|
|
|
if (true) {
|
|
module.exports = autoResize;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 299 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* A overlay that renders ALL available rows & columns positioned on top of the original Walkontable instance and all other overlays.
|
|
* Used for debugging purposes to see if the other overlays (that render only part of the rows & columns) are positioned correctly
|
|
*
|
|
* @class DebugOverlay
|
|
*/
|
|
var DebugOverlay = function (_Overlay) {
|
|
_inherits(DebugOverlay, _Overlay);
|
|
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
*/
|
|
function DebugOverlay(wotInstance) {
|
|
_classCallCheck(this, DebugOverlay);
|
|
|
|
var _this = _possibleConstructorReturn(this, (DebugOverlay.__proto__ || Object.getPrototypeOf(DebugOverlay)).call(this, wotInstance));
|
|
|
|
_this.clone = _this.makeClone(_base2.default.CLONE_DEBUG);
|
|
_this.clone.wtTable.holder.style.opacity = 0.4;
|
|
_this.clone.wtTable.holder.style.textShadow = '0 0 2px #ff0000';
|
|
|
|
(0, _element.addClass)(_this.clone.wtTable.holder.parentNode, 'wtDebugVisible');
|
|
return _this;
|
|
}
|
|
|
|
return DebugOverlay;
|
|
}(_base2.default);
|
|
|
|
_base2.default.registerOverlay(_base2.default.CLONE_DEBUG, DebugOverlay);
|
|
|
|
exports.default = DebugOverlay;
|
|
|
|
/***/ }),
|
|
/* 300 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @class LeftOverlay
|
|
*/
|
|
var LeftOverlay = function (_Overlay) {
|
|
_inherits(LeftOverlay, _Overlay);
|
|
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
*/
|
|
function LeftOverlay(wotInstance) {
|
|
_classCallCheck(this, LeftOverlay);
|
|
|
|
var _this = _possibleConstructorReturn(this, (LeftOverlay.__proto__ || Object.getPrototypeOf(LeftOverlay)).call(this, wotInstance));
|
|
|
|
_this.clone = _this.makeClone(_base2.default.CLONE_LEFT);
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Checks if overlay should be fully rendered
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(LeftOverlay, [{
|
|
key: 'shouldBeRendered',
|
|
value: function shouldBeRendered() {
|
|
return !!(this.wot.getSetting('fixedColumnsLeft') || this.wot.getSetting('rowHeaders').length);
|
|
}
|
|
|
|
/**
|
|
* Updates the left overlay position
|
|
*/
|
|
|
|
}, {
|
|
key: 'resetFixedPosition',
|
|
value: function resetFixedPosition() {
|
|
if (!this.needFullRender || !this.wot.wtTable.holder.parentNode) {
|
|
// removed from DOM
|
|
return;
|
|
}
|
|
var overlayRoot = this.clone.wtTable.holder.parentNode;
|
|
var headerPosition = 0;
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
|
|
if (this.trimmingContainer === window && (!preventOverflow || preventOverflow !== 'horizontal')) {
|
|
var box = this.wot.wtTable.hider.getBoundingClientRect();
|
|
var left = Math.ceil(box.left);
|
|
var right = Math.ceil(box.right);
|
|
var finalLeft = void 0;
|
|
var finalTop = void 0;
|
|
|
|
finalTop = this.wot.wtTable.hider.style.top;
|
|
finalTop = finalTop === '' ? 0 : finalTop;
|
|
|
|
if (left < 0 && right - overlayRoot.offsetWidth > 0) {
|
|
finalLeft = -left;
|
|
} else {
|
|
finalLeft = 0;
|
|
}
|
|
headerPosition = finalLeft;
|
|
finalLeft += 'px';
|
|
|
|
(0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop);
|
|
} else {
|
|
headerPosition = this.getScrollPosition();
|
|
(0, _element.resetCssTransform)(overlayRoot);
|
|
}
|
|
this.adjustHeaderBordersPosition(headerPosition);
|
|
|
|
this.adjustElementsSize();
|
|
}
|
|
|
|
/**
|
|
* Sets the main overlay's horizontal scroll position
|
|
*
|
|
* @param {Number} pos
|
|
*/
|
|
|
|
}, {
|
|
key: 'setScrollPosition',
|
|
value: function setScrollPosition(pos) {
|
|
if (this.mainTableScrollableElement === window) {
|
|
window.scrollTo(pos, (0, _element.getWindowScrollTop)());
|
|
} else {
|
|
this.mainTableScrollableElement.scrollLeft = pos;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Triggers onScroll hook callback
|
|
*/
|
|
|
|
}, {
|
|
key: 'onScroll',
|
|
value: function onScroll() {
|
|
this.wot.getSetting('onScrollVertically');
|
|
}
|
|
|
|
/**
|
|
* Calculates total sum cells width
|
|
*
|
|
* @param {Number} from Column index which calculates started from
|
|
* @param {Number} to Column index where calculation is finished
|
|
* @returns {Number} Width sum
|
|
*/
|
|
|
|
}, {
|
|
key: 'sumCellSizes',
|
|
value: function sumCellSizes(from, to) {
|
|
var sum = 0;
|
|
var defaultColumnWidth = this.wot.wtSettings.defaultColumnWidth;
|
|
|
|
while (from < to) {
|
|
sum += this.wot.wtTable.getStretchedColumnWidth(from) || defaultColumnWidth;
|
|
from++;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
/**
|
|
* Adjust overlay root element, childs and master table element sizes (width, height).
|
|
*
|
|
* @param {Boolean} [force=false]
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustElementsSize',
|
|
value: function adjustElementsSize() {
|
|
var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
this.updateTrimmingContainer();
|
|
|
|
if (this.needFullRender || force) {
|
|
this.adjustRootElementSize();
|
|
this.adjustRootChildrenSize();
|
|
|
|
if (!force) {
|
|
this.areElementSizesAdjusted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adjust overlay root element size (width and height).
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustRootElementSize',
|
|
value: function adjustRootElementSize() {
|
|
var masterHolder = this.wot.wtTable.holder;
|
|
var scrollbarHeight = masterHolder.clientHeight === masterHolder.offsetHeight ? 0 : (0, _element.getScrollbarWidth)();
|
|
var overlayRoot = this.clone.wtTable.holder.parentNode;
|
|
var overlayRootStyle = overlayRoot.style;
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
var tableWidth = void 0;
|
|
|
|
if (this.trimmingContainer !== window || preventOverflow === 'vertical') {
|
|
var height = this.wot.wtViewport.getWorkspaceHeight() - scrollbarHeight;
|
|
|
|
height = Math.min(height, (0, _element.innerHeight)(this.wot.wtTable.wtRootElement));
|
|
|
|
overlayRootStyle.height = height + 'px';
|
|
} else {
|
|
overlayRootStyle.height = '';
|
|
}
|
|
|
|
this.clone.wtTable.holder.style.height = overlayRootStyle.height;
|
|
|
|
tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE);
|
|
overlayRootStyle.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px';
|
|
}
|
|
|
|
/**
|
|
* Adjust overlay root childs size
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustRootChildrenSize',
|
|
value: function adjustRootChildrenSize() {
|
|
var scrollbarWidth = (0, _element.getScrollbarWidth)();
|
|
|
|
this.clone.wtTable.hider.style.height = this.hider.style.height;
|
|
this.clone.wtTable.holder.style.height = this.clone.wtTable.holder.parentNode.style.height;
|
|
|
|
if (scrollbarWidth === 0) {
|
|
scrollbarWidth = 30;
|
|
}
|
|
this.clone.wtTable.holder.style.width = parseInt(this.clone.wtTable.holder.parentNode.style.width, 10) + scrollbarWidth + 'px';
|
|
}
|
|
|
|
/**
|
|
* Adjust the overlay dimensions and position
|
|
*/
|
|
|
|
}, {
|
|
key: 'applyToDOM',
|
|
value: function applyToDOM() {
|
|
var total = this.wot.getSetting('totalColumns');
|
|
|
|
if (!this.areElementSizesAdjusted) {
|
|
this.adjustElementsSize();
|
|
}
|
|
if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') {
|
|
this.spreader.style.left = this.wot.wtViewport.columnsRenderCalculator.startPosition + 'px';
|
|
} else if (total === 0) {
|
|
this.spreader.style.left = '0';
|
|
} else {
|
|
throw new Error('Incorrect value of the columnsRenderCalculator');
|
|
}
|
|
this.spreader.style.right = '';
|
|
|
|
if (this.needFullRender) {
|
|
this.syncOverlayOffset();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Synchronize calculated top position to an element
|
|
*/
|
|
|
|
}, {
|
|
key: 'syncOverlayOffset',
|
|
value: function syncOverlayOffset() {
|
|
if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') {
|
|
this.clone.wtTable.spreader.style.top = this.wot.wtViewport.rowsRenderCalculator.startPosition + 'px';
|
|
} else {
|
|
this.clone.wtTable.spreader.style.top = '';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scrolls horizontally to a column at the left edge of the viewport
|
|
*
|
|
* @param sourceCol {Number} Column index which you want to scroll to
|
|
* @param [beyondRendered=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default)
|
|
*/
|
|
|
|
}, {
|
|
key: 'scrollTo',
|
|
value: function scrollTo(sourceCol, beyondRendered) {
|
|
var newX = this.getTableParentOffset();
|
|
var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
|
|
var mainHolder = sourceInstance.wtTable.holder;
|
|
var scrollbarCompensation = 0;
|
|
|
|
if (beyondRendered && mainHolder.offsetWidth !== mainHolder.clientWidth) {
|
|
scrollbarCompensation = (0, _element.getScrollbarWidth)();
|
|
}
|
|
if (beyondRendered) {
|
|
newX += this.sumCellSizes(0, sourceCol + 1);
|
|
newX -= this.wot.wtViewport.getViewportWidth();
|
|
} else {
|
|
newX += this.sumCellSizes(this.wot.getSetting('fixedColumnsLeft'), sourceCol);
|
|
}
|
|
newX += scrollbarCompensation;
|
|
|
|
this.setScrollPosition(newX);
|
|
}
|
|
|
|
/**
|
|
* Gets table parent left position
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getTableParentOffset',
|
|
value: function getTableParentOffset() {
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
var offset = 0;
|
|
|
|
if (!preventOverflow && this.trimmingContainer === window) {
|
|
offset = this.wot.wtTable.holderOffset.left;
|
|
}
|
|
|
|
return offset;
|
|
}
|
|
|
|
/**
|
|
* Gets the main overlay's horizontal scroll position
|
|
*
|
|
* @returns {Number} Main table's vertical scroll position
|
|
*/
|
|
|
|
}, {
|
|
key: 'getScrollPosition',
|
|
value: function getScrollPosition() {
|
|
return (0, _element.getScrollLeft)(this.mainTableScrollableElement);
|
|
}
|
|
|
|
/**
|
|
* Adds css classes to hide the header border's header (cell-selection border hiding issue)
|
|
*
|
|
* @param {Number} position Header X position if trimming container is window or scroll top if not
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustHeaderBordersPosition',
|
|
value: function adjustHeaderBordersPosition(position) {
|
|
var masterParent = this.wot.wtTable.holder.parentNode;
|
|
var rowHeaders = this.wot.getSetting('rowHeaders');
|
|
var fixedColumnsLeft = this.wot.getSetting('fixedColumnsLeft');
|
|
var totalRows = this.wot.getSetting('totalRows');
|
|
|
|
if (totalRows) {
|
|
(0, _element.removeClass)(masterParent, 'emptyRows');
|
|
} else {
|
|
(0, _element.addClass)(masterParent, 'emptyRows');
|
|
}
|
|
|
|
if (fixedColumnsLeft && !rowHeaders.length) {
|
|
(0, _element.addClass)(masterParent, 'innerBorderLeft');
|
|
} else if (!fixedColumnsLeft && rowHeaders.length) {
|
|
var previousState = (0, _element.hasClass)(masterParent, 'innerBorderLeft');
|
|
|
|
if (position) {
|
|
(0, _element.addClass)(masterParent, 'innerBorderLeft');
|
|
} else {
|
|
(0, _element.removeClass)(masterParent, 'innerBorderLeft');
|
|
}
|
|
if (!previousState && position || previousState && !position) {
|
|
this.wot.wtOverlays.adjustElementsSize();
|
|
}
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return LeftOverlay;
|
|
}(_base2.default);
|
|
|
|
_base2.default.registerOverlay(_base2.default.CLONE_LEFT, LeftOverlay);
|
|
|
|
exports.default = LeftOverlay;
|
|
|
|
/***/ }),
|
|
/* 301 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @class TopOverlay
|
|
*/
|
|
var TopOverlay = function (_Overlay) {
|
|
_inherits(TopOverlay, _Overlay);
|
|
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
*/
|
|
function TopOverlay(wotInstance) {
|
|
_classCallCheck(this, TopOverlay);
|
|
|
|
var _this = _possibleConstructorReturn(this, (TopOverlay.__proto__ || Object.getPrototypeOf(TopOverlay)).call(this, wotInstance));
|
|
|
|
_this.clone = _this.makeClone(_base2.default.CLONE_TOP);
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Checks if overlay should be fully rendered
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(TopOverlay, [{
|
|
key: 'shouldBeRendered',
|
|
value: function shouldBeRendered() {
|
|
return !!(this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length);
|
|
}
|
|
|
|
/**
|
|
* Updates the top overlay position
|
|
*/
|
|
|
|
}, {
|
|
key: 'resetFixedPosition',
|
|
value: function resetFixedPosition() {
|
|
if (!this.needFullRender || !this.wot.wtTable.holder.parentNode) {
|
|
// removed from DOM
|
|
return;
|
|
}
|
|
var overlayRoot = this.clone.wtTable.holder.parentNode;
|
|
var headerPosition = 0;
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
|
|
if (this.trimmingContainer === window && (!preventOverflow || preventOverflow !== 'vertical')) {
|
|
var box = this.wot.wtTable.hider.getBoundingClientRect();
|
|
var top = Math.ceil(box.top);
|
|
var bottom = Math.ceil(box.bottom);
|
|
var finalLeft = void 0;
|
|
var finalTop = void 0;
|
|
|
|
finalLeft = this.wot.wtTable.hider.style.left;
|
|
finalLeft = finalLeft === '' ? 0 : finalLeft;
|
|
|
|
if (top < 0 && bottom - overlayRoot.offsetHeight > 0) {
|
|
finalTop = -top;
|
|
} else {
|
|
finalTop = 0;
|
|
}
|
|
headerPosition = finalTop;
|
|
finalTop += 'px';
|
|
|
|
(0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop);
|
|
} else {
|
|
headerPosition = this.getScrollPosition();
|
|
(0, _element.resetCssTransform)(overlayRoot);
|
|
}
|
|
|
|
this.adjustHeaderBordersPosition(headerPosition);
|
|
|
|
this.adjustElementsSize();
|
|
}
|
|
|
|
/**
|
|
* Sets the main overlay's vertical scroll position
|
|
*
|
|
* @param {Number} pos
|
|
*/
|
|
|
|
}, {
|
|
key: 'setScrollPosition',
|
|
value: function setScrollPosition(pos) {
|
|
if (this.mainTableScrollableElement === window) {
|
|
window.scrollTo((0, _element.getWindowScrollLeft)(), pos);
|
|
} else {
|
|
this.mainTableScrollableElement.scrollTop = pos;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Triggers onScroll hook callback
|
|
*/
|
|
|
|
}, {
|
|
key: 'onScroll',
|
|
value: function onScroll() {
|
|
this.wot.getSetting('onScrollHorizontally');
|
|
}
|
|
|
|
/**
|
|
* Calculates total sum cells height
|
|
*
|
|
* @param {Number} from Row index which calculates started from
|
|
* @param {Number} to Row index where calculation is finished
|
|
* @returns {Number} Height sum
|
|
*/
|
|
|
|
}, {
|
|
key: 'sumCellSizes',
|
|
value: function sumCellSizes(from, to) {
|
|
var sum = 0;
|
|
var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight;
|
|
|
|
while (from < to) {
|
|
var height = this.wot.wtTable.getRowHeight(from);
|
|
|
|
sum += height === void 0 ? defaultRowHeight : height;
|
|
from++;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
/**
|
|
* Adjust overlay root element, childs and master table element sizes (width, height).
|
|
*
|
|
* @param {Boolean} [force=false]
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustElementsSize',
|
|
value: function adjustElementsSize() {
|
|
var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
this.updateTrimmingContainer();
|
|
|
|
if (this.needFullRender || force) {
|
|
this.adjustRootElementSize();
|
|
this.adjustRootChildrenSize();
|
|
|
|
if (!force) {
|
|
this.areElementSizesAdjusted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adjust overlay root element size (width and height).
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustRootElementSize',
|
|
value: function adjustRootElementSize() {
|
|
var masterHolder = this.wot.wtTable.holder;
|
|
var scrollbarWidth = masterHolder.clientWidth === masterHolder.offsetWidth ? 0 : (0, _element.getScrollbarWidth)();
|
|
var overlayRoot = this.clone.wtTable.holder.parentNode;
|
|
var overlayRootStyle = overlayRoot.style;
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
var tableHeight = void 0;
|
|
|
|
if (this.trimmingContainer !== window || preventOverflow === 'horizontal') {
|
|
var width = this.wot.wtViewport.getWorkspaceWidth() - scrollbarWidth;
|
|
|
|
width = Math.min(width, (0, _element.innerWidth)(this.wot.wtTable.wtRootElement));
|
|
|
|
overlayRootStyle.width = width + 'px';
|
|
} else {
|
|
overlayRootStyle.width = '';
|
|
}
|
|
|
|
this.clone.wtTable.holder.style.width = overlayRootStyle.width;
|
|
|
|
tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE);
|
|
overlayRootStyle.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px';
|
|
}
|
|
|
|
/**
|
|
* Adjust overlay root childs size
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustRootChildrenSize',
|
|
value: function adjustRootChildrenSize() {
|
|
var scrollbarWidth = (0, _element.getScrollbarWidth)();
|
|
|
|
this.clone.wtTable.hider.style.width = this.hider.style.width;
|
|
this.clone.wtTable.holder.style.width = this.clone.wtTable.holder.parentNode.style.width;
|
|
|
|
if (scrollbarWidth === 0) {
|
|
scrollbarWidth = 30;
|
|
}
|
|
this.clone.wtTable.holder.style.height = parseInt(this.clone.wtTable.holder.parentNode.style.height, 10) + scrollbarWidth + 'px';
|
|
}
|
|
|
|
/**
|
|
* Adjust the overlay dimensions and position
|
|
*/
|
|
|
|
}, {
|
|
key: 'applyToDOM',
|
|
value: function applyToDOM() {
|
|
var total = this.wot.getSetting('totalRows');
|
|
|
|
if (!this.areElementSizesAdjusted) {
|
|
this.adjustElementsSize();
|
|
}
|
|
if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') {
|
|
this.spreader.style.top = this.wot.wtViewport.rowsRenderCalculator.startPosition + 'px';
|
|
} else if (total === 0) {
|
|
// can happen if there are 0 rows
|
|
this.spreader.style.top = '0';
|
|
} else {
|
|
throw new Error('Incorrect value of the rowsRenderCalculator');
|
|
}
|
|
this.spreader.style.bottom = '';
|
|
|
|
if (this.needFullRender) {
|
|
this.syncOverlayOffset();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Synchronize calculated left position to an element
|
|
*/
|
|
|
|
}, {
|
|
key: 'syncOverlayOffset',
|
|
value: function syncOverlayOffset() {
|
|
if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') {
|
|
this.clone.wtTable.spreader.style.left = this.wot.wtViewport.columnsRenderCalculator.startPosition + 'px';
|
|
} else {
|
|
this.clone.wtTable.spreader.style.left = '';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scrolls vertically to a row
|
|
*
|
|
* @param sourceRow {Number} Row index which you want to scroll to
|
|
* @param [bottomEdge=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default)
|
|
*/
|
|
|
|
}, {
|
|
key: 'scrollTo',
|
|
value: function scrollTo(sourceRow, bottomEdge) {
|
|
var newY = this.getTableParentOffset();
|
|
var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
|
|
var mainHolder = sourceInstance.wtTable.holder;
|
|
var scrollbarCompensation = 0;
|
|
|
|
if (bottomEdge && mainHolder.offsetHeight !== mainHolder.clientHeight) {
|
|
scrollbarCompensation = (0, _element.getScrollbarWidth)();
|
|
}
|
|
|
|
if (bottomEdge) {
|
|
var fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
|
|
var fixedRowsTop = this.wot.getSetting('fixedRowsTop');
|
|
var totalRows = this.wot.getSetting('totalRows');
|
|
|
|
newY += this.sumCellSizes(0, sourceRow + 1);
|
|
newY -= this.wot.wtViewport.getViewportHeight() - this.sumCellSizes(totalRows - fixedRowsBottom, totalRows);
|
|
// Fix 1 pixel offset when cell is selected
|
|
newY += 1;
|
|
} else {
|
|
newY += this.sumCellSizes(this.wot.getSetting('fixedRowsTop'), sourceRow);
|
|
}
|
|
newY += scrollbarCompensation;
|
|
|
|
this.setScrollPosition(newY);
|
|
}
|
|
|
|
/**
|
|
* Gets table parent top position
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getTableParentOffset',
|
|
value: function getTableParentOffset() {
|
|
if (this.mainTableScrollableElement === window) {
|
|
return this.wot.wtTable.holderOffset.top;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Gets the main overlay's vertical scroll position
|
|
*
|
|
* @returns {Number} Main table's vertical scroll position
|
|
*/
|
|
|
|
}, {
|
|
key: 'getScrollPosition',
|
|
value: function getScrollPosition() {
|
|
return (0, _element.getScrollTop)(this.mainTableScrollableElement);
|
|
}
|
|
|
|
/**
|
|
* Redraw borders of selection
|
|
*
|
|
* @param {WalkontableSelection} selection Selection for redraw
|
|
*/
|
|
|
|
}, {
|
|
key: 'redrawSelectionBorders',
|
|
value: function redrawSelectionBorders(selection) {
|
|
if (selection && selection.cellRange) {
|
|
var border = selection.getBorder(this.wot);
|
|
|
|
if (border) {
|
|
var corners = selection.getCorners();
|
|
border.disappear();
|
|
border.appear(corners);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Redrawing borders of all selections
|
|
*/
|
|
|
|
}, {
|
|
key: 'redrawAllSelectionsBorders',
|
|
value: function redrawAllSelectionsBorders() {
|
|
var selections = this.wot.selections;
|
|
|
|
this.redrawSelectionBorders(selections.current);
|
|
this.redrawSelectionBorders(selections.area);
|
|
this.redrawSelectionBorders(selections.fill);
|
|
this.wot.wtTable.wot.wtOverlays.leftOverlay.refresh();
|
|
}
|
|
|
|
/**
|
|
* Adds css classes to hide the header border's header (cell-selection border hiding issue)
|
|
*
|
|
* @param {Number} position Header Y position if trimming container is window or scroll top if not
|
|
*/
|
|
|
|
}, {
|
|
key: 'adjustHeaderBordersPosition',
|
|
value: function adjustHeaderBordersPosition(position) {
|
|
var masterParent = this.wot.wtTable.holder.parentNode;
|
|
var totalColumns = this.wot.getSetting('totalColumns');
|
|
|
|
if (totalColumns) {
|
|
(0, _element.removeClass)(masterParent, 'emptyColumns');
|
|
} else {
|
|
(0, _element.addClass)(masterParent, 'emptyColumns');
|
|
}
|
|
|
|
if (this.wot.getSetting('fixedRowsTop') === 0 && this.wot.getSetting('columnHeaders').length > 0) {
|
|
var previousState = (0, _element.hasClass)(masterParent, 'innerBorderTop');
|
|
|
|
if (position || this.wot.getSetting('totalRows') === 0) {
|
|
(0, _element.addClass)(masterParent, 'innerBorderTop');
|
|
} else {
|
|
(0, _element.removeClass)(masterParent, 'innerBorderTop');
|
|
}
|
|
|
|
if (!previousState && position || previousState && !position) {
|
|
this.wot.wtOverlays.adjustElementsSize();
|
|
|
|
// cell borders should be positioned once again,
|
|
// because we added / removed 1px border from table header
|
|
this.redrawAllSelectionsBorders();
|
|
}
|
|
}
|
|
|
|
// nasty workaround for double border in the header, TODO: find a pure-css solution
|
|
if (this.wot.getSetting('rowHeaders').length === 0) {
|
|
var secondHeaderCell = this.clone.wtTable.THEAD.querySelectorAll('th:nth-of-type(2)');
|
|
|
|
if (secondHeaderCell) {
|
|
for (var i = 0; i < secondHeaderCell.length; i++) {
|
|
secondHeaderCell[i].style['border-left-width'] = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return TopOverlay;
|
|
}(_base2.default);
|
|
|
|
_base2.default.registerOverlay(_base2.default.CLONE_TOP, TopOverlay);
|
|
|
|
exports.default = TopOverlay;
|
|
|
|
/***/ }),
|
|
/* 302 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _base = __webpack_require__(28);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @class TopLeftCornerOverlay
|
|
*/
|
|
var TopLeftCornerOverlay = function (_Overlay) {
|
|
_inherits(TopLeftCornerOverlay, _Overlay);
|
|
|
|
/**
|
|
* @param {Walkontable} wotInstance
|
|
*/
|
|
function TopLeftCornerOverlay(wotInstance) {
|
|
_classCallCheck(this, TopLeftCornerOverlay);
|
|
|
|
var _this = _possibleConstructorReturn(this, (TopLeftCornerOverlay.__proto__ || Object.getPrototypeOf(TopLeftCornerOverlay)).call(this, wotInstance));
|
|
|
|
_this.clone = _this.makeClone(_base2.default.CLONE_TOP_LEFT_CORNER);
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Checks if overlay should be fully rendered
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(TopLeftCornerOverlay, [{
|
|
key: 'shouldBeRendered',
|
|
value: function shouldBeRendered() {
|
|
return !!((this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length) && (this.wot.getSetting('fixedColumnsLeft') || this.wot.getSetting('rowHeaders').length));
|
|
}
|
|
|
|
/**
|
|
* Updates the corner overlay position
|
|
*/
|
|
|
|
}, {
|
|
key: 'resetFixedPosition',
|
|
value: function resetFixedPosition() {
|
|
this.updateTrimmingContainer();
|
|
|
|
if (!this.wot.wtTable.holder.parentNode) {
|
|
// removed from DOM
|
|
return;
|
|
}
|
|
var overlayRoot = this.clone.wtTable.holder.parentNode;
|
|
var tableHeight = (0, _element.outerHeight)(this.clone.wtTable.TABLE);
|
|
var tableWidth = (0, _element.outerWidth)(this.clone.wtTable.TABLE);
|
|
var preventOverflow = this.wot.getSetting('preventOverflow');
|
|
|
|
if (this.trimmingContainer === window) {
|
|
var box = this.wot.wtTable.hider.getBoundingClientRect();
|
|
var top = Math.ceil(box.top);
|
|
var left = Math.ceil(box.left);
|
|
var bottom = Math.ceil(box.bottom);
|
|
var right = Math.ceil(box.right);
|
|
var finalLeft = '0';
|
|
var finalTop = '0';
|
|
|
|
if (!preventOverflow || preventOverflow === 'vertical') {
|
|
if (left < 0 && right - overlayRoot.offsetWidth > 0) {
|
|
finalLeft = -left + 'px';
|
|
}
|
|
}
|
|
|
|
if (!preventOverflow || preventOverflow === 'horizontal') {
|
|
if (top < 0 && bottom - overlayRoot.offsetHeight > 0) {
|
|
finalTop = -top + 'px';
|
|
}
|
|
}
|
|
(0, _element.setOverlayPosition)(overlayRoot, finalLeft, finalTop);
|
|
} else {
|
|
(0, _element.resetCssTransform)(overlayRoot);
|
|
}
|
|
overlayRoot.style.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px';
|
|
overlayRoot.style.width = (tableWidth === 0 ? tableWidth : tableWidth + 4) + 'px';
|
|
}
|
|
}]);
|
|
|
|
return TopLeftCornerOverlay;
|
|
}(_base2.default);
|
|
|
|
_base2.default.registerOverlay(_base2.default.CLONE_TOP_LEFT_CORNER, TopLeftCornerOverlay);
|
|
|
|
exports.default = TopLeftCornerOverlay;
|
|
|
|
/***/ }),
|
|
/* 303 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _border2 = __webpack_require__(250);
|
|
|
|
var _border3 = _interopRequireDefault(_border2);
|
|
|
|
var _coords = __webpack_require__(43);
|
|
|
|
var _coords2 = _interopRequireDefault(_coords);
|
|
|
|
var _range = __webpack_require__(69);
|
|
|
|
var _range2 = _interopRequireDefault(_range);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Selection
|
|
*/
|
|
var Selection = function () {
|
|
/**
|
|
* @param {Object} settings
|
|
* @param {CellRange} cellRange
|
|
*/
|
|
function Selection(settings, cellRange) {
|
|
_classCallCheck(this, Selection);
|
|
|
|
this.settings = settings;
|
|
this.cellRange = cellRange || null;
|
|
this.instanceBorders = {};
|
|
}
|
|
|
|
/**
|
|
* Each Walkontable clone requires it's own border for every selection. This method creates and returns selection
|
|
* borders per instance
|
|
*
|
|
* @param {Walkontable} wotInstance
|
|
* @returns {Border}
|
|
*/
|
|
|
|
|
|
_createClass(Selection, [{
|
|
key: 'getBorder',
|
|
value: function getBorder(wotInstance) {
|
|
if (this.instanceBorders[wotInstance.guid]) {
|
|
return this.instanceBorders[wotInstance.guid];
|
|
}
|
|
|
|
// where is this returned?
|
|
this.instanceBorders[wotInstance.guid] = new _border3.default(wotInstance, this.settings);
|
|
}
|
|
|
|
/**
|
|
* Checks if selection is empty
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isEmpty',
|
|
value: function isEmpty() {
|
|
return this.cellRange === null;
|
|
}
|
|
|
|
/**
|
|
* Adds a cell coords to the selection
|
|
*
|
|
* @param {CellCoords} coords
|
|
*/
|
|
|
|
}, {
|
|
key: 'add',
|
|
value: function add(coords) {
|
|
if (this.isEmpty()) {
|
|
this.cellRange = new _range2.default(coords, coords, coords);
|
|
} else {
|
|
this.cellRange.expand(coords);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If selection range from or to property equals oldCoords, replace it with newCoords. Return boolean
|
|
* information about success
|
|
*
|
|
* @param {CellCoords} oldCoords
|
|
* @param {CellCoords} newCoords
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'replace',
|
|
value: function replace(oldCoords, newCoords) {
|
|
if (!this.isEmpty()) {
|
|
if (this.cellRange.from.isEqual(oldCoords)) {
|
|
this.cellRange.from = newCoords;
|
|
|
|
return true;
|
|
}
|
|
if (this.cellRange.to.isEqual(oldCoords)) {
|
|
this.cellRange.to = newCoords;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Clears selection
|
|
*/
|
|
|
|
}, {
|
|
key: 'clear',
|
|
value: function clear() {
|
|
this.cellRange = null;
|
|
}
|
|
|
|
/**
|
|
* Returns the top left (TL) and bottom right (BR) selection coordinates
|
|
*
|
|
* @returns {Array} Returns array of coordinates for example `[1, 1, 5, 5]`
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCorners',
|
|
value: function getCorners() {
|
|
var topLeft = this.cellRange.getTopLeftCorner();
|
|
var bottomRight = this.cellRange.getBottomRightCorner();
|
|
|
|
return [topLeft.row, topLeft.col, bottomRight.row, bottomRight.col];
|
|
}
|
|
|
|
/**
|
|
* Adds class name to cell element at given coords
|
|
*
|
|
* @param {Walkontable} wotInstance Walkontable instance
|
|
* @param {Number} sourceRow Cell row coord
|
|
* @param {Number} sourceColumn Cell column coord
|
|
* @param {String} className Class name
|
|
*/
|
|
|
|
}, {
|
|
key: 'addClassAtCoords',
|
|
value: function addClassAtCoords(wotInstance, sourceRow, sourceColumn, className) {
|
|
var TD = wotInstance.wtTable.getCell(new _coords2.default(sourceRow, sourceColumn));
|
|
|
|
if ((typeof TD === 'undefined' ? 'undefined' : _typeof(TD)) === 'object') {
|
|
(0, _element.addClass)(TD, className);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param wotInstance
|
|
*/
|
|
|
|
}, {
|
|
key: 'draw',
|
|
value: function draw(wotInstance) {
|
|
if (this.isEmpty()) {
|
|
if (this.settings.border) {
|
|
var border = this.getBorder(wotInstance);
|
|
|
|
if (border) {
|
|
border.disappear();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
var renderedRows = wotInstance.wtTable.getRenderedRowsCount();
|
|
var renderedColumns = wotInstance.wtTable.getRenderedColumnsCount();
|
|
var corners = this.getCorners();
|
|
var sourceRow = void 0,
|
|
sourceCol = void 0,
|
|
TH = void 0;
|
|
|
|
for (var column = 0; column < renderedColumns; column++) {
|
|
sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(column);
|
|
|
|
if (sourceCol >= corners[1] && sourceCol <= corners[3]) {
|
|
TH = wotInstance.wtTable.getColumnHeader(sourceCol);
|
|
|
|
if (TH) {
|
|
var newClasses = [];
|
|
|
|
if (this.settings.highlightHeaderClassName) {
|
|
newClasses.push(this.settings.highlightHeaderClassName);
|
|
}
|
|
|
|
if (this.settings.highlightColumnClassName) {
|
|
newClasses.push(this.settings.highlightColumnClassName);
|
|
}
|
|
|
|
(0, _element.addClass)(TH, newClasses);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (var row = 0; row < renderedRows; row++) {
|
|
sourceRow = wotInstance.wtTable.rowFilter.renderedToSource(row);
|
|
|
|
if (sourceRow >= corners[0] && sourceRow <= corners[2]) {
|
|
TH = wotInstance.wtTable.getRowHeader(sourceRow);
|
|
|
|
if (TH) {
|
|
var _newClasses = [];
|
|
|
|
if (this.settings.highlightHeaderClassName) {
|
|
_newClasses.push(this.settings.highlightHeaderClassName);
|
|
}
|
|
|
|
if (this.settings.highlightRowClassName) {
|
|
_newClasses.push(this.settings.highlightRowClassName);
|
|
}
|
|
|
|
(0, _element.addClass)(TH, _newClasses);
|
|
}
|
|
}
|
|
|
|
for (var _column = 0; _column < renderedColumns; _column++) {
|
|
sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(_column);
|
|
|
|
if (sourceRow >= corners[0] && sourceRow <= corners[2] && sourceCol >= corners[1] && sourceCol <= corners[3]) {
|
|
// selected cell
|
|
if (this.settings.className) {
|
|
this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.className);
|
|
}
|
|
} else if (sourceRow >= corners[0] && sourceRow <= corners[2]) {
|
|
// selection is in this row
|
|
if (this.settings.highlightRowClassName) {
|
|
this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightRowClassName);
|
|
}
|
|
} else if (sourceCol >= corners[1] && sourceCol <= corners[3]) {
|
|
// selection is in this column
|
|
if (this.settings.highlightColumnClassName) {
|
|
this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightColumnClassName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
wotInstance.getSetting('onBeforeDrawBorders', corners, this.settings.className);
|
|
|
|
if (this.settings.border) {
|
|
var _border = this.getBorder(wotInstance);
|
|
|
|
if (_border) {
|
|
// warning! border.appear modifies corners!
|
|
_border.appear(corners);
|
|
}
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return Selection;
|
|
}();
|
|
|
|
exports.default = Selection;
|
|
|
|
/***/ }),
|
|
/* 304 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var CELL_TYPE = 'autocomplete';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)(CELL_TYPE),
|
|
renderer: (0, _renderers.getRenderer)(CELL_TYPE),
|
|
validator: (0, _validators.getValidator)(CELL_TYPE)
|
|
};
|
|
|
|
/***/ }),
|
|
/* 305 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var CELL_TYPE = 'checkbox';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)(CELL_TYPE),
|
|
renderer: (0, _renderers.getRenderer)(CELL_TYPE)
|
|
};
|
|
|
|
/***/ }),
|
|
/* 306 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var CELL_TYPE = 'date';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)(CELL_TYPE),
|
|
// displays small gray arrow on right side of the cell
|
|
renderer: (0, _renderers.getRenderer)('autocomplete'),
|
|
validator: (0, _validators.getValidator)(CELL_TYPE)
|
|
};
|
|
|
|
/***/ }),
|
|
/* 307 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var CELL_TYPE = 'dropdown';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)(CELL_TYPE),
|
|
// displays small gray arrow on right side of the cell
|
|
renderer: (0, _renderers.getRenderer)('autocomplete'),
|
|
validator: (0, _validators.getValidator)('autocomplete')
|
|
};
|
|
|
|
/***/ }),
|
|
/* 308 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var CELL_TYPE = 'handsontable';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)(CELL_TYPE),
|
|
// displays small gray arrow on right side of the cell
|
|
renderer: (0, _renderers.getRenderer)('autocomplete')
|
|
};
|
|
|
|
/***/ }),
|
|
/* 309 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var CELL_TYPE = 'numeric';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)(CELL_TYPE),
|
|
renderer: (0, _renderers.getRenderer)(CELL_TYPE),
|
|
validator: (0, _validators.getValidator)(CELL_TYPE),
|
|
dataType: 'number'
|
|
};
|
|
|
|
/***/ }),
|
|
/* 310 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var CELL_TYPE = 'password';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)(CELL_TYPE),
|
|
renderer: (0, _renderers.getRenderer)(CELL_TYPE),
|
|
copyable: false
|
|
};
|
|
|
|
/***/ }),
|
|
/* 311 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var CELL_TYPE = 'text';
|
|
|
|
exports.default = {
|
|
editor: (0, _browser.isMobileBrowser)() ? (0, _editors.getEditor)('mobile') : (0, _editors.getEditor)(CELL_TYPE),
|
|
renderer: (0, _renderers.getRenderer)(CELL_TYPE)
|
|
};
|
|
|
|
/***/ }),
|
|
/* 312 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var CELL_TYPE = 'time';
|
|
|
|
exports.default = {
|
|
editor: (0, _editors.getEditor)('text'),
|
|
// displays small gray arrow on right side of the cell
|
|
renderer: (0, _renderers.getRenderer)('text'),
|
|
validator: (0, _validators.getValidator)(CELL_TYPE)
|
|
};
|
|
|
|
/***/ }),
|
|
/* 313 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _SheetClip = __webpack_require__(248);
|
|
|
|
var _SheetClip2 = _interopRequireDefault(_SheetClip);
|
|
|
|
var _data = __webpack_require__(65);
|
|
|
|
var _setting = __webpack_require__(66);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _interval = __webpack_require__(386);
|
|
|
|
var _interval2 = _interopRequireDefault(_interval);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _multiMap = __webpack_require__(324);
|
|
|
|
var _multiMap2 = _interopRequireDefault(_multiMap);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* Utility class that gets and saves data from/to the data source using mapping of columns numbers to object property names
|
|
* @todo refactor arguments of methods getRange, getText to be numbers (not objects)
|
|
* @todo remove priv, GridSettings from object constructor
|
|
*
|
|
* @param {Object} instance Instance of Handsontable
|
|
* @param {*} priv
|
|
* @param {*} GridSettings Grid settings
|
|
* @util
|
|
* @class DataMap
|
|
*/
|
|
function DataMap(instance, priv, GridSettings) {
|
|
var _this = this;
|
|
|
|
this.instance = instance;
|
|
this.priv = priv;
|
|
this.GridSettings = GridSettings;
|
|
this.dataSource = this.instance.getSettings().data;
|
|
this.cachedLength = null;
|
|
this.skipCache = false;
|
|
this.latestSourceRowsCount = 0;
|
|
|
|
if (this.dataSource && this.dataSource[0]) {
|
|
this.duckSchema = this.recursiveDuckSchema(this.dataSource[0]);
|
|
} else {
|
|
this.duckSchema = {};
|
|
}
|
|
this.createMap();
|
|
this.interval = _interval2.default.create(function () {
|
|
return _this.clearLengthCache();
|
|
}, '15fps');
|
|
|
|
this.instance.addHook('skipLengthCache', function (delay) {
|
|
return _this.onSkipLengthCache(delay);
|
|
});
|
|
this.onSkipLengthCache(500);
|
|
}
|
|
|
|
DataMap.prototype.DESTINATION_RENDERER = 1;
|
|
DataMap.prototype.DESTINATION_CLIPBOARD_GENERATOR = 2;
|
|
|
|
/**
|
|
* @param {Object|Array} object
|
|
* @returns {Object|Array}
|
|
*/
|
|
DataMap.prototype.recursiveDuckSchema = function (object) {
|
|
return (0, _object.duckSchema)(object);
|
|
};
|
|
|
|
/**
|
|
* @param {Object} schema
|
|
* @param {Number} lastCol
|
|
* @param {Number} parent
|
|
* @returns {Number}
|
|
*/
|
|
DataMap.prototype.recursiveDuckColumns = function (schema, lastCol, parent) {
|
|
var prop, i;
|
|
if (typeof lastCol === 'undefined') {
|
|
lastCol = 0;
|
|
parent = '';
|
|
}
|
|
if ((typeof schema === 'undefined' ? 'undefined' : _typeof(schema)) === 'object' && !Array.isArray(schema)) {
|
|
for (i in schema) {
|
|
if ((0, _object.hasOwnProperty)(schema, i)) {
|
|
if (schema[i] === null) {
|
|
prop = parent + i;
|
|
this.colToPropCache.push(prop);
|
|
this.propToColCache.set(prop, lastCol);
|
|
|
|
lastCol++;
|
|
} else {
|
|
lastCol = this.recursiveDuckColumns(schema[i], lastCol, i + '.');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return lastCol;
|
|
};
|
|
|
|
DataMap.prototype.createMap = function () {
|
|
var i = void 0;
|
|
var schema = this.getSchema();
|
|
|
|
if (typeof schema === 'undefined') {
|
|
throw new Error('trying to create `columns` definition but you didn\'t provide `schema` nor `data`');
|
|
}
|
|
|
|
this.colToPropCache = [];
|
|
this.propToColCache = new _multiMap2.default();
|
|
|
|
var columns = this.instance.getSettings().columns;
|
|
|
|
if (columns) {
|
|
var maxCols = this.instance.getSettings().maxCols;
|
|
var columnsLen = Math.min(maxCols, columns.length);
|
|
var filteredIndex = 0;
|
|
var columnsAsFunc = false;
|
|
var schemaLen = (0, _object.deepObjectSize)(schema);
|
|
|
|
if (typeof columns === 'function') {
|
|
columnsLen = schemaLen > 0 ? schemaLen : this.instance.countSourceCols();
|
|
columnsAsFunc = true;
|
|
}
|
|
|
|
for (i = 0; i < columnsLen; i++) {
|
|
var column = columnsAsFunc ? columns(i) : columns[i];
|
|
|
|
if ((0, _object.isObject)(column)) {
|
|
if (typeof column.data !== 'undefined') {
|
|
var index = columnsAsFunc ? filteredIndex : i;
|
|
this.colToPropCache[index] = column.data;
|
|
this.propToColCache.set(column.data, index);
|
|
}
|
|
|
|
filteredIndex++;
|
|
}
|
|
}
|
|
} else {
|
|
this.recursiveDuckColumns(schema);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns property name that corresponds with the given column index.
|
|
*
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Number} Physical column index.
|
|
*/
|
|
DataMap.prototype.colToProp = function (col) {
|
|
col = this.instance.runHooks('modifyCol', col);
|
|
|
|
if (!isNaN(col) && this.colToPropCache && typeof this.colToPropCache[col] !== 'undefined') {
|
|
return this.colToPropCache[col];
|
|
}
|
|
|
|
return col;
|
|
};
|
|
|
|
/**
|
|
* @param {Object} prop
|
|
* @fires Hooks#modifyCol
|
|
* @returns {*}
|
|
*/
|
|
DataMap.prototype.propToCol = function (prop) {
|
|
var col;
|
|
|
|
if (typeof this.propToColCache.get(prop) === 'undefined') {
|
|
col = prop;
|
|
} else {
|
|
col = this.propToColCache.get(prop);
|
|
}
|
|
col = this.instance.runHooks('unmodifyCol', col);
|
|
|
|
return col;
|
|
};
|
|
|
|
/**
|
|
* @returns {Object}
|
|
*/
|
|
DataMap.prototype.getSchema = function () {
|
|
var schema = this.instance.getSettings().dataSchema;
|
|
|
|
if (schema) {
|
|
if (typeof schema === 'function') {
|
|
return schema();
|
|
}
|
|
return schema;
|
|
}
|
|
|
|
return this.duckSchema;
|
|
};
|
|
|
|
/**
|
|
* Creates row at the bottom of the data array.
|
|
*
|
|
* @param {Number} [index] Physical index of the row before which the new row will be inserted.
|
|
* @param {Number} [amount] An amount of rows to add.
|
|
* @param {String} [source] Source of method call.
|
|
* @fires Hooks#afterCreateRow
|
|
* @returns {Number} Returns number of created rows.
|
|
*/
|
|
DataMap.prototype.createRow = function (index, amount, source) {
|
|
var row,
|
|
colCount = this.instance.countCols(),
|
|
numberOfCreatedRows = 0,
|
|
currentIndex;
|
|
|
|
if (!amount) {
|
|
amount = 1;
|
|
}
|
|
|
|
if (typeof index !== 'number' || index >= this.instance.countSourceRows()) {
|
|
index = this.instance.countSourceRows();
|
|
}
|
|
this.instance.runHooks('beforeCreateRow', index, amount, source);
|
|
|
|
currentIndex = index;
|
|
var maxRows = this.instance.getSettings().maxRows;
|
|
|
|
while (numberOfCreatedRows < amount && this.instance.countSourceRows() < maxRows) {
|
|
if (this.instance.dataType === 'array') {
|
|
if (this.instance.getSettings().dataSchema) {
|
|
// Clone template array
|
|
row = (0, _object.deepClone)(this.getSchema());
|
|
} else {
|
|
row = [];
|
|
/* eslint-disable no-loop-func */
|
|
(0, _number.rangeEach)(colCount - 1, function () {
|
|
return row.push(null);
|
|
});
|
|
}
|
|
} else if (this.instance.dataType === 'function') {
|
|
row = this.instance.getSettings().dataSchema(index);
|
|
} else {
|
|
row = {};
|
|
(0, _object.deepExtend)(row, this.getSchema());
|
|
}
|
|
|
|
if (index === this.instance.countSourceRows()) {
|
|
this.dataSource.push(row);
|
|
} else {
|
|
this.spliceData(index, 0, row);
|
|
}
|
|
|
|
numberOfCreatedRows++;
|
|
currentIndex++;
|
|
}
|
|
|
|
this.instance.runHooks('afterCreateRow', index, numberOfCreatedRows, source);
|
|
this.instance.forceFullRender = true; // used when data was changed
|
|
|
|
return numberOfCreatedRows;
|
|
};
|
|
|
|
/**
|
|
* Creates col at the right of the data array.
|
|
*
|
|
* @param {Number} [index] Visual index of the column before which the new column will be inserted
|
|
* @param {Number} [amount] An amount of columns to add.
|
|
* @param {String} [source] Source of method call.
|
|
* @fires Hooks#afterCreateCol
|
|
* @returns {Number} Returns number of created columns
|
|
*/
|
|
DataMap.prototype.createCol = function (index, amount, source) {
|
|
if (!this.instance.isColumnModificationAllowed()) {
|
|
throw new Error('Cannot create new column. When data source in an object, ' + 'you can only have as much columns as defined in first data row, data schema or in the \'columns\' setting.' + 'If you want to be able to add new columns, you have to use array datasource.');
|
|
}
|
|
var rlen = this.instance.countSourceRows(),
|
|
data = this.dataSource,
|
|
constructor,
|
|
numberOfCreatedCols = 0,
|
|
currentIndex;
|
|
|
|
if (!amount) {
|
|
amount = 1;
|
|
}
|
|
|
|
if (typeof index !== 'number' || index >= this.instance.countCols()) {
|
|
index = this.instance.countCols();
|
|
}
|
|
this.instance.runHooks('beforeCreateCol', index, amount, source);
|
|
|
|
currentIndex = index;
|
|
|
|
var maxCols = this.instance.getSettings().maxCols;
|
|
while (numberOfCreatedCols < amount && this.instance.countCols() < maxCols) {
|
|
constructor = (0, _setting.columnFactory)(this.GridSettings, this.priv.columnsSettingConflicts);
|
|
|
|
if (typeof index !== 'number' || index >= this.instance.countCols()) {
|
|
if (rlen > 0) {
|
|
for (var r = 0; r < rlen; r++) {
|
|
if (typeof data[r] === 'undefined') {
|
|
data[r] = [];
|
|
}
|
|
data[r].push(null);
|
|
}
|
|
} else {
|
|
data.push([null]);
|
|
}
|
|
// Add new column constructor
|
|
this.priv.columnSettings.push(constructor);
|
|
} else {
|
|
for (var _r = 0; _r < rlen; _r++) {
|
|
data[_r].splice(currentIndex, 0, null);
|
|
}
|
|
// Add new column constructor at given index
|
|
this.priv.columnSettings.splice(currentIndex, 0, constructor);
|
|
}
|
|
|
|
numberOfCreatedCols++;
|
|
currentIndex++;
|
|
}
|
|
|
|
this.instance.runHooks('afterCreateCol', index, numberOfCreatedCols, source);
|
|
this.instance.forceFullRender = true; // used when data was changed
|
|
|
|
return numberOfCreatedCols;
|
|
};
|
|
|
|
/**
|
|
* Removes row from the data array.
|
|
*
|
|
* @param {Number} [index] Visual index of the row to be removed. If not provided, the last row will be removed
|
|
* @param {Number} [amount] Amount of the rows to be removed. If not provided, one row will be removed
|
|
* @param {String} [source] Source of method call.
|
|
* @fires Hooks#beforeRemoveRow
|
|
* @fires Hooks#afterRemoveRow
|
|
*/
|
|
DataMap.prototype.removeRow = function (index, amount, source) {
|
|
if (!amount) {
|
|
amount = 1;
|
|
}
|
|
if (typeof index !== 'number') {
|
|
index = -amount;
|
|
}
|
|
|
|
amount = this.instance.runHooks('modifyRemovedAmount', amount, index);
|
|
|
|
index = (this.instance.countSourceRows() + index) % this.instance.countSourceRows();
|
|
|
|
var logicRows = this.visualRowsToPhysical(index, amount);
|
|
var actionWasNotCancelled = this.instance.runHooks('beforeRemoveRow', index, amount, logicRows, source);
|
|
|
|
if (actionWasNotCancelled === false) {
|
|
return;
|
|
}
|
|
|
|
var data = this.dataSource;
|
|
var newData = void 0;
|
|
|
|
newData = this.filterData(index, amount);
|
|
|
|
if (newData) {
|
|
data.length = 0;
|
|
Array.prototype.push.apply(data, newData);
|
|
}
|
|
|
|
this.instance.runHooks('afterRemoveRow', index, amount, logicRows, source);
|
|
|
|
this.instance.forceFullRender = true; // used when data was changed
|
|
};
|
|
|
|
/**
|
|
* Removes column from the data array.
|
|
*
|
|
* @param {Number} [index] Visual index of the column to be removed. If not provided, the last column will be removed
|
|
* @param {Number} [amount] Amount of the columns to be removed. If not provided, one column will be removed
|
|
* @param {String} [source] Source of method call.
|
|
* @fires Hooks#beforeRemoveCol
|
|
* @fires Hooks#afterRemoveCol
|
|
*/
|
|
DataMap.prototype.removeCol = function (index, amount, source) {
|
|
if (this.instance.dataType === 'object' || this.instance.getSettings().columns) {
|
|
throw new Error('cannot remove column with object data source or columns option specified');
|
|
}
|
|
if (!amount) {
|
|
amount = 1;
|
|
}
|
|
if (typeof index !== 'number') {
|
|
index = -amount;
|
|
}
|
|
|
|
index = (this.instance.countCols() + index) % this.instance.countCols();
|
|
|
|
var logicColumns = this.visualColumnsToPhysical(index, amount);
|
|
var descendingLogicColumns = logicColumns.slice(0).sort(function (a, b) {
|
|
return b - a;
|
|
});
|
|
var actionWasNotCancelled = this.instance.runHooks('beforeRemoveCol', index, amount, logicColumns, source);
|
|
|
|
if (actionWasNotCancelled === false) {
|
|
return;
|
|
}
|
|
|
|
var isTableUniform = true;
|
|
var removedColumnsCount = descendingLogicColumns.length;
|
|
var data = this.dataSource;
|
|
|
|
for (var c = 0; c < removedColumnsCount; c++) {
|
|
if (isTableUniform && logicColumns[0] !== logicColumns[c] - c) {
|
|
isTableUniform = false;
|
|
}
|
|
}
|
|
|
|
if (isTableUniform) {
|
|
for (var r = 0, rlen = this.instance.countSourceRows(); r < rlen; r++) {
|
|
data[r].splice(logicColumns[0], amount);
|
|
}
|
|
} else {
|
|
for (var _r2 = 0, _rlen = this.instance.countSourceRows(); _r2 < _rlen; _r2++) {
|
|
for (var _c = 0; _c < removedColumnsCount; _c++) {
|
|
data[_r2].splice(descendingLogicColumns[_c], 1);
|
|
}
|
|
}
|
|
|
|
for (var _c2 = 0; _c2 < removedColumnsCount; _c2++) {
|
|
this.priv.columnSettings.splice(logicColumns[_c2], 1);
|
|
}
|
|
}
|
|
|
|
this.instance.runHooks('afterRemoveCol', index, amount, logicColumns, source);
|
|
|
|
this.instance.forceFullRender = true; // used when data was changed
|
|
};
|
|
|
|
/**
|
|
* Add/Removes data from the column.
|
|
*
|
|
* @param {Number} col Physical index of column in which do you want to do splice
|
|
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end
|
|
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed
|
|
* @returns {Array} Returns removed portion of columns
|
|
*/
|
|
DataMap.prototype.spliceCol = function (col, index, amount /* , elements...*/) {
|
|
var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : [];
|
|
|
|
var colData = this.instance.getDataAtCol(col);
|
|
var removed = colData.slice(index, index + amount);
|
|
var after = colData.slice(index + amount);
|
|
|
|
(0, _array.extendArray)(elements, after);
|
|
var i = 0;
|
|
while (i < amount) {
|
|
elements.push(null); // add null in place of removed elements
|
|
i++;
|
|
}
|
|
(0, _array.to2dArray)(elements);
|
|
this.instance.populateFromArray(index, col, elements, null, null, 'spliceCol');
|
|
|
|
return removed;
|
|
};
|
|
|
|
/**
|
|
* Add/Removes data from the row.
|
|
*
|
|
* @param {Number} row Physical index of row in which do you want to do splice
|
|
* @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end.
|
|
* @param {Number} amount An integer indicating the number of old array elements to remove. If amount is 0, no elements are removed.
|
|
* @returns {Array} Returns removed portion of rows
|
|
*/
|
|
DataMap.prototype.spliceRow = function (row, index, amount /* , elements...*/) {
|
|
var elements = arguments.length >= 4 ? [].slice.call(arguments, 3) : [];
|
|
|
|
var rowData = this.instance.getSourceDataAtRow(row);
|
|
var removed = rowData.slice(index, index + amount);
|
|
var after = rowData.slice(index + amount);
|
|
|
|
(0, _array.extendArray)(elements, after);
|
|
var i = 0;
|
|
while (i < amount) {
|
|
elements.push(null); // add null in place of removed elements
|
|
i++;
|
|
}
|
|
this.instance.populateFromArray(row, index, [elements], null, null, 'spliceRow');
|
|
|
|
return removed;
|
|
};
|
|
|
|
/**
|
|
* Add/remove row(s) to/from the data source.
|
|
*
|
|
* @param {Number} index Physical index of the element to remove.
|
|
* @param {Number} amount Number of rows to add/remove.
|
|
* @param {Object} element Row to add.
|
|
*/
|
|
DataMap.prototype.spliceData = function (index, amount, element) {
|
|
var continueSplicing = this.instance.runHooks('beforeDataSplice', index, amount, element);
|
|
|
|
if (continueSplicing !== false) {
|
|
this.dataSource.splice(index, amount, element);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Filter unwanted data elements from the data source.
|
|
*
|
|
* @param {Number} index Visual index of the element to remove.
|
|
* @param {Number} amount Number of rows to add/remove.
|
|
* @returns {Array}
|
|
*/
|
|
DataMap.prototype.filterData = function (index, amount) {
|
|
var physicalRows = this.visualRowsToPhysical(index, amount);
|
|
var continueSplicing = this.instance.runHooks('beforeDataFilter', index, amount, physicalRows);
|
|
|
|
if (continueSplicing !== false) {
|
|
var newData = this.dataSource.filter(function (row, index) {
|
|
return physicalRows.indexOf(index) == -1;
|
|
});
|
|
|
|
return newData;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns single value from the data array.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} prop
|
|
*/
|
|
DataMap.prototype.get = function (row, prop) {
|
|
row = this.instance.runHooks('modifyRow', row);
|
|
|
|
var dataRow = this.dataSource[row];
|
|
// TODO: To remove, use 'modifyData' hook instead (see below)
|
|
var modifiedRowData = this.instance.runHooks('modifyRowData', row);
|
|
|
|
dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow;
|
|
//
|
|
|
|
var value = null;
|
|
|
|
// try to get value under property `prop` (includes dot)
|
|
if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) {
|
|
value = dataRow[prop];
|
|
} else if (typeof prop === 'string' && prop.indexOf('.') > -1) {
|
|
var sliced = prop.split('.');
|
|
var out = dataRow;
|
|
|
|
if (!out) {
|
|
return null;
|
|
}
|
|
for (var i = 0, ilen = sliced.length; i < ilen; i++) {
|
|
out = out[sliced[i]];
|
|
|
|
if (typeof out === 'undefined') {
|
|
return null;
|
|
}
|
|
}
|
|
value = out;
|
|
} else if (typeof prop === 'function') {
|
|
/**
|
|
* allows for interacting with complex structures, for example
|
|
* d3/jQuery getter/setter properties:
|
|
*
|
|
* {columns: [{
|
|
* data: function(row, value){
|
|
* if(arguments.length === 1){
|
|
* return row.property();
|
|
* }
|
|
* row.property(value);
|
|
* }
|
|
* }]}
|
|
*/
|
|
value = prop(this.dataSource.slice(row, row + 1)[0]);
|
|
}
|
|
|
|
if (this.instance.hasHook('modifyData')) {
|
|
var valueHolder = (0, _object.createObjectPropListener)(value);
|
|
|
|
this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'get');
|
|
|
|
if (valueHolder.isTouched()) {
|
|
value = valueHolder.value;
|
|
}
|
|
}
|
|
|
|
return value;
|
|
};
|
|
|
|
var copyableLookup = (0, _data.cellMethodLookupFactory)('copyable', false);
|
|
|
|
/**
|
|
* Returns single value from the data array (intended for clipboard copy to an external application).
|
|
*
|
|
* @param {Number} row Physical row index.
|
|
* @param {Number} prop
|
|
* @returns {String}
|
|
*/
|
|
DataMap.prototype.getCopyable = function (row, prop) {
|
|
if (copyableLookup.call(this.instance, row, this.propToCol(prop))) {
|
|
return this.get(row, prop);
|
|
}
|
|
return '';
|
|
};
|
|
|
|
/**
|
|
* Saves single value to the data array.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} prop
|
|
* @param {String} value
|
|
* @param {String} [source] Source of hook runner.
|
|
*/
|
|
DataMap.prototype.set = function (row, prop, value, source) {
|
|
row = this.instance.runHooks('modifyRow', row, source || 'datamapGet');
|
|
|
|
var dataRow = this.dataSource[row];
|
|
// TODO: To remove, use 'modifyData' hook instead (see below)
|
|
var modifiedRowData = this.instance.runHooks('modifyRowData', row);
|
|
|
|
dataRow = isNaN(modifiedRowData) ? modifiedRowData : dataRow;
|
|
//
|
|
|
|
if (this.instance.hasHook('modifyData')) {
|
|
var valueHolder = (0, _object.createObjectPropListener)(value);
|
|
|
|
this.instance.runHooks('modifyData', row, this.propToCol(prop), valueHolder, 'set');
|
|
|
|
if (valueHolder.isTouched()) {
|
|
value = valueHolder.value;
|
|
}
|
|
}
|
|
|
|
// try to set value under property `prop` (includes dot)
|
|
if (dataRow && dataRow.hasOwnProperty && (0, _object.hasOwnProperty)(dataRow, prop)) {
|
|
dataRow[prop] = value;
|
|
} else if (typeof prop === 'string' && prop.indexOf('.') > -1) {
|
|
var sliced = prop.split('.');
|
|
var out = dataRow;
|
|
var i = 0;
|
|
var ilen = void 0;
|
|
|
|
for (i = 0, ilen = sliced.length - 1; i < ilen; i++) {
|
|
if (typeof out[sliced[i]] === 'undefined') {
|
|
out[sliced[i]] = {};
|
|
}
|
|
out = out[sliced[i]];
|
|
}
|
|
out[sliced[i]] = value;
|
|
} else if (typeof prop === 'function') {
|
|
/* see the `function` handler in `get` */
|
|
prop(this.dataSource.slice(row, row + 1)[0], value);
|
|
} else {
|
|
dataRow[prop] = value;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* This ridiculous piece of code maps rows Id that are present in table data to those displayed for user.
|
|
* The trick is, the physical row id (stored in settings.data) is not necessary the same
|
|
* as the visual (displayed) row id (e.g. when sorting is applied).
|
|
*
|
|
* @param {Number} index Visual row index.
|
|
* @param {Number} amount
|
|
* @fires Hooks#modifyRow
|
|
* @returns {Number}
|
|
*/
|
|
DataMap.prototype.visualRowsToPhysical = function (index, amount) {
|
|
var totalRows = this.instance.countSourceRows();
|
|
var physicRow = (totalRows + index) % totalRows;
|
|
var logicRows = [];
|
|
var rowsToRemove = amount;
|
|
var row;
|
|
|
|
while (physicRow < totalRows && rowsToRemove) {
|
|
row = this.instance.runHooks('modifyRow', physicRow);
|
|
logicRows.push(row);
|
|
|
|
rowsToRemove--;
|
|
physicRow++;
|
|
}
|
|
|
|
return logicRows;
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param index Visual column index.
|
|
* @param amount
|
|
* @returns {Array}
|
|
*/
|
|
DataMap.prototype.visualColumnsToPhysical = function (index, amount) {
|
|
var totalCols = this.instance.countCols();
|
|
var physicalCol = (totalCols + index) % totalCols;
|
|
var visualCols = [];
|
|
var colsToRemove = amount;
|
|
|
|
while (physicalCol < totalCols && colsToRemove) {
|
|
var col = this.instance.runHooks('modifyCol', physicalCol);
|
|
|
|
visualCols.push(col);
|
|
|
|
colsToRemove--;
|
|
physicalCol++;
|
|
}
|
|
|
|
return visualCols;
|
|
};
|
|
|
|
/**
|
|
* Clears the data array.
|
|
*/
|
|
DataMap.prototype.clear = function () {
|
|
for (var r = 0; r < this.instance.countSourceRows(); r++) {
|
|
for (var c = 0; c < this.instance.countCols(); c++) {
|
|
this.set(r, this.colToProp(c), '');
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Clear cached data length.
|
|
*/
|
|
DataMap.prototype.clearLengthCache = function () {
|
|
this.cachedLength = null;
|
|
};
|
|
|
|
/**
|
|
* Get data length.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
DataMap.prototype.getLength = function () {
|
|
var _this2 = this;
|
|
|
|
var maxRows = void 0,
|
|
maxRowsFromSettings = this.instance.getSettings().maxRows;
|
|
|
|
if (maxRowsFromSettings < 0 || maxRowsFromSettings === 0) {
|
|
maxRows = 0;
|
|
} else {
|
|
maxRows = maxRowsFromSettings || Infinity;
|
|
}
|
|
|
|
var length = this.instance.countSourceRows();
|
|
|
|
if (this.instance.hasHook('modifyRow')) {
|
|
var reValidate = this.skipCache;
|
|
|
|
this.interval.start();
|
|
if (length !== this.latestSourceRowsCount) {
|
|
reValidate = true;
|
|
}
|
|
|
|
this.latestSourceRowsCount = length;
|
|
if (this.cachedLength === null || reValidate) {
|
|
(0, _number.rangeEach)(length - 1, function (row) {
|
|
row = _this2.instance.runHooks('modifyRow', row);
|
|
|
|
if (row === null) {
|
|
--length;
|
|
}
|
|
});
|
|
this.cachedLength = length;
|
|
} else {
|
|
length = this.cachedLength;
|
|
}
|
|
} else {
|
|
this.interval.stop();
|
|
}
|
|
|
|
return Math.min(length, maxRows);
|
|
};
|
|
|
|
/**
|
|
* Returns the data array.
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
DataMap.prototype.getAll = function () {
|
|
var start = {
|
|
row: 0,
|
|
col: 0
|
|
};
|
|
|
|
var end = {
|
|
row: Math.max(this.instance.countSourceRows() - 1, 0),
|
|
col: Math.max(this.instance.countCols() - 1, 0)
|
|
};
|
|
|
|
if (start.row - end.row === 0 && !this.instance.countSourceRows()) {
|
|
return [];
|
|
}
|
|
|
|
return this.getRange(start, end, DataMap.prototype.DESTINATION_RENDERER);
|
|
};
|
|
|
|
/**
|
|
* Returns data range as array.
|
|
*
|
|
* @param {Object} [start] Start selection position. Visual indexes.
|
|
* @param {Object} [end] End selection position. Visual indexes.
|
|
* @param {Number} destination Destination of datamap.get
|
|
* @returns {Array}
|
|
*/
|
|
DataMap.prototype.getRange = function (start, end, destination) {
|
|
var r,
|
|
rlen,
|
|
c,
|
|
clen,
|
|
output = [],
|
|
row;
|
|
|
|
var maxRows = this.instance.getSettings().maxRows;
|
|
var maxCols = this.instance.getSettings().maxCols;
|
|
|
|
if (maxRows === 0 || maxCols === 0) {
|
|
return [];
|
|
}
|
|
|
|
var getFn = destination === this.DESTINATION_CLIPBOARD_GENERATOR ? this.getCopyable : this.get;
|
|
|
|
rlen = Math.min(Math.max(maxRows - 1, 0), Math.max(start.row, end.row));
|
|
clen = Math.min(Math.max(maxCols - 1, 0), Math.max(start.col, end.col));
|
|
|
|
for (r = Math.min(start.row, end.row); r <= rlen; r++) {
|
|
row = [];
|
|
var physicalRow = this.instance.runHooks('modifyRow', r);
|
|
|
|
for (c = Math.min(start.col, end.col); c <= clen; c++) {
|
|
|
|
if (physicalRow === null) {
|
|
break;
|
|
}
|
|
row.push(getFn.call(this, r, this.colToProp(c)));
|
|
}
|
|
if (physicalRow !== null) {
|
|
output.push(row);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
};
|
|
|
|
/**
|
|
* Return data as text (tab separated columns).
|
|
*
|
|
* @param {Object} [start] Start selection position. Visual indexes.
|
|
* @param {Object} [end] End selection position. Visual indexes.
|
|
* @returns {String}
|
|
*/
|
|
DataMap.prototype.getText = function (start, end) {
|
|
return _SheetClip2.default.stringify(this.getRange(start, end, this.DESTINATION_RENDERER));
|
|
};
|
|
|
|
/**
|
|
* Return data as copyable text (tab separated columns intended for clipboard copy to an external application).
|
|
*
|
|
* @param {Object} [start] Start selection position. Visual indexes.
|
|
* @param {Object} [end] End selection position. Visual indexes.
|
|
* @returns {String}
|
|
*/
|
|
DataMap.prototype.getCopyableText = function (start, end) {
|
|
return _SheetClip2.default.stringify(this.getRange(start, end, this.DESTINATION_CLIPBOARD_GENERATOR));
|
|
};
|
|
|
|
/**
|
|
* `skipLengthCache` callback.
|
|
* @private
|
|
* @param {Number} delay Time of the delay in milliseconds.
|
|
*/
|
|
DataMap.prototype.onSkipLengthCache = function (delay) {
|
|
var _this3 = this;
|
|
|
|
this.skipCache = true;
|
|
setTimeout(function () {
|
|
_this3.skipCache = false;
|
|
}, delay);
|
|
};
|
|
|
|
/**
|
|
* Destroy instance.
|
|
*/
|
|
DataMap.prototype.destroy = function () {
|
|
this.interval.stop();
|
|
|
|
this.interval = null;
|
|
this.instance = null;
|
|
this.priv = null;
|
|
this.GridSettings = null;
|
|
this.dataSource = null;
|
|
this.cachedLength = null;
|
|
this.duckSchema = null;
|
|
};
|
|
|
|
exports.default = DataMap;
|
|
|
|
/***/ }),
|
|
/* 314 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class DataSource
|
|
* @private
|
|
*/
|
|
var DataSource = function () {
|
|
function DataSource(hotInstance) {
|
|
var dataSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
|
|
_classCallCheck(this, DataSource);
|
|
|
|
/**
|
|
* Instance of Handsontable.
|
|
*
|
|
* @type {Handsontable}
|
|
*/
|
|
this.hot = hotInstance;
|
|
/**
|
|
* Data source
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
this.data = dataSource;
|
|
/**
|
|
* Type of data source.
|
|
*
|
|
* @type {String}
|
|
* @default 'array'
|
|
*/
|
|
this.dataType = 'array';
|
|
|
|
this.colToProp = function () {};
|
|
this.propToCol = function () {};
|
|
}
|
|
|
|
/**
|
|
* Get all data.
|
|
*
|
|
* @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided
|
|
* in another format.
|
|
* @returns {Array}
|
|
*/
|
|
|
|
|
|
_createClass(DataSource, [{
|
|
key: 'getData',
|
|
value: function getData() {
|
|
var toArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
var result = this.data;
|
|
|
|
if (toArray) {
|
|
result = this.getByRange({ row: 0, col: 0 }, { row: Math.max(this.countRows() - 1, 0), col: Math.max(this.countColumns() - 1, 0) }, true);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Set new data source.
|
|
*
|
|
* @param data {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'setData',
|
|
value: function setData(data) {
|
|
this.data = data;
|
|
}
|
|
|
|
/**
|
|
* Returns array of column values from the data source. `column` is the index of the row in the data source.
|
|
*
|
|
* @param {Number} column Visual column index.
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getAtColumn',
|
|
value: function getAtColumn(column) {
|
|
var _this = this;
|
|
|
|
var result = [];
|
|
|
|
(0, _array.arrayEach)(this.data, function (row) {
|
|
var property = _this.colToProp(column);
|
|
|
|
if (typeof property === 'string') {
|
|
row = (0, _object.getProperty)(row, property);
|
|
} else {
|
|
row = row[property];
|
|
}
|
|
result.push(row);
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Returns a single row of the data (array or object, depending on what you have). `row` is the index of the row in the data source.
|
|
*
|
|
* @param {Number} row Physical row index.
|
|
* @returns {Array|Object}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getAtRow',
|
|
value: function getAtRow(row) {
|
|
return this.data[row];
|
|
}
|
|
|
|
/**
|
|
* Returns a single value from the data.
|
|
*
|
|
* @param {Number} row Physical row index.
|
|
* @param {Number} column Visual column index.
|
|
* @returns {*}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getAtCell',
|
|
value: function getAtCell(row, column) {
|
|
var result = null;
|
|
|
|
var modifyRowData = this.hot.runHooks('modifyRowData', row);
|
|
|
|
var dataRow = isNaN(modifyRowData) ? modifyRowData : this.data[row];
|
|
|
|
if (dataRow) {
|
|
var prop = this.colToProp(column);
|
|
|
|
if (typeof prop === 'string') {
|
|
result = (0, _object.getProperty)(dataRow, prop);
|
|
} else if (typeof prop === 'function') {
|
|
result = prop(this.data.slice(row, row + 1)[0]);
|
|
} else {
|
|
result = dataRow[prop];
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Returns source data by passed range.
|
|
*
|
|
* @param {Object} start Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects).
|
|
* @param {Object} end Object with physical `row` and `col` keys (or visual column index, if data type is an array of objects).
|
|
* @param {Boolean} [toArray=false] If `true` return source data as an array of arrays even when source data was provided
|
|
* in another format.
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getByRange',
|
|
value: function getByRange(start, end) {
|
|
var _this2 = this;
|
|
|
|
var toArray = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
|
|
var startRow = Math.min(start.row, end.row);
|
|
var startCol = Math.min(start.col, end.col);
|
|
var endRow = Math.max(start.row, end.row);
|
|
var endCol = Math.max(start.col, end.col);
|
|
var result = [];
|
|
|
|
(0, _number.rangeEach)(startRow, endRow, function (currentRow) {
|
|
var row = _this2.getAtRow(currentRow);
|
|
var newRow = void 0;
|
|
|
|
if (_this2.dataType === 'array') {
|
|
newRow = row.slice(startCol, endCol + 1);
|
|
} else if (_this2.dataType === 'object') {
|
|
newRow = toArray ? [] : {};
|
|
|
|
(0, _number.rangeEach)(startCol, endCol, function (column) {
|
|
var prop = _this2.colToProp(column);
|
|
|
|
if (toArray) {
|
|
newRow.push(row[prop]);
|
|
} else {
|
|
newRow[prop] = row[prop];
|
|
}
|
|
});
|
|
}
|
|
|
|
result.push(newRow);
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count number of rows.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'countRows',
|
|
value: function countRows() {
|
|
return Array.isArray(this.data) ? this.data.length : 0;
|
|
}
|
|
|
|
/**
|
|
* Count number of columns.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'countColumns',
|
|
value: function countColumns() {
|
|
var result = 0;
|
|
|
|
if (Array.isArray(this.data)) {
|
|
if (this.dataType === 'array') {
|
|
result = this.data[0].length;
|
|
} else if (this.dataType === 'object') {
|
|
result = Object.keys(this.data[0]).length;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Destroy instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.data = null;
|
|
this.hot = null;
|
|
}
|
|
}]);
|
|
|
|
return DataSource;
|
|
}();
|
|
|
|
exports.default = DataSource;
|
|
|
|
/***/ }),
|
|
/* 315 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _baseEditor = __webpack_require__(37);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function EditorManager(instance, priv, selection) {
|
|
var _this = this,
|
|
destroyed = false,
|
|
eventManager,
|
|
activeEditor;
|
|
|
|
eventManager = new _eventManager2.default(instance);
|
|
|
|
function moveSelectionAfterEnter(shiftKey) {
|
|
selection.setSelectedHeaders(false, false, false);
|
|
var enterMoves = typeof priv.settings.enterMoves === 'function' ? priv.settings.enterMoves(event) : priv.settings.enterMoves;
|
|
|
|
if (shiftKey) {
|
|
// move selection up
|
|
selection.transformStart(-enterMoves.row, -enterMoves.col);
|
|
} else {
|
|
// move selection down (add a new row if needed)
|
|
selection.transformStart(enterMoves.row, enterMoves.col, true);
|
|
}
|
|
}
|
|
|
|
function moveSelectionUp(shiftKey) {
|
|
if (shiftKey) {
|
|
if (selection.selectedHeader.cols) {
|
|
selection.setSelectedHeaders(selection.selectedHeader.rows, false, false);
|
|
}
|
|
selection.transformEnd(-1, 0);
|
|
} else {
|
|
selection.setSelectedHeaders(false, false, false);
|
|
selection.transformStart(-1, 0);
|
|
}
|
|
}
|
|
|
|
function moveSelectionDown(shiftKey) {
|
|
if (shiftKey) {
|
|
// expanding selection down with shift
|
|
selection.transformEnd(1, 0);
|
|
} else {
|
|
selection.setSelectedHeaders(false, false, false);
|
|
selection.transformStart(1, 0);
|
|
}
|
|
}
|
|
|
|
function moveSelectionRight(shiftKey) {
|
|
if (shiftKey) {
|
|
selection.transformEnd(0, 1);
|
|
} else {
|
|
selection.setSelectedHeaders(false, false, false);
|
|
selection.transformStart(0, 1);
|
|
}
|
|
}
|
|
|
|
function moveSelectionLeft(shiftKey) {
|
|
if (shiftKey) {
|
|
if (selection.selectedHeader.rows) {
|
|
selection.setSelectedHeaders(false, selection.selectedHeader.cols, false);
|
|
}
|
|
selection.transformEnd(0, -1);
|
|
} else {
|
|
selection.setSelectedHeaders(false, false, false);
|
|
selection.transformStart(0, -1);
|
|
}
|
|
}
|
|
|
|
function onKeyDown(event) {
|
|
var ctrlDown, rangeModifier;
|
|
|
|
if (!instance.isListening()) {
|
|
return;
|
|
}
|
|
instance.runHooks('beforeKeyDown', event);
|
|
|
|
if (destroyed) {
|
|
return;
|
|
}
|
|
if ((0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
priv.lastKeyCode = event.keyCode;
|
|
|
|
if (!selection.isSelected()) {
|
|
return;
|
|
}
|
|
// catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
|
|
ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
|
|
|
|
if (activeEditor && !activeEditor.isWaiting()) {
|
|
if (!(0, _unicode.isMetaKey)(event.keyCode) && !(0, _unicode.isCtrlKey)(event.keyCode) && !ctrlDown && !_this.isEditorOpened()) {
|
|
_this.openEditor('', event);
|
|
|
|
return;
|
|
}
|
|
}
|
|
rangeModifier = event.shiftKey ? selection.setRangeEnd : selection.setRangeStart;
|
|
|
|
switch (event.keyCode) {
|
|
case _unicode.KEY_CODES.A:
|
|
if (!_this.isEditorOpened() && ctrlDown) {
|
|
selection.selectAll();
|
|
|
|
event.preventDefault();
|
|
(0, _event.stopPropagation)(event);
|
|
}
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_UP:
|
|
if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
|
|
_this.closeEditorAndSaveChanges(ctrlDown);
|
|
}
|
|
moveSelectionUp(event.shiftKey);
|
|
|
|
event.preventDefault();
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_DOWN:
|
|
if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
|
|
_this.closeEditorAndSaveChanges(ctrlDown);
|
|
}
|
|
|
|
moveSelectionDown(event.shiftKey);
|
|
|
|
event.preventDefault();
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_RIGHT:
|
|
if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
|
|
_this.closeEditorAndSaveChanges(ctrlDown);
|
|
}
|
|
|
|
moveSelectionRight(event.shiftKey);
|
|
|
|
event.preventDefault();
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_LEFT:
|
|
if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
|
|
_this.closeEditorAndSaveChanges(ctrlDown);
|
|
}
|
|
|
|
moveSelectionLeft(event.shiftKey);
|
|
|
|
event.preventDefault();
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.TAB:
|
|
selection.setSelectedHeaders(false, false, false);
|
|
var tabMoves = typeof priv.settings.tabMoves === 'function' ? priv.settings.tabMoves(event) : priv.settings.tabMoves;
|
|
|
|
if (event.shiftKey) {
|
|
// move selection left
|
|
selection.transformStart(-tabMoves.row, -tabMoves.col);
|
|
} else {
|
|
// move selection right (add a new column if needed)
|
|
selection.transformStart(tabMoves.row, tabMoves.col, true);
|
|
}
|
|
event.preventDefault();
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.BACKSPACE:
|
|
case _unicode.KEY_CODES.DELETE:
|
|
selection.empty(event);
|
|
_this.prepareEditor();
|
|
event.preventDefault();
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.F2:
|
|
/* F2 */
|
|
_this.openEditor(null, event);
|
|
|
|
if (activeEditor) {
|
|
activeEditor.enableFullEditMode();
|
|
}
|
|
event.preventDefault(); // prevent Opera from opening 'Go to Page dialog'
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ENTER:
|
|
/* return/enter */
|
|
if (_this.isEditorOpened()) {
|
|
|
|
if (activeEditor && activeEditor.state !== _baseEditor.EditorState.WAITING) {
|
|
_this.closeEditorAndSaveChanges(ctrlDown);
|
|
}
|
|
moveSelectionAfterEnter(event.shiftKey);
|
|
} else if (instance.getSettings().enterBeginsEditing) {
|
|
_this.openEditor(null, event);
|
|
|
|
if (activeEditor) {
|
|
activeEditor.enableFullEditMode();
|
|
}
|
|
} else {
|
|
moveSelectionAfterEnter(event.shiftKey);
|
|
}
|
|
event.preventDefault(); // don't add newline to field
|
|
(0, _event.stopImmediatePropagation)(event); // required by HandsontableEditor
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ESCAPE:
|
|
if (_this.isEditorOpened()) {
|
|
_this.closeEditorAndRestoreOriginalValue(ctrlDown);
|
|
}
|
|
event.preventDefault();
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.HOME:
|
|
selection.setSelectedHeaders(false, false, false);
|
|
if (event.ctrlKey || event.metaKey) {
|
|
rangeModifier(new _src.CellCoords(0, priv.selRange.from.col));
|
|
} else {
|
|
rangeModifier(new _src.CellCoords(priv.selRange.from.row, 0));
|
|
}
|
|
event.preventDefault(); // don't scroll the window
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.END:
|
|
selection.setSelectedHeaders(false, false, false);
|
|
if (event.ctrlKey || event.metaKey) {
|
|
rangeModifier(new _src.CellCoords(instance.countRows() - 1, priv.selRange.from.col));
|
|
} else {
|
|
rangeModifier(new _src.CellCoords(priv.selRange.from.row, instance.countCols() - 1));
|
|
}
|
|
event.preventDefault(); // don't scroll the window
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.PAGE_UP:
|
|
selection.setSelectedHeaders(false, false, false);
|
|
selection.transformStart(-instance.countVisibleRows(), 0);
|
|
event.preventDefault(); // don't page up the window
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.PAGE_DOWN:
|
|
selection.setSelectedHeaders(false, false, false);
|
|
selection.transformStart(instance.countVisibleRows(), 0);
|
|
event.preventDefault(); // don't page down the window
|
|
(0, _event.stopPropagation)(event);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
instance.addHook('afterDocumentKeyDown', onKeyDown);
|
|
|
|
eventManager.addEventListener(document.documentElement, 'keydown', function (event) {
|
|
if (!destroyed) {
|
|
instance.runHooks('afterDocumentKeyDown', event);
|
|
}
|
|
});
|
|
|
|
function onDblClick(event, coords, elem) {
|
|
// may be TD or TH
|
|
if (elem.nodeName == 'TD') {
|
|
_this.openEditor();
|
|
|
|
if (activeEditor) {
|
|
activeEditor.enableFullEditMode();
|
|
}
|
|
}
|
|
}
|
|
instance.view.wt.update('onCellDblClick', onDblClick);
|
|
|
|
instance.addHook('afterDestroy', function () {
|
|
destroyed = true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Destroy current editor, if exists.
|
|
*
|
|
* @function destroyEditor
|
|
* @memberof! Handsontable.EditorManager#
|
|
* @param {Boolean} revertOriginal
|
|
*/
|
|
this.destroyEditor = function (revertOriginal) {
|
|
this.closeEditor(revertOriginal);
|
|
};
|
|
|
|
/**
|
|
* Get active editor.
|
|
*
|
|
* @function getActiveEditor
|
|
* @memberof! Handsontable.EditorManager#
|
|
* @returns {*}
|
|
*/
|
|
this.getActiveEditor = function () {
|
|
return activeEditor;
|
|
};
|
|
|
|
/**
|
|
* Prepare text input to be displayed at given grid cell.
|
|
*
|
|
* @function prepareEditor
|
|
* @memberof! Handsontable.EditorManager#
|
|
*/
|
|
this.prepareEditor = function () {
|
|
var row, col, prop, td, originalValue, cellProperties, editorClass;
|
|
|
|
if (activeEditor && activeEditor.isWaiting()) {
|
|
this.closeEditor(false, false, function (dataSaved) {
|
|
if (dataSaved) {
|
|
_this.prepareEditor();
|
|
}
|
|
});
|
|
|
|
return;
|
|
}
|
|
row = priv.selRange.highlight.row;
|
|
col = priv.selRange.highlight.col;
|
|
prop = instance.colToProp(col);
|
|
td = instance.getCell(row, col);
|
|
|
|
originalValue = instance.getSourceDataAtCell(instance.runHooks('modifyRow', row), col);
|
|
cellProperties = instance.getCellMeta(row, col);
|
|
editorClass = instance.getCellEditor(cellProperties);
|
|
|
|
if (editorClass) {
|
|
activeEditor = (0, _editors.getEditorInstance)(editorClass, instance);
|
|
activeEditor.prepare(row, col, prop, td, originalValue, cellProperties);
|
|
} else {
|
|
activeEditor = void 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Check is editor is opened/showed.
|
|
*
|
|
* @function isEditorOpened
|
|
* @memberof! Handsontable.EditorManager#
|
|
* @returns {Boolean}
|
|
*/
|
|
this.isEditorOpened = function () {
|
|
return activeEditor && activeEditor.isOpened();
|
|
};
|
|
|
|
/**
|
|
* Open editor with initial value.
|
|
*
|
|
* @function openEditor
|
|
* @memberof! Handsontable.EditorManager#
|
|
* @param {String} initialValue
|
|
* @param {DOMEvent} event
|
|
*/
|
|
this.openEditor = function (initialValue, event) {
|
|
if (activeEditor && !activeEditor.cellProperties.readOnly) {
|
|
activeEditor.beginEditing(initialValue, event);
|
|
} else if (activeEditor && activeEditor.cellProperties.readOnly) {
|
|
|
|
// move the selection after opening the editor with ENTER key
|
|
if (event && event.keyCode === _unicode.KEY_CODES.ENTER) {
|
|
moveSelectionAfterEnter();
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Close editor, finish editing cell.
|
|
*
|
|
* @function closeEditor
|
|
* @memberof! Handsontable.EditorManager#
|
|
* @param {Boolean} restoreOriginalValue
|
|
* @param {Boolean} [ctrlDown]
|
|
* @param {Function} [callback]
|
|
*/
|
|
this.closeEditor = function (restoreOriginalValue, ctrlDown, callback) {
|
|
if (activeEditor) {
|
|
activeEditor.finishEditing(restoreOriginalValue, ctrlDown, callback);
|
|
} else if (callback) {
|
|
callback(false);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Close editor and save changes.
|
|
*
|
|
* @function closeEditorAndSaveChanges
|
|
* @memberof! Handsontable.EditorManager#
|
|
* @param {Boolean} ctrlDown
|
|
*/
|
|
this.closeEditorAndSaveChanges = function (ctrlDown) {
|
|
return this.closeEditor(false, ctrlDown);
|
|
};
|
|
|
|
/**
|
|
* Close editor and restore original value.
|
|
*
|
|
* @function closeEditorAndRestoreOriginalValue
|
|
* @memberof! Handsontable.EditorManager#
|
|
* @param {Boolean} ctrlDown
|
|
*/
|
|
this.closeEditorAndRestoreOriginalValue = function (ctrlDown) {
|
|
return this.closeEditor(true, ctrlDown);
|
|
};
|
|
|
|
init();
|
|
}
|
|
|
|
exports.default = EditorManager;
|
|
|
|
/***/ }),
|
|
/* 316 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _baseEditor = __webpack_require__(37);
|
|
|
|
var _baseEditor2 = _interopRequireDefault(_baseEditor);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @private
|
|
* @editor CheckboxEditor
|
|
* @class CheckboxEditor
|
|
*/
|
|
var CheckboxEditor = function (_BaseEditor) {
|
|
_inherits(CheckboxEditor, _BaseEditor);
|
|
|
|
function CheckboxEditor() {
|
|
_classCallCheck(this, CheckboxEditor);
|
|
|
|
return _possibleConstructorReturn(this, (CheckboxEditor.__proto__ || Object.getPrototypeOf(CheckboxEditor)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(CheckboxEditor, [{
|
|
key: 'beginEditing',
|
|
value: function beginEditing(initialValue, event) {
|
|
// editorManager return double click event as undefined
|
|
if (event === void 0) {
|
|
var checkbox = this.TD.querySelector('input[type="checkbox"]');
|
|
|
|
if (!(0, _element.hasClass)(checkbox, 'htBadValue')) {
|
|
checkbox.click();
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: 'finishEditing',
|
|
value: function finishEditing() {}
|
|
}, {
|
|
key: 'init',
|
|
value: function init() {}
|
|
}, {
|
|
key: 'open',
|
|
value: function open() {}
|
|
}, {
|
|
key: 'close',
|
|
value: function close() {}
|
|
}, {
|
|
key: 'getValue',
|
|
value: function getValue() {}
|
|
}, {
|
|
key: 'setValue',
|
|
value: function setValue() {}
|
|
}, {
|
|
key: 'focus',
|
|
value: function focus() {}
|
|
}]);
|
|
|
|
return CheckboxEditor;
|
|
}(_baseEditor2.default);
|
|
|
|
exports.default = CheckboxEditor;
|
|
|
|
/***/ }),
|
|
/* 317 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _moment = __webpack_require__(36);
|
|
|
|
var _moment2 = _interopRequireDefault(_moment);
|
|
|
|
var _pikaday = __webpack_require__(419);
|
|
|
|
var _pikaday2 = _interopRequireDefault(_pikaday);
|
|
|
|
__webpack_require__(411);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _textEditor = __webpack_require__(44);
|
|
|
|
var _textEditor2 = _interopRequireDefault(_textEditor);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @private
|
|
* @editor DateEditor
|
|
* @class DateEditor
|
|
* @dependencies TextEditor moment pikaday
|
|
*/
|
|
var DateEditor = function (_TextEditor) {
|
|
_inherits(DateEditor, _TextEditor);
|
|
|
|
/**
|
|
* @param {Core} hotInstance Handsontable instance
|
|
* @private
|
|
*/
|
|
function DateEditor(hotInstance) {
|
|
_classCallCheck(this, DateEditor);
|
|
|
|
// TODO: Move this option to general settings
|
|
var _this = _possibleConstructorReturn(this, (DateEditor.__proto__ || Object.getPrototypeOf(DateEditor)).call(this, hotInstance));
|
|
|
|
_this.defaultDateFormat = 'DD/MM/YYYY';
|
|
_this.isCellEdited = false;
|
|
_this.parentDestroyed = false;
|
|
return _this;
|
|
}
|
|
|
|
_createClass(DateEditor, [{
|
|
key: 'init',
|
|
value: function init() {
|
|
var _this2 = this;
|
|
|
|
if (typeof _moment2.default !== 'function') {
|
|
throw new Error('You need to include moment.js to your project.');
|
|
}
|
|
|
|
if (typeof _pikaday2.default !== 'function') {
|
|
throw new Error('You need to include Pikaday to your project.');
|
|
}
|
|
_get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'init', this).call(this);
|
|
this.instance.addHook('afterDestroy', function () {
|
|
_this2.parentDestroyed = true;
|
|
_this2.destroyElements();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Create data picker instance
|
|
*/
|
|
|
|
}, {
|
|
key: 'createElements',
|
|
value: function createElements() {
|
|
_get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'createElements', this).call(this);
|
|
|
|
this.datePicker = document.createElement('DIV');
|
|
this.datePickerStyle = this.datePicker.style;
|
|
this.datePickerStyle.position = 'absolute';
|
|
this.datePickerStyle.top = 0;
|
|
this.datePickerStyle.left = 0;
|
|
this.datePickerStyle.zIndex = 9999;
|
|
|
|
(0, _element.addClass)(this.datePicker, 'htDatepickerHolder');
|
|
document.body.appendChild(this.datePicker);
|
|
|
|
this.$datePicker = new _pikaday2.default(this.getDatePickerConfig());
|
|
var eventManager = new _eventManager2.default(this);
|
|
|
|
/**
|
|
* Prevent recognizing clicking on datepicker as clicking outside of table
|
|
*/
|
|
eventManager.addEventListener(this.datePicker, 'mousedown', function (event) {
|
|
return (0, _event.stopPropagation)(event);
|
|
});
|
|
this.hideDatepicker();
|
|
}
|
|
|
|
/**
|
|
* Destroy data picker instance
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroyElements',
|
|
value: function destroyElements() {
|
|
this.$datePicker.destroy();
|
|
}
|
|
|
|
/**
|
|
* Prepare editor to appear
|
|
*
|
|
* @param {Number} row Row index
|
|
* @param {Number} col Column index
|
|
* @param {String} prop Property name (passed when datasource is an array of objects)
|
|
* @param {HTMLTableCellElement} td Table cell element
|
|
* @param {*} originalValue Original value
|
|
* @param {Object} cellProperties Object with cell properties ({@see Core#getCellMeta})
|
|
*/
|
|
|
|
}, {
|
|
key: 'prepare',
|
|
value: function prepare(row, col, prop, td, originalValue, cellProperties) {
|
|
this._opened = false;
|
|
_get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'prepare', this).call(this, row, col, prop, td, originalValue, cellProperties);
|
|
}
|
|
|
|
/**
|
|
* Open editor
|
|
*
|
|
* @param {Event} [event=null]
|
|
*/
|
|
|
|
}, {
|
|
key: 'open',
|
|
value: function open() {
|
|
var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
|
|
_get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'open', this).call(this);
|
|
this.showDatepicker(event);
|
|
}
|
|
|
|
/**
|
|
* Close editor
|
|
*/
|
|
|
|
}, {
|
|
key: 'close',
|
|
value: function close() {
|
|
var _this3 = this;
|
|
|
|
this._opened = false;
|
|
this.instance._registerTimeout(setTimeout(function () {
|
|
_this3.instance.selection.refreshBorders();
|
|
}, 0));
|
|
|
|
_get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'close', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* @param {Boolean} [isCancelled=false]
|
|
* @param {Boolean} [ctrlDown=false]
|
|
*/
|
|
|
|
}, {
|
|
key: 'finishEditing',
|
|
value: function finishEditing() {
|
|
var isCancelled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
var ctrlDown = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
|
|
if (isCancelled) {
|
|
// pressed ESC, restore original value
|
|
// var value = this.instance.getDataAtCell(this.row, this.col);
|
|
var value = this.originalValue;
|
|
|
|
if (value !== void 0) {
|
|
this.setValue(value);
|
|
}
|
|
}
|
|
this.hideDatepicker();
|
|
_get(DateEditor.prototype.__proto__ || Object.getPrototypeOf(DateEditor.prototype), 'finishEditing', this).call(this, isCancelled, ctrlDown);
|
|
}
|
|
|
|
/**
|
|
* Show data picker
|
|
*
|
|
* @param {Event} event
|
|
*/
|
|
|
|
}, {
|
|
key: 'showDatepicker',
|
|
value: function showDatepicker(event) {
|
|
this.$datePicker.config(this.getDatePickerConfig());
|
|
|
|
var offset = this.TD.getBoundingClientRect();
|
|
var dateFormat = this.cellProperties.dateFormat || this.defaultDateFormat;
|
|
var datePickerConfig = this.$datePicker.config();
|
|
var dateStr = void 0;
|
|
var isMouseDown = this.instance.view.isMouseDown();
|
|
var isMeta = event ? (0, _unicode.isMetaKey)(event.keyCode) : false;
|
|
|
|
this.datePickerStyle.top = window.pageYOffset + offset.top + (0, _element.outerHeight)(this.TD) + 'px';
|
|
this.datePickerStyle.left = window.pageXOffset + offset.left + 'px';
|
|
|
|
this.$datePicker._onInputFocus = function () {};
|
|
datePickerConfig.format = dateFormat;
|
|
|
|
if (this.originalValue) {
|
|
dateStr = this.originalValue;
|
|
|
|
if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) {
|
|
this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true);
|
|
}
|
|
|
|
// workaround for date/time cells - pikaday resets the cell value to 12:00 AM by default, this will overwrite the value.
|
|
if (this.getValue() !== this.originalValue) {
|
|
this.setValue(this.originalValue);
|
|
}
|
|
|
|
if (!isMeta && !isMouseDown) {
|
|
this.setValue('');
|
|
}
|
|
} else if (this.cellProperties.defaultDate) {
|
|
dateStr = this.cellProperties.defaultDate;
|
|
|
|
datePickerConfig.defaultDate = dateStr;
|
|
|
|
if ((0, _moment2.default)(dateStr, dateFormat, true).isValid()) {
|
|
this.$datePicker.setMoment((0, _moment2.default)(dateStr, dateFormat), true);
|
|
}
|
|
|
|
if (!isMeta && !isMouseDown) {
|
|
this.setValue('');
|
|
}
|
|
} else {
|
|
// if a default date is not defined, set a soft-default-date: display the current day and month in the
|
|
// datepicker, but don't fill the editor input
|
|
this.$datePicker.gotoToday();
|
|
}
|
|
|
|
this.datePickerStyle.display = 'block';
|
|
this.$datePicker.show();
|
|
}
|
|
|
|
/**
|
|
* Hide data picker
|
|
*/
|
|
|
|
}, {
|
|
key: 'hideDatepicker',
|
|
value: function hideDatepicker() {
|
|
this.datePickerStyle.display = 'none';
|
|
this.$datePicker.hide();
|
|
}
|
|
|
|
/**
|
|
* Get date picker options.
|
|
*
|
|
* @returns {Object}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getDatePickerConfig',
|
|
value: function getDatePickerConfig() {
|
|
var _this4 = this;
|
|
|
|
var htInput = this.TEXTAREA;
|
|
var options = {};
|
|
|
|
if (this.cellProperties && this.cellProperties.datePickerConfig) {
|
|
(0, _object.deepExtend)(options, this.cellProperties.datePickerConfig);
|
|
}
|
|
var origOnSelect = options.onSelect;
|
|
var origOnClose = options.onClose;
|
|
|
|
options.field = htInput;
|
|
options.trigger = htInput;
|
|
options.container = this.datePicker;
|
|
options.bound = false;
|
|
options.format = options.format || this.defaultDateFormat;
|
|
options.reposition = options.reposition || false;
|
|
options.onSelect = function (dateStr) {
|
|
if (!isNaN(dateStr.getTime())) {
|
|
dateStr = (0, _moment2.default)(dateStr).format(_this4.cellProperties.dateFormat || _this4.defaultDateFormat);
|
|
}
|
|
_this4.setValue(dateStr);
|
|
_this4.hideDatepicker();
|
|
|
|
if (origOnSelect) {
|
|
origOnSelect();
|
|
}
|
|
};
|
|
options.onClose = function () {
|
|
if (!_this4.parentDestroyed) {
|
|
_this4.finishEditing(false);
|
|
}
|
|
if (origOnClose) {
|
|
origOnClose();
|
|
}
|
|
};
|
|
|
|
return options;
|
|
}
|
|
}]);
|
|
|
|
return DateEditor;
|
|
}(_textEditor2.default);
|
|
|
|
exports.default = DateEditor;
|
|
|
|
/***/ }),
|
|
/* 318 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _autocompleteEditor = __webpack_require__(263);
|
|
|
|
var _autocompleteEditor2 = _interopRequireDefault(_autocompleteEditor);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @private
|
|
* @editor DropdownEditor
|
|
* @class DropdownEditor
|
|
* @dependencies AutocompleteEditor
|
|
*/
|
|
var DropdownEditor = function (_AutocompleteEditor) {
|
|
_inherits(DropdownEditor, _AutocompleteEditor);
|
|
|
|
function DropdownEditor() {
|
|
_classCallCheck(this, DropdownEditor);
|
|
|
|
return _possibleConstructorReturn(this, (DropdownEditor.__proto__ || Object.getPrototypeOf(DropdownEditor)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(DropdownEditor, [{
|
|
key: 'prepare',
|
|
value: function prepare(row, col, prop, td, originalValue, cellProperties) {
|
|
_get(DropdownEditor.prototype.__proto__ || Object.getPrototypeOf(DropdownEditor.prototype), 'prepare', this).call(this, row, col, prop, td, originalValue, cellProperties);
|
|
this.cellProperties.filter = false;
|
|
this.cellProperties.strict = true;
|
|
}
|
|
}]);
|
|
|
|
return DropdownEditor;
|
|
}(_autocompleteEditor2.default);
|
|
|
|
_pluginHooks2.default.getSingleton().add('beforeValidate', function (value, row, col, source) {
|
|
var cellMeta = this.getCellMeta(row, this.propToCol(col));
|
|
|
|
if (cellMeta.editor === DropdownEditor) {
|
|
if (cellMeta.strict === void 0) {
|
|
cellMeta.filter = false;
|
|
cellMeta.strict = true;
|
|
}
|
|
}
|
|
});
|
|
|
|
exports.default = DropdownEditor;
|
|
|
|
/***/ }),
|
|
/* 319 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _baseEditor = __webpack_require__(37);
|
|
|
|
var _baseEditor2 = _interopRequireDefault(_baseEditor);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var MobileTextEditor = _baseEditor2.default.prototype.extend();
|
|
var domDimensionsCache = {};
|
|
|
|
/**
|
|
* @private
|
|
* @editor MobileTextEditor
|
|
* @class MobileTextEditor
|
|
*/
|
|
var createControls = function createControls() {
|
|
this.controls = {};
|
|
|
|
this.controls.leftButton = document.createElement('DIV');
|
|
this.controls.leftButton.className = 'leftButton';
|
|
this.controls.rightButton = document.createElement('DIV');
|
|
this.controls.rightButton.className = 'rightButton';
|
|
this.controls.upButton = document.createElement('DIV');
|
|
this.controls.upButton.className = 'upButton';
|
|
this.controls.downButton = document.createElement('DIV');
|
|
this.controls.downButton.className = 'downButton';
|
|
|
|
for (var button in this.controls) {
|
|
if (Object.prototype.hasOwnProperty.call(this.controls, button)) {
|
|
this.positionControls.appendChild(this.controls[button]);
|
|
}
|
|
}
|
|
};
|
|
|
|
MobileTextEditor.prototype.valueChanged = function () {
|
|
return this.initValue != this.getValue();
|
|
};
|
|
|
|
MobileTextEditor.prototype.init = function () {
|
|
var that = this;
|
|
this.eventManager = new _eventManager2.default(this.instance);
|
|
|
|
this.createElements();
|
|
this.bindEvents();
|
|
|
|
this.instance.addHook('afterDestroy', function () {
|
|
that.destroy();
|
|
});
|
|
};
|
|
|
|
MobileTextEditor.prototype.getValue = function () {
|
|
return this.TEXTAREA.value;
|
|
};
|
|
|
|
MobileTextEditor.prototype.setValue = function (newValue) {
|
|
this.initValue = newValue;
|
|
|
|
this.TEXTAREA.value = newValue;
|
|
};
|
|
|
|
MobileTextEditor.prototype.createElements = function () {
|
|
this.editorContainer = document.createElement('DIV');
|
|
this.editorContainer.className = 'htMobileEditorContainer';
|
|
|
|
this.cellPointer = document.createElement('DIV');
|
|
this.cellPointer.className = 'cellPointer';
|
|
|
|
this.moveHandle = document.createElement('DIV');
|
|
this.moveHandle.className = 'moveHandle';
|
|
|
|
this.inputPane = document.createElement('DIV');
|
|
this.inputPane.className = 'inputs';
|
|
|
|
this.positionControls = document.createElement('DIV');
|
|
this.positionControls.className = 'positionControls';
|
|
|
|
this.TEXTAREA = document.createElement('TEXTAREA');
|
|
(0, _element.addClass)(this.TEXTAREA, 'handsontableInput');
|
|
|
|
this.inputPane.appendChild(this.TEXTAREA);
|
|
|
|
this.editorContainer.appendChild(this.cellPointer);
|
|
this.editorContainer.appendChild(this.moveHandle);
|
|
this.editorContainer.appendChild(this.inputPane);
|
|
this.editorContainer.appendChild(this.positionControls);
|
|
|
|
createControls.call(this);
|
|
|
|
document.body.appendChild(this.editorContainer);
|
|
};
|
|
|
|
MobileTextEditor.prototype.onBeforeKeyDown = function (event) {
|
|
var instance = this;
|
|
var that = instance.getActiveEditor();
|
|
|
|
if (event.target !== that.TEXTAREA || (0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
|
|
switch (event.keyCode) {
|
|
case _unicode.KEY_CODES.ENTER:
|
|
that.close();
|
|
event.preventDefault(); // don't add newline to field
|
|
break;
|
|
case _unicode.KEY_CODES.BACKSPACE:
|
|
(0, _event.stopImmediatePropagation)(event); // backspace, delete, home, end should only work locally when cell is edited (not in table context)
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
};
|
|
|
|
MobileTextEditor.prototype.open = function () {
|
|
this.instance.addHook('beforeKeyDown', this.onBeforeKeyDown);
|
|
|
|
(0, _element.addClass)(this.editorContainer, 'active');
|
|
(0, _element.removeClass)(this.cellPointer, 'hidden');
|
|
|
|
this.updateEditorPosition();
|
|
};
|
|
|
|
MobileTextEditor.prototype.focus = function () {
|
|
this.TEXTAREA.focus();
|
|
(0, _element.setCaretPosition)(this.TEXTAREA, this.TEXTAREA.value.length);
|
|
};
|
|
|
|
MobileTextEditor.prototype.close = function () {
|
|
this.TEXTAREA.blur();
|
|
this.instance.removeHook('beforeKeyDown', this.onBeforeKeyDown);
|
|
|
|
(0, _element.removeClass)(this.editorContainer, 'active');
|
|
};
|
|
|
|
MobileTextEditor.prototype.scrollToView = function () {
|
|
var coords = this.instance.getSelectedRange().highlight;
|
|
this.instance.view.scrollViewport(coords);
|
|
};
|
|
|
|
MobileTextEditor.prototype.hideCellPointer = function () {
|
|
if (!(0, _element.hasClass)(this.cellPointer, 'hidden')) {
|
|
(0, _element.addClass)(this.cellPointer, 'hidden');
|
|
}
|
|
};
|
|
|
|
MobileTextEditor.prototype.updateEditorPosition = function (x, y) {
|
|
if (x && y) {
|
|
x = parseInt(x, 10);
|
|
y = parseInt(y, 10);
|
|
|
|
this.editorContainer.style.top = y + 'px';
|
|
this.editorContainer.style.left = x + 'px';
|
|
} else {
|
|
var selection = this.instance.getSelected(),
|
|
selectedCell = this.instance.getCell(selection[0], selection[1]);
|
|
|
|
// cache sizes
|
|
if (!domDimensionsCache.cellPointer) {
|
|
domDimensionsCache.cellPointer = {
|
|
height: (0, _element.outerHeight)(this.cellPointer),
|
|
width: (0, _element.outerWidth)(this.cellPointer)
|
|
};
|
|
}
|
|
if (!domDimensionsCache.editorContainer) {
|
|
domDimensionsCache.editorContainer = {
|
|
width: (0, _element.outerWidth)(this.editorContainer)
|
|
};
|
|
}
|
|
|
|
if (selectedCell !== undefined) {
|
|
var scrollLeft = this.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollLeft)(this.instance.view.wt.wtOverlays.leftOverlay.holder);
|
|
var scrollTop = this.instance.view.wt.wtOverlays.topOverlay.trimmingContainer == window ? 0 : (0, _element.getScrollTop)(this.instance.view.wt.wtOverlays.topOverlay.holder);
|
|
|
|
var selectedCellOffset = (0, _element.offset)(selectedCell),
|
|
selectedCellWidth = (0, _element.outerWidth)(selectedCell),
|
|
currentScrollPosition = {
|
|
x: scrollLeft,
|
|
y: scrollTop
|
|
};
|
|
|
|
this.editorContainer.style.top = parseInt(selectedCellOffset.top + (0, _element.outerHeight)(selectedCell) - currentScrollPosition.y + domDimensionsCache.cellPointer.height, 10) + 'px';
|
|
this.editorContainer.style.left = parseInt(window.innerWidth / 2 - domDimensionsCache.editorContainer.width / 2, 10) + 'px';
|
|
|
|
if (selectedCellOffset.left + selectedCellWidth / 2 > parseInt(this.editorContainer.style.left, 10) + domDimensionsCache.editorContainer.width) {
|
|
this.editorContainer.style.left = window.innerWidth - domDimensionsCache.editorContainer.width + 'px';
|
|
} else if (selectedCellOffset.left + selectedCellWidth / 2 < parseInt(this.editorContainer.style.left, 10) + 20) {
|
|
this.editorContainer.style.left = 0 + 'px';
|
|
}
|
|
|
|
this.cellPointer.style.left = parseInt(selectedCellOffset.left - domDimensionsCache.cellPointer.width / 2 - (0, _element.offset)(this.editorContainer).left + selectedCellWidth / 2 - currentScrollPosition.x, 10) + 'px';
|
|
}
|
|
}
|
|
};
|
|
|
|
MobileTextEditor.prototype.updateEditorData = function () {
|
|
var selected = this.instance.getSelected(),
|
|
selectedValue = this.instance.getDataAtCell(selected[0], selected[1]);
|
|
|
|
this.row = selected[0];
|
|
this.col = selected[1];
|
|
this.setValue(selectedValue);
|
|
this.updateEditorPosition();
|
|
};
|
|
|
|
MobileTextEditor.prototype.prepareAndSave = function () {
|
|
var val;
|
|
|
|
if (!this.valueChanged()) {
|
|
return;
|
|
}
|
|
|
|
if (this.instance.getSettings().trimWhitespace) {
|
|
val = [[String.prototype.trim.call(this.getValue())]];
|
|
} else {
|
|
val = [[this.getValue()]];
|
|
}
|
|
|
|
this.saveValue(val);
|
|
};
|
|
|
|
MobileTextEditor.prototype.bindEvents = function () {
|
|
var that = this;
|
|
|
|
this.eventManager.addEventListener(this.controls.leftButton, 'touchend', function (event) {
|
|
that.prepareAndSave();
|
|
that.instance.selection.transformStart(0, -1, null, true);
|
|
that.updateEditorData();
|
|
event.preventDefault();
|
|
});
|
|
this.eventManager.addEventListener(this.controls.rightButton, 'touchend', function (event) {
|
|
that.prepareAndSave();
|
|
that.instance.selection.transformStart(0, 1, null, true);
|
|
that.updateEditorData();
|
|
event.preventDefault();
|
|
});
|
|
this.eventManager.addEventListener(this.controls.upButton, 'touchend', function (event) {
|
|
that.prepareAndSave();
|
|
that.instance.selection.transformStart(-1, 0, null, true);
|
|
that.updateEditorData();
|
|
event.preventDefault();
|
|
});
|
|
this.eventManager.addEventListener(this.controls.downButton, 'touchend', function (event) {
|
|
that.prepareAndSave();
|
|
that.instance.selection.transformStart(1, 0, null, true);
|
|
that.updateEditorData();
|
|
event.preventDefault();
|
|
});
|
|
|
|
this.eventManager.addEventListener(this.moveHandle, 'touchstart', function (event) {
|
|
if (event.touches.length == 1) {
|
|
var touch = event.touches[0];
|
|
var onTouchPosition = {
|
|
x: that.editorContainer.offsetLeft,
|
|
y: that.editorContainer.offsetTop
|
|
};
|
|
var onTouchOffset = {
|
|
x: touch.pageX - onTouchPosition.x,
|
|
y: touch.pageY - onTouchPosition.y
|
|
};
|
|
|
|
that.eventManager.addEventListener(this, 'touchmove', function (event) {
|
|
var touch = event.touches[0];
|
|
that.updateEditorPosition(touch.pageX - onTouchOffset.x, touch.pageY - onTouchOffset.y);
|
|
that.hideCellPointer();
|
|
event.preventDefault();
|
|
});
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(document.body, 'touchend', function (event) {
|
|
if (!(0, _element.isChildOf)(event.target, that.editorContainer) && !(0, _element.isChildOf)(event.target, that.instance.rootElement)) {
|
|
that.close();
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.leftOverlay.holder, 'scroll', function (event) {
|
|
if (that.instance.view.wt.wtOverlays.leftOverlay.trimmingContainer != window) {
|
|
that.hideCellPointer();
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(this.instance.view.wt.wtOverlays.topOverlay.holder, 'scroll', function (event) {
|
|
if (that.instance.view.wt.wtOverlays.topOverlay.trimmingContainer != window) {
|
|
that.hideCellPointer();
|
|
}
|
|
});
|
|
};
|
|
|
|
MobileTextEditor.prototype.destroy = function () {
|
|
this.eventManager.clear();
|
|
|
|
this.editorContainer.parentNode.removeChild(this.editorContainer);
|
|
};
|
|
|
|
exports.default = MobileTextEditor;
|
|
|
|
/***/ }),
|
|
/* 320 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _numbro = __webpack_require__(51);
|
|
|
|
var _numbro2 = _interopRequireDefault(_numbro);
|
|
|
|
var _textEditor = __webpack_require__(44);
|
|
|
|
var _textEditor2 = _interopRequireDefault(_textEditor);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @private
|
|
* @editor NumericEditor
|
|
* @class NumericEditor
|
|
* @dependencies TextEditor numbro
|
|
*/
|
|
var NumericEditor = function (_TextEditor) {
|
|
_inherits(NumericEditor, _TextEditor);
|
|
|
|
function NumericEditor() {
|
|
_classCallCheck(this, NumericEditor);
|
|
|
|
return _possibleConstructorReturn(this, (NumericEditor.__proto__ || Object.getPrototypeOf(NumericEditor)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(NumericEditor, [{
|
|
key: 'beginEditing',
|
|
|
|
/**
|
|
* @param {*} initialValue
|
|
*/
|
|
value: function beginEditing(initialValue) {
|
|
if (typeof initialValue === 'undefined' && this.originalValue) {
|
|
if (typeof this.cellProperties.language !== 'undefined') {
|
|
_numbro2.default.culture(this.cellProperties.language);
|
|
}
|
|
var decimalDelimiter = _numbro2.default.cultureData().delimiters.decimal;
|
|
initialValue = ('' + this.originalValue).replace('.', decimalDelimiter);
|
|
}
|
|
_get(NumericEditor.prototype.__proto__ || Object.getPrototypeOf(NumericEditor.prototype), 'beginEditing', this).call(this, initialValue);
|
|
}
|
|
}]);
|
|
|
|
return NumericEditor;
|
|
}(_textEditor2.default);
|
|
|
|
exports.default = NumericEditor;
|
|
|
|
/***/ }),
|
|
/* 321 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _textEditor = __webpack_require__(44);
|
|
|
|
var _textEditor2 = _interopRequireDefault(_textEditor);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @private
|
|
* @editor PasswordEditor
|
|
* @class PasswordEditor
|
|
* @dependencies TextEditor
|
|
*/
|
|
var PasswordEditor = function (_TextEditor) {
|
|
_inherits(PasswordEditor, _TextEditor);
|
|
|
|
function PasswordEditor() {
|
|
_classCallCheck(this, PasswordEditor);
|
|
|
|
return _possibleConstructorReturn(this, (PasswordEditor.__proto__ || Object.getPrototypeOf(PasswordEditor)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(PasswordEditor, [{
|
|
key: 'createElements',
|
|
value: function createElements() {
|
|
_get(PasswordEditor.prototype.__proto__ || Object.getPrototypeOf(PasswordEditor.prototype), 'createElements', this).call(this);
|
|
|
|
this.TEXTAREA = document.createElement('input');
|
|
this.TEXTAREA.setAttribute('type', 'password');
|
|
this.TEXTAREA.className = 'handsontableInput';
|
|
this.textareaStyle = this.TEXTAREA.style;
|
|
this.textareaStyle.width = 0;
|
|
this.textareaStyle.height = 0;
|
|
|
|
(0, _element.empty)(this.TEXTAREA_PARENT);
|
|
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
|
|
}
|
|
}]);
|
|
|
|
return PasswordEditor;
|
|
}(_textEditor2.default);
|
|
|
|
exports.default = PasswordEditor;
|
|
|
|
/***/ }),
|
|
/* 322 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _baseEditor = __webpack_require__(37);
|
|
|
|
var _baseEditor2 = _interopRequireDefault(_baseEditor);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var SelectEditor = _baseEditor2.default.prototype.extend();
|
|
|
|
/**
|
|
* @private
|
|
* @editor SelectEditor
|
|
* @class SelectEditor
|
|
*/
|
|
SelectEditor.prototype.init = function () {
|
|
this.select = document.createElement('SELECT');
|
|
(0, _element.addClass)(this.select, 'htSelectEditor');
|
|
this.select.style.display = 'none';
|
|
this.instance.rootElement.appendChild(this.select);
|
|
this.registerHooks();
|
|
};
|
|
|
|
SelectEditor.prototype.registerHooks = function () {
|
|
var _this = this;
|
|
|
|
this.instance.addHook('afterScrollHorizontally', function () {
|
|
return _this.refreshDimensions();
|
|
});
|
|
this.instance.addHook('afterScrollVertically', function () {
|
|
return _this.refreshDimensions();
|
|
});
|
|
this.instance.addHook('afterColumnResize', function () {
|
|
return _this.refreshDimensions();
|
|
});
|
|
this.instance.addHook('afterRowResize', function () {
|
|
return _this.refreshDimensions();
|
|
});
|
|
};
|
|
|
|
SelectEditor.prototype.prepare = function () {
|
|
_baseEditor2.default.prototype.prepare.apply(this, arguments);
|
|
|
|
var selectOptions = this.cellProperties.selectOptions;
|
|
var options;
|
|
|
|
if (typeof selectOptions == 'function') {
|
|
options = this.prepareOptions(selectOptions(this.row, this.col, this.prop));
|
|
} else {
|
|
options = this.prepareOptions(selectOptions);
|
|
}
|
|
|
|
(0, _element.empty)(this.select);
|
|
|
|
for (var option in options) {
|
|
if (Object.prototype.hasOwnProperty.call(options, option)) {
|
|
var optionElement = document.createElement('OPTION');
|
|
optionElement.value = option;
|
|
(0, _element.fastInnerHTML)(optionElement, options[option]);
|
|
this.select.appendChild(optionElement);
|
|
}
|
|
}
|
|
};
|
|
|
|
SelectEditor.prototype.prepareOptions = function (optionsToPrepare) {
|
|
var preparedOptions = {};
|
|
|
|
if (Array.isArray(optionsToPrepare)) {
|
|
for (var i = 0, len = optionsToPrepare.length; i < len; i++) {
|
|
preparedOptions[optionsToPrepare[i]] = optionsToPrepare[i];
|
|
}
|
|
} else if ((typeof optionsToPrepare === 'undefined' ? 'undefined' : _typeof(optionsToPrepare)) == 'object') {
|
|
preparedOptions = optionsToPrepare;
|
|
}
|
|
|
|
return preparedOptions;
|
|
};
|
|
|
|
SelectEditor.prototype.getValue = function () {
|
|
return this.select.value;
|
|
};
|
|
|
|
SelectEditor.prototype.setValue = function (value) {
|
|
this.select.value = value;
|
|
};
|
|
|
|
var onBeforeKeyDown = function onBeforeKeyDown(event) {
|
|
var instance = this;
|
|
var editor = instance.getActiveEditor();
|
|
|
|
switch (event.keyCode) {
|
|
case _unicode.KEY_CODES.ARROW_UP:
|
|
var previousOptionIndex = editor.select.selectedIndex - 1;
|
|
if (previousOptionIndex >= 0) {
|
|
editor.select[previousOptionIndex].selected = true;
|
|
}
|
|
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
event.preventDefault();
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_DOWN:
|
|
var nextOptionIndex = editor.select.selectedIndex + 1;
|
|
if (nextOptionIndex <= editor.select.length - 1) {
|
|
editor.select[nextOptionIndex].selected = true;
|
|
}
|
|
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
event.preventDefault();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
};
|
|
|
|
SelectEditor.prototype.open = function () {
|
|
this._opened = true;
|
|
this.refreshDimensions();
|
|
this.select.style.display = '';
|
|
this.instance.addHook('beforeKeyDown', onBeforeKeyDown);
|
|
};
|
|
|
|
SelectEditor.prototype.close = function () {
|
|
this._opened = false;
|
|
this.select.style.display = 'none';
|
|
this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
|
|
};
|
|
|
|
SelectEditor.prototype.focus = function () {
|
|
this.select.focus();
|
|
};
|
|
|
|
SelectEditor.prototype.refreshValue = function () {
|
|
var sourceData = this.instance.getSourceDataAtCell(this.row, this.prop);
|
|
this.originalValue = sourceData;
|
|
|
|
this.setValue(sourceData);
|
|
this.refreshDimensions();
|
|
};
|
|
|
|
SelectEditor.prototype.refreshDimensions = function () {
|
|
if (this.state !== _baseEditor.EditorState.EDITING) {
|
|
return;
|
|
}
|
|
this.TD = this.getEditedCell();
|
|
|
|
// TD is outside of the viewport.
|
|
if (!this.TD) {
|
|
this.close();
|
|
|
|
return;
|
|
}
|
|
var width = (0, _element.outerWidth)(this.TD) + 1,
|
|
height = (0, _element.outerHeight)(this.TD) + 1,
|
|
currentOffset = (0, _element.offset)(this.TD),
|
|
containerOffset = (0, _element.offset)(this.instance.rootElement),
|
|
scrollableContainer = (0, _element.getScrollableElement)(this.TD),
|
|
editTop = currentOffset.top - containerOffset.top - 1 - (scrollableContainer.scrollTop || 0),
|
|
editLeft = currentOffset.left - containerOffset.left - 1 - (scrollableContainer.scrollLeft || 0),
|
|
editorSection = this.checkEditorSection(),
|
|
cssTransformOffset;
|
|
|
|
var settings = this.instance.getSettings();
|
|
var rowHeadersCount = settings.rowHeaders ? 1 : 0;
|
|
var colHeadersCount = settings.colHeaders ? 1 : 0;
|
|
|
|
switch (editorSection) {
|
|
case 'top':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'left':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'top-left-corner':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'bottom-left-corner':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomLeftCornerOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
case 'bottom':
|
|
cssTransformOffset = (0, _element.getCssTransform)(this.instance.view.wt.wtOverlays.bottomOverlay.clone.wtTable.holder.parentNode);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (this.instance.getSelected()[0] === 0) {
|
|
editTop += 1;
|
|
}
|
|
|
|
if (this.instance.getSelected()[1] === 0) {
|
|
editLeft += 1;
|
|
}
|
|
|
|
var selectStyle = this.select.style;
|
|
|
|
if (cssTransformOffset && cssTransformOffset != -1) {
|
|
selectStyle[cssTransformOffset[0]] = cssTransformOffset[1];
|
|
} else {
|
|
(0, _element.resetCssTransform)(this.select);
|
|
}
|
|
var cellComputedStyle = (0, _element.getComputedStyle)(this.TD);
|
|
|
|
if (parseInt(cellComputedStyle.borderTopWidth, 10) > 0) {
|
|
height -= 1;
|
|
}
|
|
if (parseInt(cellComputedStyle.borderLeftWidth, 10) > 0) {
|
|
width -= 1;
|
|
}
|
|
|
|
selectStyle.height = height + 'px';
|
|
selectStyle.minWidth = width + 'px';
|
|
selectStyle.top = editTop + 'px';
|
|
selectStyle.left = editLeft + 'px';
|
|
selectStyle.margin = '0px';
|
|
};
|
|
|
|
SelectEditor.prototype.getEditedCell = function () {
|
|
var editorSection = this.checkEditorSection(),
|
|
editedCell;
|
|
|
|
switch (editorSection) {
|
|
case 'top':
|
|
editedCell = this.instance.view.wt.wtOverlays.topOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.select.style.zIndex = 101;
|
|
break;
|
|
case 'corner':
|
|
editedCell = this.instance.view.wt.wtOverlays.topLeftCornerOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.select.style.zIndex = 103;
|
|
break;
|
|
case 'left':
|
|
editedCell = this.instance.view.wt.wtOverlays.leftOverlay.clone.wtTable.getCell({
|
|
row: this.row,
|
|
col: this.col
|
|
});
|
|
this.select.style.zIndex = 102;
|
|
break;
|
|
default:
|
|
editedCell = this.instance.getCell(this.row, this.col);
|
|
this.select.style.zIndex = '';
|
|
break;
|
|
}
|
|
|
|
return editedCell != -1 && editedCell != -2 ? editedCell : void 0;
|
|
};
|
|
|
|
exports.default = SelectEditor;
|
|
|
|
/***/ }),
|
|
/* 323 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
__webpack_require__(97);
|
|
|
|
__webpack_require__(114);
|
|
|
|
__webpack_require__(123);
|
|
|
|
__webpack_require__(124);
|
|
|
|
__webpack_require__(108);
|
|
|
|
__webpack_require__(122);
|
|
|
|
__webpack_require__(105);
|
|
|
|
__webpack_require__(106);
|
|
|
|
__webpack_require__(107);
|
|
|
|
__webpack_require__(96);
|
|
|
|
__webpack_require__(119);
|
|
|
|
__webpack_require__(117);
|
|
|
|
__webpack_require__(115);
|
|
|
|
__webpack_require__(120);
|
|
|
|
__webpack_require__(121);
|
|
|
|
__webpack_require__(116);
|
|
|
|
__webpack_require__(118);
|
|
|
|
__webpack_require__(109);
|
|
|
|
__webpack_require__(110);
|
|
|
|
__webpack_require__(111);
|
|
|
|
__webpack_require__(113);
|
|
|
|
__webpack_require__(112);
|
|
|
|
__webpack_require__(94);
|
|
|
|
__webpack_require__(95);
|
|
|
|
__webpack_require__(90);
|
|
|
|
__webpack_require__(93);
|
|
|
|
__webpack_require__(92);
|
|
|
|
__webpack_require__(91);
|
|
|
|
__webpack_require__(68);
|
|
|
|
__webpack_require__(99);
|
|
|
|
__webpack_require__(100);
|
|
|
|
__webpack_require__(102);
|
|
|
|
__webpack_require__(101);
|
|
|
|
__webpack_require__(98);
|
|
|
|
__webpack_require__(104);
|
|
|
|
__webpack_require__(103);
|
|
|
|
__webpack_require__(125);
|
|
|
|
__webpack_require__(128);
|
|
|
|
__webpack_require__(126);
|
|
|
|
__webpack_require__(127);
|
|
|
|
__webpack_require__(130);
|
|
|
|
__webpack_require__(129);
|
|
|
|
__webpack_require__(132);
|
|
|
|
__webpack_require__(131);
|
|
|
|
__webpack_require__(294);
|
|
|
|
__webpack_require__(295);
|
|
|
|
__webpack_require__(296);
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
var _validators = __webpack_require__(26);
|
|
|
|
var _cellTypes = __webpack_require__(63);
|
|
|
|
var _core = __webpack_require__(64);
|
|
|
|
var _core2 = _interopRequireDefault(_core);
|
|
|
|
var _jquery = __webpack_require__(292);
|
|
|
|
var _jquery2 = _interopRequireDefault(_jquery);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _ghostTable = __webpack_require__(67);
|
|
|
|
var _ghostTable2 = _interopRequireDefault(_ghostTable);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var arrayHelpers = _interopRequireWildcard(_array);
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var browserHelpers = _interopRequireWildcard(_browser);
|
|
|
|
var _data = __webpack_require__(65);
|
|
|
|
var dataHelpers = _interopRequireWildcard(_data);
|
|
|
|
var _date = __webpack_require__(89);
|
|
|
|
var dateHelpers = _interopRequireWildcard(_date);
|
|
|
|
var _feature = __webpack_require__(34);
|
|
|
|
var featureHelpers = _interopRequireWildcard(_feature);
|
|
|
|
var _function = __webpack_require__(35);
|
|
|
|
var functionHelpers = _interopRequireWildcard(_function);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var mixedHelpers = _interopRequireWildcard(_mixed);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var numberHelpers = _interopRequireWildcard(_number);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var objectHelpers = _interopRequireWildcard(_object);
|
|
|
|
var _setting = __webpack_require__(66);
|
|
|
|
var settingHelpers = _interopRequireWildcard(_setting);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
var stringHelpers = _interopRequireWildcard(_string);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var unicodeHelpers = _interopRequireWildcard(_unicode);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var domHelpers = _interopRequireWildcard(_element);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var domEventHelpers = _interopRequireWildcard(_event);
|
|
|
|
var _index = __webpack_require__(293);
|
|
|
|
var plugins = _interopRequireWildcard(_index);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _defaultSettings = __webpack_require__(88);
|
|
|
|
var _defaultSettings2 = _interopRequireDefault(_defaultSettings);
|
|
|
|
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)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function Handsontable(rootElement, userSettings) {
|
|
var instance = new _core2.default(rootElement, userSettings || {});
|
|
|
|
instance.init();
|
|
|
|
return instance;
|
|
}
|
|
|
|
(0, _jquery2.default)(Handsontable);
|
|
|
|
Handsontable.Core = _core2.default;
|
|
Handsontable.DefaultSettings = _defaultSettings2.default;
|
|
Handsontable.EventManager = _eventManager2.default;
|
|
Handsontable._getListenersCounter = _eventManager.getListenersCounter; // For MemoryLeak tests
|
|
|
|
Handsontable.buildDate = "2017-07-10T08:08:33.664Z";
|
|
Handsontable.packageName = "handsontable";
|
|
Handsontable.version = "0.33.0";
|
|
|
|
var baseVersion = undefined;
|
|
|
|
if (baseVersion) {
|
|
Handsontable.baseVersion = baseVersion;
|
|
}
|
|
|
|
// Export Hooks singleton
|
|
Handsontable.hooks = _pluginHooks2.default.getSingleton();
|
|
|
|
// TODO: Remove this exports after rewrite tests about this module
|
|
Handsontable.__GhostTable = _ghostTable2.default;
|
|
//
|
|
|
|
// Export all helpers to the Handsontable object
|
|
var HELPERS = [arrayHelpers, browserHelpers, dataHelpers, dateHelpers, featureHelpers, functionHelpers, mixedHelpers, numberHelpers, objectHelpers, settingHelpers, stringHelpers, unicodeHelpers];
|
|
var DOM = [domHelpers, domEventHelpers];
|
|
|
|
Handsontable.helper = {};
|
|
Handsontable.dom = {};
|
|
|
|
// Fill general helpers.
|
|
arrayHelpers.arrayEach(HELPERS, function (helper) {
|
|
arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) {
|
|
if (key.charAt(0) !== '_') {
|
|
Handsontable.helper[key] = helper[key];
|
|
}
|
|
});
|
|
});
|
|
|
|
// Fill DOM helpers.
|
|
arrayHelpers.arrayEach(DOM, function (helper) {
|
|
arrayHelpers.arrayEach(Object.getOwnPropertyNames(helper), function (key) {
|
|
if (key.charAt(0) !== '_') {
|
|
Handsontable.dom[key] = helper[key];
|
|
}
|
|
});
|
|
});
|
|
|
|
// Export cell types.
|
|
Handsontable.cellTypes = {};
|
|
|
|
arrayHelpers.arrayEach((0, _cellTypes.getRegisteredCellTypeNames)(), function (cellTypeName) {
|
|
Handsontable.cellTypes[cellTypeName] = (0, _cellTypes.getCellType)(cellTypeName);
|
|
});
|
|
|
|
Handsontable.cellTypes.registerCellType = _cellTypes.registerCellType;
|
|
Handsontable.cellTypes.getCellType = _cellTypes.getCellType;
|
|
|
|
// Export all registered editors from the Handsontable.
|
|
Handsontable.editors = {};
|
|
|
|
arrayHelpers.arrayEach((0, _editors.getRegisteredEditorNames)(), function (editorName) {
|
|
Handsontable.editors[stringHelpers.toUpperCaseFirst(editorName) + 'Editor'] = (0, _editors.getEditor)(editorName);
|
|
});
|
|
|
|
Handsontable.editors.registerEditor = _editors.registerEditor;
|
|
Handsontable.editors.getEditor = _editors.getEditor;
|
|
|
|
// Export all registered renderers from the Handsontable.
|
|
Handsontable.renderers = {};
|
|
|
|
arrayHelpers.arrayEach((0, _renderers.getRegisteredRendererNames)(), function (rendererName) {
|
|
var renderer = (0, _renderers.getRenderer)(rendererName);
|
|
|
|
if (rendererName === 'base') {
|
|
Handsontable.renderers.cellDecorator = renderer;
|
|
}
|
|
Handsontable.renderers[stringHelpers.toUpperCaseFirst(rendererName) + 'Renderer'] = renderer;
|
|
});
|
|
|
|
Handsontable.renderers.registerRenderer = _renderers.registerRenderer;
|
|
Handsontable.renderers.getRenderer = _renderers.getRenderer;
|
|
|
|
// Export all registered validators from the Handsontable.
|
|
Handsontable.validators = {};
|
|
|
|
arrayHelpers.arrayEach((0, _validators.getRegisteredValidatorNames)(), function (validatorName) {
|
|
Handsontable.validators[stringHelpers.toUpperCaseFirst(validatorName) + 'Validator'] = (0, _validators.getValidator)(validatorName);
|
|
});
|
|
|
|
Handsontable.validators.registerValidator = _validators.registerValidator;
|
|
Handsontable.validators.getValidator = _validators.getValidator;
|
|
|
|
// Export all registered plugins from the Handsontable.
|
|
Handsontable.plugins = {};
|
|
|
|
arrayHelpers.arrayEach(Object.getOwnPropertyNames(plugins), function (pluginName) {
|
|
var plugin = plugins[pluginName];
|
|
|
|
if (pluginName === 'Base') {
|
|
Handsontable.plugins[pluginName + 'Plugin'] = plugin;
|
|
} else {
|
|
Handsontable.plugins[pluginName] = plugin;
|
|
}
|
|
});
|
|
|
|
Handsontable.plugins.registerPlugin = _plugins.registerPlugin;
|
|
|
|
// Export Handsontable
|
|
module.exports = Handsontable;
|
|
|
|
/***/ }),
|
|
/* 324 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
function MultiMap() {
|
|
var map = {
|
|
arrayMap: [],
|
|
weakMap: new WeakMap()
|
|
};
|
|
|
|
return {
|
|
get: function get(key) {
|
|
if (canBeAnArrayMapKey(key)) {
|
|
return map.arrayMap[key];
|
|
} else if (canBeAWeakMapKey(key)) {
|
|
return map.weakMap.get(key);
|
|
}
|
|
},
|
|
set: function set(key, value) {
|
|
if (canBeAnArrayMapKey(key)) {
|
|
map.arrayMap[key] = value;
|
|
} else if (canBeAWeakMapKey(key)) {
|
|
map.weakMap.set(key, value);
|
|
} else {
|
|
throw new Error('Invalid key type');
|
|
}
|
|
},
|
|
delete: function _delete(key) {
|
|
if (canBeAnArrayMapKey(key)) {
|
|
delete map.arrayMap[key];
|
|
} else if (canBeAWeakMapKey(key)) {
|
|
map.weakMap.delete(key);
|
|
}
|
|
}
|
|
};
|
|
|
|
function canBeAnArrayMapKey(obj) {
|
|
return obj !== null && !isNaNSymbol(obj) && (typeof obj == 'string' || typeof obj == 'number');
|
|
}
|
|
|
|
function canBeAWeakMapKey(obj) {
|
|
return obj !== null && ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) == 'object' || typeof obj == 'function');
|
|
}
|
|
|
|
function isNaNSymbol(obj) {
|
|
/* eslint-disable no-self-compare */
|
|
return obj !== obj; // NaN === NaN is always false
|
|
}
|
|
}
|
|
|
|
exports.default = MultiMap;
|
|
|
|
/***/ }),
|
|
/* 325 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _feature = __webpack_require__(34);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _ghostTable = __webpack_require__(67);
|
|
|
|
var _ghostTable2 = _interopRequireDefault(_ghostTable);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _samplesGenerator = __webpack_require__(269);
|
|
|
|
var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var privatePool = new WeakMap();
|
|
|
|
/**
|
|
* @plugin AutoColumnSize
|
|
*
|
|
* @description
|
|
* This plugin allows to set column widths based on their widest cells.
|
|
*
|
|
* By default, the plugin is declared as `undefined`, which makes it enabled (same as if it was declared as `true`).
|
|
* Enabling this plugin may decrease the overall table performance, as it needs to calculate the widths of all cells to
|
|
* resize the columns accordingly.
|
|
* If you experience problems with the performance, try turning this feature off and declaring the column widths manually.
|
|
*
|
|
* Column width calculations are divided into sync and async part. Each of this parts has their own advantages and
|
|
* disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't
|
|
* block the browser UI.
|
|
*
|
|
* To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object:
|
|
* ```js
|
|
* ...
|
|
* // as a number (300 columns in sync, rest async)
|
|
* autoColumnSize: {syncLimit: 300},
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as a string (percent)
|
|
* autoColumnSize: {syncLimit: '40%'},
|
|
* ...
|
|
* ```
|
|
*
|
|
* To configure this plugin see {@link Options#autoColumnSize}.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* var hot = new Handsontable(document.getElementById('example'), {
|
|
* date: getData(),
|
|
* autoColumnSize: true
|
|
* });
|
|
* // Access to plugin instance:
|
|
* var plugin = hot.getPlugin('autoColumnSize');
|
|
*
|
|
* plugin.getColumnWidth(4);
|
|
*
|
|
* if (plugin.isEnabled()) {
|
|
* // code...
|
|
* }
|
|
* ...
|
|
* ```
|
|
*/
|
|
|
|
var AutoColumnSize = function (_BasePlugin) {
|
|
_inherits(AutoColumnSize, _BasePlugin);
|
|
|
|
_createClass(AutoColumnSize, null, [{
|
|
key: 'CALCULATION_STEP',
|
|
get: function get() {
|
|
return 50;
|
|
}
|
|
}, {
|
|
key: 'SYNC_CALCULATION_LIMIT',
|
|
get: function get() {
|
|
return 50;
|
|
}
|
|
}]);
|
|
|
|
function AutoColumnSize(hotInstance) {
|
|
_classCallCheck(this, AutoColumnSize);
|
|
|
|
var _this = _possibleConstructorReturn(this, (AutoColumnSize.__proto__ || Object.getPrototypeOf(AutoColumnSize)).call(this, hotInstance));
|
|
|
|
privatePool.set(_this, {
|
|
/**
|
|
* Cached column header names. It is used to diff current column headers with previous state and detect which
|
|
* columns width should be updated.
|
|
*
|
|
* @private
|
|
* @type {Array}
|
|
*/
|
|
cachedColumnHeaders: []
|
|
});
|
|
/**
|
|
* Cached columns widths.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
_this.widths = [];
|
|
/**
|
|
* Instance of {@link GhostTable} for rows and columns size calculations.
|
|
*
|
|
* @type {GhostTable}
|
|
*/
|
|
_this.ghostTable = new _ghostTable2.default(_this.hot);
|
|
/**
|
|
* Instance of {@link SamplesGenerator} for generating samples necessary for columns width calculations.
|
|
*
|
|
* @type {SamplesGenerator}
|
|
*/
|
|
_this.samplesGenerator = new _samplesGenerator2.default(function (row, col) {
|
|
return _this.hot.getDataAtCell(row, col);
|
|
});
|
|
/**
|
|
* `true` only if the first calculation was performed
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.firstCalculation = true;
|
|
/**
|
|
* `true` if the size calculation is in progress.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.inProgress = false;
|
|
|
|
// moved to constructor to allow auto-sizing the columns when the plugin is disabled
|
|
_this.addHook('beforeColumnResize', function (col, size, isDblClick) {
|
|
return _this.onBeforeColumnResize(col, size, isDblClick);
|
|
});
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(AutoColumnSize, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return this.hot.getSettings().autoColumnSize !== false && !this.hot.getSettings().colWidths;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this2 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
|
|
var setting = this.hot.getSettings().autoColumnSize;
|
|
|
|
if (setting && setting.useHeaders != null) {
|
|
this.ghostTable.setSetting('useHeaders', setting.useHeaders);
|
|
}
|
|
|
|
this.addHook('afterLoadData', function () {
|
|
return _this2.onAfterLoadData();
|
|
});
|
|
this.addHook('beforeChange', function (changes) {
|
|
return _this2.onBeforeChange(changes);
|
|
});
|
|
|
|
this.addHook('beforeRender', function (force) {
|
|
return _this2.onBeforeRender(force);
|
|
});
|
|
this.addHook('modifyColWidth', function (width, col) {
|
|
return _this2.getColumnWidth(col, width);
|
|
});
|
|
this.addHook('afterInit', function () {
|
|
return _this2.onAfterInit();
|
|
});
|
|
_get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Update plugin state.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
var changedColumns = this.findColumnsWhereHeaderWasChanged();
|
|
|
|
if (changedColumns.length) {
|
|
this.clearCache(changedColumns);
|
|
}
|
|
_get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
_get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Calculate a columns width.
|
|
*
|
|
* @param {Number|Object} colRange Column range object.
|
|
* @param {Number|Object} rowRange Row range object.
|
|
* @param {Boolean} [force=false] If `true` force calculate width even when value was cached earlier.
|
|
*/
|
|
|
|
}, {
|
|
key: 'calculateColumnsWidth',
|
|
value: function calculateColumnsWidth() {
|
|
var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countCols() - 1 };
|
|
|
|
var _this3 = this;
|
|
|
|
var rowRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { from: 0, to: this.hot.countRows() - 1 };
|
|
var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
|
|
if (typeof colRange === 'number') {
|
|
colRange = { from: colRange, to: colRange };
|
|
}
|
|
if (typeof rowRange === 'number') {
|
|
rowRange = { from: rowRange, to: rowRange };
|
|
}
|
|
|
|
(0, _number.rangeEach)(colRange.from, colRange.to, function (col) {
|
|
if (force || _this3.widths[col] === void 0 && !_this3.hot._getColWidthFromSettings(col)) {
|
|
var samples = _this3.samplesGenerator.generateColumnSamples(col, rowRange);
|
|
|
|
samples.forEach(function (sample, col) {
|
|
return _this3.ghostTable.addColumn(col, sample);
|
|
});
|
|
}
|
|
});
|
|
|
|
if (this.ghostTable.columns.length) {
|
|
this.ghostTable.getWidths(function (col, width) {
|
|
_this3.widths[col] = width;
|
|
});
|
|
this.ghostTable.clean();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate all columns width.
|
|
*
|
|
* @param {Object|Number} rowRange Row range object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'calculateAllColumnsWidth',
|
|
value: function calculateAllColumnsWidth() {
|
|
var _this4 = this;
|
|
|
|
var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countRows() - 1 };
|
|
|
|
var current = 0;
|
|
var length = this.hot.countCols() - 1;
|
|
var timer = null;
|
|
|
|
this.inProgress = true;
|
|
|
|
var loop = function loop() {
|
|
// When hot was destroyed after calculating finished cancel frame
|
|
if (!_this4.hot) {
|
|
(0, _feature.cancelAnimationFrame)(timer);
|
|
_this4.inProgress = false;
|
|
|
|
return;
|
|
}
|
|
|
|
_this4.calculateColumnsWidth({
|
|
from: current,
|
|
to: Math.min(current + AutoColumnSize.CALCULATION_STEP, length)
|
|
}, rowRange);
|
|
|
|
current = current + AutoColumnSize.CALCULATION_STEP + 1;
|
|
|
|
if (current < length) {
|
|
timer = (0, _feature.requestAnimationFrame)(loop);
|
|
} else {
|
|
(0, _feature.cancelAnimationFrame)(timer);
|
|
_this4.inProgress = false;
|
|
|
|
// @TODO Should call once per render cycle, currently fired separately in different plugins
|
|
_this4.hot.view.wt.wtOverlays.adjustElementsSize(true);
|
|
// tmp
|
|
if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) {
|
|
_this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw();
|
|
}
|
|
}
|
|
};
|
|
// sync
|
|
if (this.firstCalculation && this.getSyncCalculationLimit()) {
|
|
this.calculateColumnsWidth({ from: 0, to: this.getSyncCalculationLimit() }, rowRange);
|
|
this.firstCalculation = false;
|
|
current = this.getSyncCalculationLimit() + 1;
|
|
}
|
|
// async
|
|
if (current < length) {
|
|
loop();
|
|
} else {
|
|
this.inProgress = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the sampling options.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSamplingOptions',
|
|
value: function setSamplingOptions() {
|
|
var setting = this.hot.getSettings().autoColumnSize;
|
|
var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoColumnSize.samplingRatio : void 0;
|
|
var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoColumnSize.allowSampleDuplicates : void 0;
|
|
|
|
if (samplingRatio && !isNaN(samplingRatio)) {
|
|
this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10));
|
|
}
|
|
|
|
if (allowSampleDuplicates) {
|
|
this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Recalculate all columns width (overwrite cache values).
|
|
*/
|
|
|
|
}, {
|
|
key: 'recalculateAllColumnsWidth',
|
|
value: function recalculateAllColumnsWidth() {
|
|
if (this.hot.view && (0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) {
|
|
this.clearCache();
|
|
this.calculateAllColumnsWidth();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get value which tells how many columns should be calculated synchronously. Rest of the columns will be calculated asynchronously.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSyncCalculationLimit',
|
|
value: function getSyncCalculationLimit() {
|
|
/* eslint-disable no-bitwise */
|
|
var limit = AutoColumnSize.SYNC_CALCULATION_LIMIT;
|
|
var colsLimit = this.hot.countCols() - 1;
|
|
|
|
if ((0, _object.isObject)(this.hot.getSettings().autoColumnSize)) {
|
|
limit = this.hot.getSettings().autoColumnSize.syncLimit;
|
|
|
|
if ((0, _string.isPercentValue)(limit)) {
|
|
limit = (0, _number.valueAccordingPercent)(colsLimit, limit);
|
|
} else {
|
|
// Force to Number
|
|
limit >>= 0;
|
|
}
|
|
}
|
|
|
|
return Math.min(limit, colsLimit);
|
|
}
|
|
|
|
/**
|
|
* Get the calculated column width.
|
|
*
|
|
* @param {Number} col Column index.
|
|
* @param {Number} [defaultWidth] Default column width. It will be picked up if no calculated width found.
|
|
* @param {Boolean} [keepMinimum=true] If `true` then returned value won't be smaller then 50 (default column width).
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getColumnWidth',
|
|
value: function getColumnWidth(col) {
|
|
var defaultWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0;
|
|
var keepMinimum = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
|
|
var width = defaultWidth;
|
|
|
|
if (width === void 0) {
|
|
width = this.widths[col];
|
|
|
|
if (keepMinimum && typeof width === 'number') {
|
|
width = Math.max(width, _src.ViewportColumnsCalculator.DEFAULT_WIDTH);
|
|
}
|
|
}
|
|
|
|
return width;
|
|
}
|
|
|
|
/**
|
|
* Get the first visible column.
|
|
*
|
|
* @returns {Number} Returns column index or -1 if table is not rendered.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getFirstVisibleColumn',
|
|
value: function getFirstVisibleColumn() {
|
|
var wot = this.hot.view.wt;
|
|
|
|
if (wot.wtViewport.columnsVisibleCalculator) {
|
|
return wot.wtTable.getFirstVisibleColumn();
|
|
}
|
|
if (wot.wtViewport.columnsRenderCalculator) {
|
|
return wot.wtTable.getFirstRenderedColumn();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Get the last visible column.
|
|
*
|
|
* @returns {Number} Returns column index or -1 if table is not rendered.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getLastVisibleColumn',
|
|
value: function getLastVisibleColumn() {
|
|
var wot = this.hot.view.wt;
|
|
|
|
if (wot.wtViewport.columnsVisibleCalculator) {
|
|
return wot.wtTable.getLastVisibleColumn();
|
|
}
|
|
if (wot.wtViewport.columnsRenderCalculator) {
|
|
return wot.wtTable.getLastRenderedColumn();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Collects all columns which titles has been changed in comparison to the previous state.
|
|
*
|
|
* @returns {Array} It returns an array of physical column indexes.
|
|
*/
|
|
|
|
}, {
|
|
key: 'findColumnsWhereHeaderWasChanged',
|
|
value: function findColumnsWhereHeaderWasChanged() {
|
|
var columnHeaders = this.hot.getColHeader();
|
|
|
|
var _privatePool$get = privatePool.get(this),
|
|
cachedColumnHeaders = _privatePool$get.cachedColumnHeaders;
|
|
|
|
var changedColumns = (0, _array.arrayReduce)(columnHeaders, function (acc, columnTitle, physicalColumn) {
|
|
var cachedColumnsLength = cachedColumnHeaders.length;
|
|
|
|
if (cachedColumnsLength - 1 < physicalColumn || cachedColumnHeaders[physicalColumn] !== columnTitle) {
|
|
acc.push(physicalColumn);
|
|
}
|
|
if (cachedColumnsLength - 1 < physicalColumn) {
|
|
cachedColumnHeaders.push(columnTitle);
|
|
} else {
|
|
cachedColumnHeaders[physicalColumn] = columnTitle;
|
|
}
|
|
|
|
return acc;
|
|
}, []);
|
|
|
|
return changedColumns;
|
|
}
|
|
|
|
/**
|
|
* Clear cache of calculated column widths. If you want to clear only selected columns pass an array with their indexes.
|
|
* Otherwise whole cache will be cleared.
|
|
*
|
|
* @param {Array} [columns=[]] List of column indexes (physical indexes) to clear.
|
|
*/
|
|
|
|
}, {
|
|
key: 'clearCache',
|
|
value: function clearCache() {
|
|
var _this5 = this;
|
|
|
|
var columns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
|
|
if (columns.length) {
|
|
(0, _array.arrayEach)(columns, function (physicalIndex) {
|
|
_this5.widths[physicalIndex] = void 0;
|
|
});
|
|
} else {
|
|
this.widths.length = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if all widths were calculated. If not then return `true` (need recalculate).
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isNeedRecalculate',
|
|
value: function isNeedRecalculate() {
|
|
return !!(0, _array.arrayFilter)(this.widths, function (item) {
|
|
return item === void 0;
|
|
}).length;
|
|
}
|
|
|
|
/**
|
|
* On before render listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeRender',
|
|
value: function onBeforeRender() {
|
|
var force = this.hot.renderCall;
|
|
var rowsCount = this.hot.countRows();
|
|
|
|
// Keep last column widths unchanged for situation when all rows was deleted or trimmed (pro #6)
|
|
if (!rowsCount) {
|
|
return;
|
|
}
|
|
|
|
this.calculateColumnsWidth({ from: this.getFirstVisibleColumn(), to: this.getLastVisibleColumn() }, void 0, force);
|
|
|
|
if (this.isNeedRecalculate() && !this.inProgress) {
|
|
this.calculateAllColumnsWidth();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On after load data listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterLoadData',
|
|
value: function onAfterLoadData() {
|
|
var _this6 = this;
|
|
|
|
if (this.hot.view) {
|
|
this.recalculateAllColumnsWidth();
|
|
} else {
|
|
// first load - initialization
|
|
setTimeout(function () {
|
|
if (_this6.hot) {
|
|
_this6.recalculateAllColumnsWidth();
|
|
}
|
|
}, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On before change listener.
|
|
*
|
|
* @private
|
|
* @param {Array} changes
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeChange',
|
|
value: function onBeforeChange(changes) {
|
|
var _this7 = this;
|
|
|
|
var changedColumns = (0, _array.arrayMap)(changes, function (_ref) {
|
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
row = _ref2[0],
|
|
column = _ref2[1];
|
|
|
|
return _this7.hot.propToCol(column);
|
|
});
|
|
|
|
this.clearCache(changedColumns);
|
|
}
|
|
|
|
/**
|
|
* On before column resize listener.
|
|
*
|
|
* @private
|
|
* @param {Number} col
|
|
* @param {Number} size
|
|
* @param {Boolean} isDblClick
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeColumnResize',
|
|
value: function onBeforeColumnResize(col, size, isDblClick) {
|
|
if (isDblClick) {
|
|
this.calculateColumnsWidth(col, void 0, true);
|
|
size = this.getColumnWidth(col, void 0, false);
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* On after Handsontable init fill plugin with all necessary values.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterInit',
|
|
value: function onAfterInit() {
|
|
privatePool.get(this).cachedColumnHeaders = this.hot.getColHeader();
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.ghostTable.clean();
|
|
_get(AutoColumnSize.prototype.__proto__ || Object.getPrototypeOf(AutoColumnSize.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return AutoColumnSize;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('autoColumnSize', AutoColumnSize);
|
|
|
|
exports.default = AutoColumnSize;
|
|
|
|
/***/ }),
|
|
/* 326 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _feature = __webpack_require__(34);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _ghostTable = __webpack_require__(67);
|
|
|
|
var _ghostTable2 = _interopRequireDefault(_ghostTable);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _samplesGenerator = __webpack_require__(269);
|
|
|
|
var _samplesGenerator2 = _interopRequireDefault(_samplesGenerator);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @plugin AutoRowSize
|
|
*
|
|
* @description
|
|
* This plugin allows to set row heights based on their highest cells.
|
|
*
|
|
* By default, the plugin is declared as `undefined`, which makes it disabled (same as if it was declared as `false`).
|
|
* Enabling this plugin may decrease the overall table performance, as it needs to calculate the heights of all cells to
|
|
* resize the rows accordingly.
|
|
* If you experience problems with the performance, try turning this feature off and declaring the row heights manually.
|
|
*
|
|
* Row height calculations are divided into sync and async part. Each of this parts has their own advantages and
|
|
* disadvantages. Synchronous calculations are faster but they block the browser UI, while the slower asynchronous operations don't
|
|
* block the browser UI.
|
|
*
|
|
* To configure the sync/async distribution, you can pass an absolute value (number of columns) or a percentage value to a config object:
|
|
* ```js
|
|
* ...
|
|
* // as a number (300 columns in sync, rest async)
|
|
* autoRowSize: {syncLimit: 300},
|
|
* ...
|
|
*
|
|
* ...
|
|
* // as a string (percent)
|
|
* autoRowSize: {syncLimit: '40%'},
|
|
* ...
|
|
* ```
|
|
*
|
|
* You can also use the `allowSampleDuplicates` option to allow sampling duplicate values when calculating the row height. Note, that this might have
|
|
* a negative impact on performance.
|
|
*
|
|
* To configure this plugin see {@link Options#autoRowSize}.
|
|
*
|
|
* @example
|
|
*
|
|
* ```js
|
|
* ...
|
|
* var hot = new Handsontable(document.getElementById('example'), {
|
|
* date: getData(),
|
|
* autoRowSize: true
|
|
* });
|
|
* // Access to plugin instance:
|
|
* var plugin = hot.getPlugin('autoRowSize');
|
|
*
|
|
* plugin.getRowHeight(4);
|
|
*
|
|
* if (plugin.isEnabled()) {
|
|
* // code...
|
|
* }
|
|
* ...
|
|
* ```
|
|
*/
|
|
var AutoRowSize = function (_BasePlugin) {
|
|
_inherits(AutoRowSize, _BasePlugin);
|
|
|
|
_createClass(AutoRowSize, null, [{
|
|
key: 'CALCULATION_STEP',
|
|
get: function get() {
|
|
return 50;
|
|
}
|
|
}, {
|
|
key: 'SYNC_CALCULATION_LIMIT',
|
|
get: function get() {
|
|
return 500;
|
|
}
|
|
}]);
|
|
|
|
function AutoRowSize(hotInstance) {
|
|
_classCallCheck(this, AutoRowSize);
|
|
|
|
/**
|
|
* Cached rows heights.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (AutoRowSize.__proto__ || Object.getPrototypeOf(AutoRowSize)).call(this, hotInstance));
|
|
|
|
_this.heights = [];
|
|
/**
|
|
* Instance of {@link GhostTable} for rows and columns size calculations.
|
|
*
|
|
* @type {GhostTable}
|
|
*/
|
|
_this.ghostTable = new _ghostTable2.default(_this.hot);
|
|
/**
|
|
* Instance of {@link SamplesGenerator} for generating samples necessary for rows height calculations.
|
|
*
|
|
* @type {SamplesGenerator}
|
|
*/
|
|
_this.samplesGenerator = new _samplesGenerator2.default(function (row, col) {
|
|
if (row >= 0) {
|
|
return _this.hot.getDataAtCell(row, col);
|
|
} else if (row === -1) {
|
|
return _this.hot.getColHeader(col);
|
|
}
|
|
return null;
|
|
});
|
|
/**
|
|
* `true` if only the first calculation was performed.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.firstCalculation = true;
|
|
/**
|
|
* `true` if the size calculation is in progress.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.inProgress = false;
|
|
|
|
// moved to constructor to allow auto-sizing the rows when the plugin is disabled
|
|
_this.addHook('beforeRowResize', function (row, size, isDblClick) {
|
|
return _this.onBeforeRowResize(row, size, isDblClick);
|
|
});
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the Handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(AutoRowSize, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return this.hot.getSettings().autoRowSize === true || (0, _object.isObject)(this.hot.getSettings().autoRowSize);
|
|
}
|
|
|
|
/**
|
|
* Enable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this2 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
|
|
this.setSamplingOptions();
|
|
|
|
this.addHook('afterLoadData', function () {
|
|
return _this2.onAfterLoadData();
|
|
});
|
|
this.addHook('beforeChange', function (changes) {
|
|
return _this2.onBeforeChange(changes);
|
|
});
|
|
this.addHook('beforeColumnMove', function () {
|
|
return _this2.recalculateAllRowsHeight();
|
|
});
|
|
this.addHook('beforeColumnResize', function () {
|
|
return _this2.recalculateAllRowsHeight();
|
|
});
|
|
this.addHook('beforeColumnSort', function () {
|
|
return _this2.clearCache();
|
|
});
|
|
this.addHook('beforeRender', function (force) {
|
|
return _this2.onBeforeRender(force);
|
|
});
|
|
this.addHook('beforeRowMove', function (rowStart, rowEnd) {
|
|
return _this2.onBeforeRowMove(rowStart, rowEnd);
|
|
});
|
|
this.addHook('modifyRowHeight', function (height, row) {
|
|
return _this2.getRowHeight(row, height);
|
|
});
|
|
this.addHook('modifyColumnHeaderHeight', function () {
|
|
return _this2.getColumnHeaderHeight();
|
|
});
|
|
_get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
_get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Calculate a given rows height.
|
|
*
|
|
* @param {Number|Object} rowRange Row range object.
|
|
* @param {Number|Object} colRange Column range object.
|
|
* @param {Boolean} [force=false] If `true` force calculate height even when value was cached earlier.
|
|
*/
|
|
|
|
}, {
|
|
key: 'calculateRowsHeight',
|
|
value: function calculateRowsHeight() {
|
|
var rowRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countRows() - 1 };
|
|
|
|
var _this3 = this;
|
|
|
|
var colRange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { from: 0, to: this.hot.countCols() - 1 };
|
|
var force = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
|
|
if (typeof rowRange === 'number') {
|
|
rowRange = { from: rowRange, to: rowRange };
|
|
}
|
|
if (typeof colRange === 'number') {
|
|
colRange = { from: colRange, to: colRange };
|
|
}
|
|
|
|
if (this.hot.getColHeader(0) !== null) {
|
|
var samples = this.samplesGenerator.generateRowSamples(-1, colRange);
|
|
|
|
this.ghostTable.addColumnHeadersRow(samples.get(-1));
|
|
}
|
|
|
|
(0, _number.rangeEach)(rowRange.from, rowRange.to, function (row) {
|
|
// For rows we must calculate row height even when user had set height value manually.
|
|
// We can shrink column but cannot shrink rows!
|
|
if (force || _this3.heights[row] === void 0) {
|
|
var _samples = _this3.samplesGenerator.generateRowSamples(row, colRange);
|
|
|
|
_samples.forEach(function (sample, row) {
|
|
_this3.ghostTable.addRow(row, sample);
|
|
});
|
|
}
|
|
});
|
|
if (this.ghostTable.rows.length) {
|
|
this.ghostTable.getHeights(function (row, height) {
|
|
_this3.heights[row] = height;
|
|
});
|
|
this.ghostTable.clean();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate the height of all the rows.
|
|
*
|
|
* @param {Object|Number} colRange Column range object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'calculateAllRowsHeight',
|
|
value: function calculateAllRowsHeight() {
|
|
var _this4 = this;
|
|
|
|
var colRange = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { from: 0, to: this.hot.countCols() - 1 };
|
|
|
|
var current = 0;
|
|
var length = this.hot.countRows() - 1;
|
|
var timer = null;
|
|
|
|
this.inProgress = true;
|
|
|
|
var loop = function loop() {
|
|
// When hot was destroyed after calculating finished cancel frame
|
|
if (!_this4.hot) {
|
|
(0, _feature.cancelAnimationFrame)(timer);
|
|
_this4.inProgress = false;
|
|
|
|
return;
|
|
}
|
|
_this4.calculateRowsHeight({ from: current, to: Math.min(current + AutoRowSize.CALCULATION_STEP, length) }, colRange);
|
|
current = current + AutoRowSize.CALCULATION_STEP + 1;
|
|
|
|
if (current < length) {
|
|
timer = (0, _feature.requestAnimationFrame)(loop);
|
|
} else {
|
|
(0, _feature.cancelAnimationFrame)(timer);
|
|
_this4.inProgress = false;
|
|
|
|
// @TODO Should call once per render cycle, currently fired separately in different plugins
|
|
_this4.hot.view.wt.wtOverlays.adjustElementsSize(true);
|
|
// tmp
|
|
if (_this4.hot.view.wt.wtOverlays.leftOverlay.needFullRender) {
|
|
_this4.hot.view.wt.wtOverlays.leftOverlay.clone.draw();
|
|
}
|
|
}
|
|
};
|
|
// sync
|
|
if (this.firstCalculation && this.getSyncCalculationLimit()) {
|
|
this.calculateRowsHeight({ from: 0, to: this.getSyncCalculationLimit() }, colRange);
|
|
this.firstCalculation = false;
|
|
current = this.getSyncCalculationLimit() + 1;
|
|
}
|
|
// async
|
|
if (current < length) {
|
|
loop();
|
|
} else {
|
|
this.inProgress = false;
|
|
this.hot.view.wt.wtOverlays.adjustElementsSize(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the sampling options.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSamplingOptions',
|
|
value: function setSamplingOptions() {
|
|
var setting = this.hot.getSettings().autoRowSize;
|
|
var samplingRatio = setting && (0, _object.hasOwnProperty)(setting, 'samplingRatio') ? this.hot.getSettings().autoRowSize.samplingRatio : void 0;
|
|
var allowSampleDuplicates = setting && (0, _object.hasOwnProperty)(setting, 'allowSampleDuplicates') ? this.hot.getSettings().autoRowSize.allowSampleDuplicates : void 0;
|
|
|
|
if (samplingRatio && !isNaN(samplingRatio)) {
|
|
this.samplesGenerator.setSampleCount(parseInt(samplingRatio, 10));
|
|
}
|
|
|
|
if (allowSampleDuplicates) {
|
|
this.samplesGenerator.setAllowDuplicates(allowSampleDuplicates);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Recalculate all rows height (overwrite cache values).
|
|
*/
|
|
|
|
}, {
|
|
key: 'recalculateAllRowsHeight',
|
|
value: function recalculateAllRowsHeight() {
|
|
if ((0, _element.isVisible)(this.hot.view.wt.wtTable.TABLE)) {
|
|
this.clearCache();
|
|
this.calculateAllRowsHeight();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get value which tells how much rows will be calculated synchronously. Rest rows will be calculated asynchronously.
|
|
*
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSyncCalculationLimit',
|
|
value: function getSyncCalculationLimit() {
|
|
/* eslint-disable no-bitwise */
|
|
var limit = AutoRowSize.SYNC_CALCULATION_LIMIT;
|
|
var rowsLimit = this.hot.countRows() - 1;
|
|
|
|
if ((0, _object.isObject)(this.hot.getSettings().autoRowSize)) {
|
|
limit = this.hot.getSettings().autoRowSize.syncLimit;
|
|
|
|
if ((0, _string.isPercentValue)(limit)) {
|
|
limit = (0, _number.valueAccordingPercent)(rowsLimit, limit);
|
|
} else {
|
|
// Force to Number
|
|
limit >>= 0;
|
|
}
|
|
}
|
|
|
|
return Math.min(limit, rowsLimit);
|
|
}
|
|
|
|
/**
|
|
* Get the calculated row height.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} [defaultHeight] Default row height. It will be pick up if no calculated height found.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getRowHeight',
|
|
value: function getRowHeight(row) {
|
|
var defaultHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : void 0;
|
|
|
|
var height = defaultHeight;
|
|
|
|
if (this.heights[row] !== void 0 && this.heights[row] > (defaultHeight || 0)) {
|
|
height = this.heights[row];
|
|
}
|
|
|
|
return height;
|
|
}
|
|
|
|
/**
|
|
* Get the calculated column header height.
|
|
*
|
|
* @returns {Number|undefined}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getColumnHeaderHeight',
|
|
value: function getColumnHeaderHeight() {
|
|
return this.heights[-1];
|
|
}
|
|
|
|
/**
|
|
* Get the first visible row.
|
|
*
|
|
* @returns {Number} Returns row index or -1 if table is not rendered.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getFirstVisibleRow',
|
|
value: function getFirstVisibleRow() {
|
|
var wot = this.hot.view.wt;
|
|
|
|
if (wot.wtViewport.rowsVisibleCalculator) {
|
|
return wot.wtTable.getFirstVisibleRow();
|
|
}
|
|
if (wot.wtViewport.rowsRenderCalculator) {
|
|
return wot.wtTable.getFirstRenderedRow();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Get the last visible row.
|
|
*
|
|
* @returns {Number} Returns row index or -1 if table is not rendered.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getLastVisibleRow',
|
|
value: function getLastVisibleRow() {
|
|
var wot = this.hot.view.wt;
|
|
|
|
if (wot.wtViewport.rowsVisibleCalculator) {
|
|
return wot.wtTable.getLastVisibleRow();
|
|
}
|
|
if (wot.wtViewport.rowsRenderCalculator) {
|
|
return wot.wtTable.getLastRenderedRow();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Clear cached heights.
|
|
*/
|
|
|
|
}, {
|
|
key: 'clearCache',
|
|
value: function clearCache() {
|
|
this.heights.length = 0;
|
|
this.heights[-1] = void 0;
|
|
}
|
|
|
|
/**
|
|
* Clear cache by range.
|
|
*
|
|
* @param {Object|Number} range Row range object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'clearCacheByRange',
|
|
value: function clearCacheByRange(range) {
|
|
var _this5 = this;
|
|
|
|
if (typeof range === 'number') {
|
|
range = { from: range, to: range };
|
|
}
|
|
(0, _number.rangeEach)(Math.min(range.from, range.to), Math.max(range.from, range.to), function (row) {
|
|
_this5.heights[row] = void 0;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isNeedRecalculate',
|
|
value: function isNeedRecalculate() {
|
|
return !!(0, _array.arrayFilter)(this.heights, function (item) {
|
|
return item === void 0;
|
|
}).length;
|
|
}
|
|
|
|
/**
|
|
* On before render listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeRender',
|
|
value: function onBeforeRender() {
|
|
var force = this.hot.renderCall;
|
|
this.calculateRowsHeight({ from: this.getFirstVisibleRow(), to: this.getLastVisibleRow() }, void 0, force);
|
|
|
|
var fixedRowsBottom = this.hot.getSettings().fixedRowsBottom;
|
|
|
|
// Calculate rows height synchronously for bottom overlay
|
|
if (fixedRowsBottom) {
|
|
var totalRows = this.hot.countRows() - 1;
|
|
this.calculateRowsHeight({ from: totalRows - fixedRowsBottom, to: totalRows });
|
|
}
|
|
|
|
if (this.isNeedRecalculate() && !this.inProgress) {
|
|
this.calculateAllRowsHeight();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On before row move listener.
|
|
*
|
|
* @private
|
|
* @param {Number} from Row index where was grabbed.
|
|
* @param {Number} to Destination row index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeRowMove',
|
|
value: function onBeforeRowMove(from, to) {
|
|
this.clearCacheByRange({ from: from, to: to });
|
|
this.calculateAllRowsHeight();
|
|
}
|
|
|
|
/**
|
|
* On before row resize listener.
|
|
*
|
|
* @private
|
|
* @param {Number} row
|
|
* @param {Number} size
|
|
* @param {Boolean} isDblClick
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeRowResize',
|
|
value: function onBeforeRowResize(row, size, isDblClick) {
|
|
if (isDblClick) {
|
|
this.calculateRowsHeight(row, void 0, true);
|
|
size = this.getRowHeight(row);
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* On after load data listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterLoadData',
|
|
value: function onAfterLoadData() {
|
|
var _this6 = this;
|
|
|
|
if (this.hot.view) {
|
|
this.recalculateAllRowsHeight();
|
|
} else {
|
|
// first load - initialization
|
|
setTimeout(function () {
|
|
if (_this6.hot) {
|
|
_this6.recalculateAllRowsHeight();
|
|
}
|
|
}, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On before change listener.
|
|
*
|
|
* @private
|
|
* @param {Array} changes
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeChange',
|
|
value: function onBeforeChange(changes) {
|
|
var range = null;
|
|
|
|
if (changes.length === 1) {
|
|
range = changes[0][0];
|
|
} else if (changes.length > 1) {
|
|
range = {
|
|
from: changes[0][0],
|
|
to: changes[changes.length - 1][0]
|
|
};
|
|
}
|
|
if (range !== null) {
|
|
this.clearCacheByRange(range);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.ghostTable.clean();
|
|
_get(AutoRowSize.prototype.__proto__ || Object.getPrototypeOf(AutoRowSize.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return AutoRowSize;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('autoRowSize', AutoRowSize);
|
|
|
|
exports.default = AutoRowSize;
|
|
|
|
/***/ }),
|
|
/* 327 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _utils = __webpack_require__(328);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
_pluginHooks2.default.getSingleton().register('modifyAutofillRange');
|
|
_pluginHooks2.default.getSingleton().register('beforeAutofill');
|
|
|
|
var INSERT_ROW_ALTER_ACTION_NAME = 'insert_row';
|
|
var INTERVAL_FOR_ADDING_ROW = 200;
|
|
|
|
/**
|
|
* This plugin provides "drag-down" and "copy-down" functionalities, both operated
|
|
* using the small square in the right bottom of the cell selection.
|
|
*
|
|
* "Drag-down" expands the value of the selected cells to the neighbouring
|
|
* cells when you drag the small square in the corner.
|
|
*
|
|
* "Copy-down" copies the value of the selection to all empty cells
|
|
* below when you double click the small square.
|
|
*
|
|
* @class Autofill
|
|
* @plugin Autofill
|
|
*/
|
|
|
|
var Autofill = function (_BasePlugin) {
|
|
_inherits(Autofill, _BasePlugin);
|
|
|
|
function Autofill(hotInstance) {
|
|
_classCallCheck(this, Autofill);
|
|
|
|
/**
|
|
* Event manager
|
|
*
|
|
* @type {EventManager}
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (Autofill.__proto__ || Object.getPrototypeOf(Autofill)).call(this, hotInstance));
|
|
|
|
_this.eventManager = new _eventManager2.default(_this);
|
|
/**
|
|
* Specifies if adding new row started.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.addingStarted = false;
|
|
/**
|
|
* Specifies if there was mouse down on the cell corner.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.mouseDownOnCellCorner = false;
|
|
/**
|
|
* Specifies if mouse was dragged outside Handsontable.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.mouseDragOutside = false;
|
|
/**
|
|
* Specifies how many cell levels were dragged using the handle.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.handleDraggedCells = 0;
|
|
/**
|
|
* Specifies allowed directions of drag.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
_this.directions = [];
|
|
/**
|
|
* Specifies if can insert new rows if needed.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
_this.autoInsertRow = false;
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the Handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(Autofill, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return this.hot.getSettings().fillHandle;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this2 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
|
|
this.mapSettings();
|
|
this.registerEvents();
|
|
|
|
this.addHook('afterOnCellCornerMouseDown', function (event) {
|
|
return _this2.onAfterCellCornerMouseDown(event);
|
|
});
|
|
this.addHook('afterOnCellCornerDblClick', function (event) {
|
|
return _this2.onCellCornerDblClick(event);
|
|
});
|
|
this.addHook('beforeOnCellMouseOver', function (event, coords, TD) {
|
|
return _this2.onBeforeCellMouseOver(coords);
|
|
});
|
|
|
|
_get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Update plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
this.disablePlugin();
|
|
this.enablePlugin();
|
|
_get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
this.clearMappedSettings();
|
|
_get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Get selection data
|
|
*
|
|
* @private
|
|
* @returns {Array} Array with the data.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getSelectionData',
|
|
value: function getSelectionData() {
|
|
var selRange = {
|
|
from: this.hot.getSelectedRange().from,
|
|
to: this.hot.getSelectedRange().to
|
|
};
|
|
|
|
return this.hot.getData(selRange.from.row, selRange.from.col, selRange.to.row, selRange.to.col);
|
|
}
|
|
|
|
/**
|
|
* Try to apply fill values to the area in fill border, omitting the selection border.
|
|
*
|
|
* @private
|
|
* @returns {Boolean} reports if fill was applied.
|
|
*/
|
|
|
|
}, {
|
|
key: 'fillIn',
|
|
value: function fillIn() {
|
|
if (this.hot.view.wt.selections.fill.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
var cornersOfSelectionAndDragAreas = this.hot.view.wt.selections.fill.getCorners();
|
|
|
|
this.resetSelectionOfDraggedArea();
|
|
|
|
var cornersOfSelectedCells = this.getCornersOfSelectedCells();
|
|
|
|
var _getDragDirectionAndR = (0, _utils.getDragDirectionAndRange)(cornersOfSelectedCells, cornersOfSelectionAndDragAreas),
|
|
directionOfDrag = _getDragDirectionAndR.directionOfDrag,
|
|
startOfDragCoords = _getDragDirectionAndR.startOfDragCoords,
|
|
endOfDragCoords = _getDragDirectionAndR.endOfDragCoords;
|
|
|
|
this.hot.runHooks('modifyAutofillRange', cornersOfSelectedCells, cornersOfSelectionAndDragAreas);
|
|
|
|
if (startOfDragCoords && startOfDragCoords.row > -1 && startOfDragCoords.col > -1) {
|
|
var selectionData = this.getSelectionData();
|
|
var deltas = (0, _utils.getDeltas)(startOfDragCoords, endOfDragCoords, selectionData, directionOfDrag);
|
|
var fillData = selectionData;
|
|
|
|
this.hot.runHooks('beforeAutofill', startOfDragCoords, endOfDragCoords, selectionData);
|
|
|
|
if (['up', 'left'].indexOf(directionOfDrag) > -1) {
|
|
fillData = [];
|
|
|
|
var dragLength = null;
|
|
var fillOffset = null;
|
|
|
|
if (directionOfDrag === 'up') {
|
|
dragLength = endOfDragCoords.row - startOfDragCoords.row + 1;
|
|
fillOffset = dragLength % selectionData.length;
|
|
|
|
for (var i = 0; i < dragLength; i++) {
|
|
fillData.push(selectionData[(i + (selectionData.length - fillOffset)) % selectionData.length]);
|
|
}
|
|
} else {
|
|
dragLength = endOfDragCoords.col - startOfDragCoords.col + 1;
|
|
fillOffset = dragLength % selectionData[0].length;
|
|
|
|
for (var _i = 0; _i < selectionData.length; _i++) {
|
|
fillData.push([]);
|
|
for (var j = 0; j < dragLength; j++) {
|
|
fillData[_i].push(selectionData[_i][(j + (selectionData[_i].length - fillOffset)) % selectionData[_i].length]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.hot.populateFromArray(startOfDragCoords.row, startOfDragCoords.col, fillData, endOfDragCoords.row, endOfDragCoords.col, this.pluginName + '.fill', null, directionOfDrag, deltas);
|
|
|
|
this.setSelection(cornersOfSelectionAndDragAreas);
|
|
} else {
|
|
// reset to avoid some range bug
|
|
this.hot.selection.refreshBorders();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Reduce the selection area if the handle was dragged outside of the table or on headers.
|
|
*
|
|
* @private
|
|
* @param {CellCoords} coords indexes of selection corners.
|
|
* @returns {CellCoords}
|
|
*/
|
|
|
|
}, {
|
|
key: 'reduceSelectionAreaIfNeeded',
|
|
value: function reduceSelectionAreaIfNeeded(coords) {
|
|
if (coords.row < 0) {
|
|
coords.row = 0;
|
|
}
|
|
|
|
if (coords.col < 0) {
|
|
coords.col = 0;
|
|
}
|
|
return coords;
|
|
}
|
|
|
|
/**
|
|
* Get the coordinates of the drag & drop borders.
|
|
*
|
|
* @private
|
|
* @param {CellCoords} coordsOfSelection `CellCoords` coord object.
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCoordsOfDragAndDropBorders',
|
|
value: function getCoordsOfDragAndDropBorders(coordsOfSelection) {
|
|
var topLeftCorner = this.hot.getSelectedRange().getTopLeftCorner();
|
|
var bottomRightCorner = this.hot.getSelectedRange().getBottomRightCorner();
|
|
var coords = void 0;
|
|
|
|
if (this.directions.includes(_utils.DIRECTIONS.vertical) && (bottomRightCorner.row < coordsOfSelection.row || topLeftCorner.row > coordsOfSelection.row)) {
|
|
coords = new _src.CellCoords(coordsOfSelection.row, bottomRightCorner.col);
|
|
} else if (this.directions.includes(_utils.DIRECTIONS.horizontal)) {
|
|
coords = new _src.CellCoords(bottomRightCorner.row, coordsOfSelection.col);
|
|
} else {
|
|
// wrong direction
|
|
return;
|
|
}
|
|
|
|
return this.reduceSelectionAreaIfNeeded(coords);
|
|
}
|
|
|
|
/**
|
|
* Show the fill border.
|
|
*
|
|
* @private
|
|
* @param {CellCoords} coordsOfSelection `CellCoords` coord object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'showBorder',
|
|
value: function showBorder(coordsOfSelection) {
|
|
var coordsOfDragAndDropBorders = this.getCoordsOfDragAndDropBorders(coordsOfSelection);
|
|
|
|
if (coordsOfDragAndDropBorders) {
|
|
this.redrawBorders(coordsOfDragAndDropBorders);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add new row
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'addRow',
|
|
value: function addRow() {
|
|
var _this3 = this;
|
|
|
|
this.hot._registerTimeout(setTimeout(function () {
|
|
_this3.hot.alter(INSERT_ROW_ALTER_ACTION_NAME, void 0, 1, _this3.pluginName + '.fill');
|
|
|
|
_this3.addingStarted = false;
|
|
}, INTERVAL_FOR_ADDING_ROW));
|
|
}
|
|
|
|
/**
|
|
* Add new rows if they are needed to continue auto-filling values.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'addNewRowIfNeeded',
|
|
value: function addNewRowIfNeeded() {
|
|
if (this.hot.view.wt.selections.fill.cellRange && this.addingStarted === false && this.autoInsertRow) {
|
|
var cornersOfSelectedCells = this.hot.getSelected();
|
|
var cornersOfSelectedDragArea = this.hot.view.wt.selections.fill.getCorners();
|
|
var nrOfTableRows = this.hot.countRows();
|
|
|
|
if (cornersOfSelectedCells[2] < nrOfTableRows - 1 && cornersOfSelectedDragArea[2] === nrOfTableRows - 1) {
|
|
this.addingStarted = true;
|
|
|
|
this.addRow();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get corners of selected cells.
|
|
*
|
|
* @private
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCornersOfSelectedCells',
|
|
value: function getCornersOfSelectedCells() {
|
|
if (this.hot.selection.isMultiple()) {
|
|
return this.hot.view.wt.selections.area.getCorners();
|
|
}
|
|
return this.hot.view.wt.selections.current.getCorners();
|
|
}
|
|
|
|
/**
|
|
* Get index of last adjacent filled in row
|
|
*
|
|
* @private
|
|
* @param {Array} cornersOfSelectedCells indexes of selection corners.
|
|
* @returns {Number} gives number greater than or equal to zero when selection adjacent can be applied.
|
|
* or -1 when selection adjacent can't be applied
|
|
*/
|
|
|
|
}, {
|
|
key: 'getIndexOfLastAdjacentFilledInRow',
|
|
value: function getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells) {
|
|
var data = this.hot.getData();
|
|
var nrOfTableRows = this.hot.countRows();
|
|
var lastFilledInRowIndex = void 0;
|
|
|
|
for (var rowIndex = cornersOfSelectedCells[2] + 1; rowIndex < nrOfTableRows; rowIndex++) {
|
|
for (var columnIndex = cornersOfSelectedCells[1]; columnIndex <= cornersOfSelectedCells[3]; columnIndex++) {
|
|
var dataInCell = data[rowIndex][columnIndex];
|
|
|
|
if (dataInCell) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
var dataInNextLeftCell = data[rowIndex][cornersOfSelectedCells[1] - 1];
|
|
var dataInNextRightCell = data[rowIndex][cornersOfSelectedCells[3] + 1];
|
|
|
|
if (!!dataInNextLeftCell || !!dataInNextRightCell) {
|
|
lastFilledInRowIndex = rowIndex;
|
|
}
|
|
}
|
|
return lastFilledInRowIndex;
|
|
}
|
|
|
|
/**
|
|
* Add a selection from the start area to the specific row index.
|
|
*
|
|
* @private
|
|
* @param {Array} selectStartArea selection area from which we start to create more comprehensive selection.
|
|
* @param {Number} rowIndex
|
|
*/
|
|
|
|
}, {
|
|
key: 'addSelectionFromStartAreaToSpecificRowIndex',
|
|
value: function addSelectionFromStartAreaToSpecificRowIndex(selectStartArea, rowIndex) {
|
|
this.hot.view.wt.selections.fill.clear();
|
|
this.hot.view.wt.selections.fill.add(new _src.CellCoords(selectStartArea[0], selectStartArea[1]));
|
|
this.hot.view.wt.selections.fill.add(new _src.CellCoords(rowIndex, selectStartArea[3]));
|
|
}
|
|
|
|
/**
|
|
* Set selection based on passed corners.
|
|
*
|
|
* @private
|
|
* @param {Array} cornersOfArea
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSelection',
|
|
value: function setSelection(cornersOfArea) {
|
|
this.hot.selection.setRangeStart(new _src.CellCoords(cornersOfArea[0], cornersOfArea[1]));
|
|
this.hot.selection.setRangeEnd(new _src.CellCoords(cornersOfArea[2], cornersOfArea[3]));
|
|
}
|
|
|
|
/**
|
|
* Try to select cells down to the last row in the left column and then returns if selection was applied.
|
|
*
|
|
* @private
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'selectAdjacent',
|
|
value: function selectAdjacent() {
|
|
var cornersOfSelectedCells = this.getCornersOfSelectedCells();
|
|
var lastFilledInRowIndex = this.getIndexOfLastAdjacentFilledInRow(cornersOfSelectedCells);
|
|
|
|
if (lastFilledInRowIndex === -1) {
|
|
return false;
|
|
}
|
|
this.addSelectionFromStartAreaToSpecificRowIndex(cornersOfSelectedCells, lastFilledInRowIndex);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Reset selection of dragged area.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'resetSelectionOfDraggedArea',
|
|
value: function resetSelectionOfDraggedArea() {
|
|
this.handleDraggedCells = 0;
|
|
|
|
this.hot.view.wt.selections.fill.clear();
|
|
}
|
|
|
|
/**
|
|
* Redraw borders.
|
|
*
|
|
* @private
|
|
* @param {CellCoords} coords `CellCoords` coord object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'redrawBorders',
|
|
value: function redrawBorders(coords) {
|
|
this.hot.view.wt.selections.fill.clear();
|
|
this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().from);
|
|
this.hot.view.wt.selections.fill.add(this.hot.getSelectedRange().to);
|
|
this.hot.view.wt.selections.fill.add(coords);
|
|
this.hot.view.render();
|
|
}
|
|
|
|
/**
|
|
* Get if mouse was dragged outside.
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} event `mousemove` event properties.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getIfMouseWasDraggedOutside',
|
|
value: function getIfMouseWasDraggedOutside(event) {
|
|
var tableBottom = (0, _element.offset)(this.hot.table).top - (window.pageYOffset || document.documentElement.scrollTop) + (0, _element.outerHeight)(this.hot.table);
|
|
var tableRight = (0, _element.offset)(this.hot.table).left - (window.pageXOffset || document.documentElement.scrollLeft) + (0, _element.outerWidth)(this.hot.table);
|
|
|
|
return event.clientY > tableBottom && event.clientX <= tableRight;
|
|
}
|
|
|
|
/**
|
|
* Bind the events used by the plugin.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerEvents',
|
|
value: function registerEvents() {
|
|
var _this4 = this;
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'mouseup', function () {
|
|
return _this4.onMouseUp();
|
|
});
|
|
this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) {
|
|
return _this4.onMouseMove(event);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* On cell corner double click callback.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onCellCornerDblClick',
|
|
value: function onCellCornerDblClick() {
|
|
var selectionApplied = this.selectAdjacent();
|
|
|
|
if (selectionApplied) {
|
|
this.fillIn();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On after cell corner mouse down listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterCellCornerMouseDown',
|
|
value: function onAfterCellCornerMouseDown() {
|
|
this.handleDraggedCells = 1;
|
|
this.mouseDownOnCellCorner = true;
|
|
}
|
|
|
|
/**
|
|
* On before cell mouse over listener.
|
|
*
|
|
* @private
|
|
* @param {CellCoords} coords `CellCoords` coord object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeCellMouseOver',
|
|
value: function onBeforeCellMouseOver(coords) {
|
|
if (this.mouseDownOnCellCorner && !this.hot.view.isMouseDown() && this.handleDraggedCells) {
|
|
this.handleDraggedCells++;
|
|
|
|
this.showBorder(coords);
|
|
this.addNewRowIfNeeded();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On mouse up listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseUp',
|
|
value: function onMouseUp() {
|
|
if (this.handleDraggedCells) {
|
|
if (this.handleDraggedCells > 1) {
|
|
this.fillIn();
|
|
}
|
|
|
|
this.handleDraggedCells = 0;
|
|
this.mouseDownOnCellCorner = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On mouse move listener.
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} event `mousemove` event properties.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseMove',
|
|
value: function onMouseMove(event) {
|
|
var mouseWasDraggedOutside = this.getIfMouseWasDraggedOutside(event);
|
|
|
|
if (this.addingStarted === false && this.handleDraggedCells > 0 && mouseWasDraggedOutside) {
|
|
this.mouseDragOutside = true;
|
|
this.addingStarted = true;
|
|
} else {
|
|
this.mouseDragOutside = false;
|
|
}
|
|
|
|
if (this.mouseDragOutside && this.autoInsertRow) {
|
|
this.addRow();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear mapped settings.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'clearMappedSettings',
|
|
value: function clearMappedSettings() {
|
|
this.directions.length = 0;
|
|
this.autoInsertRow = false;
|
|
}
|
|
|
|
/**
|
|
* Map settings.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'mapSettings',
|
|
value: function mapSettings() {
|
|
var mappedSettings = (0, _utils.getMappedFillHandleSetting)(this.hot.getSettings().fillHandle);
|
|
this.directions = mappedSettings.directions;
|
|
this.autoInsertRow = mappedSettings.autoInsertRow;
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
_get(Autofill.prototype.__proto__ || Object.getPrototypeOf(Autofill.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return Autofill;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('autofill', Autofill);
|
|
|
|
exports.default = Autofill;
|
|
|
|
/***/ }),
|
|
/* 328 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.DIRECTIONS = undefined;
|
|
exports.getDeltas = getDeltas;
|
|
exports.getDragDirectionAndRange = getDragDirectionAndRange;
|
|
exports.getMappedFillHandleSetting = getMappedFillHandleSetting;
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var DIRECTIONS = exports.DIRECTIONS = {
|
|
horizontal: 'horizontal',
|
|
vertical: 'vertical'
|
|
};
|
|
|
|
/**
|
|
* Get deltas array.
|
|
*
|
|
* @param {CellCoords} start
|
|
* @param {CellCoords} end
|
|
* @param {Array} data
|
|
* @param {String} direction
|
|
* @returns {Array}
|
|
*/
|
|
function getDeltas(start, end, data, direction) {
|
|
var rowsLength = data.length;
|
|
var columnsLength = data ? data[0].length : 0;
|
|
var deltas = [];
|
|
var diffRow = end.row - start.row;
|
|
var diffCol = end.col - start.col;
|
|
|
|
if (['down', 'up'].indexOf(direction) !== -1) {
|
|
var arr = [];
|
|
|
|
for (var col = 0; col <= diffCol; col++) {
|
|
var startValue = parseInt(data[0][col], 10);
|
|
var endValue = parseInt(data[rowsLength - 1][col], 10);
|
|
var delta = (direction === 'down' ? endValue - startValue : startValue - endValue) / (rowsLength - 1) || 0;
|
|
|
|
arr.push(delta);
|
|
}
|
|
|
|
deltas.push(arr);
|
|
}
|
|
|
|
if (['right', 'left'].indexOf(direction) !== -1) {
|
|
for (var row = 0; row <= diffRow; row++) {
|
|
var _startValue = parseInt(data[row][0], 10);
|
|
var _endValue = parseInt(data[row][columnsLength - 1], 10);
|
|
var _delta = (direction === 'right' ? _endValue - _startValue : _startValue - _endValue) / (columnsLength - 1) || 0;
|
|
|
|
deltas.push([_delta]);
|
|
}
|
|
}
|
|
|
|
return deltas;
|
|
}
|
|
|
|
/**
|
|
* Get direction between positions and cords of selections difference (drag area)
|
|
*
|
|
* @param {Array} startSelection
|
|
* @param {Array} endSelection
|
|
* @returns {{direction: String, start: CellCoords, end: CellCoords}}
|
|
*/
|
|
function getDragDirectionAndRange(startSelection, endSelection) {
|
|
var startOfDragCoords = void 0,
|
|
endOfDragCoords = void 0,
|
|
directionOfDrag = void 0;
|
|
|
|
if (endSelection[0] === startSelection[0] && endSelection[1] < startSelection[1]) {
|
|
directionOfDrag = 'left';
|
|
|
|
startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]);
|
|
endOfDragCoords = new _src.CellCoords(endSelection[2], startSelection[1] - 1);
|
|
} else if (endSelection[0] === startSelection[0] && endSelection[3] > startSelection[3]) {
|
|
directionOfDrag = 'right';
|
|
|
|
startOfDragCoords = new _src.CellCoords(endSelection[0], startSelection[3] + 1);
|
|
endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]);
|
|
} else if (endSelection[0] < startSelection[0] && endSelection[1] === startSelection[1]) {
|
|
directionOfDrag = 'up';
|
|
|
|
startOfDragCoords = new _src.CellCoords(endSelection[0], endSelection[1]);
|
|
endOfDragCoords = new _src.CellCoords(startSelection[0] - 1, endSelection[3]);
|
|
} else if (endSelection[2] > startSelection[2] && endSelection[1] === startSelection[1]) {
|
|
directionOfDrag = 'down';
|
|
|
|
startOfDragCoords = new _src.CellCoords(startSelection[2] + 1, endSelection[1]);
|
|
endOfDragCoords = new _src.CellCoords(endSelection[2], endSelection[3]);
|
|
}
|
|
|
|
return {
|
|
directionOfDrag: directionOfDrag,
|
|
startOfDragCoords: startOfDragCoords,
|
|
endOfDragCoords: endOfDragCoords
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get mapped FillHandle setting containing information about
|
|
* allowed FillHandle directions and if allowed is automatic insertion of rows on drag
|
|
*
|
|
* @param {Boolean|Object} fillHandle property of Handsontable settings
|
|
* @returns {{directions: Array, autoInsertRow: Boolean}} object allowing access to information
|
|
* about FillHandle in more useful way
|
|
*/
|
|
function getMappedFillHandleSetting(fillHandle) {
|
|
var mappedSettings = {};
|
|
|
|
if (fillHandle === true) {
|
|
mappedSettings.directions = Object.keys(DIRECTIONS);
|
|
mappedSettings.autoInsertRow = true;
|
|
} else if ((0, _object.isObject)(fillHandle)) {
|
|
if ((0, _mixed.isDefined)(fillHandle.autoInsertRow)) {
|
|
|
|
// autoInsertRow for horizontal direction will be always false
|
|
|
|
if (fillHandle.direction === DIRECTIONS.horizontal) {
|
|
mappedSettings.autoInsertRow = false;
|
|
} else {
|
|
mappedSettings.autoInsertRow = fillHandle.autoInsertRow;
|
|
}
|
|
} else {
|
|
mappedSettings.autoInsertRow = false;
|
|
}
|
|
|
|
if ((0, _mixed.isDefined)(fillHandle.direction)) {
|
|
mappedSettings.directions = [fillHandle.direction];
|
|
} else {
|
|
mappedSettings.directions = Object.keys(DIRECTIONS);
|
|
}
|
|
} else if (typeof fillHandle === 'string') {
|
|
mappedSettings.directions = [fillHandle];
|
|
mappedSettings.autoInsertRow = true;
|
|
} else {
|
|
mappedSettings.directions = [];
|
|
mappedSettings.autoInsertRow = false;
|
|
}
|
|
|
|
return mappedSettings;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 329 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _moment = __webpack_require__(36);
|
|
|
|
var _moment2 = _interopRequireDefault(_moment);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _mergeSort = __webpack_require__(387);
|
|
|
|
var _mergeSort2 = _interopRequireDefault(_mergeSort);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
_pluginHooks2.default.getSingleton().register('beforeColumnSort');
|
|
_pluginHooks2.default.getSingleton().register('afterColumnSort');
|
|
|
|
// TODO: Implement mixin arrayMapper to ColumnSorting plugin.
|
|
|
|
/**
|
|
* @plugin ColumnSorting
|
|
*
|
|
* @description
|
|
* This plugin sorts the view by a column (but does not sort the data source!).
|
|
* To enable the plugin, set the `columnSorting` property to either:
|
|
* * a boolean value (`true`/`false`),
|
|
* * an object defining the initial sorting order (see the example below).
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as boolean
|
|
* columnSorting: true
|
|
* ...
|
|
* // as a object with initial order (sort ascending column at index 2)
|
|
* columnSorting: {
|
|
* column: 2,
|
|
* sortOrder: true, // true = ascending, false = descending, undefined = original order
|
|
* sortEmptyCells: true // true = the table sorts empty cells, false = the table moves all empty cells to the end of the table
|
|
* }
|
|
* ...
|
|
* ```
|
|
* @dependencies ObserveChanges
|
|
*/
|
|
|
|
var ColumnSorting = function (_BasePlugin) {
|
|
_inherits(ColumnSorting, _BasePlugin);
|
|
|
|
function ColumnSorting(hotInstance) {
|
|
_classCallCheck(this, ColumnSorting);
|
|
|
|
var _this2 = _possibleConstructorReturn(this, (ColumnSorting.__proto__ || Object.getPrototypeOf(ColumnSorting)).call(this, hotInstance));
|
|
|
|
_this2.sortIndicators = [];
|
|
_this2.lastSortedColumn = null;
|
|
_this2.sortEmptyCells = false;
|
|
return _this2;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ColumnSorting, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return !!this.hot.getSettings().columnSorting;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this3 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
|
|
this.setPluginOptions();
|
|
|
|
var _this = this;
|
|
this.hot.sortIndex = [];
|
|
|
|
this.hot.sort = function () {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
|
|
return _this.sortByColumn.apply(_this, _toConsumableArray(args));
|
|
};
|
|
|
|
if (typeof this.hot.getSettings().observeChanges === 'undefined') {
|
|
this.enableObserveChangesPlugin();
|
|
}
|
|
|
|
this.addHook('afterTrimRow', function (row) {
|
|
return _this3.sort();
|
|
});
|
|
this.addHook('afterUntrimRow', function (row) {
|
|
return _this3.sort();
|
|
});
|
|
this.addHook('modifyRow', function (row) {
|
|
return _this3.translateRow(row);
|
|
});
|
|
this.addHook('unmodifyRow', function (row) {
|
|
return _this3.untranslateRow(row);
|
|
});
|
|
this.addHook('afterUpdateSettings', function () {
|
|
return _this3.onAfterUpdateSettings();
|
|
});
|
|
this.addHook('afterGetColHeader', function (col, TH) {
|
|
return _this3.getColHeader(col, TH);
|
|
});
|
|
this.addHook('afterOnCellMouseDown', function (event, target) {
|
|
return _this3.onAfterOnCellMouseDown(event, target);
|
|
});
|
|
this.addHook('afterCreateRow', function () {
|
|
_this.afterCreateRow.apply(_this, arguments);
|
|
});
|
|
this.addHook('afterRemoveRow', function () {
|
|
_this.afterRemoveRow.apply(_this, arguments);
|
|
});
|
|
this.addHook('afterInit', function () {
|
|
return _this3.sortBySettings();
|
|
});
|
|
this.addHook('afterLoadData', function () {
|
|
_this3.hot.sortIndex = [];
|
|
|
|
if (_this3.hot.view) {
|
|
_this3.sortBySettings();
|
|
}
|
|
});
|
|
if (this.hot.view) {
|
|
this.sortBySettings();
|
|
}
|
|
_get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
this.hot.sort = void 0;
|
|
_get(ColumnSorting.prototype.__proto__ || Object.getPrototypeOf(ColumnSorting.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* afterUpdateSettings callback.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterUpdateSettings',
|
|
value: function onAfterUpdateSettings() {
|
|
this.sortBySettings();
|
|
}
|
|
}, {
|
|
key: 'sortBySettings',
|
|
value: function sortBySettings() {
|
|
var sortingSettings = this.hot.getSettings().columnSorting;
|
|
var loadedSortingState = this.loadSortingState();
|
|
var sortingColumn = void 0;
|
|
var sortingOrder = void 0;
|
|
|
|
if (typeof loadedSortingState === 'undefined') {
|
|
sortingColumn = sortingSettings.column;
|
|
sortingOrder = sortingSettings.sortOrder;
|
|
} else {
|
|
sortingColumn = loadedSortingState.sortColumn;
|
|
sortingOrder = loadedSortingState.sortOrder;
|
|
}
|
|
if (typeof sortingColumn === 'number') {
|
|
this.lastSortedColumn = sortingColumn;
|
|
this.sortByColumn(sortingColumn, sortingOrder);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set sorted column and order info
|
|
*
|
|
* @param {number} col Sorted visual column index.
|
|
* @param {boolean|undefined} order Sorting order (`true` for ascending, `false` for descending).
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSortingColumn',
|
|
value: function setSortingColumn(col, order) {
|
|
if (typeof col == 'undefined') {
|
|
this.hot.sortColumn = void 0;
|
|
this.hot.sortOrder = void 0;
|
|
|
|
return;
|
|
} else if (this.hot.sortColumn === col && typeof order == 'undefined') {
|
|
if (this.hot.sortOrder === false) {
|
|
this.hot.sortOrder = void 0;
|
|
} else {
|
|
this.hot.sortOrder = !this.hot.sortOrder;
|
|
}
|
|
} else {
|
|
this.hot.sortOrder = typeof order === 'undefined' ? true : order;
|
|
}
|
|
|
|
this.hot.sortColumn = col;
|
|
}
|
|
}, {
|
|
key: 'sortByColumn',
|
|
value: function sortByColumn(col, order) {
|
|
this.setSortingColumn(col, order);
|
|
|
|
if (typeof this.hot.sortColumn == 'undefined') {
|
|
return;
|
|
}
|
|
|
|
var allowSorting = this.hot.runHooks('beforeColumnSort', this.hot.sortColumn, this.hot.sortOrder);
|
|
|
|
if (allowSorting !== false) {
|
|
this.sort();
|
|
}
|
|
this.updateOrderClass();
|
|
this.updateSortIndicator();
|
|
|
|
this.hot.runHooks('afterColumnSort', this.hot.sortColumn, this.hot.sortOrder);
|
|
|
|
this.hot.render();
|
|
this.saveSortingState();
|
|
}
|
|
|
|
/**
|
|
* Save the sorting state
|
|
*/
|
|
|
|
}, {
|
|
key: 'saveSortingState',
|
|
value: function saveSortingState() {
|
|
var sortingState = {};
|
|
|
|
if (typeof this.hot.sortColumn != 'undefined') {
|
|
sortingState.sortColumn = this.hot.sortColumn;
|
|
}
|
|
|
|
if (typeof this.hot.sortOrder != 'undefined') {
|
|
sortingState.sortOrder = this.hot.sortOrder;
|
|
}
|
|
|
|
if ((0, _object.hasOwnProperty)(sortingState, 'sortColumn') || (0, _object.hasOwnProperty)(sortingState, 'sortOrder')) {
|
|
this.hot.runHooks('persistentStateSave', 'columnSorting', sortingState);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load the sorting state.
|
|
*
|
|
* @returns {*} Previously saved sorting state.
|
|
*/
|
|
|
|
}, {
|
|
key: 'loadSortingState',
|
|
value: function loadSortingState() {
|
|
var storedState = {};
|
|
this.hot.runHooks('persistentStateLoad', 'columnSorting', storedState);
|
|
|
|
return storedState.value;
|
|
}
|
|
|
|
/**
|
|
* Update sorting class name state.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updateOrderClass',
|
|
value: function updateOrderClass() {
|
|
var orderClass = void 0;
|
|
|
|
if (this.hot.sortOrder === true) {
|
|
orderClass = 'ascending';
|
|
} else if (this.hot.sortOrder === false) {
|
|
orderClass = 'descending';
|
|
}
|
|
this.sortOrderClass = orderClass;
|
|
}
|
|
}, {
|
|
key: 'enableObserveChangesPlugin',
|
|
value: function enableObserveChangesPlugin() {
|
|
var _this = this;
|
|
|
|
this.hot._registerTimeout(setTimeout(function () {
|
|
_this.hot.updateSettings({
|
|
observeChanges: true
|
|
});
|
|
}, 0));
|
|
}
|
|
|
|
/**
|
|
* Default sorting algorithm.
|
|
*
|
|
* @param {Boolean} sortOrder Sorting order - `true` for ascending, `false` for descending.
|
|
* @param {Object} columnMeta Column meta object.
|
|
* @returns {Function} The comparing function.
|
|
*/
|
|
|
|
}, {
|
|
key: 'defaultSort',
|
|
value: function defaultSort(sortOrder, columnMeta) {
|
|
return function (a, b) {
|
|
if (typeof a[1] == 'string') {
|
|
a[1] = a[1].toLowerCase();
|
|
}
|
|
if (typeof b[1] == 'string') {
|
|
b[1] = b[1].toLowerCase();
|
|
}
|
|
|
|
if (a[1] === b[1]) {
|
|
return 0;
|
|
}
|
|
|
|
if ((0, _mixed.isEmpty)(a[1])) {
|
|
if ((0, _mixed.isEmpty)(b[1])) {
|
|
return 0;
|
|
}
|
|
|
|
if (columnMeta.columnSorting.sortEmptyCells) {
|
|
return sortOrder ? -1 : 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
if ((0, _mixed.isEmpty)(b[1])) {
|
|
if ((0, _mixed.isEmpty)(a[1])) {
|
|
return 0;
|
|
}
|
|
|
|
if (columnMeta.columnSorting.sortEmptyCells) {
|
|
return sortOrder ? 1 : -1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
if (isNaN(a[1]) && !isNaN(b[1])) {
|
|
return sortOrder ? 1 : -1;
|
|
} else if (!isNaN(a[1]) && isNaN(b[1])) {
|
|
return sortOrder ? -1 : 1;
|
|
} else if (!(isNaN(a[1]) || isNaN(b[1]))) {
|
|
a[1] = parseFloat(a[1]);
|
|
b[1] = parseFloat(b[1]);
|
|
}
|
|
if (a[1] < b[1]) {
|
|
return sortOrder ? -1 : 1;
|
|
}
|
|
if (a[1] > b[1]) {
|
|
return sortOrder ? 1 : -1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Date sorting algorithm
|
|
* @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending).
|
|
* @param {Object} columnMeta Column meta object.
|
|
* @returns {Function} The compare function.
|
|
*/
|
|
|
|
}, {
|
|
key: 'dateSort',
|
|
value: function dateSort(sortOrder, columnMeta) {
|
|
return function (a, b) {
|
|
if (a[1] === b[1]) {
|
|
return 0;
|
|
}
|
|
|
|
if ((0, _mixed.isEmpty)(a[1])) {
|
|
if ((0, _mixed.isEmpty)(b[1])) {
|
|
return 0;
|
|
}
|
|
|
|
if (columnMeta.columnSorting.sortEmptyCells) {
|
|
return sortOrder ? -1 : 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
if ((0, _mixed.isEmpty)(b[1])) {
|
|
if ((0, _mixed.isEmpty)(a[1])) {
|
|
return 0;
|
|
}
|
|
|
|
if (columnMeta.columnSorting.sortEmptyCells) {
|
|
return sortOrder ? 1 : -1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
var aDate = (0, _moment2.default)(a[1], columnMeta.dateFormat);
|
|
var bDate = (0, _moment2.default)(b[1], columnMeta.dateFormat);
|
|
|
|
if (!aDate.isValid()) {
|
|
return 1;
|
|
}
|
|
if (!bDate.isValid()) {
|
|
return -1;
|
|
}
|
|
|
|
if (bDate.isAfter(aDate)) {
|
|
return sortOrder ? -1 : 1;
|
|
}
|
|
if (bDate.isBefore(aDate)) {
|
|
return sortOrder ? 1 : -1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Numeric sorting algorithm.
|
|
*
|
|
* @param {Boolean} sortOrder Sorting order (`true` for ascending, `false` for descending).
|
|
* @param {Object} columnMeta Column meta object.
|
|
* @returns {Function} The compare function.
|
|
*/
|
|
|
|
}, {
|
|
key: 'numericSort',
|
|
value: function numericSort(sortOrder, columnMeta) {
|
|
return function (a, b) {
|
|
var parsedA = parseFloat(a[1]);
|
|
var parsedB = parseFloat(b[1]);
|
|
|
|
// Watch out when changing this part of code!
|
|
// Check below returns 0 (as expected) when comparing empty string, null, undefined
|
|
if (parsedA === parsedB || isNaN(parsedA) && isNaN(parsedB)) {
|
|
return 0;
|
|
}
|
|
|
|
if (columnMeta.columnSorting.sortEmptyCells) {
|
|
if ((0, _mixed.isEmpty)(a[1])) {
|
|
return sortOrder ? -1 : 1;
|
|
}
|
|
|
|
if ((0, _mixed.isEmpty)(b[1])) {
|
|
return sortOrder ? 1 : -1;
|
|
}
|
|
}
|
|
|
|
if (isNaN(parsedA)) {
|
|
return 1;
|
|
}
|
|
|
|
if (isNaN(parsedB)) {
|
|
return -1;
|
|
}
|
|
|
|
if (parsedA < parsedB) {
|
|
return sortOrder ? -1 : 1;
|
|
} else if (parsedA > parsedB) {
|
|
return sortOrder ? 1 : -1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Perform the sorting.
|
|
*/
|
|
|
|
}, {
|
|
key: 'sort',
|
|
value: function sort() {
|
|
if (typeof this.hot.sortOrder == 'undefined') {
|
|
this.hot.sortIndex.length = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn);
|
|
var emptyRows = this.hot.countEmptyRows();
|
|
var sortFunction = void 0;
|
|
var nrOfRows = void 0;
|
|
|
|
this.hot.sortingEnabled = false; // this is required by translateRow plugin hook
|
|
this.hot.sortIndex.length = 0;
|
|
|
|
if (typeof colMeta.columnSorting.sortEmptyCells === 'undefined') {
|
|
colMeta.columnSorting = { sortEmptyCells: this.sortEmptyCells };
|
|
}
|
|
|
|
if (this.hot.getSettings().maxRows === Number.POSITIVE_INFINITY) {
|
|
nrOfRows = this.hot.countRows() - this.hot.getSettings().minSpareRows;
|
|
} else {
|
|
nrOfRows = this.hot.countRows() - emptyRows;
|
|
}
|
|
|
|
for (var i = 0, ilen = nrOfRows; i < ilen; i++) {
|
|
this.hot.sortIndex.push([i, this.hot.getDataAtCell(i, this.hot.sortColumn)]);
|
|
}
|
|
|
|
if (colMeta.sortFunction) {
|
|
sortFunction = colMeta.sortFunction;
|
|
} else {
|
|
switch (colMeta.type) {
|
|
case 'date':
|
|
sortFunction = this.dateSort;
|
|
break;
|
|
case 'numeric':
|
|
sortFunction = this.numericSort;
|
|
break;
|
|
default:
|
|
sortFunction = this.defaultSort;
|
|
}
|
|
}
|
|
|
|
(0, _mergeSort2.default)(this.hot.sortIndex, sortFunction(this.hot.sortOrder, colMeta));
|
|
|
|
// Append spareRows
|
|
for (var _i = this.hot.sortIndex.length; _i < this.hot.countRows(); _i++) {
|
|
this.hot.sortIndex.push([_i, this.hot.getDataAtCell(_i, this.hot.sortColumn)]);
|
|
}
|
|
|
|
this.hot.sortingEnabled = true; // this is required by translateRow plugin hook
|
|
}
|
|
|
|
/**
|
|
* Update indicator states.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updateSortIndicator',
|
|
value: function updateSortIndicator() {
|
|
if (typeof this.hot.sortOrder == 'undefined') {
|
|
return;
|
|
}
|
|
var colMeta = this.hot.getCellMeta(0, this.hot.sortColumn);
|
|
|
|
this.sortIndicators[this.hot.sortColumn] = colMeta.sortIndicator;
|
|
}
|
|
|
|
/**
|
|
* `modifyRow` hook callback. Translates physical row index to the sorted row index.
|
|
*
|
|
* @param {Number} row Row index.
|
|
* @returns {Number} Sorted row index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'translateRow',
|
|
value: function translateRow(row) {
|
|
if (this.hot.sortingEnabled && typeof this.hot.sortOrder !== 'undefined' && this.hot.sortIndex && this.hot.sortIndex.length && this.hot.sortIndex[row]) {
|
|
return this.hot.sortIndex[row][0];
|
|
}
|
|
|
|
return row;
|
|
}
|
|
|
|
/**
|
|
* Translates sorted row index to physical row index.
|
|
*
|
|
* @param {Number} row Sorted (visual) row index.
|
|
* @returns {number} Physical row index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'untranslateRow',
|
|
value: function untranslateRow(row) {
|
|
if (this.hot.sortingEnabled && this.hot.sortIndex && this.hot.sortIndex.length) {
|
|
for (var i = 0; i < this.hot.sortIndex.length; i++) {
|
|
if (this.hot.sortIndex[i][0] == row) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* `afterGetColHeader` callback. Adds column sorting css classes to clickable headers.
|
|
*
|
|
* @private
|
|
* @param {Number} col Visual column index.
|
|
* @param {Element} TH TH HTML element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getColHeader',
|
|
value: function getColHeader(col, TH) {
|
|
if (col < 0 || !TH.parentNode) {
|
|
return false;
|
|
}
|
|
|
|
var headerLink = TH.querySelector('.colHeader');
|
|
var colspan = TH.getAttribute('colspan');
|
|
var TRs = TH.parentNode.parentNode.childNodes;
|
|
var headerLevel = Array.prototype.indexOf.call(TRs, TH.parentNode);
|
|
headerLevel -= TRs.length;
|
|
|
|
if (!headerLink) {
|
|
return;
|
|
}
|
|
|
|
if (this.hot.getSettings().columnSorting && col >= 0 && headerLevel === -1) {
|
|
(0, _element.addClass)(headerLink, 'columnSorting');
|
|
}
|
|
(0, _element.removeClass)(headerLink, 'descending');
|
|
(0, _element.removeClass)(headerLink, 'ascending');
|
|
|
|
if (this.sortIndicators[col]) {
|
|
if (col === this.hot.sortColumn) {
|
|
if (this.sortOrderClass === 'ascending') {
|
|
(0, _element.addClass)(headerLink, 'ascending');
|
|
} else if (this.sortOrderClass === 'descending') {
|
|
(0, _element.addClass)(headerLink, 'descending');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if any column is in a sorted state.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isSorted',
|
|
value: function isSorted() {
|
|
return typeof this.hot.sortColumn != 'undefined';
|
|
}
|
|
|
|
/**
|
|
* `afterCreateRow` callback. Updates the sorting state after a row have been created.
|
|
*
|
|
* @private
|
|
* @param {Number} index Visual row index.
|
|
* @param {Number} amount
|
|
*/
|
|
|
|
}, {
|
|
key: 'afterCreateRow',
|
|
value: function afterCreateRow(index, amount) {
|
|
if (!this.isSorted()) {
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < this.hot.sortIndex.length; i++) {
|
|
if (this.hot.sortIndex[i][0] >= index) {
|
|
this.hot.sortIndex[i][0] += amount;
|
|
}
|
|
}
|
|
|
|
for (var _i2 = 0; _i2 < amount; _i2++) {
|
|
this.hot.sortIndex.splice(index + _i2, 0, [index + _i2, this.hot.getSourceData()[index + _i2][this.hot.sortColumn + this.hot.colOffset()]]);
|
|
}
|
|
|
|
this.saveSortingState();
|
|
}
|
|
|
|
/**
|
|
* `afterRemoveRow` hook callback.
|
|
*
|
|
* @private
|
|
* @param {Number} index Visual row index.
|
|
* @param {Number} amount
|
|
*/
|
|
|
|
}, {
|
|
key: 'afterRemoveRow',
|
|
value: function afterRemoveRow(index, amount) {
|
|
if (!this.isSorted()) {
|
|
return;
|
|
}
|
|
var removedRows = this.hot.sortIndex.splice(index, amount);
|
|
|
|
removedRows = (0, _array.arrayMap)(removedRows, function (row) {
|
|
return row[0];
|
|
});
|
|
|
|
function countRowShift(logicalRow) {
|
|
// Todo: compare perf between reduce vs sort->each->brake
|
|
return (0, _array.arrayReduce)(removedRows, function (count, removedLogicalRow) {
|
|
if (logicalRow > removedLogicalRow) {
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}, 0);
|
|
}
|
|
|
|
this.hot.sortIndex = (0, _array.arrayMap)(this.hot.sortIndex, function (logicalRow, physicalRow) {
|
|
var rowShift = countRowShift(logicalRow[0]);
|
|
|
|
if (rowShift) {
|
|
logicalRow[0] -= rowShift;
|
|
}
|
|
|
|
return logicalRow;
|
|
});
|
|
|
|
this.saveSortingState();
|
|
}
|
|
|
|
/**
|
|
* Set options by passed settings
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPluginOptions',
|
|
value: function setPluginOptions() {
|
|
var columnSorting = this.hot.getSettings().columnSorting;
|
|
|
|
if ((typeof columnSorting === 'undefined' ? 'undefined' : _typeof(columnSorting)) === 'object') {
|
|
this.sortEmptyCells = columnSorting.sortEmptyCells || false;
|
|
} else {
|
|
this.sortEmptyCells = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* `onAfterOnCellMouseDown` hook callback.
|
|
*
|
|
* @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 (coords.row > -1) {
|
|
return;
|
|
}
|
|
|
|
if ((0, _element.hasClass)(event.realTarget, 'columnSorting')) {
|
|
// reset order state on every new column header click
|
|
if (coords.col !== this.lastSortedColumn) {
|
|
this.hot.sortOrder = true;
|
|
}
|
|
|
|
this.lastSortedColumn = coords.col;
|
|
|
|
this.sortByColumn(coords.col);
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return ColumnSorting;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('columnSorting', ColumnSorting);
|
|
|
|
exports.default = ColumnSorting;
|
|
|
|
/***/ }),
|
|
/* 330 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* Comment editor for the Comments plugin.
|
|
*
|
|
* @class CommentEditor
|
|
* @plugin Comments
|
|
*/
|
|
var CommentEditor = function () {
|
|
_createClass(CommentEditor, null, [{
|
|
key: 'CLASS_EDITOR_CONTAINER',
|
|
get: function get() {
|
|
return 'htCommentsContainer';
|
|
}
|
|
}, {
|
|
key: 'CLASS_EDITOR',
|
|
get: function get() {
|
|
return 'htComments';
|
|
}
|
|
}, {
|
|
key: 'CLASS_INPUT',
|
|
get: function get() {
|
|
return 'htCommentTextArea';
|
|
}
|
|
}, {
|
|
key: 'CLASS_CELL',
|
|
get: function get() {
|
|
return 'htCommentCell';
|
|
}
|
|
}]);
|
|
|
|
function CommentEditor() {
|
|
_classCallCheck(this, CommentEditor);
|
|
|
|
this.editor = this.createEditor();
|
|
this.editorStyle = this.editor.style;
|
|
|
|
this.hidden = true;
|
|
|
|
this.hide();
|
|
}
|
|
|
|
/**
|
|
* Set position of the comments editor according to the provided x and y coordinates.
|
|
*
|
|
* @param {Number} x X position (in pixels).
|
|
* @param {Number} y Y position (in pixels).
|
|
*/
|
|
|
|
|
|
_createClass(CommentEditor, [{
|
|
key: 'setPosition',
|
|
value: function setPosition(x, y) {
|
|
this.editorStyle.left = x + 'px';
|
|
this.editorStyle.top = y + 'px';
|
|
}
|
|
|
|
/**
|
|
* Set the editor size according to the provided arguments.
|
|
*
|
|
* @param {Number} width Width in pixels.
|
|
* @param {Number} height Height in pixels.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setSize',
|
|
value: function setSize(width, height) {
|
|
if (width && height) {
|
|
var input = this.getInputElement();
|
|
|
|
input.style.width = width + 'px';
|
|
input.style.height = height + 'px';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reset the editor size to its initial state.
|
|
*/
|
|
|
|
}, {
|
|
key: 'resetSize',
|
|
value: function resetSize() {
|
|
var input = this.getInputElement();
|
|
|
|
input.style.width = '';
|
|
input.style.height = '';
|
|
}
|
|
|
|
/**
|
|
* Set the read-only state for the comments editor.
|
|
*
|
|
* @param {Boolean} state The new read only state.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setReadOnlyState',
|
|
value: function setReadOnlyState(state) {
|
|
var input = this.getInputElement();
|
|
|
|
input.readOnly = state;
|
|
}
|
|
|
|
/**
|
|
* Show the comments editor.
|
|
*/
|
|
|
|
}, {
|
|
key: 'show',
|
|
value: function show() {
|
|
this.editorStyle.display = 'block';
|
|
this.hidden = false;
|
|
}
|
|
|
|
/**
|
|
* Hide the comments editor.
|
|
*/
|
|
|
|
}, {
|
|
key: 'hide',
|
|
value: function hide() {
|
|
this.editorStyle.display = 'none';
|
|
this.hidden = true;
|
|
}
|
|
|
|
/**
|
|
* Checks if the editor is visible.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isVisible',
|
|
value: function isVisible() {
|
|
return this.editorStyle.display === 'block';
|
|
}
|
|
|
|
/**
|
|
* Set the comment value.
|
|
*
|
|
* @param {String} [value] The value to use.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setValue',
|
|
value: function setValue() {
|
|
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
|
|
value = value || '';
|
|
this.getInputElement().value = value;
|
|
}
|
|
|
|
/**
|
|
* Get the comment value.
|
|
*
|
|
* @returns {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getValue',
|
|
value: function getValue() {
|
|
return this.getInputElement().value;
|
|
}
|
|
|
|
/**
|
|
* Checks if the comment input element is focused.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isFocused',
|
|
value: function isFocused() {
|
|
return document.activeElement === this.getInputElement();
|
|
}
|
|
|
|
/**
|
|
* Focus the comments input element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'focus',
|
|
value: function focus() {
|
|
this.getInputElement().focus();
|
|
}
|
|
|
|
/**
|
|
* Create the `textarea` to be used as a comments editor.
|
|
*
|
|
* @returns {HTMLElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createEditor',
|
|
value: function createEditor() {
|
|
var container = document.querySelector('.' + CommentEditor.CLASS_EDITOR_CONTAINER);
|
|
var editor = void 0;
|
|
var textArea = void 0;
|
|
|
|
if (!container) {
|
|
container = document.createElement('div');
|
|
(0, _element.addClass)(container, CommentEditor.CLASS_EDITOR_CONTAINER);
|
|
document.body.appendChild(container);
|
|
}
|
|
editor = document.createElement('div');
|
|
(0, _element.addClass)(editor, CommentEditor.CLASS_EDITOR);
|
|
|
|
textArea = document.createElement('textarea');
|
|
(0, _element.addClass)(textArea, CommentEditor.CLASS_INPUT);
|
|
|
|
editor.appendChild(textArea);
|
|
container.appendChild(editor);
|
|
|
|
return editor;
|
|
}
|
|
|
|
/**
|
|
* Get the input element.
|
|
*
|
|
* @returns {HTMLElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getInputElement',
|
|
value: function getInputElement() {
|
|
return this.editor.querySelector('.' + CommentEditor.CLASS_INPUT);
|
|
}
|
|
|
|
/**
|
|
* Destroy the comments editor.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.editor.parentNode.removeChild(this.editor);
|
|
this.editor = null;
|
|
this.editorStyle = null;
|
|
}
|
|
}]);
|
|
|
|
return CommentEditor;
|
|
}();
|
|
|
|
exports.default = CommentEditor;
|
|
|
|
/***/ }),
|
|
/* 331 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _commentEditor = __webpack_require__(330);
|
|
|
|
var _commentEditor2 = _interopRequireDefault(_commentEditor);
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var _displaySwitch = __webpack_require__(332);
|
|
|
|
var _displaySwitch2 = _interopRequireDefault(_displaySwitch);
|
|
|
|
__webpack_require__(412);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
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; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var privatePool = new WeakMap();
|
|
var META_COMMENT = 'comment';
|
|
var META_COMMENT_VALUE = 'value';
|
|
var META_STYLE = 'style';
|
|
var META_READONLY = 'readOnly';
|
|
|
|
/**
|
|
* @plugin Comments
|
|
*
|
|
* @description
|
|
* This plugin allows setting and managing cell comments by either an option in the context menu or with the use of the API.
|
|
*
|
|
* To enable the plugin, you'll need to set the comments property of the config object to `true`:
|
|
* ```js
|
|
* ...
|
|
* comments: true
|
|
* ...
|
|
* ```
|
|
*
|
|
* or object with extra predefined plugin config:
|
|
*
|
|
* ```js
|
|
* ...
|
|
* comments: {
|
|
* displayDelay: 1000
|
|
* }
|
|
* ...
|
|
* ```
|
|
*
|
|
* To add comments at the table initialization, define the `comment` property in the `cell` config array as in an example below.
|
|
*
|
|
* @example
|
|
*
|
|
* ```js
|
|
* ...
|
|
* var hot = new Handsontable(document.getElementById('example'), {
|
|
* date: getData(),
|
|
* comments: true,
|
|
* cell: [
|
|
* {row: 1, col: 1, comment: {value: 'Foo'}},
|
|
* {row: 2, col: 2, comment: {value: 'Bar'}}
|
|
* ]
|
|
* });
|
|
*
|
|
* // Access to the Comments plugin instance:
|
|
* var commentsPlugin = hot.getPlugin('comments');
|
|
*
|
|
* // Manage comments programmatically:
|
|
* commentsPlugin.editor.setCommentAtCell(1, 6, 'Comment contents');
|
|
* commentsPlugin.showAtCell(1, 6);
|
|
* commentsPlugin.removeCommentAtCell(1, 6);
|
|
*
|
|
* // You can also set range once and use proper methods:
|
|
* commentsPlugin.setRange({row: 1, col: 6});
|
|
* commentsPlugin.setComment('Comment contents');
|
|
* commentsPlugin.show();
|
|
* commentsPlugin.removeComment();
|
|
* ...
|
|
* ```
|
|
*/
|
|
|
|
var Comments = function (_BasePlugin) {
|
|
_inherits(Comments, _BasePlugin);
|
|
|
|
function Comments(hotInstance) {
|
|
_classCallCheck(this, Comments);
|
|
|
|
/**
|
|
* Instance of {@link CommentEditor}.
|
|
*
|
|
* @type {CommentEditor}
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (Comments.__proto__ || Object.getPrototypeOf(Comments)).call(this, hotInstance));
|
|
|
|
_this.editor = null;
|
|
/**
|
|
* Instance of {@link DisplaySwitch}.
|
|
*
|
|
* @type {DisplaySwitch}
|
|
*/
|
|
_this.displaySwitch = null;
|
|
/**
|
|
* Instance of {@link EventManager}.
|
|
*
|
|
* @private
|
|
* @type {EventManager}
|
|
*/
|
|
_this.eventManager = null;
|
|
/**
|
|
* Current cell range.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
_this.range = {};
|
|
/**
|
|
* @private
|
|
* @type {Boolean}
|
|
*/
|
|
_this.mouseDown = false;
|
|
/**
|
|
* @private
|
|
* @type {Boolean}
|
|
*/
|
|
_this.contextMenuEvent = false;
|
|
/**
|
|
* @private
|
|
* @type {*}
|
|
*/
|
|
_this.timer = null;
|
|
|
|
privatePool.set(_this, {
|
|
tempEditorDimensions: {},
|
|
cellBelowCursor: null
|
|
});
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the Handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(Comments, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return !!this.hot.getSettings().comments;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this2 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
|
|
if (!this.editor) {
|
|
this.editor = new _commentEditor2.default();
|
|
}
|
|
|
|
if (!this.eventManager) {
|
|
this.eventManager = new _eventManager2.default(this);
|
|
}
|
|
|
|
if (!this.displaySwitch) {
|
|
this.displaySwitch = new _displaySwitch2.default(this.getDisplayDelaySetting());
|
|
}
|
|
|
|
this.addHook('afterContextMenuDefaultOptions', function (options) {
|
|
return _this2.addToContextMenu(options);
|
|
});
|
|
this.addHook('afterRenderer', function (TD, row, col, prop, value, cellProperties) {
|
|
return _this2.onAfterRenderer(TD, cellProperties);
|
|
});
|
|
this.addHook('afterScrollHorizontally', function () {
|
|
return _this2.hide();
|
|
});
|
|
this.addHook('afterScrollVertically', function () {
|
|
return _this2.hide();
|
|
});
|
|
this.addHook('afterBeginEditing', function (args) {
|
|
return _this2.onAfterBeginEditing(args);
|
|
});
|
|
|
|
this.displaySwitch.addLocalHook('hide', function () {
|
|
return _this2.hide();
|
|
});
|
|
this.displaySwitch.addLocalHook('show', function (row, col) {
|
|
return _this2.showAtCell(row, col);
|
|
});
|
|
|
|
this.registerListeners();
|
|
|
|
_get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Update plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
this.disablePlugin();
|
|
this.enablePlugin();
|
|
_get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'updatePlugin', this).call(this);
|
|
|
|
this.displaySwitch.updateDelay(this.getDisplayDelaySetting());
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
_get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Register all necessary DOM listeners.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerListeners',
|
|
value: function registerListeners() {
|
|
var _this3 = this;
|
|
|
|
this.eventManager.addEventListener(document, 'mouseover', function (event) {
|
|
return _this3.onMouseOver(event);
|
|
});
|
|
this.eventManager.addEventListener(document, 'mousedown', function (event) {
|
|
return _this3.onMouseDown(event);
|
|
});
|
|
this.eventManager.addEventListener(document, 'mouseup', function (event) {
|
|
return _this3.onMouseUp(event);
|
|
});
|
|
this.eventManager.addEventListener(this.editor.getInputElement(), 'blur', function (event) {
|
|
return _this3.onEditorBlur(event);
|
|
});
|
|
this.eventManager.addEventListener(this.editor.getInputElement(), 'mousedown', function (event) {
|
|
return _this3.onEditorMouseDown(event);
|
|
});
|
|
this.eventManager.addEventListener(this.editor.getInputElement(), 'mouseup', function (event) {
|
|
return _this3.onEditorMouseUp(event);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Set current cell range to be able to use general methods like {@link Comments#setComment},
|
|
* {@link Comments#removeComment}, {@link Comments#show}.
|
|
*
|
|
* @param {Object} range Object with `from` and `to` properties, each with `row` and `col` properties.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setRange',
|
|
value: function setRange(range) {
|
|
this.range = range;
|
|
}
|
|
|
|
/**
|
|
* Clear the currently selected cell.
|
|
*/
|
|
|
|
}, {
|
|
key: 'clearRange',
|
|
value: function clearRange() {
|
|
this.range = {};
|
|
}
|
|
|
|
/**
|
|
* Check if the event target is a cell containing a comment.
|
|
*
|
|
* @param {Event} event DOM event
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'targetIsCellWithComment',
|
|
value: function targetIsCellWithComment(event) {
|
|
var closestCell = (0, _element.closest)(event.target, 'TD', 'TBODY');
|
|
|
|
return !!(closestCell && (0, _element.hasClass)(closestCell, 'htCommentCell') && (0, _element.closest)(closestCell, [this.hot.rootElement]));
|
|
}
|
|
|
|
/**
|
|
* Check if the event target is a comment textarea.
|
|
*
|
|
* @param {Event} event DOM event.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'targetIsCommentTextArea',
|
|
value: function targetIsCommentTextArea(event) {
|
|
return this.editor.getInputElement() === event.target;
|
|
}
|
|
|
|
/**
|
|
* Set a comment for a cell according to the previously set range (see {@link Comments#setRange}).
|
|
*
|
|
* @param {String} value Comment contents.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setComment',
|
|
value: function setComment(value) {
|
|
if (!this.range.from) {
|
|
throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())');
|
|
}
|
|
var editorValue = this.editor.getValue();
|
|
var comment = '';
|
|
|
|
if (value != null) {
|
|
comment = value;
|
|
} else if (editorValue != null) {
|
|
comment = editorValue;
|
|
}
|
|
|
|
var row = this.range.from.row;
|
|
var col = this.range.from.col;
|
|
|
|
this.updateCommentMeta(row, col, _defineProperty({}, META_COMMENT_VALUE, comment));
|
|
this.hot.render();
|
|
}
|
|
|
|
/**
|
|
* Set a comment for a cell.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {String} value Comment contents.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setCommentAtCell',
|
|
value: function setCommentAtCell(row, col, value) {
|
|
this.setRange({
|
|
from: new _src.CellCoords(row, col)
|
|
});
|
|
this.setComment(value);
|
|
}
|
|
|
|
/**
|
|
* Remove a comment from a cell according to previously set range (see {@link Comments#setRange}).
|
|
*
|
|
* @param {Boolean} [forceRender = true] If set to `true`, the table will be re-rendered at the end of the operation.
|
|
*/
|
|
|
|
}, {
|
|
key: 'removeComment',
|
|
value: function removeComment() {
|
|
var forceRender = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
|
|
if (!this.range.from) {
|
|
throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())');
|
|
}
|
|
|
|
this.hot.setCellMeta(this.range.from.row, this.range.from.col, META_COMMENT, void 0);
|
|
|
|
if (forceRender) {
|
|
this.hot.render();
|
|
}
|
|
|
|
this.hide();
|
|
}
|
|
|
|
/**
|
|
* Remove comment from a cell.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param {Boolean} [forceRender = true] If `true`, the table will be re-rendered at the end of the operation.
|
|
*/
|
|
|
|
}, {
|
|
key: 'removeCommentAtCell',
|
|
value: function removeCommentAtCell(row, col) {
|
|
var forceRender = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
|
|
this.setRange({
|
|
from: new _src.CellCoords(row, col)
|
|
});
|
|
this.removeComment(forceRender);
|
|
}
|
|
|
|
/**
|
|
* Get comment from a cell at the predefined range.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getComment',
|
|
value: function getComment() {
|
|
var row = this.range.from.row;
|
|
var column = this.range.from.col;
|
|
|
|
return this.getCommentMeta(row, column, META_COMMENT_VALUE);
|
|
}
|
|
|
|
/**
|
|
* Get comment from a cell at the provided coordinates.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} column Visual column index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCommentAtCell',
|
|
value: function getCommentAtCell(row, column) {
|
|
return this.getCommentMeta(row, column, META_COMMENT_VALUE);
|
|
}
|
|
|
|
/**
|
|
* Show the comment editor accordingly to the previously set range (see {@link Comments#setRange}).
|
|
*
|
|
* @returns {Boolean} Returns `true` if comment editor was shown.
|
|
*/
|
|
|
|
}, {
|
|
key: 'show',
|
|
value: function show() {
|
|
if (!this.range.from) {
|
|
throw new Error('Before using this method, first set cell range (hot.getPlugin("comment").setRange())');
|
|
}
|
|
var meta = this.hot.getCellMeta(this.range.from.row, this.range.from.col);
|
|
|
|
this.refreshEditor(true);
|
|
this.editor.setValue(meta[META_COMMENT] ? meta[META_COMMENT][META_COMMENT_VALUE] : null || '');
|
|
|
|
if (this.editor.hidden) {
|
|
this.editor.show();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Show comment editor according to cell coordinates.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Boolean} Returns `true` if comment editor was shown.
|
|
*/
|
|
|
|
}, {
|
|
key: 'showAtCell',
|
|
value: function showAtCell(row, col) {
|
|
this.setRange({
|
|
from: new _src.CellCoords(row, col)
|
|
});
|
|
|
|
return this.show();
|
|
}
|
|
|
|
/**
|
|
* Hide the comment editor.
|
|
*/
|
|
|
|
}, {
|
|
key: 'hide',
|
|
value: function hide() {
|
|
if (!this.editor.hidden) {
|
|
this.editor.hide();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refresh comment editor position and styling.
|
|
*
|
|
* @param {Boolean} [force=false] If `true` then recalculation will be forced.
|
|
*/
|
|
|
|
}, {
|
|
key: 'refreshEditor',
|
|
value: function refreshEditor() {
|
|
var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
if (!force && (!this.range.from || !this.editor.isVisible())) {
|
|
return;
|
|
}
|
|
var scrollableElement = (0, _element.getScrollableElement)(this.hot.view.wt.wtTable.TABLE);
|
|
var TD = this.hot.view.wt.wtTable.getCell(this.range.from);
|
|
var row = this.range.from.row;
|
|
var column = this.range.from.col;
|
|
var cellOffset = (0, _element.offset)(TD);
|
|
var lastColWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(column);
|
|
var cellTopOffset = cellOffset.top < 0 ? 0 : cellOffset.top;
|
|
var cellLeftOffset = cellOffset.left;
|
|
|
|
if (this.hot.view.wt.wtViewport.hasVerticalScroll() && scrollableElement !== window) {
|
|
cellTopOffset -= this.hot.view.wt.wtOverlays.topOverlay.getScrollPosition();
|
|
}
|
|
|
|
if (this.hot.view.wt.wtViewport.hasHorizontalScroll() && scrollableElement !== window) {
|
|
cellLeftOffset -= this.hot.view.wt.wtOverlays.leftOverlay.getScrollPosition();
|
|
}
|
|
|
|
var x = cellLeftOffset + lastColWidth;
|
|
var y = cellTopOffset;
|
|
|
|
var commentStyle = this.getCommentMeta(row, column, META_STYLE);
|
|
var readOnly = this.getCommentMeta(row, column, META_READONLY);
|
|
|
|
if (commentStyle) {
|
|
this.editor.setSize(commentStyle.width, commentStyle.height);
|
|
} else {
|
|
this.editor.resetSize();
|
|
}
|
|
|
|
this.editor.setReadOnlyState(readOnly);
|
|
|
|
this.editor.setPosition(x, y);
|
|
}
|
|
|
|
/**
|
|
* Check if there is a comment for selected range.
|
|
*
|
|
* @private
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'checkSelectionCommentsConsistency',
|
|
value: function checkSelectionCommentsConsistency() {
|
|
var selected = this.hot.getSelectedRange();
|
|
|
|
if (!selected) {
|
|
return false;
|
|
}
|
|
var hasComment = false;
|
|
var cell = selected.from; // IN EXCEL THERE IS COMMENT ONLY FOR TOP LEFT CELL IN SELECTION
|
|
|
|
if (this.getCommentMeta(cell.row, cell.col, META_COMMENT_VALUE)) {
|
|
hasComment = true;
|
|
}
|
|
|
|
return hasComment;
|
|
}
|
|
|
|
/**
|
|
* Set or update the comment-related cell meta.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} column Visual column index.
|
|
* @param {Object} metaObject Object defining all the comment-related meta information.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updateCommentMeta',
|
|
value: function updateCommentMeta(row, column, metaObject) {
|
|
var oldComment = this.hot.getCellMeta(row, column)[META_COMMENT];
|
|
var newComment = void 0;
|
|
|
|
if (oldComment) {
|
|
newComment = (0, _object.deepClone)(oldComment);
|
|
(0, _object.deepExtend)(newComment, metaObject);
|
|
} else {
|
|
newComment = metaObject;
|
|
}
|
|
|
|
this.hot.setCellMeta(row, column, META_COMMENT, newComment);
|
|
}
|
|
|
|
/**
|
|
* Get the comment related meta information.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} column Visual column index.
|
|
* @param {String} property Cell meta property.
|
|
* @returns {Mixed}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getCommentMeta',
|
|
value: function getCommentMeta(row, column, property) {
|
|
var cellMeta = this.hot.getCellMeta(row, column);
|
|
|
|
if (!cellMeta[META_COMMENT]) {
|
|
return void 0;
|
|
}
|
|
|
|
return cellMeta[META_COMMENT][property];
|
|
}
|
|
|
|
/**
|
|
* `mousedown` event callback.
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} event The `mousedown` event.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseDown',
|
|
value: function onMouseDown(event) {
|
|
this.mouseDown = true;
|
|
|
|
if (!this.hot.view || !this.hot.view.wt) {
|
|
return;
|
|
}
|
|
|
|
if (!this.contextMenuEvent && !this.targetIsCommentTextArea(event)) {
|
|
var eventCell = (0, _element.closest)(event.target, 'TD', 'TBODY');
|
|
var coordinates = null;
|
|
|
|
if (eventCell) {
|
|
coordinates = this.hot.view.wt.wtTable.getCoords(eventCell);
|
|
}
|
|
|
|
if (!eventCell || this.range.from && coordinates && (this.range.from.row !== coordinates.row || this.range.from.col !== coordinates.col)) {
|
|
this.hide();
|
|
}
|
|
}
|
|
this.contextMenuEvent = false;
|
|
}
|
|
|
|
/**
|
|
* `mouseover` event callback.
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} event The `mouseover` event.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseOver',
|
|
value: function onMouseOver(event) {
|
|
var priv = privatePool.get(this);
|
|
|
|
priv.cellBelowCursor = document.elementFromPoint(event.clientX, event.clientY);
|
|
|
|
if (this.mouseDown || this.editor.isFocused() || (0, _element.hasClass)(event.target, 'wtBorder') || priv.cellBelowCursor !== event.target || !this.editor) {
|
|
return;
|
|
}
|
|
|
|
if (this.targetIsCellWithComment(event)) {
|
|
var coordinates = this.hot.view.wt.wtTable.getCoords(event.target);
|
|
var range = {
|
|
from: new _src.CellCoords(coordinates.row, coordinates.col)
|
|
};
|
|
|
|
this.displaySwitch.show(range);
|
|
} else if ((0, _element.isChildOf)(event.target, document) && !this.targetIsCommentTextArea(event)) {
|
|
this.displaySwitch.hide();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* `mouseup` event callback.
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} event The `mouseup` event.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseUp',
|
|
value: function onMouseUp(event) {
|
|
this.mouseDown = false;
|
|
}
|
|
|
|
/** *
|
|
* The `afterRenderer` hook callback..
|
|
*
|
|
* @private
|
|
* @param {HTMLTableCellElement} TD The rendered `TD` element.
|
|
* @param {Object} cellProperties The rendered cell's property object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterRenderer',
|
|
value: function onAfterRenderer(TD, cellProperties) {
|
|
if (cellProperties[META_COMMENT] && cellProperties[META_COMMENT][META_COMMENT_VALUE]) {
|
|
(0, _element.addClass)(TD, cellProperties.commentedCellClassName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* `blur` event callback for the comment editor.
|
|
*
|
|
* @private
|
|
* @param {Event} event The `blur` event.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onEditorBlur',
|
|
value: function onEditorBlur(event) {
|
|
this.setComment();
|
|
}
|
|
|
|
/**
|
|
* `mousedown` hook. Along with `onEditorMouseUp` used to simulate the textarea resizing event.
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} event The `mousedown` event.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onEditorMouseDown',
|
|
value: function onEditorMouseDown(event) {
|
|
var priv = privatePool.get(this);
|
|
|
|
priv.tempEditorDimensions = {
|
|
width: (0, _element.outerWidth)(event.target),
|
|
height: (0, _element.outerHeight)(event.target)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* `mouseup` hook. Along with `onEditorMouseDown` used to simulate the textarea resizing event.
|
|
*
|
|
* @private
|
|
* @param {MouseEvent} event The `mouseup` event.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onEditorMouseUp',
|
|
value: function onEditorMouseUp(event) {
|
|
var priv = privatePool.get(this);
|
|
var currentWidth = (0, _element.outerWidth)(event.target);
|
|
var currentHeight = (0, _element.outerHeight)(event.target);
|
|
|
|
if (currentWidth !== priv.tempEditorDimensions.width + 1 || currentHeight !== priv.tempEditorDimensions.height + 2) {
|
|
this.updateCommentMeta(this.range.from.row, this.range.from.col, _defineProperty({}, META_STYLE, {
|
|
width: currentWidth,
|
|
height: currentHeight
|
|
}));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Context Menu's "Add comment" callback. Results in showing the comment editor.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onContextMenuAddComment',
|
|
value: function onContextMenuAddComment() {
|
|
var _this4 = this;
|
|
|
|
this.displaySwitch.cancelHiding();
|
|
var coords = this.hot.getSelectedRange();
|
|
|
|
this.contextMenuEvent = true;
|
|
this.setRange({
|
|
from: coords.from
|
|
});
|
|
this.show();
|
|
setTimeout(function () {
|
|
if (_this4.hot) {
|
|
_this4.hot.deselectCell();
|
|
_this4.editor.focus();
|
|
}
|
|
}, 10);
|
|
}
|
|
|
|
/**
|
|
* Context Menu's "remove comment" callback.
|
|
*
|
|
* @private
|
|
* @param {Object} selection The current selection.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onContextMenuRemoveComment',
|
|
value: function onContextMenuRemoveComment(selection) {
|
|
this.contextMenuEvent = true;
|
|
|
|
for (var i = selection.start.row; i <= selection.end.row; i++) {
|
|
for (var j = selection.start.col; j <= selection.end.col; j++) {
|
|
this.removeCommentAtCell(i, j, false);
|
|
}
|
|
}
|
|
|
|
this.hot.render();
|
|
}
|
|
|
|
/**
|
|
* Context Menu's "make comment read-only" callback.
|
|
*
|
|
* @private
|
|
* @param {Object} selection The current selection.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onContextMenuMakeReadOnly',
|
|
value: function onContextMenuMakeReadOnly(selection) {
|
|
this.contextMenuEvent = true;
|
|
|
|
for (var i = selection.start.row; i <= selection.end.row; i++) {
|
|
for (var j = selection.start.col; j <= selection.end.col; j++) {
|
|
var currentState = !!this.getCommentMeta(i, j, META_READONLY);
|
|
|
|
this.updateCommentMeta(i, j, _defineProperty({}, META_READONLY, !currentState));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add Comments plugin options to the Context Menu.
|
|
*
|
|
* @private
|
|
* @param {Object} defaultOptions
|
|
*/
|
|
|
|
}, {
|
|
key: 'addToContextMenu',
|
|
value: function addToContextMenu(defaultOptions) {
|
|
var _this5 = this;
|
|
|
|
defaultOptions.items.push({
|
|
name: '---------'
|
|
}, {
|
|
key: 'commentsAddEdit',
|
|
name: function name() {
|
|
return _this5.checkSelectionCommentsConsistency() ? 'Edit comment' : 'Add comment';
|
|
},
|
|
callback: function callback() {
|
|
return _this5.onContextMenuAddComment();
|
|
},
|
|
disabled: function disabled() {
|
|
return !(this.getSelected() && !this.selection.selectedHeader.corner);
|
|
}
|
|
}, {
|
|
key: 'commentsRemove',
|
|
name: function name() {
|
|
return 'Delete comment';
|
|
},
|
|
|
|
callback: function callback(key, selection) {
|
|
return _this5.onContextMenuRemoveComment(selection);
|
|
},
|
|
disabled: function disabled() {
|
|
return _this5.hot.selection.selectedHeader.corner;
|
|
}
|
|
}, {
|
|
key: 'commentsReadOnly',
|
|
name: function name() {
|
|
var _this6 = this;
|
|
|
|
var label = 'Read only comment';
|
|
var hasProperty = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var readOnlyProperty = _this6.getCellMeta(row, col)[META_COMMENT];
|
|
if (readOnlyProperty) {
|
|
readOnlyProperty = readOnlyProperty[META_READONLY];
|
|
}
|
|
|
|
if (readOnlyProperty) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasProperty) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
|
|
callback: function callback(key, selection) {
|
|
return _this5.onContextMenuMakeReadOnly(selection);
|
|
},
|
|
disabled: function disabled() {
|
|
return _this5.hot.selection.selectedHeader.corner || !_this5.checkSelectionCommentsConsistency();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get `displayDelay` setting of comment plugin.
|
|
*
|
|
* @returns {Number|undefined}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getDisplayDelaySetting',
|
|
value: function getDisplayDelaySetting() {
|
|
var commentSetting = this.hot.getSettings().comments;
|
|
|
|
if ((0, _object.isObject)(commentSetting)) {
|
|
return commentSetting.displayDelay;
|
|
}
|
|
|
|
return void 0;
|
|
}
|
|
|
|
/**
|
|
* `afterBeginEditing` hook callback.
|
|
*
|
|
* @private
|
|
* @param {Number} row Visual row index of the currently edited cell.
|
|
* @param {Number} column Visual column index of the currently edited cell.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterBeginEditing',
|
|
value: function onAfterBeginEditing(row, column) {
|
|
this.hide();
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
if (this.editor) {
|
|
this.editor.destroy();
|
|
}
|
|
|
|
if (this.displaySwitch) {
|
|
this.displaySwitch.destroy();
|
|
}
|
|
|
|
_get(Comments.prototype.__proto__ || Object.getPrototypeOf(Comments.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return Comments;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('comments', Comments);
|
|
|
|
exports.default = Comments;
|
|
|
|
/***/ }),
|
|
/* 332 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _function = __webpack_require__(35);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _localHooks = __webpack_require__(70);
|
|
|
|
var _localHooks2 = _interopRequireDefault(_localHooks);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var DEFAULT_DISPLAY_DELAY = 250;
|
|
var DEFAULT_HIDE_DELAY = 250;
|
|
|
|
/**
|
|
* Display switch for the Comments plugin. Manages the time of delayed displaying / hiding comments.
|
|
*
|
|
* @class DisplaySwitch
|
|
* @plugin Comments
|
|
*/
|
|
|
|
var DisplaySwitch = function () {
|
|
function DisplaySwitch(displayDelay) {
|
|
_classCallCheck(this, DisplaySwitch);
|
|
|
|
/**
|
|
* Flag to determine if comment can be showed or hidden. State `true` mean that last performed action
|
|
* was an attempt to show comment element. State `false` mean that it was attempt to hide comment element.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
this.wasLastActionShow = true;
|
|
/**
|
|
* Show comment after predefined delay. It keeps reference to immutable `debounce` function.
|
|
*
|
|
* @type {Function}
|
|
*/
|
|
this.showDebounced = null;
|
|
/**
|
|
* Reference to timer, run by `setTimeout`, which is hiding comment
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
this.hidingTimer = null;
|
|
|
|
this.updateDelay(displayDelay);
|
|
}
|
|
|
|
/**
|
|
* Responsible for hiding comment after proper delay.
|
|
*/
|
|
|
|
|
|
_createClass(DisplaySwitch, [{
|
|
key: 'hide',
|
|
value: function hide() {
|
|
var _this = this;
|
|
|
|
this.wasLastActionShow = false;
|
|
|
|
this.hidingTimer = setTimeout(function () {
|
|
if (_this.wasLastActionShow === false) {
|
|
_this.runLocalHooks('hide');
|
|
}
|
|
}, DEFAULT_HIDE_DELAY);
|
|
}
|
|
|
|
/**
|
|
* Responsible for showing comment after proper delay.
|
|
*
|
|
* @param {Object} range Coordinates of selected cell.
|
|
*/
|
|
|
|
}, {
|
|
key: 'show',
|
|
value: function show(range) {
|
|
this.wasLastActionShow = true;
|
|
this.showDebounced(range);
|
|
}
|
|
}, {
|
|
key: 'cancelHiding',
|
|
|
|
|
|
/**
|
|
* Cancel hiding comment.
|
|
*/
|
|
value: function cancelHiding() {
|
|
this.wasLastActionShow = true;
|
|
|
|
clearTimeout(this.hidingTimer);
|
|
this.hidingTimer = null;
|
|
}
|
|
|
|
/**
|
|
* Update the switch settings.
|
|
*
|
|
* @param {Number} displayDelay Delay of showing the comments (in milliseconds).
|
|
*/
|
|
|
|
}, {
|
|
key: 'updateDelay',
|
|
value: function updateDelay() {
|
|
var _this2 = this;
|
|
|
|
var displayDelay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_DISPLAY_DELAY;
|
|
|
|
this.showDebounced = (0, _function.debounce)(function (range) {
|
|
if (_this2.wasLastActionShow) {
|
|
_this2.runLocalHooks('show', range.from.row, range.from.col);
|
|
}
|
|
}, displayDelay);
|
|
}
|
|
|
|
/**
|
|
* Destroy the switcher.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.clearLocalHooks();
|
|
}
|
|
}]);
|
|
|
|
return DisplaySwitch;
|
|
}();
|
|
|
|
(0, _object.mixin)(DisplaySwitch, _localHooks2.default);
|
|
|
|
exports.default = DisplaySwitch;
|
|
|
|
/***/ }),
|
|
/* 333 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* Command executor for ContextMenu.
|
|
*
|
|
* @class CommandExecutor
|
|
* @plugin ContextMenu
|
|
*/
|
|
var CommandExecutor = function () {
|
|
function CommandExecutor(hotInstance) {
|
|
_classCallCheck(this, CommandExecutor);
|
|
|
|
this.hot = hotInstance;
|
|
this.commands = {};
|
|
this.commonCallback = null;
|
|
}
|
|
|
|
/**
|
|
* Register command.
|
|
*
|
|
* @param {String} name Command name.
|
|
* @param {Object} commandDescriptor Command descriptor object with properties like `key` (command id),
|
|
* `callback` (task to execute), `name` (command name), `disabled` (command availability).
|
|
*/
|
|
|
|
|
|
_createClass(CommandExecutor, [{
|
|
key: 'registerCommand',
|
|
value: function registerCommand(name, commandDescriptor) {
|
|
this.commands[name] = commandDescriptor;
|
|
}
|
|
|
|
/**
|
|
* Set common callback which will be trigger on every executed command.
|
|
*
|
|
* @param {Function} callback Function which will be fired on every command execute.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setCommonCallback',
|
|
value: function setCommonCallback(callback) {
|
|
this.commonCallback = callback;
|
|
}
|
|
|
|
/**
|
|
* Execute command by its name.
|
|
*
|
|
* @param {String} commandName Command id.
|
|
* @param {*} params Arguments passed to command task.
|
|
*/
|
|
|
|
}, {
|
|
key: 'execute',
|
|
value: function execute(commandName) {
|
|
var _this = this;
|
|
|
|
for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
params[_key - 1] = arguments[_key];
|
|
}
|
|
|
|
var commandSplit = commandName.split(':');
|
|
commandName = commandSplit[0];
|
|
|
|
var subCommandName = commandSplit.length === 2 ? commandSplit[1] : null;
|
|
var command = this.commands[commandName];
|
|
|
|
if (!command) {
|
|
throw new Error('Menu command \'' + commandName + '\' not exists.');
|
|
}
|
|
if (subCommandName && command.submenu) {
|
|
command = findSubCommand(subCommandName, command.submenu.items);
|
|
}
|
|
if (command.disabled === true) {
|
|
return;
|
|
}
|
|
if (typeof command.disabled == 'function' && command.disabled.call(this.hot) === true) {
|
|
return;
|
|
}
|
|
if ((0, _object.hasOwnProperty)(command, 'submenu')) {
|
|
return;
|
|
}
|
|
var callbacks = [];
|
|
|
|
if (typeof command.callback === 'function') {
|
|
callbacks.push(command.callback);
|
|
}
|
|
if (typeof this.commonCallback === 'function') {
|
|
callbacks.push(this.commonCallback);
|
|
}
|
|
params.unshift(commandSplit.join(':'));
|
|
(0, _array.arrayEach)(callbacks, function (callback) {
|
|
return callback.apply(_this.hot, params);
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return CommandExecutor;
|
|
}();
|
|
|
|
function findSubCommand(subCommandName, subCommands) {
|
|
var command = void 0;
|
|
|
|
(0, _array.arrayEach)(subCommands, function (cmd) {
|
|
var cmds = cmd.key ? cmd.key.split(':') : null;
|
|
|
|
if (Array.isArray(cmds) && cmds[1] === subCommandName) {
|
|
command = cmd;
|
|
|
|
return false;
|
|
}
|
|
});
|
|
|
|
return command;
|
|
}
|
|
|
|
exports.default = CommandExecutor;
|
|
|
|
/***/ }),
|
|
/* 334 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _commandExecutor = __webpack_require__(333);
|
|
|
|
var _commandExecutor2 = _interopRequireDefault(_commandExecutor);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _itemsFactory = __webpack_require__(336);
|
|
|
|
var _itemsFactory2 = _interopRequireDefault(_itemsFactory);
|
|
|
|
var _menu = __webpack_require__(337);
|
|
|
|
var _menu2 = _interopRequireDefault(_menu);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _predefinedItems = __webpack_require__(71);
|
|
|
|
__webpack_require__(413);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
_pluginHooks2.default.getSingleton().register('afterContextMenuDefaultOptions');
|
|
_pluginHooks2.default.getSingleton().register('afterContextMenuShow');
|
|
_pluginHooks2.default.getSingleton().register('afterContextMenuHide');
|
|
_pluginHooks2.default.getSingleton().register('afterContextMenuExecute');
|
|
|
|
/**
|
|
* @description
|
|
* This plugin creates the Handsontable Context 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 context menu demo](http://docs.handsontable.com/demo-context-menu.html) for examples.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* // as a boolean
|
|
* contextMenu: true
|
|
* ...
|
|
* // as a array
|
|
* contextMenu: ['row_above', 'row_below', '---------', 'undo', 'redo']
|
|
* ...
|
|
* ```
|
|
*
|
|
* @plugin ContextMenu
|
|
*/
|
|
|
|
var ContextMenu = function (_BasePlugin) {
|
|
_inherits(ContextMenu, _BasePlugin);
|
|
|
|
_createClass(ContextMenu, null, [{
|
|
key: 'DEFAULT_ITEMS',
|
|
|
|
/**
|
|
* Default menu items order when `contextMenu` is enabled by `true`.
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
get: function get() {
|
|
return [_predefinedItems.ROW_ABOVE, _predefinedItems.ROW_BELOW, _predefinedItems.SEPARATOR, _predefinedItems.COLUMN_LEFT, _predefinedItems.COLUMN_RIGHT, _predefinedItems.SEPARATOR, _predefinedItems.REMOVE_ROW, _predefinedItems.REMOVE_COLUMN, _predefinedItems.SEPARATOR, _predefinedItems.UNDO, _predefinedItems.REDO, _predefinedItems.SEPARATOR, _predefinedItems.READ_ONLY, _predefinedItems.SEPARATOR, _predefinedItems.ALIGNMENT];
|
|
}
|
|
}]);
|
|
|
|
function ContextMenu(hotInstance) {
|
|
_classCallCheck(this, ContextMenu);
|
|
|
|
/**
|
|
* Instance of {@link EventManager}.
|
|
*
|
|
* @type {EventManager}
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (ContextMenu.__proto__ || Object.getPrototypeOf(ContextMenu)).call(this, hotInstance));
|
|
|
|
_this.eventManager = new _eventManager2.default(_this);
|
|
/**
|
|
* Instance of {@link CommandExecutor}.
|
|
*
|
|
* @type {CommandExecutor}
|
|
*/
|
|
_this.commandExecutor = new _commandExecutor2.default(_this.hot);
|
|
/**
|
|
* Instance of {@link ItemsFactory}.
|
|
*
|
|
* @type {ItemsFactory}
|
|
*/
|
|
_this.itemsFactory = null;
|
|
/**
|
|
* Instance of {@link Menu}.
|
|
*
|
|
* @type {Menu}
|
|
*/
|
|
_this.menu = null;
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the Handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ContextMenu, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return this.hot.getSettings().contextMenu;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this2 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
this.itemsFactory = new _itemsFactory2.default(this.hot, ContextMenu.DEFAULT_ITEMS);
|
|
|
|
var settings = this.hot.getSettings().contextMenu;
|
|
var predefinedItems = {
|
|
items: this.itemsFactory.getItems(settings)
|
|
};
|
|
this.registerEvents();
|
|
|
|
if (typeof settings.callback === 'function') {
|
|
this.commandExecutor.setCommonCallback(settings.callback);
|
|
}
|
|
_get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'enablePlugin', this).call(this);
|
|
|
|
this.callOnPluginsReady(function () {
|
|
_this2.hot.runHooks('afterContextMenuDefaultOptions', predefinedItems);
|
|
|
|
_this2.itemsFactory.setPredefinedItems(predefinedItems.items);
|
|
var menuItems = _this2.itemsFactory.getItems(settings);
|
|
|
|
_this2.menu = new _menu2.default(_this2.hot, {
|
|
className: 'htContextMenu',
|
|
keepInViewport: true
|
|
});
|
|
_this2.hot.runHooks('beforeContextMenuSetItems', menuItems);
|
|
|
|
_this2.menu.setMenuItems(menuItems);
|
|
|
|
_this2.menu.addLocalHook('afterOpen', function () {
|
|
return _this2.onMenuAfterOpen();
|
|
});
|
|
_this2.menu.addLocalHook('afterClose', function () {
|
|
return _this2.onMenuAfterClose();
|
|
});
|
|
_this2.menu.addLocalHook('executeCommand', function () {
|
|
for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
|
|
params[_key] = arguments[_key];
|
|
}
|
|
|
|
return _this2.executeCommand.apply(_this2, 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 to use the latest options you have specified.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
this.disablePlugin();
|
|
this.enablePlugin();
|
|
|
|
_get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
this.close();
|
|
|
|
if (this.menu) {
|
|
this.menu.destroy();
|
|
this.menu = null;
|
|
}
|
|
_get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Register dom listeners.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerEvents',
|
|
value: function registerEvents() {
|
|
var _this3 = this;
|
|
|
|
this.eventManager.addEventListener(this.hot.rootElement, 'contextmenu', function (event) {
|
|
return _this3.onContextMenu(event);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Open menu and re-position it based on dom event object.
|
|
*
|
|
* @param {Event} event The event object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'open',
|
|
value: function open(event) {
|
|
if (!this.menu) {
|
|
return;
|
|
}
|
|
this.menu.open();
|
|
this.menu.setPosition({
|
|
top: parseInt((0, _event.pageY)(event), 10) - (0, _element.getWindowScrollTop)(),
|
|
left: parseInt((0, _event.pageX)(event), 10) - (0, _element.getWindowScrollLeft)()
|
|
});
|
|
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* Close menu.
|
|
*/
|
|
|
|
}, {
|
|
key: 'close',
|
|
value: function close() {
|
|
if (!this.menu) {
|
|
return;
|
|
}
|
|
this.menu.close();
|
|
}
|
|
|
|
/**
|
|
* Execute context menu command.
|
|
*
|
|
* You can execute all predefined commands:
|
|
* * `'row_above'` - Insert row above
|
|
* * `'row_below'` - Insert row below
|
|
* * `'col_left'` - Insert column on the left
|
|
* * `'col_right'` - Insert column on the 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
|
|
* @param {*} params
|
|
*/
|
|
|
|
}, {
|
|
key: 'executeCommand',
|
|
value: function executeCommand() {
|
|
for (var _len2 = arguments.length, params = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
params[_key2] = arguments[_key2];
|
|
}
|
|
|
|
this.commandExecutor.execute.apply(this.commandExecutor, params);
|
|
}
|
|
|
|
/**
|
|
* On context menu listener.
|
|
*
|
|
* @private
|
|
* @param {Event} event
|
|
*/
|
|
|
|
}, {
|
|
key: 'onContextMenu',
|
|
value: function onContextMenu(event) {
|
|
var settings = this.hot.getSettings();
|
|
var showRowHeaders = settings.rowHeaders;
|
|
var showColHeaders = settings.colHeaders;
|
|
|
|
function isValidElement(element) {
|
|
return element.nodeName === 'TD' || element.parentNode.nodeName === 'TD';
|
|
}
|
|
// if event is from hot-table we must get web component element not element inside him
|
|
var element = event.realTarget;
|
|
this.close();
|
|
|
|
if ((0, _element.hasClass)(element, 'handsontableInput')) {
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
(0, _event.stopPropagation)(event);
|
|
|
|
if (!(showRowHeaders || showColHeaders)) {
|
|
if (!isValidElement(element) && !((0, _element.hasClass)(element, 'current') && (0, _element.hasClass)(element, 'wtBorder'))) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.open(event);
|
|
}
|
|
|
|
/**
|
|
* On menu after open listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMenuAfterOpen',
|
|
value: function onMenuAfterOpen() {
|
|
this.hot.runHooks('afterContextMenuShow', this);
|
|
}
|
|
|
|
/**
|
|
* On menu after close listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMenuAfterClose',
|
|
value: function onMenuAfterClose() {
|
|
this.hot.listen();
|
|
this.hot.runHooks('afterContextMenuHide', this);
|
|
}
|
|
|
|
/**
|
|
* Destroy instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.close();
|
|
|
|
if (this.menu) {
|
|
this.menu.destroy();
|
|
}
|
|
_get(ContextMenu.prototype.__proto__ || Object.getPrototypeOf(ContextMenu.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return ContextMenu;
|
|
}(_base2.default);
|
|
|
|
ContextMenu.SEPARATOR = {
|
|
name: _predefinedItems.SEPARATOR
|
|
};
|
|
|
|
(0, _plugins.registerPlugin)('contextMenu', ContextMenu);
|
|
|
|
exports.default = ContextMenu;
|
|
|
|
/***/ }),
|
|
/* 335 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* Helper class for checking if element will fit at the desired side of cursor.
|
|
*
|
|
* @class Cursor
|
|
* @plugin ContextMenu
|
|
*/
|
|
var Cursor = function () {
|
|
function Cursor(object) {
|
|
_classCallCheck(this, Cursor);
|
|
|
|
var windowScrollTop = (0, _element.getWindowScrollTop)();
|
|
var windowScrollLeft = (0, _element.getWindowScrollLeft)();
|
|
var top = void 0,
|
|
topRelative = void 0;
|
|
var left = void 0,
|
|
leftRelative = void 0;
|
|
var cellHeight = void 0,
|
|
cellWidth = void 0;
|
|
|
|
this.type = this.getSourceType(object);
|
|
|
|
if (this.type === 'literal') {
|
|
top = parseInt(object.top, 10);
|
|
left = parseInt(object.left, 10);
|
|
cellHeight = object.height || 0;
|
|
cellWidth = object.width || 0;
|
|
topRelative = top;
|
|
leftRelative = left;
|
|
top += windowScrollTop;
|
|
left += windowScrollLeft;
|
|
} else if (this.type === 'event') {
|
|
top = parseInt((0, _event.pageY)(object), 10);
|
|
left = parseInt((0, _event.pageX)(object), 10);
|
|
cellHeight = object.target.clientHeight;
|
|
cellWidth = object.target.clientWidth;
|
|
topRelative = top - windowScrollTop;
|
|
leftRelative = left - windowScrollLeft;
|
|
}
|
|
|
|
this.top = top;
|
|
this.topRelative = topRelative;
|
|
this.left = left;
|
|
this.leftRelative = leftRelative;
|
|
this.scrollTop = windowScrollTop;
|
|
this.scrollLeft = windowScrollLeft;
|
|
this.cellHeight = cellHeight;
|
|
this.cellWidth = cellWidth;
|
|
}
|
|
|
|
/**
|
|
* Get source type name.
|
|
*
|
|
* @param {*} object Event or Object with coordinates.
|
|
* @returns {String} Returns one of this values: `'literal'`, `'event'`.
|
|
*/
|
|
|
|
|
|
_createClass(Cursor, [{
|
|
key: 'getSourceType',
|
|
value: function getSourceType(object) {
|
|
var type = 'literal';
|
|
|
|
if (object instanceof Event) {
|
|
type = 'event';
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
/**
|
|
* Checks if element can be placed above the cursor.
|
|
*
|
|
* @param {HTMLElement} element Element to check if it's size will fit above the cursor.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'fitsAbove',
|
|
value: function fitsAbove(element) {
|
|
return this.topRelative >= element.offsetHeight;
|
|
}
|
|
|
|
/**
|
|
* Checks if element can be placed below the cursor.
|
|
*
|
|
* @param {HTMLElement} element Element to check if it's size will fit below the cursor.
|
|
* @param {Number} [viewportHeight] The viewport height.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'fitsBelow',
|
|
value: function fitsBelow(element) {
|
|
var viewportHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window.innerHeight;
|
|
|
|
return this.topRelative + element.offsetHeight <= viewportHeight;
|
|
}
|
|
|
|
/**
|
|
* Checks if element can be placed on the right of the cursor.
|
|
*
|
|
* @param {HTMLElement} element Element to check if it's size will fit on the right of the cursor.
|
|
* @param {Number} [viewportWidth] The viewport width.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'fitsOnRight',
|
|
value: function fitsOnRight(element) {
|
|
var viewportWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window.innerWidth;
|
|
|
|
return this.leftRelative + this.cellWidth + element.offsetWidth <= viewportWidth;
|
|
}
|
|
|
|
/**
|
|
* Checks if element can be placed on the left on the cursor.
|
|
*
|
|
* @param {HTMLElement} element Element to check if it's size will fit on the left of the cursor.
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'fitsOnLeft',
|
|
value: function fitsOnLeft(element) {
|
|
return this.leftRelative >= element.offsetWidth;
|
|
}
|
|
}]);
|
|
|
|
return Cursor;
|
|
}();
|
|
|
|
exports.default = Cursor;
|
|
|
|
/***/ }),
|
|
/* 336 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _predefinedItems = __webpack_require__(71);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* Predefined items class factory for menu items.
|
|
*
|
|
* @class ItemsFactory
|
|
* @plugin ContextMenu
|
|
*/
|
|
var ItemsFactory = function () {
|
|
function ItemsFactory(hotInstance) {
|
|
var orderPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
|
|
_classCallCheck(this, ItemsFactory);
|
|
|
|
this.hot = hotInstance;
|
|
this.predefinedItems = (0, _predefinedItems.predefinedItems)();
|
|
this.defaultOrderPattern = orderPattern;
|
|
}
|
|
|
|
/**
|
|
* Set predefined items.
|
|
*
|
|
* @param {Array} predefinedItems Array of predefined items.
|
|
*/
|
|
|
|
|
|
_createClass(ItemsFactory, [{
|
|
key: 'setPredefinedItems',
|
|
value: function setPredefinedItems(predefinedItems) {
|
|
var _this = this;
|
|
|
|
var items = {};
|
|
|
|
this.defaultOrderPattern.length = 0;
|
|
|
|
(0, _object.objectEach)(predefinedItems, function (value, key) {
|
|
var menuItemKey = '';
|
|
|
|
if (value.name === _predefinedItems.SEPARATOR) {
|
|
items[_predefinedItems.SEPARATOR] = value;
|
|
menuItemKey = _predefinedItems.SEPARATOR;
|
|
|
|
// Menu item added as a property to array
|
|
} else if (isNaN(parseInt(key, 10))) {
|
|
value.key = value.key === void 0 ? key : value.key;
|
|
items[key] = value;
|
|
menuItemKey = value.key;
|
|
} else {
|
|
items[value.key] = value;
|
|
menuItemKey = value.key;
|
|
}
|
|
_this.defaultOrderPattern.push(menuItemKey);
|
|
});
|
|
this.predefinedItems = items;
|
|
}
|
|
|
|
/**
|
|
* Get all menu items based on pattern.
|
|
*
|
|
* @param {Array|Object|Boolean} pattern Pattern which you can define by displaying menu items order. If `true` default
|
|
* pattern will be used.
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getItems',
|
|
value: function getItems() {
|
|
var pattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
|
|
return _getItems(pattern, this.defaultOrderPattern, this.predefinedItems);
|
|
}
|
|
}]);
|
|
|
|
return ItemsFactory;
|
|
}();
|
|
|
|
function _getItems() {
|
|
var pattern = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
var defaultPattern = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
var items = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
|
|
var result = [];
|
|
|
|
if (pattern && pattern.items) {
|
|
pattern = pattern.items;
|
|
} else if (!Array.isArray(pattern)) {
|
|
pattern = defaultPattern;
|
|
}
|
|
if ((0, _object.isObject)(pattern)) {
|
|
(0, _object.objectEach)(pattern, function (value, key) {
|
|
var item = items[typeof value === 'string' ? value : key];
|
|
|
|
if (!item) {
|
|
item = value;
|
|
}
|
|
if ((0, _object.isObject)(value)) {
|
|
(0, _object.extend)(item, value);
|
|
} else if (typeof item === 'string') {
|
|
item = { name: item };
|
|
}
|
|
if (item.key === void 0) {
|
|
item.key = key;
|
|
}
|
|
result.push(item);
|
|
});
|
|
} else {
|
|
(0, _array.arrayEach)(pattern, function (name, key) {
|
|
var item = items[name];
|
|
|
|
// Item deleted from settings `allowInsertRow: false` etc.
|
|
if (!item && _predefinedItems.ITEMS.indexOf(name) >= 0) {
|
|
return;
|
|
}
|
|
if (!item) {
|
|
item = { name: name, key: '' + key };
|
|
}
|
|
if ((0, _object.isObject)(name)) {
|
|
(0, _object.extend)(item, name);
|
|
}
|
|
if (item.key === void 0) {
|
|
item.key = key;
|
|
}
|
|
result.push(item);
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
exports.default = ItemsFactory;
|
|
|
|
/***/ }),
|
|
/* 337 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _core = __webpack_require__(64);
|
|
|
|
var _core2 = _interopRequireDefault(_core);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _cursor = __webpack_require__(335);
|
|
|
|
var _cursor2 = _interopRequireDefault(_cursor);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _function = __webpack_require__(35);
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _localHooks = __webpack_require__(70);
|
|
|
|
var _localHooks2 = _interopRequireDefault(_localHooks);
|
|
|
|
var _predefinedItems = __webpack_require__(71);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Menu
|
|
* @plugin ContextMenu
|
|
*/
|
|
var Menu = function () {
|
|
function Menu(hotInstance, options) {
|
|
_classCallCheck(this, Menu);
|
|
|
|
this.hot = hotInstance;
|
|
this.options = options || {
|
|
parent: null,
|
|
name: null,
|
|
className: '',
|
|
keepInViewport: true,
|
|
standalone: false
|
|
};
|
|
this.eventManager = new _eventManager2.default(this);
|
|
this.container = this.createContainer(this.options.name);
|
|
this.hotMenu = null;
|
|
this.hotSubMenus = {};
|
|
this.parentMenu = this.options.parent || null;
|
|
this.menuItems = null;
|
|
this.origOutsideClickDeselects = null;
|
|
this.keyEvent = false;
|
|
|
|
this.offset = {
|
|
above: 0,
|
|
below: 0,
|
|
left: 0,
|
|
right: 0
|
|
};
|
|
this._afterScrollCallback = null;
|
|
|
|
this.registerEvents();
|
|
}
|
|
|
|
/**
|
|
* Register event listeners.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
|
|
_createClass(Menu, [{
|
|
key: 'registerEvents',
|
|
value: function registerEvents() {
|
|
var _this = this;
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'mousedown', function (event) {
|
|
return _this.onDocumentMouseDown(event);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Set array of objects which defines menu items.
|
|
*
|
|
* @param {Array} menuItems Menu items to display.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setMenuItems',
|
|
value: function setMenuItems(menuItems) {
|
|
this.menuItems = menuItems;
|
|
}
|
|
|
|
/**
|
|
* Set offset menu position for specified area (`above`, `below`, `left` or `right`).
|
|
*
|
|
* @param {String} area Specified area name (`above`, `below`, `left` or `right`).
|
|
* @param {Number} offset Offset value.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setOffset',
|
|
value: function setOffset(area) {
|
|
var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
|
|
this.offset[area] = offset;
|
|
}
|
|
|
|
/**
|
|
* Check if menu is using as sub-menu.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isSubMenu',
|
|
value: function isSubMenu() {
|
|
return this.parentMenu !== null;
|
|
}
|
|
|
|
/**
|
|
* Open menu.
|
|
*/
|
|
|
|
}, {
|
|
key: 'open',
|
|
value: function open() {
|
|
var _this2 = this;
|
|
|
|
this.container.removeAttribute('style');
|
|
this.container.style.display = 'block';
|
|
|
|
var delayedOpenSubMenu = (0, _function.debounce)(function (row) {
|
|
return _this2.openSubMenu(row);
|
|
}, 300);
|
|
|
|
var filteredItems = (0, _array.arrayFilter)(this.menuItems, function (item) {
|
|
return (0, _utils.isItemHidden)(item, _this2.hot);
|
|
});
|
|
|
|
filteredItems = (0, _utils.filterSeparators)(filteredItems, _predefinedItems.SEPARATOR);
|
|
|
|
var settings = {
|
|
data: filteredItems,
|
|
colHeaders: false,
|
|
colWidths: [200],
|
|
autoRowSize: false,
|
|
readOnly: true,
|
|
copyPaste: false,
|
|
columns: [{
|
|
data: 'name',
|
|
renderer: function renderer(hot, TD, row, col, prop, value) {
|
|
return _this2.menuItemRenderer(hot, TD, row, col, prop, value);
|
|
}
|
|
}],
|
|
renderAllRows: true,
|
|
fragmentSelection: 'cell',
|
|
disableVisualSelection: 'area',
|
|
beforeKeyDown: function beforeKeyDown(event) {
|
|
return _this2.onBeforeKeyDown(event);
|
|
},
|
|
afterOnCellMouseOver: function afterOnCellMouseOver(event, coords, TD) {
|
|
if (_this2.isAllSubMenusClosed()) {
|
|
delayedOpenSubMenu(coords.row);
|
|
} else {
|
|
_this2.openSubMenu(coords.row);
|
|
}
|
|
},
|
|
rowHeights: function rowHeights(row) {
|
|
return filteredItems[row].name === _predefinedItems.SEPARATOR ? 1 : 23;
|
|
}
|
|
};
|
|
this.origOutsideClickDeselects = this.hot.getSettings().outsideClickDeselects;
|
|
this.hot.getSettings().outsideClickDeselects = false;
|
|
this.hotMenu = new _core2.default(this.container, settings);
|
|
this.hotMenu.addHook('afterInit', function () {
|
|
return _this2.onAfterInit();
|
|
});
|
|
this.hotMenu.addHook('afterSelection', function (r, c, r2, c2, preventScrolling) {
|
|
return _this2.onAfterSelection(r, c, r2, c2, preventScrolling);
|
|
});
|
|
this.hotMenu.init();
|
|
this.hotMenu.listen();
|
|
this.blockMainTableCallbacks();
|
|
this.runLocalHooks('afterOpen');
|
|
}
|
|
|
|
/**
|
|
* Close menu.
|
|
*
|
|
* @param {Boolean} [closeParent=false] if `true` try to close parent menu if exists.
|
|
*/
|
|
|
|
}, {
|
|
key: 'close',
|
|
value: function close() {
|
|
var closeParent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
if (!this.isOpened()) {
|
|
return;
|
|
}
|
|
if (closeParent && this.parentMenu) {
|
|
this.parentMenu.close();
|
|
} else {
|
|
this.closeAllSubMenus();
|
|
this.container.style.display = 'none';
|
|
this.releaseMainTableCallbacks();
|
|
this.hotMenu.destroy();
|
|
this.hotMenu = null;
|
|
this.hot.getSettings().outsideClickDeselects = this.origOutsideClickDeselects;
|
|
this.runLocalHooks('afterClose');
|
|
|
|
if (this.parentMenu) {
|
|
this.parentMenu.hotMenu.listen();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Open sub menu at the provided row index.
|
|
*
|
|
* @param {Number} row Row index.
|
|
* @returns {Menu|Boolean} Returns created menu or `false` if no one menu was created.
|
|
*/
|
|
|
|
}, {
|
|
key: 'openSubMenu',
|
|
value: function openSubMenu(row) {
|
|
if (!this.hotMenu) {
|
|
return false;
|
|
}
|
|
var cell = this.hotMenu.getCell(row, 0);
|
|
|
|
this.closeAllSubMenus();
|
|
|
|
if (!cell || !(0, _utils.hasSubMenu)(cell)) {
|
|
return false;
|
|
}
|
|
var dataItem = this.hotMenu.getSourceDataAtRow(row);
|
|
var subMenu = new Menu(this.hot, {
|
|
parent: this,
|
|
name: dataItem.name,
|
|
className: this.options.className,
|
|
keepInViewport: true
|
|
});
|
|
subMenu.setMenuItems(dataItem.submenu.items);
|
|
subMenu.open();
|
|
subMenu.setPosition(cell.getBoundingClientRect());
|
|
this.hotSubMenus[dataItem.key] = subMenu;
|
|
|
|
return subMenu;
|
|
}
|
|
|
|
/**
|
|
* Close sub menu at row index.
|
|
*
|
|
* @param {Number} row Row index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'closeSubMenu',
|
|
value: function closeSubMenu(row) {
|
|
var dataItem = this.hotMenu.getSourceDataAtRow(row);
|
|
var menus = this.hotSubMenus[dataItem.key];
|
|
|
|
if (menus) {
|
|
menus.destroy();
|
|
delete this.hotSubMenus[dataItem.key];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close all opened sub menus.
|
|
*/
|
|
|
|
}, {
|
|
key: 'closeAllSubMenus',
|
|
value: function closeAllSubMenus() {
|
|
var _this3 = this;
|
|
|
|
(0, _array.arrayEach)(this.hotMenu.getData(), function (value, row) {
|
|
return _this3.closeSubMenu(row);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Checks if all created and opened sub menus are closed.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isAllSubMenusClosed',
|
|
value: function isAllSubMenusClosed() {
|
|
return Object.keys(this.hotSubMenus).length === 0;
|
|
}
|
|
|
|
/**
|
|
* Destroy instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.clearLocalHooks();
|
|
this.close();
|
|
this.parentMenu = null;
|
|
this.eventManager.destroy();
|
|
}
|
|
|
|
/**
|
|
* Checks if menu was opened.
|
|
*
|
|
* @returns {Boolean} Returns `true` if menu was opened.
|
|
*/
|
|
|
|
}, {
|
|
key: 'isOpened',
|
|
value: function isOpened() {
|
|
return this.hotMenu !== null;
|
|
}
|
|
|
|
/**
|
|
* Execute menu command.
|
|
*
|
|
* @param {Event} [event]
|
|
*/
|
|
|
|
}, {
|
|
key: 'executeCommand',
|
|
value: function executeCommand(event) {
|
|
if (!this.isOpened() || !this.hotMenu.getSelected()) {
|
|
return;
|
|
}
|
|
var selectedItem = this.hotMenu.getSourceDataAtRow(this.hotMenu.getSelected()[0]);
|
|
|
|
this.runLocalHooks('select', selectedItem, event);
|
|
|
|
if (selectedItem.isCommand === false || selectedItem.name === _predefinedItems.SEPARATOR) {
|
|
return;
|
|
}
|
|
var selRange = this.hot.getSelectedRange();
|
|
var normalizedSelection = selRange ? (0, _utils.normalizeSelection)(selRange) : {};
|
|
var autoClose = true;
|
|
|
|
// Don't close context menu if item is disabled or it has submenu
|
|
if (selectedItem.disabled === true || typeof selectedItem.disabled === 'function' && selectedItem.disabled.call(this.hot) === true || selectedItem.submenu) {
|
|
autoClose = false;
|
|
}
|
|
|
|
this.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event);
|
|
|
|
if (this.isSubMenu()) {
|
|
this.parentMenu.runLocalHooks('executeCommand', selectedItem.key, normalizedSelection, event);
|
|
}
|
|
|
|
if (autoClose) {
|
|
this.close(true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set menu position based on dom event or based on literal object.
|
|
*
|
|
* @param {Event|Object} coords Event or literal Object with coordinates.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPosition',
|
|
value: function setPosition(coords) {
|
|
var cursor = new _cursor2.default(coords);
|
|
|
|
if (this.options.keepInViewport) {
|
|
if (cursor.fitsBelow(this.container)) {
|
|
this.setPositionBelowCursor(cursor);
|
|
} else if (cursor.fitsAbove(this.container)) {
|
|
this.setPositionAboveCursor(cursor);
|
|
} else {
|
|
this.setPositionBelowCursor(cursor);
|
|
}
|
|
if (cursor.fitsOnRight(this.container)) {
|
|
this.setPositionOnRightOfCursor(cursor);
|
|
} else {
|
|
this.setPositionOnLeftOfCursor(cursor);
|
|
}
|
|
} else {
|
|
this.setPositionBelowCursor(cursor);
|
|
this.setPositionOnRightOfCursor(cursor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set menu position above cursor object.
|
|
*
|
|
* @param {Cursor} cursor `Cursor` object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPositionAboveCursor',
|
|
value: function setPositionAboveCursor(cursor) {
|
|
var top = this.offset.above + cursor.top - this.container.offsetHeight;
|
|
|
|
if (this.isSubMenu()) {
|
|
top = cursor.top + cursor.cellHeight - this.container.offsetHeight + 3;
|
|
}
|
|
this.container.style.top = top + 'px';
|
|
}
|
|
|
|
/**
|
|
* Set menu position below cursor object.
|
|
*
|
|
* @param {Cursor} cursor `Cursor` object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPositionBelowCursor',
|
|
value: function setPositionBelowCursor(cursor) {
|
|
var top = this.offset.below + cursor.top;
|
|
|
|
if (this.isSubMenu()) {
|
|
top = cursor.top - 1;
|
|
}
|
|
this.container.style.top = top + 'px';
|
|
}
|
|
|
|
/**
|
|
* Set menu position on the right of cursor object.
|
|
*
|
|
* @param {Cursor} cursor `Cursor` object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPositionOnRightOfCursor',
|
|
value: function setPositionOnRightOfCursor(cursor) {
|
|
var left = void 0;
|
|
|
|
if (this.isSubMenu()) {
|
|
left = 1 + cursor.left + cursor.cellWidth;
|
|
} else {
|
|
left = this.offset.right + 1 + cursor.left;
|
|
}
|
|
|
|
this.container.style.left = left + 'px';
|
|
}
|
|
|
|
/**
|
|
* Set menu position on the left of cursor object.
|
|
*
|
|
* @param {Cursor} cursor `Cursor` object.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setPositionOnLeftOfCursor',
|
|
value: function setPositionOnLeftOfCursor(cursor) {
|
|
var left = this.offset.left + cursor.left - this.container.offsetWidth + (0, _element.getScrollbarWidth)() + 4;
|
|
|
|
this.container.style.left = left + 'px';
|
|
}
|
|
|
|
/**
|
|
* Select first cell in opened menu.
|
|
*/
|
|
|
|
}, {
|
|
key: 'selectFirstCell',
|
|
value: function selectFirstCell() {
|
|
var cell = this.hotMenu.getCell(0, 0);
|
|
|
|
if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
|
|
this.selectNextCell(0, 0);
|
|
} else {
|
|
this.hotMenu.selectCell(0, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Select last cell in opened menu.
|
|
*/
|
|
|
|
}, {
|
|
key: 'selectLastCell',
|
|
value: function selectLastCell() {
|
|
var lastRow = this.hotMenu.countRows() - 1;
|
|
var cell = this.hotMenu.getCell(lastRow, 0);
|
|
|
|
if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
|
|
this.selectPrevCell(lastRow, 0);
|
|
} else {
|
|
this.hotMenu.selectCell(lastRow, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Select next cell in opened menu.
|
|
*
|
|
* @param {Number} row Row index.
|
|
* @param {Number} col Column index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'selectNextCell',
|
|
value: function selectNextCell(row, col) {
|
|
var nextRow = row + 1;
|
|
var cell = nextRow < this.hotMenu.countRows() ? this.hotMenu.getCell(nextRow, col) : null;
|
|
|
|
if (!cell) {
|
|
return;
|
|
}
|
|
if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
|
|
this.selectNextCell(nextRow, col);
|
|
} else {
|
|
this.hotMenu.selectCell(nextRow, col);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Select previous cell in opened menu.
|
|
*
|
|
* @param {Number} row Row index.
|
|
* @param {Number} col Column index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'selectPrevCell',
|
|
value: function selectPrevCell(row, col) {
|
|
var prevRow = row - 1;
|
|
var cell = prevRow >= 0 ? this.hotMenu.getCell(prevRow, col) : null;
|
|
|
|
if (!cell) {
|
|
return;
|
|
}
|
|
if ((0, _utils.isSeparator)(cell) || (0, _utils.isDisabled)(cell) || (0, _utils.isSelectionDisabled)(cell)) {
|
|
this.selectPrevCell(prevRow, col);
|
|
} else {
|
|
this.hotMenu.selectCell(prevRow, col);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Menu item renderer.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'menuItemRenderer',
|
|
value: function menuItemRenderer(hot, TD, row, col, prop, value) {
|
|
var _this4 = this;
|
|
|
|
var item = hot.getSourceDataAtRow(row);
|
|
var wrapper = document.createElement('div');
|
|
|
|
var isSubMenu = function isSubMenu(item) {
|
|
return (0, _object.hasOwnProperty)(item, 'submenu');
|
|
};
|
|
var itemIsSeparator = function itemIsSeparator(item) {
|
|
return new RegExp(_predefinedItems.SEPARATOR, 'i').test(item.name);
|
|
};
|
|
var itemIsDisabled = function itemIsDisabled(item) {
|
|
return item.disabled === true || typeof item.disabled == 'function' && item.disabled.call(_this4.hot) === true;
|
|
};
|
|
var itemIsSelectionDisabled = function itemIsSelectionDisabled(item) {
|
|
return item.disableSelection;
|
|
};
|
|
|
|
if (typeof value === 'function') {
|
|
value = value.call(this.hot);
|
|
}
|
|
(0, _element.empty)(TD);
|
|
(0, _element.addClass)(wrapper, 'htItemWrapper');
|
|
TD.appendChild(wrapper);
|
|
|
|
if (itemIsSeparator(item)) {
|
|
(0, _element.addClass)(TD, 'htSeparator');
|
|
} else if (typeof item.renderer === 'function') {
|
|
(0, _element.addClass)(TD, 'htCustomMenuRenderer');
|
|
TD.appendChild(item.renderer(hot, wrapper, row, col, prop, value));
|
|
} else {
|
|
(0, _element.fastInnerHTML)(wrapper, value);
|
|
}
|
|
if (itemIsDisabled(item)) {
|
|
(0, _element.addClass)(TD, 'htDisabled');
|
|
this.eventManager.addEventListener(TD, 'mouseenter', function () {
|
|
return hot.deselectCell();
|
|
});
|
|
} else if (itemIsSelectionDisabled(item)) {
|
|
(0, _element.addClass)(TD, 'htSelectionDisabled');
|
|
this.eventManager.addEventListener(TD, 'mouseenter', function () {
|
|
return hot.deselectCell();
|
|
});
|
|
} else if (isSubMenu(item)) {
|
|
(0, _element.addClass)(TD, 'htSubmenu');
|
|
|
|
if (itemIsSelectionDisabled(item)) {
|
|
this.eventManager.addEventListener(TD, 'mouseenter', function () {
|
|
return hot.deselectCell();
|
|
});
|
|
} else {
|
|
this.eventManager.addEventListener(TD, 'mouseenter', function () {
|
|
return hot.selectCell(row, col, void 0, void 0, false, false);
|
|
});
|
|
}
|
|
} else {
|
|
(0, _element.removeClass)(TD, 'htSubmenu');
|
|
(0, _element.removeClass)(TD, 'htDisabled');
|
|
|
|
if (itemIsSelectionDisabled(item)) {
|
|
this.eventManager.addEventListener(TD, 'mouseenter', function () {
|
|
return hot.deselectCell();
|
|
});
|
|
} else {
|
|
this.eventManager.addEventListener(TD, 'mouseenter', function () {
|
|
return hot.selectCell(row, col, void 0, void 0, false, false);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create container/wrapper for handsontable.
|
|
*
|
|
* @private
|
|
* @param {String} [name] Class name.
|
|
* @returns {HTMLElement}
|
|
*/
|
|
|
|
}, {
|
|
key: 'createContainer',
|
|
value: function createContainer() {
|
|
var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
|
|
if (name) {
|
|
name = name.replace(/[^A-z0-9]/g, '_');
|
|
name = this.options.className + 'Sub_' + name;
|
|
}
|
|
var container = void 0;
|
|
|
|
if (name) {
|
|
container = document.querySelector('.' + this.options.className + '.' + name);
|
|
} else {
|
|
container = document.querySelector('.' + this.options.className);
|
|
}
|
|
if (!container) {
|
|
container = document.createElement('div');
|
|
(0, _element.addClass)(container, 'htMenu ' + this.options.className);
|
|
|
|
if (name) {
|
|
(0, _element.addClass)(container, name);
|
|
}
|
|
document.getElementsByTagName('body')[0].appendChild(container);
|
|
}
|
|
|
|
return container;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'blockMainTableCallbacks',
|
|
value: function blockMainTableCallbacks() {
|
|
this._afterScrollCallback = function () {};
|
|
this.hot.addHook('afterScrollVertically', this._afterScrollCallback);
|
|
this.hot.addHook('afterScrollHorizontally', this._afterScrollCallback);
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'releaseMainTableCallbacks',
|
|
value: function releaseMainTableCallbacks() {
|
|
if (this._afterScrollCallback) {
|
|
this.hot.removeHook('afterScrollVertically', this._afterScrollCallback);
|
|
this.hot.removeHook('afterScrollHorizontally', this._afterScrollCallback);
|
|
this._afterScrollCallback = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On before key down listener.
|
|
*
|
|
* @private
|
|
* @param {Event} event
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeKeyDown',
|
|
value: function onBeforeKeyDown(event) {
|
|
var selection = this.hotMenu.getSelected();
|
|
var stopEvent = false;
|
|
this.keyEvent = true;
|
|
|
|
switch (event.keyCode) {
|
|
case _unicode.KEY_CODES.ESCAPE:
|
|
this.close();
|
|
stopEvent = true;
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ENTER:
|
|
if (selection) {
|
|
if (this.hotMenu.getSourceDataAtRow(selection[0]).submenu) {
|
|
stopEvent = true;
|
|
} else {
|
|
this.executeCommand(event);
|
|
this.close(true);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_DOWN:
|
|
if (selection) {
|
|
this.selectNextCell(selection[0], selection[1]);
|
|
} else {
|
|
this.selectFirstCell();
|
|
}
|
|
stopEvent = true;
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_UP:
|
|
if (selection) {
|
|
this.selectPrevCell(selection[0], selection[1]);
|
|
} else {
|
|
this.selectLastCell();
|
|
}
|
|
stopEvent = true;
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_RIGHT:
|
|
if (selection) {
|
|
var menu = this.openSubMenu(selection[0]);
|
|
|
|
if (menu) {
|
|
menu.selectFirstCell();
|
|
}
|
|
}
|
|
stopEvent = true;
|
|
|
|
break;
|
|
|
|
case _unicode.KEY_CODES.ARROW_LEFT:
|
|
if (selection && this.isSubMenu()) {
|
|
this.close();
|
|
|
|
if (this.parentMenu) {
|
|
this.parentMenu.hotMenu.listen();
|
|
}
|
|
stopEvent = true;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (stopEvent) {
|
|
event.preventDefault();
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
}
|
|
|
|
this.keyEvent = false;
|
|
}
|
|
|
|
/**
|
|
* On after init listener.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterInit',
|
|
value: function onAfterInit() {
|
|
var data = this.hotMenu.getSettings().data;
|
|
var hiderStyle = this.hotMenu.view.wt.wtTable.hider.style;
|
|
var holderStyle = this.hotMenu.view.wt.wtTable.holder.style;
|
|
var currentHiderWidth = parseInt(hiderStyle.width, 10);
|
|
|
|
var realHeight = (0, _array.arrayReduce)(data, function (accumulator, value) {
|
|
return accumulator + (value.name === _predefinedItems.SEPARATOR ? 1 : 26);
|
|
}, 0);
|
|
|
|
holderStyle.width = currentHiderWidth + 22 + 'px';
|
|
holderStyle.height = realHeight + 4 + 'px';
|
|
hiderStyle.height = holderStyle.height;
|
|
}
|
|
|
|
/**
|
|
* On after selection listener.
|
|
*
|
|
* @param {Number} r Selection start row index.
|
|
* @param {Number} c Selection start column index.
|
|
* @param {Number} r2 Selection end row index.
|
|
* @param {Number} c2 Selection end column index.
|
|
* @param {Object} preventScrolling Object with `value` property where its value change will be observed.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterSelection',
|
|
value: function onAfterSelection(r, c, r2, c2, preventScrolling) {
|
|
if (this.keyEvent === false) {
|
|
preventScrolling.value = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Document mouse down listener.
|
|
*
|
|
* @private
|
|
* @param {Event} event
|
|
*/
|
|
|
|
}, {
|
|
key: 'onDocumentMouseDown',
|
|
value: function onDocumentMouseDown(event) {
|
|
if (!this.isOpened()) {
|
|
return;
|
|
}
|
|
if (this.container && (0, _element.isChildOf)(event.target, this.container)) {
|
|
this.executeCommand(event);
|
|
}
|
|
// Close menu when clicked element is not belongs to menu itself
|
|
if (this.options.standalone && this.hotMenu && !(0, _element.isChildOf)(event.target, this.hotMenu.rootElement)) {
|
|
this.close(true);
|
|
|
|
// Automatically close menu when clicked element is not belongs to menu or submenu (not necessarily to itself)
|
|
} else if ((this.isAllSubMenusClosed() || this.isSubMenu()) && !(0, _element.isChildOf)(event.target, '.htMenu') && (0, _element.isChildOf)(event.target, document)) {
|
|
this.close(true);
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return Menu;
|
|
}();
|
|
|
|
(0, _object.mixin)(Menu, _localHooks2.default);
|
|
|
|
exports.default = Menu;
|
|
|
|
/***/ }),
|
|
/* 338 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = alignmentItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var _separator = __webpack_require__(72);
|
|
|
|
var KEY = exports.KEY = 'alignment';
|
|
|
|
function alignmentItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Alignment',
|
|
disabled: function disabled() {
|
|
return !(this.getSelectedRange() && !this.selection.selectedHeader.corner);
|
|
},
|
|
|
|
submenu: {
|
|
items: [{
|
|
key: KEY + ':left',
|
|
name: function name() {
|
|
var _this = this;
|
|
|
|
var label = 'Left';
|
|
var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var className = _this.getCellMeta(row, col).className;
|
|
|
|
if (className && className.indexOf('htLeft') !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasClass) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this2 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
|
|
return _this2.getCellMeta(row, col).className;
|
|
});
|
|
var type = 'horizontal';
|
|
var alignment = 'htLeft';
|
|
|
|
this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
|
|
(0, _utils.align)(range, type, alignment, function (row, col) {
|
|
return _this2.getCellMeta(row, col);
|
|
}, function (row, col, key, value) {
|
|
return _this2.setCellMeta(row, col, key, value);
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
disabled: false
|
|
}, {
|
|
key: KEY + ':center',
|
|
name: function name() {
|
|
var _this3 = this;
|
|
|
|
var label = 'Center';
|
|
var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var className = _this3.getCellMeta(row, col).className;
|
|
|
|
if (className && className.indexOf('htCenter') !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasClass) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this4 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
|
|
return _this4.getCellMeta(row, col).className;
|
|
});
|
|
var type = 'horizontal';
|
|
var alignment = 'htCenter';
|
|
|
|
this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
|
|
(0, _utils.align)(range, type, alignment, function (row, col) {
|
|
return _this4.getCellMeta(row, col);
|
|
}, function (row, col, key, value) {
|
|
return _this4.setCellMeta(row, col, key, value);
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
disabled: false
|
|
}, {
|
|
key: KEY + ':right',
|
|
name: function name() {
|
|
var _this5 = this;
|
|
|
|
var label = 'Right';
|
|
var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var className = _this5.getCellMeta(row, col).className;
|
|
|
|
if (className && className.indexOf('htRight') !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasClass) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this6 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
|
|
return _this6.getCellMeta(row, col).className;
|
|
});
|
|
var type = 'horizontal';
|
|
var alignment = 'htRight';
|
|
|
|
this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
|
|
(0, _utils.align)(range, type, alignment, function (row, col) {
|
|
return _this6.getCellMeta(row, col);
|
|
}, function (row, col, key, value) {
|
|
return _this6.setCellMeta(row, col, key, value);
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
disabled: false
|
|
}, {
|
|
key: KEY + ':justify',
|
|
name: function name() {
|
|
var _this7 = this;
|
|
|
|
var label = 'Justify';
|
|
var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var className = _this7.getCellMeta(row, col).className;
|
|
|
|
if (className && className.indexOf('htJustify') !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasClass) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this8 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
|
|
return _this8.getCellMeta(row, col).className;
|
|
});
|
|
var type = 'horizontal';
|
|
var alignment = 'htJustify';
|
|
|
|
this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
|
|
(0, _utils.align)(range, type, alignment, function (row, col) {
|
|
return _this8.getCellMeta(row, col);
|
|
}, function (row, col, key, value) {
|
|
return _this8.setCellMeta(row, col, key, value);
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
disabled: false
|
|
}, {
|
|
name: _separator.KEY
|
|
}, {
|
|
key: KEY + ':top',
|
|
name: function name() {
|
|
var _this9 = this;
|
|
|
|
var label = 'Top';
|
|
var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var className = _this9.getCellMeta(row, col).className;
|
|
|
|
if (className && className.indexOf('htTop') !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasClass) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this10 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
|
|
return _this10.getCellMeta(row, col).className;
|
|
});
|
|
var type = 'vertical';
|
|
var alignment = 'htTop';
|
|
|
|
this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
|
|
(0, _utils.align)(range, type, alignment, function (row, col) {
|
|
return _this10.getCellMeta(row, col);
|
|
}, function (row, col, key, value) {
|
|
return _this10.setCellMeta(row, col, key, value);
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
disabled: false
|
|
}, {
|
|
key: KEY + ':middle',
|
|
name: function name() {
|
|
var _this11 = this;
|
|
|
|
var label = 'Middle';
|
|
var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var className = _this11.getCellMeta(row, col).className;
|
|
|
|
if (className && className.indexOf('htMiddle') !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasClass) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this12 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
|
|
return _this12.getCellMeta(row, col).className;
|
|
});
|
|
var type = 'vertical';
|
|
var alignment = 'htMiddle';
|
|
|
|
this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
|
|
(0, _utils.align)(range, type, alignment, function (row, col) {
|
|
return _this12.getCellMeta(row, col);
|
|
}, function (row, col, key, value) {
|
|
return _this12.setCellMeta(row, col, key, value);
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
disabled: false
|
|
}, {
|
|
key: KEY + ':bottom',
|
|
name: function name() {
|
|
var _this13 = this;
|
|
|
|
var label = 'Bottom';
|
|
var hasClass = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
var className = _this13.getCellMeta(row, col).className;
|
|
|
|
if (className && className.indexOf('htBottom') !== -1) {
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if (hasClass) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this14 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var stateBefore = (0, _utils.getAlignmentClasses)(range, function (row, col) {
|
|
return _this14.getCellMeta(row, col).className;
|
|
});
|
|
var type = 'vertical';
|
|
var alignment = 'htBottom';
|
|
|
|
this.runHooks('beforeCellAlignment', stateBefore, range, type, alignment);
|
|
(0, _utils.align)(range, type, alignment, function (row, col) {
|
|
return _this14.getCellMeta(row, col);
|
|
}, function (row, col, key, value) {
|
|
return _this14.setCellMeta(row, col, key, value);
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
disabled: false
|
|
}]
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 339 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = clearColumnItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'clear_column';
|
|
|
|
function clearColumnItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Clear column',
|
|
|
|
callback: function callback(key, selection) {
|
|
var column = selection.start.col;
|
|
|
|
if (this.countRows()) {
|
|
this.populateFromArray(0, column, [[null]], Math.max(selection.start.row, selection.end.row), column, 'ContextMenu.clearColumn');
|
|
}
|
|
},
|
|
disabled: function disabled() {
|
|
var selected = (0, _utils.getValidSelection)(this);
|
|
|
|
if (!selected) {
|
|
return true;
|
|
}
|
|
var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1];
|
|
var rowSelected = entireRowSelection.join(',') == selected.join(',');
|
|
|
|
return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || rowSelected;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 340 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = columnLeftItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'col_left';
|
|
|
|
function columnLeftItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Insert column on the left',
|
|
callback: function callback(key, selection) {
|
|
this.alter('insert_col', selection.start.col, 1, 'ContextMenu.columnLeft');
|
|
},
|
|
disabled: function disabled() {
|
|
var selected = (0, _utils.getValidSelection)(this);
|
|
|
|
if (!selected) {
|
|
return true;
|
|
}
|
|
if (!this.isColumnModificationAllowed()) {
|
|
return true;
|
|
}
|
|
var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1];
|
|
var rowSelected = entireRowSelection.join(',') == selected.join(',');
|
|
var onlyOneColumn = this.countCols() === 1;
|
|
|
|
return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected;
|
|
},
|
|
hidden: function hidden() {
|
|
return !this.getSettings().allowInsertColumn;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 341 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = columnRightItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'col_right';
|
|
|
|
function columnRightItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Insert column on the right',
|
|
|
|
callback: function callback(key, selection) {
|
|
this.alter('insert_col', selection.end.col + 1, 1, 'ContextMenu.columnRight');
|
|
},
|
|
disabled: function disabled() {
|
|
var selected = (0, _utils.getValidSelection)(this);
|
|
|
|
if (!selected) {
|
|
return true;
|
|
}
|
|
if (!this.isColumnModificationAllowed()) {
|
|
return true;
|
|
}
|
|
var entireRowSelection = [selected[0], 0, selected[0], this.countCols() - 1];
|
|
var rowSelected = entireRowSelection.join(',') == selected.join(',');
|
|
var onlyOneColumn = this.countCols() === 1;
|
|
|
|
return selected[1] < 0 || this.countCols() >= this.getSettings().maxCols || !onlyOneColumn && rowSelected;
|
|
},
|
|
hidden: function hidden() {
|
|
return !this.getSettings().allowInsertColumn;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 342 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = readOnlyItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'make_read_only';
|
|
|
|
function readOnlyItem() {
|
|
return {
|
|
key: KEY,
|
|
name: function name() {
|
|
var _this = this;
|
|
|
|
var label = 'Read only';
|
|
var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(this.getSelectedRange(), function (row, col) {
|
|
return _this.getCellMeta(row, col).readOnly;
|
|
});
|
|
|
|
if (atLeastOneReadOnly) {
|
|
label = (0, _utils.markLabelAsSelected)(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var _this2 = this;
|
|
|
|
var range = this.getSelectedRange();
|
|
var atLeastOneReadOnly = (0, _utils.checkSelectionConsistency)(range, function (row, col) {
|
|
return _this2.getCellMeta(row, col).readOnly;
|
|
});
|
|
|
|
range.forAll(function (row, col) {
|
|
_this2.setCellMeta(row, col, 'readOnly', !atLeastOneReadOnly);
|
|
});
|
|
this.render();
|
|
},
|
|
disabled: function disabled() {
|
|
return !(this.getSelectedRange() && !this.selection.selectedHeader.corner);
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 343 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = redoItem;
|
|
var KEY = exports.KEY = 'redo';
|
|
|
|
function redoItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Redo',
|
|
|
|
callback: function callback() {
|
|
this.redo();
|
|
},
|
|
disabled: function disabled() {
|
|
return this.undoRedo && !this.undoRedo.isRedoAvailable();
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 344 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = removeColumnItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'remove_col';
|
|
|
|
function removeColumnItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Remove column',
|
|
|
|
callback: function callback(key, selection) {
|
|
var amount = selection.end.col - selection.start.col + 1;
|
|
|
|
this.alter('remove_col', selection.start.col, amount, 'ContextMenu.removeColumn');
|
|
},
|
|
disabled: function disabled() {
|
|
var selected = (0, _utils.getValidSelection)(this);
|
|
var totalColumns = this.countCols();
|
|
|
|
return !selected || this.selection.selectedHeader.rows || this.selection.selectedHeader.corner || !this.isColumnModificationAllowed() || !totalColumns;
|
|
},
|
|
hidden: function hidden() {
|
|
return !this.getSettings().allowRemoveColumn;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 345 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = removeRowItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'remove_row';
|
|
|
|
function removeRowItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Remove row',
|
|
|
|
callback: function callback(key, selection) {
|
|
var amount = selection.end.row - selection.start.row + 1;
|
|
|
|
this.alter('remove_row', selection.start.row, amount, 'ContextMenu.removeRow');
|
|
},
|
|
disabled: function disabled() {
|
|
var selected = (0, _utils.getValidSelection)(this);
|
|
var totalRows = this.countRows();
|
|
|
|
return !selected || this.selection.selectedHeader.cols || this.selection.selectedHeader.corner || !totalRows;
|
|
},
|
|
hidden: function hidden() {
|
|
return !this.getSettings().allowRemoveRow;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 346 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = rowAboveItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'row_above';
|
|
|
|
function rowAboveItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Insert row above',
|
|
|
|
callback: function callback(key, selection) {
|
|
this.alter('insert_row', selection.start.row, 1, 'ContextMenu.rowAbove');
|
|
},
|
|
disabled: function disabled() {
|
|
var selected = (0, _utils.getValidSelection)(this);
|
|
|
|
return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows;
|
|
},
|
|
hidden: function hidden() {
|
|
return !this.getSettings().allowInsertRow;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 347 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.KEY = undefined;
|
|
exports.default = rowBelowItem;
|
|
|
|
var _utils = __webpack_require__(17);
|
|
|
|
var KEY = exports.KEY = 'row_below';
|
|
|
|
function rowBelowItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Insert row below',
|
|
|
|
callback: function callback(key, selection) {
|
|
this.alter('insert_row', selection.end.row + 1, 1, 'ContextMenu.rowBelow');
|
|
},
|
|
disabled: function disabled() {
|
|
var selected = (0, _utils.getValidSelection)(this);
|
|
|
|
return !selected || this.selection.selectedHeader.cols || this.countRows() >= this.getSettings().maxRows;
|
|
},
|
|
hidden: function hidden() {
|
|
return !this.getSettings().allowInsertRow;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 348 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = undoItem;
|
|
var KEY = exports.KEY = 'undo';
|
|
|
|
function undoItem() {
|
|
return {
|
|
key: KEY,
|
|
name: 'Undo',
|
|
|
|
callback: function callback() {
|
|
this.undo();
|
|
},
|
|
disabled: function disabled() {
|
|
return this.undoRedo && !this.undoRedo.isUndoAvailable();
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 349 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = copyItem;
|
|
function copyItem(copyPastePlugin) {
|
|
return {
|
|
key: 'copy',
|
|
name: 'Copy',
|
|
callback: function callback() {
|
|
copyPastePlugin.setCopyableText();
|
|
copyPastePlugin.copy(true);
|
|
},
|
|
|
|
disabled: false,
|
|
hidden: false
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 350 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = cutItem;
|
|
function cutItem(copyPastePlugin) {
|
|
return {
|
|
key: 'cut',
|
|
name: 'Cut',
|
|
callback: function callback() {
|
|
copyPastePlugin.setCopyableText();
|
|
copyPastePlugin.cut(true);
|
|
},
|
|
|
|
disabled: false,
|
|
hidden: false
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 351 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _SheetClip = __webpack_require__(248);
|
|
|
|
var _SheetClip2 = _interopRequireDefault(_SheetClip);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _textarea = __webpack_require__(352);
|
|
|
|
var _textarea2 = _interopRequireDefault(_textarea);
|
|
|
|
var _copy = __webpack_require__(349);
|
|
|
|
var _copy2 = _interopRequireDefault(_copy);
|
|
|
|
var _cut = __webpack_require__(350);
|
|
|
|
var _cut2 = _interopRequireDefault(_cut);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
__webpack_require__(414);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
_pluginHooks2.default.getSingleton().register('afterCopyLimit');
|
|
_pluginHooks2.default.getSingleton().register('modifyCopyableRange');
|
|
_pluginHooks2.default.getSingleton().register('beforeCut');
|
|
_pluginHooks2.default.getSingleton().register('afterCut');
|
|
_pluginHooks2.default.getSingleton().register('beforePaste');
|
|
_pluginHooks2.default.getSingleton().register('afterPaste');
|
|
_pluginHooks2.default.getSingleton().register('beforeCopy');
|
|
_pluginHooks2.default.getSingleton().register('afterCopy');
|
|
|
|
var ROWS_LIMIT = 1000;
|
|
var COLUMNS_LIMIT = 1000;
|
|
var privatePool = new WeakMap();
|
|
|
|
/**
|
|
* @description
|
|
* This plugin enables the copy/paste functionality in the Handsontable.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* copyPaste: true,
|
|
* ...
|
|
* ```
|
|
* @class CopyPaste
|
|
* @plugin CopyPaste
|
|
*/
|
|
|
|
var CopyPaste = function (_BasePlugin) {
|
|
_inherits(CopyPaste, _BasePlugin);
|
|
|
|
function CopyPaste(hotInstance) {
|
|
_classCallCheck(this, CopyPaste);
|
|
|
|
/**
|
|
* Event manager
|
|
*
|
|
* @type {EventManager}
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (CopyPaste.__proto__ || Object.getPrototypeOf(CopyPaste)).call(this, hotInstance));
|
|
|
|
_this.eventManager = new _eventManager2.default(_this);
|
|
/**
|
|
* Maximum number of columns than can be copied to clipboard using <kbd>CTRL</kbd> + <kbd>C</kbd>.
|
|
*
|
|
* @private
|
|
* @type {Number}
|
|
* @default 1000
|
|
*/
|
|
_this.columnsLimit = COLUMNS_LIMIT;
|
|
/**
|
|
* Ranges of the cells coordinates, which should be used to copy/cut/paste actions.
|
|
*
|
|
* @private
|
|
* @type {Array}
|
|
*/
|
|
_this.copyableRanges = [];
|
|
/**
|
|
* Defines paste (<kbd>CTRL</kbd> + <kbd>V</kbd>) behavior.
|
|
* * Default value `"overwrite"` will paste clipboard value over current selection.
|
|
* * When set to `"shift_down"`, clipboard data will be pasted in place of current selection, while all selected cells are moved down.
|
|
* * When set to `"shift_right"`, clipboard data will be pasted in place of current selection, while all selected cells are moved right.
|
|
*
|
|
* @private
|
|
* @type {String}
|
|
* @default 'overwrite'
|
|
*/
|
|
_this.pasteMode = 'overwrite';
|
|
/**
|
|
* Maximum number of rows than can be copied to clipboard using <kbd>CTRL</kbd> + <kbd>C</kbd>.
|
|
*
|
|
* @private
|
|
* @type {Number}
|
|
* @default 1000
|
|
*/
|
|
_this.rowsLimit = ROWS_LIMIT;
|
|
/**
|
|
* The `textarea` element which is necessary to process copying, cutting off and pasting.
|
|
*
|
|
* @private
|
|
* @type {HTMLElement}
|
|
* @default undefined
|
|
*/
|
|
_this.textarea = void 0;
|
|
|
|
privatePool.set(_this, {
|
|
isTriggeredByPaste: false
|
|
});
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if plugin is enabled.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(CopyPaste, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return !!this.hot.getSettings().copyPaste;
|
|
}
|
|
|
|
/**
|
|
* Enable the plugin.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this2 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
|
|
var settings = this.hot.getSettings();
|
|
|
|
this.textarea = _textarea2.default.getSingleton();
|
|
|
|
if (_typeof(settings.copyPaste) === 'object') {
|
|
this.pasteMode = settings.copyPaste.pasteMode || this.pasteMode;
|
|
this.rowsLimit = settings.copyPaste.rowsLimit || this.rowsLimit;
|
|
this.columnsLimit = settings.copyPaste.columnsLimit || this.columnsLimit;
|
|
}
|
|
|
|
this.addHook('afterContextMenuDefaultOptions', function (options) {
|
|
return _this2.onAfterContextMenuDefaultOptions(options);
|
|
});
|
|
this.addHook('beforeKeyDown', function (event) {
|
|
return _this2.onBeforeKeyDown(event);
|
|
});
|
|
// this.addHook('beforeOnCellMouseDown', () => this.onBeforeOnCellMouseDown());
|
|
|
|
this.registerEvents();
|
|
|
|
_get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
/**
|
|
* Updates the plugin to use the latest options you have specified.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
this.disablePlugin();
|
|
this.enablePlugin();
|
|
|
|
_get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
if (this.textarea) {
|
|
this.textarea.destroy();
|
|
}
|
|
|
|
_get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Prepares copyable text in the invisible textarea.
|
|
*
|
|
* @function setCopyable
|
|
* @memberof CopyPaste#
|
|
*/
|
|
|
|
}, {
|
|
key: 'setCopyableText',
|
|
value: function setCopyableText() {
|
|
var selRange = this.hot.getSelectedRange();
|
|
var topLeft = selRange.getTopLeftCorner();
|
|
var bottomRight = selRange.getBottomRightCorner();
|
|
var startRow = topLeft.row;
|
|
var startCol = topLeft.col;
|
|
var endRow = bottomRight.row;
|
|
var endCol = bottomRight.col;
|
|
var finalEndRow = Math.min(endRow, startRow + this.rowsLimit - 1);
|
|
var finalEndCol = Math.min(endCol, startCol + this.columnsLimit - 1);
|
|
|
|
this.copyableRanges.length = 0;
|
|
|
|
this.copyableRanges.push({
|
|
startRow: startRow,
|
|
startCol: startCol,
|
|
endRow: finalEndRow,
|
|
endCol: finalEndCol
|
|
});
|
|
|
|
this.copyableRanges = this.hot.runHooks('modifyCopyableRange', this.copyableRanges);
|
|
|
|
var copyableData = this.getRangedCopyableData(this.copyableRanges);
|
|
|
|
this.textarea.setValue(copyableData);
|
|
|
|
if (endRow !== finalEndRow || endCol !== finalEndCol) {
|
|
this.hot.runHooks('afterCopyLimit', endRow - startRow + 1, endCol - startCol + 1, this.rowsLimit, this.columnsLimit);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create copyable text releated to range objects.
|
|
*
|
|
* @since 0.19.0
|
|
* @param {Array} ranges Array of Objects with properties `startRow`, `endRow`, `startCol` and `endCol`.
|
|
* @returns {String} Returns string which will be copied into clipboard.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getRangedCopyableData',
|
|
value: function getRangedCopyableData(ranges) {
|
|
var _this3 = this;
|
|
|
|
var dataSet = [];
|
|
var copyableRows = [];
|
|
var copyableColumns = [];
|
|
|
|
// Count all copyable rows and columns
|
|
(0, _array.arrayEach)(ranges, function (range) {
|
|
(0, _number.rangeEach)(range.startRow, range.endRow, function (row) {
|
|
if (copyableRows.indexOf(row) === -1) {
|
|
copyableRows.push(row);
|
|
}
|
|
});
|
|
(0, _number.rangeEach)(range.startCol, range.endCol, function (column) {
|
|
if (copyableColumns.indexOf(column) === -1) {
|
|
copyableColumns.push(column);
|
|
}
|
|
});
|
|
});
|
|
// Concat all rows and columns data defined in ranges into one copyable string
|
|
(0, _array.arrayEach)(copyableRows, function (row) {
|
|
var rowSet = [];
|
|
|
|
(0, _array.arrayEach)(copyableColumns, function (column) {
|
|
rowSet.push(_this3.hot.getCopyableData(row, column));
|
|
});
|
|
|
|
dataSet.push(rowSet);
|
|
});
|
|
|
|
return _SheetClip2.default.stringify(dataSet);
|
|
}
|
|
|
|
/**
|
|
* Create copyable text releated to range objects.
|
|
*
|
|
* @since 0.31.1
|
|
* @param {Array} ranges Array of Objects with properties `startRow`, `startCol`, `endRow` and `endCol`.
|
|
* @returns {Array} Returns array of arrays which will be copied into clipboard.
|
|
*/
|
|
|
|
}, {
|
|
key: 'getRangedData',
|
|
value: function getRangedData(ranges) {
|
|
var _this4 = this;
|
|
|
|
var dataSet = [];
|
|
var copyableRows = [];
|
|
var copyableColumns = [];
|
|
|
|
// Count all copyable rows and columns
|
|
(0, _array.arrayEach)(ranges, function (range) {
|
|
(0, _number.rangeEach)(range.startRow, range.endRow, function (row) {
|
|
if (copyableRows.indexOf(row) === -1) {
|
|
copyableRows.push(row);
|
|
}
|
|
});
|
|
(0, _number.rangeEach)(range.startCol, range.endCol, function (column) {
|
|
if (copyableColumns.indexOf(column) === -1) {
|
|
copyableColumns.push(column);
|
|
}
|
|
});
|
|
});
|
|
// Concat all rows and columns data defined in ranges into one copyable string
|
|
(0, _array.arrayEach)(copyableRows, function (row) {
|
|
var rowSet = [];
|
|
|
|
(0, _array.arrayEach)(copyableColumns, function (column) {
|
|
rowSet.push(_this4.hot.getCopyableData(row, column));
|
|
});
|
|
|
|
dataSet.push(rowSet);
|
|
});
|
|
|
|
return dataSet;
|
|
}
|
|
|
|
/**
|
|
* Copy action.
|
|
*
|
|
* @param {Boolean} isTriggeredByClick Flag to determine that copy action was executed by the mouse click.
|
|
*/
|
|
|
|
}, {
|
|
key: 'copy',
|
|
value: function copy(isTriggeredByClick) {
|
|
var rangedData = this.getRangedData(this.copyableRanges);
|
|
|
|
var allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges);
|
|
|
|
if (allowCopying) {
|
|
this.textarea.setValue(_SheetClip2.default.stringify(rangedData));
|
|
this.textarea.select();
|
|
|
|
if (isTriggeredByClick) {
|
|
document.execCommand('copy');
|
|
}
|
|
|
|
this.hot.runHooks('afterCopy', rangedData, this.copyableRanges);
|
|
} else {
|
|
this.textarea.setValue('');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cut action.
|
|
*
|
|
* @param {Boolean} isTriggeredByClick Flag to determine that cut action was executed by the mouse click.
|
|
*/
|
|
|
|
}, {
|
|
key: 'cut',
|
|
value: function cut(isTriggeredByClick) {
|
|
var rangedData = this.getRangedData(this.copyableRanges);
|
|
|
|
var allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);
|
|
|
|
if (allowCuttingOut) {
|
|
this.textarea.setValue(_SheetClip2.default.stringify(rangedData));
|
|
this.hot.selection.empty();
|
|
this.textarea.select();
|
|
|
|
if (isTriggeredByClick) {
|
|
document.execCommand('cut');
|
|
}
|
|
|
|
this.hot.runHooks('afterCut', rangedData, this.copyableRanges);
|
|
} else {
|
|
this.textarea.setValue('');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Simulated paste action.
|
|
*
|
|
* @param {String} [value=''] New value, which should be `pasted`.
|
|
*/
|
|
|
|
}, {
|
|
key: 'paste',
|
|
value: function paste() {
|
|
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
|
|
this.textarea.setValue(value);
|
|
|
|
this.onPaste();
|
|
this.onInput();
|
|
}
|
|
|
|
/**
|
|
* Register event listeners.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerEvents',
|
|
value: function registerEvents() {
|
|
var _this5 = this;
|
|
|
|
this.eventManager.addEventListener(this.textarea.element, 'paste', function (event) {
|
|
return _this5.onPaste(event);
|
|
});
|
|
this.eventManager.addEventListener(this.textarea.element, 'input', function (event) {
|
|
return _this5.onInput(event);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Trigger to make possible observe `onInput` in textarea.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'triggerPaste',
|
|
value: function triggerPaste() {
|
|
this.textarea.select();
|
|
|
|
this.onPaste();
|
|
}
|
|
|
|
/**
|
|
* `paste` event callback on textarea element.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onPaste',
|
|
value: function onPaste() {
|
|
var priv = privatePool.get(this);
|
|
|
|
priv.isTriggeredByPaste = true;
|
|
}
|
|
|
|
/**
|
|
* `input` event callback is called after `paste` event callback.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onInput',
|
|
value: function onInput() {
|
|
var _this6 = this;
|
|
|
|
var priv = privatePool.get(this);
|
|
|
|
if (!this.hot.isListening() || !priv.isTriggeredByPaste) {
|
|
return;
|
|
}
|
|
|
|
priv.isTriggeredByPaste = false;
|
|
|
|
var input = void 0,
|
|
inputArray = void 0,
|
|
selected = void 0,
|
|
coordsFrom = void 0,
|
|
coordsTo = void 0,
|
|
cellRange = void 0,
|
|
topLeftCorner = void 0,
|
|
bottomRightCorner = void 0,
|
|
areaStart = void 0,
|
|
areaEnd = void 0;
|
|
|
|
input = this.textarea.getValue();
|
|
inputArray = _SheetClip2.default.parse(input);
|
|
|
|
var allowPasting = !!this.hot.runHooks('beforePaste', inputArray, this.copyableRanges);
|
|
|
|
if (!allowPasting) {
|
|
return;
|
|
}
|
|
|
|
selected = this.hot.getSelected();
|
|
coordsFrom = new _src.CellCoords(selected[0], selected[1]);
|
|
coordsTo = new _src.CellCoords(selected[2], selected[3]);
|
|
cellRange = new _src.CellRange(coordsFrom, coordsFrom, coordsTo);
|
|
topLeftCorner = cellRange.getTopLeftCorner();
|
|
bottomRightCorner = cellRange.getBottomRightCorner();
|
|
areaStart = topLeftCorner;
|
|
areaEnd = new _src.CellCoords(Math.max(bottomRightCorner.row, inputArray.length - 1 + topLeftCorner.row), Math.max(bottomRightCorner.col, inputArray[0].length - 1 + topLeftCorner.col));
|
|
|
|
var isSelRowAreaCoverInputValue = coordsTo.row - coordsFrom.row >= inputArray.length - 1;
|
|
var isSelColAreaCoverInputValue = coordsTo.col - coordsFrom.col >= inputArray[0].length - 1;
|
|
|
|
this.hot.addHookOnce('afterChange', function (changes, source) {
|
|
var changesLength = changes ? changes.length : 0;
|
|
|
|
if (changesLength) {
|
|
var offset = { row: 0, col: 0 };
|
|
var highestColumnIndex = -1;
|
|
|
|
(0, _array.arrayEach)(changes, function (change, index) {
|
|
var nextChange = changesLength > index + 1 ? changes[index + 1] : null;
|
|
|
|
if (nextChange) {
|
|
if (!isSelRowAreaCoverInputValue) {
|
|
offset.row += Math.max(nextChange[0] - change[0] - 1, 0);
|
|
}
|
|
if (!isSelColAreaCoverInputValue && change[1] > highestColumnIndex) {
|
|
highestColumnIndex = change[1];
|
|
offset.col += Math.max(nextChange[1] - change[1] - 1, 0);
|
|
}
|
|
}
|
|
});
|
|
_this6.hot.selectCell(areaStart.row, areaStart.col, areaEnd.row + offset.row, areaEnd.col + offset.col);
|
|
}
|
|
});
|
|
|
|
this.hot.populateFromArray(areaStart.row, areaStart.col, inputArray, areaEnd.row, areaEnd.col, 'CopyPaste.paste', this.pasteMode);
|
|
this.hot.runHooks('afterPaste', inputArray, this.copyableRanges);
|
|
}
|
|
|
|
/**
|
|
* Add copy, cut and paste options to the Context Menu.
|
|
*
|
|
* @private
|
|
* @param {Object} options Contains default added options of the Context Menu.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterContextMenuDefaultOptions',
|
|
value: function onAfterContextMenuDefaultOptions(options) {
|
|
options.items.push({
|
|
name: '---------'
|
|
}, (0, _copy2.default)(this), (0, _cut2.default)(this));
|
|
}
|
|
|
|
/**
|
|
* beforeKeyDown callback.
|
|
*
|
|
* @private
|
|
* @param {Event} event
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeKeyDown',
|
|
value: function onBeforeKeyDown(event) {
|
|
var _this7 = this;
|
|
|
|
if (!this.hot.getSelected()) {
|
|
return;
|
|
}
|
|
if (this.hot.getActiveEditor() && this.hot.getActiveEditor().isOpened()) {
|
|
return;
|
|
}
|
|
if ((0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
if (!this.textarea.isActive() && (0, _element.getSelectionText)()) {
|
|
return;
|
|
}
|
|
|
|
if ((0, _unicode.isCtrlKey)(event.keyCode)) {
|
|
// When fragmentSelection is enabled and some text is selected then don't blur selection calling 'setCopyableText'
|
|
if (this.hot.getSettings().fragmentSelection && (0, _element.getSelectionText)()) {
|
|
return;
|
|
}
|
|
|
|
// when CTRL is pressed, prepare selectable text in textarea
|
|
this.setCopyableText();
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
|
|
return;
|
|
}
|
|
|
|
// catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
|
|
var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
|
|
|
|
if (ctrlDown) {
|
|
if (event.keyCode == _unicode.KEY_CODES.A) {
|
|
setTimeout(function () {
|
|
_this7.setCopyableText();
|
|
}, 0);
|
|
}
|
|
if (event.keyCode == _unicode.KEY_CODES.X) {
|
|
this.cut();
|
|
}
|
|
if (event.keyCode == _unicode.KEY_CODES.C) {
|
|
this.copy();
|
|
}
|
|
if (event.keyCode == _unicode.KEY_CODES.V) {
|
|
this.triggerPaste();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
if (this.textarea) {
|
|
this.textarea.destroy();
|
|
}
|
|
|
|
_get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return CopyPaste;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('CopyPaste', CopyPaste);
|
|
|
|
exports.default = CopyPaste;
|
|
|
|
/***/ }),
|
|
/* 352 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Textarea
|
|
*
|
|
* @plugin CopyPaste
|
|
*/
|
|
var Textarea = function () {
|
|
_createClass(Textarea, null, [{
|
|
key: 'getSingleton',
|
|
value: function getSingleton() {
|
|
globalSingleton.append();
|
|
|
|
return globalSingleton;
|
|
}
|
|
}]);
|
|
|
|
function Textarea() {
|
|
_classCallCheck(this, Textarea);
|
|
|
|
/**
|
|
* Main textarea element.
|
|
*
|
|
* @type {HTMLElement}
|
|
*/
|
|
this.element = void 0;
|
|
/**
|
|
* Store information about append to the document.body.
|
|
*
|
|
* @type {Boolean}
|
|
*/
|
|
this.isAppended = false;
|
|
/**
|
|
* Reference counter.
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
this.refCounter = 0;
|
|
}
|
|
|
|
/**
|
|
* Apends textarea element to the `body`
|
|
*/
|
|
|
|
|
|
_createClass(Textarea, [{
|
|
key: 'append',
|
|
value: function append() {
|
|
if (this.hasBeenDestroyed()) {
|
|
this.create();
|
|
}
|
|
|
|
this.refCounter++;
|
|
|
|
if (!this.isAppended && document.body) {
|
|
if (document.body) {
|
|
this.isAppended = true;
|
|
document.body.appendChild(this.element);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prepares textarea element with proper attributes.
|
|
*/
|
|
|
|
}, {
|
|
key: 'create',
|
|
value: function create() {
|
|
this.element = document.createElement('textarea');
|
|
this.element.id = 'HandsontableCopyPaste';
|
|
this.element.className = 'copyPaste';
|
|
this.element.tabIndex = -1;
|
|
this.element.autocomplete = 'off';
|
|
this.element.wrap = 'off';
|
|
}
|
|
|
|
/**
|
|
* Deselects textarea element if is active.
|
|
*/
|
|
|
|
}, {
|
|
key: 'deselect',
|
|
value: function deselect() {
|
|
if (this.element === document.activeElement) {
|
|
document.activeElement.blur();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroy instance
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.refCounter--;
|
|
this.refCounter = this.refCounter < 0 ? 0 : this.refCounter;
|
|
|
|
if (this.hasBeenDestroyed() && this.element && this.element.parentNode) {
|
|
this.element.parentNode.removeChild(this.element);
|
|
this.element = null;
|
|
this.isAppended = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Getter for the element.
|
|
*
|
|
* @returns {String}
|
|
*/
|
|
|
|
}, {
|
|
key: 'getValue',
|
|
value: function getValue() {
|
|
return this.element.value;
|
|
}
|
|
|
|
/**
|
|
* Check if instance has been destroyed
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'hasBeenDestroyed',
|
|
value: function hasBeenDestroyed() {
|
|
return this.refCounter < 1;
|
|
}
|
|
|
|
/**
|
|
* Check if the element is an active element in frame.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
}, {
|
|
key: 'isActive',
|
|
value: function isActive() {
|
|
return this.element === document.activeElement;
|
|
}
|
|
|
|
/**
|
|
* Sets focus on the element and select content.
|
|
*/
|
|
|
|
}, {
|
|
key: 'select',
|
|
value: function select() {
|
|
this.element.focus();
|
|
this.element.select();
|
|
}
|
|
|
|
/**
|
|
* Setter for the element.
|
|
*
|
|
* @param {String} data Value which should be insert into the element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setValue',
|
|
value: function setValue(data) {
|
|
this.element.value = data;
|
|
}
|
|
}]);
|
|
|
|
return Textarea;
|
|
}();
|
|
|
|
var globalSingleton = new Textarea();
|
|
|
|
exports.default = Textarea;
|
|
|
|
/***/ }),
|
|
/* 353 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function CustomBorders() {}
|
|
/** *
|
|
* Current instance (table where borders should be placed)
|
|
*/
|
|
var instance;
|
|
|
|
/**
|
|
* 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: ''}
|
|
* ],
|
|
* ...
|
|
* ```
|
|
* @private
|
|
* @class CustomBorders
|
|
* @plugin CustomBorders
|
|
*/
|
|
|
|
/** *
|
|
* Check if plugin should be enabled.
|
|
*/
|
|
var checkEnable = function checkEnable(customBorders) {
|
|
if (typeof customBorders === 'boolean') {
|
|
if (customBorders === true) {
|
|
return true;
|
|
}
|
|
}
|
|
if ((typeof customBorders === 'undefined' ? 'undefined' : _typeof(customBorders)) === 'object') {
|
|
if (customBorders.length > 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/** *
|
|
* Initialize plugin.
|
|
*/
|
|
var init = function init() {
|
|
if (checkEnable(this.getSettings().customBorders)) {
|
|
if (!this.customBorders) {
|
|
instance = this;
|
|
this.customBorders = new CustomBorders();
|
|
}
|
|
}
|
|
};
|
|
|
|
/** *
|
|
* Get index of border from the settings.
|
|
*
|
|
* @param {String} className
|
|
* @returns {Number}
|
|
*/
|
|
var getSettingIndex = function getSettingIndex(className) {
|
|
for (var i = 0; i < instance.view.wt.selections.length; i++) {
|
|
if (instance.view.wt.selections[i].settings.className == className) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
};
|
|
|
|
/** *
|
|
* Insert WalkontableSelection instance into Walkontable settings.
|
|
*
|
|
* @param border
|
|
*/
|
|
var insertBorderIntoSettings = function insertBorderIntoSettings(border) {
|
|
var coordinates = {
|
|
row: border.row,
|
|
col: border.col
|
|
};
|
|
var selection = new _src.Selection(border, new _src.CellRange(coordinates, coordinates, coordinates));
|
|
var index = getSettingIndex(border.className);
|
|
|
|
if (index >= 0) {
|
|
instance.view.wt.selections[index] = selection;
|
|
} else {
|
|
instance.view.wt.selections.push(selection);
|
|
}
|
|
};
|
|
|
|
/** *
|
|
* Prepare borders from setting (single cell).
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @param borderObj
|
|
*/
|
|
var prepareBorderFromCustomAdded = function prepareBorderFromCustomAdded(row, col, borderObj) {
|
|
var border = createEmptyBorders(row, col);
|
|
border = extendDefaultBorder(border, borderObj);
|
|
this.setCellMeta(row, col, 'borders', border);
|
|
|
|
insertBorderIntoSettings(border);
|
|
};
|
|
|
|
/** *
|
|
* Prepare borders from setting (object).
|
|
*
|
|
* @param {Object} rowObj
|
|
*/
|
|
var prepareBorderFromCustomAddedRange = function prepareBorderFromCustomAddedRange(rowObj) {
|
|
var range = rowObj.range;
|
|
|
|
for (var row = range.from.row; row <= range.to.row; row++) {
|
|
for (var col = range.from.col; col <= range.to.col; col++) {
|
|
var border = createEmptyBorders(row, col);
|
|
var add = 0;
|
|
|
|
if (row == range.from.row) {
|
|
add++;
|
|
|
|
if ((0, _object.hasOwnProperty)(rowObj, 'top')) {
|
|
border.top = rowObj.top;
|
|
}
|
|
}
|
|
|
|
if (row == range.to.row) {
|
|
add++;
|
|
|
|
if ((0, _object.hasOwnProperty)(rowObj, 'bottom')) {
|
|
border.bottom = rowObj.bottom;
|
|
}
|
|
}
|
|
|
|
if (col == range.from.col) {
|
|
add++;
|
|
|
|
if ((0, _object.hasOwnProperty)(rowObj, 'left')) {
|
|
border.left = rowObj.left;
|
|
}
|
|
}
|
|
|
|
if (col == range.to.col) {
|
|
add++;
|
|
|
|
if ((0, _object.hasOwnProperty)(rowObj, 'right')) {
|
|
border.right = rowObj.right;
|
|
}
|
|
}
|
|
|
|
if (add > 0) {
|
|
this.setCellMeta(row, col, 'borders', border);
|
|
insertBorderIntoSettings(border);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/** *
|
|
* Create separated class name for borders for each cell.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @returns {String}
|
|
*/
|
|
var createClassName = function createClassName(row, col) {
|
|
return 'border_row' + row + 'col' + col;
|
|
};
|
|
|
|
/** *
|
|
* Create default single border for each position (top/right/bottom/left).
|
|
*
|
|
* @returns {Object} `{{width: number, color: string}}`
|
|
*/
|
|
var createDefaultCustomBorder = function createDefaultCustomBorder() {
|
|
return {
|
|
width: 1,
|
|
color: '#000'
|
|
};
|
|
};
|
|
|
|
/** *
|
|
* Create default object for empty border.
|
|
*
|
|
* @returns {Object} `{{hide: boolean}}`
|
|
*/
|
|
var createSingleEmptyBorder = function createSingleEmptyBorder() {
|
|
return {
|
|
hide: true
|
|
};
|
|
};
|
|
|
|
/** *
|
|
* Create default Handsontable border object.
|
|
*
|
|
* @returns {Object} `{{width: number, color: string, cornerVisible: boolean}}`
|
|
*/
|
|
var createDefaultHtBorder = function createDefaultHtBorder() {
|
|
return {
|
|
width: 1,
|
|
color: '#000',
|
|
cornerVisible: false
|
|
};
|
|
};
|
|
|
|
/** *
|
|
* Prepare empty border for each cell with all custom borders hidden.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
* @returns {Object} `{{className: *, border: *, row: *, col: *, top: {hide: boolean}, right: {hide: boolean}, bottom: {hide: boolean}, left: {hide: boolean}}}`
|
|
*/
|
|
var createEmptyBorders = function createEmptyBorders(row, col) {
|
|
return {
|
|
className: createClassName(row, col),
|
|
border: createDefaultHtBorder(),
|
|
row: row,
|
|
col: col,
|
|
top: createSingleEmptyBorder(),
|
|
right: createSingleEmptyBorder(),
|
|
bottom: createSingleEmptyBorder(),
|
|
left: createSingleEmptyBorder()
|
|
};
|
|
};
|
|
|
|
var extendDefaultBorder = function extendDefaultBorder(defaultBorder, customBorder) {
|
|
if ((0, _object.hasOwnProperty)(customBorder, 'border')) {
|
|
defaultBorder.border = customBorder.border;
|
|
}
|
|
|
|
if ((0, _object.hasOwnProperty)(customBorder, 'top')) {
|
|
defaultBorder.top = customBorder.top;
|
|
}
|
|
|
|
if ((0, _object.hasOwnProperty)(customBorder, 'right')) {
|
|
defaultBorder.right = customBorder.right;
|
|
}
|
|
|
|
if ((0, _object.hasOwnProperty)(customBorder, 'bottom')) {
|
|
defaultBorder.bottom = customBorder.bottom;
|
|
}
|
|
|
|
if ((0, _object.hasOwnProperty)(customBorder, 'left')) {
|
|
defaultBorder.left = customBorder.left;
|
|
}
|
|
|
|
return defaultBorder;
|
|
};
|
|
|
|
/**
|
|
* Remove borders divs from DOM.
|
|
*
|
|
* @param borderClassName
|
|
*/
|
|
var removeBordersFromDom = function removeBordersFromDom(borderClassName) {
|
|
var borders = document.querySelectorAll('.' + borderClassName);
|
|
|
|
for (var i = 0; i < borders.length; i++) {
|
|
if (borders[i]) {
|
|
if (borders[i].nodeName != 'TD') {
|
|
var parent = borders[i].parentNode;
|
|
|
|
if (parent.parentNode) {
|
|
parent.parentNode.removeChild(parent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/** *
|
|
* Remove border (triggered from context menu).
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} col Visual column index.
|
|
*/
|
|
var removeAllBorders = function removeAllBorders(row, col) {
|
|
var borderClassName = createClassName(row, col);
|
|
removeBordersFromDom(borderClassName);
|
|
this.removeCellMeta(row, col, 'borders');
|
|
};
|
|
|
|
/** *
|
|
* Set borders for each cell re. to border position
|
|
*
|
|
* @param row Visual row index.
|
|
* @param col Visual column index.
|
|
* @param place
|
|
* @param remove
|
|
*/
|
|
var setBorder = function setBorder(row, col, place, remove) {
|
|
|
|
var bordersMeta = this.getCellMeta(row, col).borders;
|
|
|
|
if (!bordersMeta || bordersMeta.border == undefined) {
|
|
bordersMeta = createEmptyBorders(row, col);
|
|
}
|
|
|
|
if (remove) {
|
|
bordersMeta[place] = createSingleEmptyBorder();
|
|
} else {
|
|
bordersMeta[place] = createDefaultCustomBorder();
|
|
}
|
|
|
|
this.setCellMeta(row, col, 'borders', bordersMeta);
|
|
|
|
var borderClassName = createClassName(row, col);
|
|
removeBordersFromDom(borderClassName);
|
|
insertBorderIntoSettings(bordersMeta);
|
|
|
|
this.render();
|
|
};
|
|
|
|
/** *
|
|
* Prepare borders based on cell and border position
|
|
*
|
|
* @param range
|
|
* @param place
|
|
* @param remove
|
|
*/
|
|
var prepareBorder = function prepareBorder(range, place, remove) {
|
|
|
|
if (range.from.row == range.to.row && range.from.col == range.to.col) {
|
|
if (place == 'noBorders') {
|
|
removeAllBorders.call(this, range.from.row, range.from.col);
|
|
} else {
|
|
setBorder.call(this, range.from.row, range.from.col, place, remove);
|
|
}
|
|
} else {
|
|
switch (place) {
|
|
case 'noBorders':
|
|
for (var column = range.from.col; column <= range.to.col; column++) {
|
|
for (var row = range.from.row; row <= range.to.row; row++) {
|
|
removeAllBorders.call(this, row, column);
|
|
}
|
|
}
|
|
break;
|
|
case 'top':
|
|
for (var topCol = range.from.col; topCol <= range.to.col; topCol++) {
|
|
setBorder.call(this, range.from.row, topCol, place, remove);
|
|
}
|
|
break;
|
|
case 'right':
|
|
for (var rowRight = range.from.row; rowRight <= range.to.row; rowRight++) {
|
|
setBorder.call(this, rowRight, range.to.col, place);
|
|
}
|
|
break;
|
|
case 'bottom':
|
|
for (var bottomCol = range.from.col; bottomCol <= range.to.col; bottomCol++) {
|
|
setBorder.call(this, range.to.row, bottomCol, place);
|
|
}
|
|
break;
|
|
case 'left':
|
|
for (var rowLeft = range.from.row; rowLeft <= range.to.row; rowLeft++) {
|
|
setBorder.call(this, rowLeft, range.from.col, place);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
/** *
|
|
* Check if selection has border by className
|
|
*
|
|
* @param hot
|
|
* @param direction
|
|
*/
|
|
var checkSelectionBorders = function checkSelectionBorders(hot, direction) {
|
|
var atLeastOneHasBorder = false;
|
|
|
|
hot.getSelectedRange().forAll(function (r, c) {
|
|
var metaBorders = hot.getCellMeta(r, c).borders;
|
|
|
|
if (metaBorders) {
|
|
if (direction) {
|
|
if (!(0, _object.hasOwnProperty)(metaBorders[direction], 'hide')) {
|
|
atLeastOneHasBorder = true;
|
|
return false; // breaks forAll
|
|
}
|
|
} else {
|
|
atLeastOneHasBorder = true;
|
|
return false; // breaks forAll
|
|
}
|
|
}
|
|
});
|
|
return atLeastOneHasBorder;
|
|
};
|
|
|
|
/** *
|
|
* Mark label in contextMenu as selected
|
|
*
|
|
* @param label
|
|
* @returns {string}
|
|
*/
|
|
var markSelected = function markSelected(label) {
|
|
return '<span class="selected">' + String.fromCharCode(10003) + '</span>' + label; // workaround for https://github.com/handsontable/handsontable/issues/1946
|
|
};
|
|
|
|
/** *
|
|
* Add border options to context menu
|
|
*
|
|
* @param defaultOptions
|
|
*/
|
|
var addBordersOptionsToContextMenu = function addBordersOptionsToContextMenu(defaultOptions) {
|
|
if (!this.getSettings().customBorders) {
|
|
return;
|
|
}
|
|
|
|
defaultOptions.items.push({
|
|
name: '---------'
|
|
});
|
|
defaultOptions.items.push({
|
|
key: 'borders',
|
|
name: 'Borders',
|
|
disabled: function disabled() {
|
|
return this.selection.selectedHeader.corner;
|
|
},
|
|
|
|
submenu: {
|
|
items: [{
|
|
key: 'borders:top',
|
|
name: function name() {
|
|
var label = 'Top';
|
|
var hasBorder = checkSelectionBorders(this, 'top');
|
|
if (hasBorder) {
|
|
label = markSelected(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var hasBorder = checkSelectionBorders(this, 'top');
|
|
prepareBorder.call(this, this.getSelectedRange(), 'top', hasBorder);
|
|
}
|
|
}, {
|
|
key: 'borders:right',
|
|
name: function name() {
|
|
var label = 'Right';
|
|
var hasBorder = checkSelectionBorders(this, 'right');
|
|
if (hasBorder) {
|
|
label = markSelected(label);
|
|
}
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var hasBorder = checkSelectionBorders(this, 'right');
|
|
prepareBorder.call(this, this.getSelectedRange(), 'right', hasBorder);
|
|
}
|
|
}, {
|
|
key: 'borders:bottom',
|
|
name: function name() {
|
|
var label = 'Bottom';
|
|
var hasBorder = checkSelectionBorders(this, 'bottom');
|
|
if (hasBorder) {
|
|
label = markSelected(label);
|
|
}
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var hasBorder = checkSelectionBorders(this, 'bottom');
|
|
prepareBorder.call(this, this.getSelectedRange(), 'bottom', hasBorder);
|
|
}
|
|
}, {
|
|
key: 'borders:left',
|
|
name: function name() {
|
|
var label = 'Left';
|
|
var hasBorder = checkSelectionBorders(this, 'left');
|
|
if (hasBorder) {
|
|
label = markSelected(label);
|
|
}
|
|
|
|
return label;
|
|
},
|
|
callback: function callback() {
|
|
var hasBorder = checkSelectionBorders(this, 'left');
|
|
prepareBorder.call(this, this.getSelectedRange(), 'left', hasBorder);
|
|
}
|
|
}, {
|
|
key: 'borders:no_borders',
|
|
name: 'Remove border(s)',
|
|
callback: function callback() {
|
|
prepareBorder.call(this, this.getSelectedRange(), 'noBorders');
|
|
},
|
|
disabled: function disabled() {
|
|
return !checkSelectionBorders(this);
|
|
}
|
|
}]
|
|
}
|
|
});
|
|
};
|
|
|
|
_pluginHooks2.default.getSingleton().add('beforeInit', init);
|
|
_pluginHooks2.default.getSingleton().add('afterContextMenuDefaultOptions', addBordersOptionsToContextMenu);
|
|
_pluginHooks2.default.getSingleton().add('afterInit', function () {
|
|
var customBorders = this.getSettings().customBorders;
|
|
|
|
if (customBorders) {
|
|
for (var i = 0; i < customBorders.length; i++) {
|
|
if (customBorders[i].range) {
|
|
prepareBorderFromCustomAddedRange.call(this, customBorders[i]);
|
|
} else {
|
|
prepareBorderFromCustomAdded.call(this, customBorders[i].row, customBorders[i].col, customBorders[i]);
|
|
}
|
|
}
|
|
|
|
this.render();
|
|
this.view.wt.draw(true);
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
/* 354 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* @description
|
|
* Plugin used to scroll Handsontable by selecting a cell and dragging outside of the visible viewport.
|
|
*
|
|
* @private
|
|
* @class DragToScroll
|
|
* @plugin DragToScroll
|
|
*/
|
|
function DragToScroll() {
|
|
this.boundaries = null;
|
|
this.callback = null;
|
|
}
|
|
|
|
/**
|
|
* @param boundaries {Object} compatible with getBoundingClientRect
|
|
*/
|
|
DragToScroll.prototype.setBoundaries = function (boundaries) {
|
|
this.boundaries = boundaries;
|
|
};
|
|
|
|
/**
|
|
* @param callback {Function}
|
|
*/
|
|
DragToScroll.prototype.setCallback = function (callback) {
|
|
this.callback = callback;
|
|
};
|
|
|
|
/**
|
|
* Check if mouse position (x, y) is outside of the viewport
|
|
* @param x
|
|
* @param y
|
|
*/
|
|
DragToScroll.prototype.check = function (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);
|
|
};
|
|
|
|
var dragToScroll;
|
|
var instance;
|
|
|
|
var setupListening = function setupListening(instance) {
|
|
instance.dragToScrollListening = false;
|
|
var scrollHandler = instance.view.wt.wtTable.holder; // native scroll
|
|
dragToScroll = new DragToScroll();
|
|
|
|
if (scrollHandler === window) {
|
|
// not much we can do currently
|
|
return;
|
|
}
|
|
|
|
dragToScroll.setBoundaries(scrollHandler.getBoundingClientRect());
|
|
dragToScroll.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;
|
|
}
|
|
});
|
|
|
|
instance.dragToScrollListening = true;
|
|
};
|
|
|
|
_pluginHooks2.default.getSingleton().add('afterInit', function () {
|
|
var instance = this;
|
|
var eventManager = new _eventManager2.default(this);
|
|
|
|
eventManager.addEventListener(document, 'mouseup', function () {
|
|
instance.dragToScrollListening = false;
|
|
});
|
|
|
|
eventManager.addEventListener(document, 'mousemove', function (event) {
|
|
if (instance.dragToScrollListening) {
|
|
dragToScroll.check(event.clientX, event.clientY);
|
|
}
|
|
});
|
|
});
|
|
|
|
_pluginHooks2.default.getSingleton().add('afterDestroy', function () {
|
|
new _eventManager2.default(this).clear();
|
|
});
|
|
|
|
_pluginHooks2.default.getSingleton().add('afterOnCellMouseDown', function () {
|
|
setupListening(this);
|
|
});
|
|
|
|
_pluginHooks2.default.getSingleton().add('afterOnCellCornerMouseDown', function () {
|
|
setupListening(this);
|
|
});
|
|
|
|
exports.default = DragToScroll;
|
|
|
|
/***/ }),
|
|
/* 355 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = freezeColumnItem;
|
|
function freezeColumnItem(manualColumnFreezePlugin) {
|
|
return {
|
|
key: 'freeze_column',
|
|
name: 'Freeze this column',
|
|
callback: function callback() {
|
|
var selectedColumn = this.getSelectedRange().from.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.from.col !== selection.to.col || selection.from.col <= this.getSettings().fixedColumnsLeft - 1) {
|
|
hide = true;
|
|
}
|
|
|
|
return hide;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 356 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = unfreezeColumnItem;
|
|
function unfreezeColumnItem(manualColumnFreezePlugin) {
|
|
return {
|
|
key: 'unfreeze_column',
|
|
name: 'Unfreeze this column',
|
|
callback: function callback() {
|
|
var selectedColumn = this.getSelectedRange().from.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.from.col !== selection.to.col || selection.from.col >= this.getSettings().fixedColumnsLeft) {
|
|
hide = true;
|
|
}
|
|
|
|
return hide;
|
|
}
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 357 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _freezeColumn = __webpack_require__(355);
|
|
|
|
var _freezeColumn2 = _interopRequireDefault(_freezeColumn);
|
|
|
|
var _unfreezeColumn = __webpack_require__(356);
|
|
|
|
var _unfreezeColumn2 = _interopRequireDefault(_unfreezeColumn);
|
|
|
|
__webpack_require__(415);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var privatePool = new WeakMap();
|
|
/**
|
|
* This plugin allows to manually "freeze" and "unfreeze" a column using an entry in the Context Menu.
|
|
* You can turn it on by setting a `manualColumnFreeze` property to `true`.
|
|
*
|
|
* @plugin ManualColumnFreeze
|
|
* @dependencies ManualColumnMove
|
|
*/
|
|
|
|
var ManualColumnFreeze = function (_BasePlugin) {
|
|
_inherits(ManualColumnFreeze, _BasePlugin);
|
|
|
|
function ManualColumnFreeze(hotInstance) {
|
|
_classCallCheck(this, ManualColumnFreeze);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ManualColumnFreeze.__proto__ || Object.getPrototypeOf(ManualColumnFreeze)).call(this, hotInstance));
|
|
|
|
privatePool.set(_this, {
|
|
moveByFreeze: false,
|
|
afterFirstUse: false
|
|
});
|
|
/**
|
|
* Original column positions
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
_this.frozenColumnsBasePositions = [];
|
|
/**
|
|
* Reference to the `ManualColumnMove` plugin.
|
|
*/
|
|
_this.manualColumnMovePlugin = void 0;
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the Handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ManualColumnFreeze, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return !!this.hot.getSettings().manualColumnFreeze;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin 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);
|
|
});
|
|
|
|
_get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
var priv = privatePool.get(this);
|
|
|
|
priv.afterFirstUse = false;
|
|
priv.moveByFreeze = false;
|
|
|
|
_get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Updates the plugin to use the latest options you have specified.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
this.disablePlugin();
|
|
this.enablePlugin();
|
|
|
|
_get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Freeze 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++);
|
|
}
|
|
|
|
/**
|
|
* Unfreeze 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--;
|
|
|
|
this.getMovePlugin().moveColumn(column, returnCol + 1);
|
|
}
|
|
|
|
/**
|
|
* Get 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 = void 0;
|
|
|
|
if (this.frozenColumnsBasePositions[column] == null) {
|
|
initialCol = movePlugin.columnsMapper.getValueByIndex(column);
|
|
|
|
while (j < initialCol) {
|
|
i++;
|
|
j = movePlugin.columnsMapper.getValueByIndex(i);
|
|
}
|
|
} else {
|
|
initialCol = this.frozenColumnsBasePositions[column];
|
|
this.frozenColumnsBasePositions[column] = void 0;
|
|
|
|
while (j <= initialCol) {
|
|
i++;
|
|
j = movePlugin.columnsMapper.getValueByIndex(i);
|
|
}
|
|
i = j;
|
|
}
|
|
|
|
return i - 1;
|
|
}
|
|
/**
|
|
* Add the manualColumnFreeze context menu entries.
|
|
*
|
|
* @private
|
|
* @param {Object} options Context menu options.
|
|
*/
|
|
|
|
}, {
|
|
key: 'addContextMenuEntry',
|
|
value: function addContextMenuEntry(options) {
|
|
options.items.push({ name: '---------' }, (0, _freezeColumn2.default)(this), (0, _unfreezeColumn2.default)(this));
|
|
}
|
|
|
|
/**
|
|
* Enabling `manualColumnMove` plugin on `afterInit` hook.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterInit',
|
|
value: function onAfterInit() {
|
|
if (!this.getMovePlugin().isEnabled()) {
|
|
this.getMovePlugin().enablePlugin();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prevent 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, index, array) {
|
|
if (value < frozenLen) {
|
|
disallowMoving = true;
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
if (disallowMoving) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (priv.moveByFreeze) {
|
|
priv.moveByFreeze = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
_get(ManualColumnFreeze.prototype.__proto__ || Object.getPrototypeOf(ManualColumnFreeze.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return ManualColumnFreeze;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('manualColumnFreeze', ManualColumnFreeze);
|
|
|
|
exports.default = ManualColumnFreeze;
|
|
|
|
/***/ }),
|
|
/* 358 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _arrayMapper = __webpack_require__(265);
|
|
|
|
var _arrayMapper2 = _interopRequireDefault(_arrayMapper);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class ColumnsMapper
|
|
* @plugin ManualColumnMove
|
|
*/
|
|
var ColumnsMapper = function () {
|
|
function ColumnsMapper(manualColumnMove) {
|
|
_classCallCheck(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.
|
|
*/
|
|
|
|
|
|
_createClass(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, _arrayMapper2.default);
|
|
|
|
exports.default = ColumnsMapper;
|
|
|
|
/***/ }),
|
|
/* 359 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _columnsMapper = __webpack_require__(358);
|
|
|
|
var _columnsMapper2 = _interopRequireDefault(_columnsMapper);
|
|
|
|
var _backlight = __webpack_require__(360);
|
|
|
|
var _backlight2 = _interopRequireDefault(_backlight);
|
|
|
|
var _guideline = __webpack_require__(361);
|
|
|
|
var _guideline2 = _interopRequireDefault(_guideline);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
__webpack_require__(416);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
_pluginHooks2.default.getSingleton().register('beforeColumnMove');
|
|
_pluginHooks2.default.getSingleton().register('afterColumnMove');
|
|
_pluginHooks2.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.
|
|
*
|
|
* 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.
|
|
*
|
|
* UI components:
|
|
* - backlight - highlight of selected columns.
|
|
* - guideline - line which shows where rows has been moved.
|
|
*
|
|
* @class ManualColumnMove
|
|
* @plugin ManualColumnMove
|
|
*/
|
|
|
|
var ManualColumnMove = function (_BasePlugin) {
|
|
_inherits(ManualColumnMove, _BasePlugin);
|
|
|
|
function ManualColumnMove(hotInstance) {
|
|
_classCallCheck(this, ManualColumnMove);
|
|
|
|
/**
|
|
* Set up WeakMap of plugin to sharing private parameters;
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (ManualColumnMove.__proto__ || Object.getPrototypeOf(ManualColumnMove)).call(this, hotInstance));
|
|
|
|
privatePool.set(_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.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
_this.removedColumns = [];
|
|
/**
|
|
* Object containing visual row indexes mapped to data source indexes.
|
|
*
|
|
* @type {RowsMapper}
|
|
*/
|
|
_this.columnsMapper = new _columnsMapper2.default(_this);
|
|
/**
|
|
* Event Manager object.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
_this.eventManager = new _eventManager2.default(_this);
|
|
/**
|
|
* Backlight UI object.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
_this.backlight = new _backlight2.default(hotInstance);
|
|
/**
|
|
* Guideline UI object.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
_this.guideline = new _guideline2.default(hotInstance);
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if plugin is enabled.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ManualColumnMove, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return !!this.hot.getSettings().manualColumnMove;
|
|
}
|
|
|
|
/**
|
|
* Enable the plugin.
|
|
*/
|
|
|
|
}, {
|
|
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 (index, amount) {
|
|
return _this2.onAfterRemoveCol(index, amount);
|
|
});
|
|
this.addHook('afterCreateCol', function (index, amount) {
|
|
return _this2.onAfterCreateCol(index, amount);
|
|
});
|
|
this.addHook('afterLoadData', function (firstTime) {
|
|
return _this2.onAfterLoadData(firstTime);
|
|
});
|
|
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);
|
|
|
|
_get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Updates the plugin to use the latest options you have specified.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
this.disablePlugin();
|
|
this.enablePlugin();
|
|
|
|
this.onAfterPluginsInitialized();
|
|
|
|
_get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin 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();
|
|
|
|
_get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Move 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.
|
|
*/
|
|
|
|
}, {
|
|
key: 'moveColumn',
|
|
value: function moveColumn(column, target) {
|
|
this.moveColumns([column], target);
|
|
}
|
|
|
|
/**
|
|
* Move 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.
|
|
*/
|
|
|
|
}, {
|
|
key: 'moveColumns',
|
|
value: function moveColumns(columns, target) {
|
|
var _this3 = this;
|
|
|
|
var priv = privatePool.get(this);
|
|
var beforeColumnHook = this.hot.runHooks('beforeColumnMove', columns, 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', columns, 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) {
|
|
var selection = this.hot.selection;
|
|
var lastRowIndex = this.hot.countRows() - 1;
|
|
|
|
selection.setRangeStartOnly(new _src.CellCoords(0, startColumn));
|
|
selection.setRangeEnd(new _src.CellCoords(lastRowIndex, endColumn), false);
|
|
}
|
|
|
|
/**
|
|
* Get 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.wtTable.getColumnWidth(i) || 0;
|
|
} else {
|
|
columnWidth = this.hot.view.wt.wtTable.getStretchedColumnWidth(i) || 0;
|
|
}
|
|
|
|
width += columnWidth;
|
|
}
|
|
|
|
return width;
|
|
}
|
|
|
|
/**
|
|
* Load 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();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check 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;
|
|
}
|
|
|
|
/**
|
|
* Save the manual column positions to the persistent state.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'persistentStateSave',
|
|
value: function persistentStateSave() {
|
|
this.hot.runHooks('persistentStateSave', 'manualColumnMove', this.columnsMapper._arrayMap);
|
|
}
|
|
|
|
/**
|
|
* Load the manual column positions from the persistent state.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'persistentStateLoad',
|
|
value: function persistentStateLoad() {
|
|
var storedState = {};
|
|
|
|
this.hot.runHooks('persistentStateLoad', 'manualColumnMove', storedState);
|
|
|
|
if (storedState.value) {
|
|
this.columnsMapper._arrayMap = storedState.value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prepare 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;
|
|
}
|
|
|
|
/**
|
|
* Update 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++;
|
|
}
|
|
}
|
|
|
|
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) {
|
|
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) {
|
|
this.hot.scrollViewportTo(void 0, firstVisible - 1);
|
|
}
|
|
}
|
|
|
|
if (priv.target.col <= firstVisible && priv.target.col >= priv.fixedColumns) {
|
|
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, array) {
|
|
if (value > maxIndex) {
|
|
columnsToRemove.push(index);
|
|
}
|
|
});
|
|
|
|
this.columnsMapper.removeItems(columnsToRemove);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bind the events used by the plugin.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerEvents',
|
|
value: function registerEvents() {
|
|
var _this4 = this;
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) {
|
|
return _this4.onMouseMove(event);
|
|
});
|
|
this.eventManager.addEventListener(document.documentElement, 'mouseup', function () {
|
|
return _this4.onMouseUp();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Unbind the events used by the plugin.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'unregisterEvents',
|
|
value: function unregisterEvents() {
|
|
this.eventManager.clear();
|
|
}
|
|
|
|
/**
|
|
* Change 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.selectedHeader.cols;
|
|
var selection = this.hot.getSelectedRange();
|
|
var priv = privatePool.get(this);
|
|
var isSortingElement = event.realTarget.className.indexOf('columnSorting') > -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.getSelectedRange();
|
|
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.selectedHeader.cols) {
|
|
(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
|
|
* @param {Number} index Visual column index of the removed column.
|
|
* @param {Number} amount Amount of removed columns.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterRemoveCol',
|
|
value: function onAfterRemoveCol(index, amount) {
|
|
this.columnsMapper.unshiftItems(this.removedColumns);
|
|
}
|
|
|
|
/**
|
|
* `afterLoadData` hook callback.
|
|
*
|
|
* @private
|
|
* @param {Boolean} firstTime True if that was loading data during the initialization.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterLoadData',
|
|
value: function onAfterLoadData(firstTime) {
|
|
this.updateColumnsMapper();
|
|
}
|
|
|
|
/**
|
|
* 'modifyRow' hook callback.
|
|
*
|
|
* @private
|
|
* @param {Number} column Visual column index.
|
|
* @returns {Number} Physical column index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onModifyCol',
|
|
value: function onModifyCol(column, source) {
|
|
if (source !== this.pluginName) {
|
|
// ugly fix for try to insert new, needed columns after pasting data
|
|
var columnInMapper = this.columnsMapper.getValueByIndex(column);
|
|
column = columnInMapper === null ? column : columnInMapper;
|
|
}
|
|
|
|
return column;
|
|
}
|
|
|
|
/**
|
|
* '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();
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.backlight.destroy();
|
|
this.guideline.destroy();
|
|
|
|
_get(ManualColumnMove.prototype.__proto__ || Object.getPrototypeOf(ManualColumnMove.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return ManualColumnMove;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('ManualColumnMove', ManualColumnMove);
|
|
|
|
exports.default = ManualColumnMove;
|
|
|
|
/***/ }),
|
|
/* 360 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(266);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var CSS_CLASSNAME = 'ht__manualColumnMove--backlight';
|
|
|
|
/**
|
|
* @class BacklightUI
|
|
* @util
|
|
*/
|
|
|
|
var BacklightUI = function (_BaseUI) {
|
|
_inherits(BacklightUI, _BaseUI);
|
|
|
|
function BacklightUI() {
|
|
_classCallCheck(this, BacklightUI);
|
|
|
|
return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(BacklightUI, [{
|
|
key: 'build',
|
|
|
|
/**
|
|
* Custom className on build process.
|
|
*/
|
|
value: function build() {
|
|
_get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this);
|
|
|
|
(0, _element.addClass)(this._element, CSS_CLASSNAME);
|
|
}
|
|
}]);
|
|
|
|
return BacklightUI;
|
|
}(_base2.default);
|
|
|
|
exports.default = BacklightUI;
|
|
|
|
/***/ }),
|
|
/* 361 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(266);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var CSS_CLASSNAME = 'ht__manualColumnMove--guideline';
|
|
|
|
/**
|
|
* @class GuidelineUI
|
|
* @util
|
|
*/
|
|
|
|
var GuidelineUI = function (_BaseUI) {
|
|
_inherits(GuidelineUI, _BaseUI);
|
|
|
|
function GuidelineUI() {
|
|
_classCallCheck(this, GuidelineUI);
|
|
|
|
return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(GuidelineUI, [{
|
|
key: 'build',
|
|
|
|
/**
|
|
* Custom className on build process.
|
|
*/
|
|
value: function build() {
|
|
_get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this);
|
|
|
|
(0, _element.addClass)(this._element, CSS_CLASSNAME);
|
|
}
|
|
}]);
|
|
|
|
return GuidelineUI;
|
|
}(_base2.default);
|
|
|
|
exports.default = GuidelineUI;
|
|
|
|
/***/ }),
|
|
/* 362 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js
|
|
|
|
/**
|
|
* @description
|
|
* ManualColumnResize Plugin.
|
|
*
|
|
* Has 2 UI components:
|
|
* - 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 = function (_BasePlugin) {
|
|
_inherits(ManualColumnResize, _BasePlugin);
|
|
|
|
function ManualColumnResize(hotInstance) {
|
|
_classCallCheck(this, ManualColumnResize);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ManualColumnResize.__proto__ || Object.getPrototypeOf(ManualColumnResize)).call(this, hotInstance));
|
|
|
|
_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 = document.createElement('DIV');
|
|
_this.guide = document.createElement('DIV');
|
|
_this.eventManager = new _eventManager2.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;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ManualColumnResize, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return this.hot.getSettings().manualColumnResize;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin 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();
|
|
|
|
_get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Updates the plugin to use the latest options you have specified.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
var initialColumnWidth = this.hot.getSettings().manualColumnResize;
|
|
|
|
if (Array.isArray(initialColumnWidth)) {
|
|
this.manualColumnWidths = initialColumnWidth;
|
|
} else if (!initialColumnWidth) {
|
|
this.manualColumnWidths = [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
_get(ManualColumnResize.prototype.__proto__ || Object.getPrototypeOf(ManualColumnResize.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Save the current sizes using the persistentState plugin.
|
|
*/
|
|
|
|
}, {
|
|
key: 'saveManualColumnWidths',
|
|
value: function saveManualColumnWidths() {
|
|
this.hot.runHooks('persistentStateSave', 'manualColumnWidths', this.manualColumnWidths);
|
|
}
|
|
|
|
/**
|
|
* Load the previously saved sizes using the persistentState plugin.
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'loadManualColumnWidths',
|
|
value: function loadManualColumnWidths() {
|
|
var storedState = {};
|
|
|
|
this.hot.runHooks('persistentStateLoad', 'manualColumnWidths', storedState);
|
|
|
|
return storedState.value;
|
|
}
|
|
|
|
/**
|
|
* Set the resize handle position.
|
|
*
|
|
* @param {HTMLCellElement} TH TH HTML element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setupHandlePosition',
|
|
value: function setupHandlePosition(TH) {
|
|
var _this3 = this;
|
|
|
|
if (!TH.parentNode) {
|
|
return false;
|
|
}
|
|
|
|
this.currentTH = TH;
|
|
|
|
var col = this.hot.view.wt.wtTable.getCoords(TH).col; // getCoords returns CellCoords
|
|
var headerHeight = (0, _element.outerHeight)(this.currentTH);
|
|
|
|
if (col >= 0) {
|
|
// if not col header
|
|
var box = this.currentTH.getBoundingClientRect();
|
|
|
|
this.currentCol = col;
|
|
this.selectedCols = [];
|
|
|
|
if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.cols) {
|
|
var _hot$getSelectedRange = this.hot.getSelectedRange(),
|
|
from = _hot$getSelectedRange.from,
|
|
to = _hot$getSelectedRange.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 = box.left - 6;
|
|
this.startWidth = parseInt(box.width, 10);
|
|
this.handle.style.top = box.top + 'px';
|
|
this.handle.style.left = this.startOffset + this.startWidth + 'px';
|
|
this.handle.style.height = headerHeight + 'px';
|
|
this.hot.rootElement.appendChild(this.handle);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refresh the resize handle position.
|
|
*/
|
|
|
|
}, {
|
|
key: 'refreshHandlePosition',
|
|
value: function refreshHandlePosition() {
|
|
this.handle.style.left = this.startOffset + this.currentWidth + 'px';
|
|
}
|
|
|
|
/**
|
|
* Set the resize guide position.
|
|
*/
|
|
|
|
}, {
|
|
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 = handleBottomPosition + 'px';
|
|
this.guide.style.left = this.handle.style.left;
|
|
this.guide.style.height = maximumVisibleElementHeight - handleHeight + 'px';
|
|
this.hot.rootElement.appendChild(this.guide);
|
|
}
|
|
|
|
/**
|
|
* Refresh the resize guide position.
|
|
*/
|
|
|
|
}, {
|
|
key: 'refreshGuidePosition',
|
|
value: function refreshGuidePosition() {
|
|
this.guide.style.left = this.handle.style.left;
|
|
}
|
|
|
|
/**
|
|
* Hide both the resize handle and resize guide.
|
|
*/
|
|
|
|
}, {
|
|
key: 'hideHandleAndGuide',
|
|
value: function hideHandleAndGuide() {
|
|
(0, _element.removeClass)(this.handle, 'active');
|
|
(0, _element.removeClass)(this.guide, 'active');
|
|
}
|
|
|
|
/**
|
|
* Check if provided element is considered a column header.
|
|
*
|
|
* @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;
|
|
}
|
|
|
|
/**
|
|
* Get the TH element from the provided element.
|
|
*
|
|
* @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
|
|
*/
|
|
|
|
}, {
|
|
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} e
|
|
*/
|
|
|
|
}, {
|
|
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++;
|
|
|
|
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} e
|
|
*/
|
|
|
|
}, {
|
|
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
|
|
* @param {MouseEvent} e
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseUp',
|
|
value: function onMouseUp(event) {
|
|
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);
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bind the mouse events.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'bindEvents',
|
|
value: function bindEvents() {
|
|
var _this8 = this;
|
|
|
|
this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) {
|
|
return _this8.onMouseOver(e);
|
|
});
|
|
this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) {
|
|
return _this8.onMouseDown(e);
|
|
});
|
|
this.eventManager.addEventListener(window, 'mousemove', function (e) {
|
|
return _this8.onMouseMove(e);
|
|
});
|
|
this.eventManager.addEventListener(window, 'mouseup', function (e) {
|
|
return _this8.onMouseUp(e);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Cache the current column width.
|
|
*
|
|
* @param {Number} column Visual column index.
|
|
* @param {Number} width Column width.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'setManualSize',
|
|
value: function setManualSize(column, width) {
|
|
width = 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.
|
|
*/
|
|
column = this.hot.runHooks('modifyCol', column);
|
|
|
|
this.manualColumnWidths[column] = width;
|
|
|
|
return width;
|
|
}
|
|
|
|
/**
|
|
* Clear cache for the current column index.
|
|
*
|
|
* @param {Number} column Visual column index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'clearManualSize',
|
|
value: function clearManualSize(column) {
|
|
column = this.hot.runHooks('modifyCol', column);
|
|
|
|
this.manualColumnWidths[column] = void 0;
|
|
}
|
|
|
|
/**
|
|
* Modify 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) {
|
|
if (this.enabled) {
|
|
column = this.hot.runHooks('modifyCol', column);
|
|
|
|
if (this.hot.getSettings().manualColumnResize && this.manualColumnWidths[column]) {
|
|
return this.manualColumnWidths[column];
|
|
}
|
|
}
|
|
|
|
return width;
|
|
}
|
|
|
|
/**
|
|
* Modify 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
|
|
* @param {Number} currentColumn Index of the resized column.
|
|
* @param {Number} newSize Calculated new column width.
|
|
* @param {Boolean} isDoubleClick Flag that determines whether there was a double-click.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onBeforeColumnResize',
|
|
value: function onBeforeColumnResize() {
|
|
// clear the header height cache information
|
|
this.hot.view.wt.wtViewport.hasOversizedColumnHeadersMarked = {};
|
|
}
|
|
}]);
|
|
|
|
return ManualColumnResize;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('manualColumnResize', ManualColumnResize);
|
|
|
|
exports.default = ManualColumnResize;
|
|
|
|
/***/ }),
|
|
/* 363 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _rowsMapper = __webpack_require__(364);
|
|
|
|
var _rowsMapper2 = _interopRequireDefault(_rowsMapper);
|
|
|
|
var _backlight = __webpack_require__(365);
|
|
|
|
var _backlight2 = _interopRequireDefault(_backlight);
|
|
|
|
var _guideline = __webpack_require__(366);
|
|
|
|
var _guideline2 = _interopRequireDefault(_guideline);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
__webpack_require__(417);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
_pluginHooks2.default.getSingleton().register('beforeRowMove');
|
|
_pluginHooks2.default.getSingleton().register('afterRowMove');
|
|
_pluginHooks2.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.
|
|
*
|
|
* 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.
|
|
*
|
|
* UI components:
|
|
* - backlight - highlight of selected rows.
|
|
* - guideline - line which shows where rows has been moved.
|
|
*
|
|
* @class ManualRowMove
|
|
* @plugin ManualRowMove
|
|
*/
|
|
|
|
var ManualRowMove = function (_BasePlugin) {
|
|
_inherits(ManualRowMove, _BasePlugin);
|
|
|
|
function ManualRowMove(hotInstance) {
|
|
_classCallCheck(this, ManualRowMove);
|
|
|
|
/**
|
|
* Set up WeakMap of plugin to sharing private parameters;
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (ManualRowMove.__proto__ || Object.getPrototypeOf(ManualRowMove)).call(this, hotInstance));
|
|
|
|
privatePool.set(_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.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
_this.removedRows = [];
|
|
/**
|
|
* Object containing visual row indexes mapped to data source indexes.
|
|
*
|
|
* @type {RowsMapper}
|
|
*/
|
|
_this.rowsMapper = new _rowsMapper2.default(_this);
|
|
/**
|
|
* Event Manager object.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
_this.eventManager = new _eventManager2.default(_this);
|
|
/**
|
|
* Backlight UI object.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
_this.backlight = new _backlight2.default(hotInstance);
|
|
/**
|
|
* Guideline UI object.
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
_this.guideline = new _guideline2.default(hotInstance);
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if plugin is enabled.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ManualRowMove, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return !!this.hot.getSettings().manualRowMove;
|
|
}
|
|
|
|
/**
|
|
* Enable the plugin.
|
|
*/
|
|
|
|
}, {
|
|
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 (index, amount) {
|
|
return _this2.onAfterRemoveRow(index, amount);
|
|
});
|
|
this.addHook('afterCreateRow', function (index, amount) {
|
|
return _this2.onAfterCreateRow(index, amount);
|
|
});
|
|
this.addHook('afterLoadData', function (firstTime) {
|
|
return _this2.onAfterLoadData(firstTime);
|
|
});
|
|
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);
|
|
|
|
_get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Updates the plugin to use the latest options you have specified.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
this.disablePlugin();
|
|
this.enablePlugin();
|
|
|
|
this.onAfterPluginsInitialized();
|
|
|
|
_get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin 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();
|
|
|
|
_get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Move 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.
|
|
*/
|
|
|
|
}, {
|
|
key: 'moveRow',
|
|
value: function moveRow(row, target) {
|
|
this.moveRows([row], target);
|
|
}
|
|
|
|
/**
|
|
* Move 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.
|
|
*/
|
|
|
|
}, {
|
|
key: 'moveRows',
|
|
value: function moveRows(rows, target) {
|
|
var _this3 = this;
|
|
|
|
var priv = privatePool.get(this);
|
|
var beforeMoveHook = this.hot.runHooks('beforeRowMove', rows, 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', rows, 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) {
|
|
var selection = this.hot.selection;
|
|
var lastColIndex = this.hot.countCols() - 1;
|
|
|
|
selection.setRangeStartOnly(new _src.CellCoords(startRow, 0));
|
|
selection.setRangeEnd(new _src.CellCoords(endRow, lastColIndex), false);
|
|
}
|
|
|
|
/**
|
|
* Get 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;
|
|
}
|
|
|
|
/**
|
|
* Load 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check 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;
|
|
}
|
|
|
|
/**
|
|
* Check 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;
|
|
}
|
|
|
|
/**
|
|
* Save the manual row positions to the persistent state.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'persistentStateSave',
|
|
value: function persistentStateSave() {
|
|
this.hot.runHooks('persistentStateSave', 'manualRowMove', this.rowsMapper._arrayMap);
|
|
}
|
|
|
|
/**
|
|
* Load the manual row positions from the persistent state.
|
|
*
|
|
* @private
|
|
* @returns {Array} Stored state.
|
|
*/
|
|
|
|
}, {
|
|
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.getSelectedRange();
|
|
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 (rootElementOffset.top + wtTable.holder.offsetHeight < priv.target.eventPageY) {
|
|
priv.target.coords.row++;
|
|
}
|
|
|
|
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, array) {
|
|
if (value > maxIndex) {
|
|
rowsToRemove.push(index);
|
|
}
|
|
});
|
|
|
|
this.rowsMapper.removeItems(rowsToRemove);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bind the events used by the plugin.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerEvents',
|
|
value: function registerEvents() {
|
|
var _this4 = this;
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'mousemove', function (event) {
|
|
return _this4.onMouseMove(event);
|
|
});
|
|
this.eventManager.addEventListener(document.documentElement, 'mouseup', function () {
|
|
return _this4.onMouseUp();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Unbind 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;
|
|
}
|
|
|
|
/**
|
|
* Change 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 wtTable = this.hot.view.wt.wtTable;
|
|
var isHeaderSelection = this.hot.selection.selectedHeader.rows;
|
|
var selection = this.hot.getSelectedRange();
|
|
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 + wtTable.getColumnWidth(-1);
|
|
|
|
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.getSelectedRange();
|
|
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.selectedHeader.rows) {
|
|
(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 = wtTable.getColumnWidth(-1);
|
|
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
|
|
* @param {Number} index Visual index of the removed row.
|
|
* @param {Number} amount Amount of removed rows.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterRemoveRow',
|
|
value: function onAfterRemoveRow(index, amount) {
|
|
this.rowsMapper.unshiftItems(this.removedRows);
|
|
}
|
|
|
|
/**
|
|
* `afterLoadData` hook callback.
|
|
*
|
|
* @private
|
|
* @param {Boolean} firstTime True if that was loading data during the initialization.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onAfterLoadData',
|
|
value: function onAfterLoadData(firstTime) {
|
|
this.updateRowsMapper();
|
|
}
|
|
|
|
/**
|
|
* 'modifyRow' hook callback.
|
|
*
|
|
* @private
|
|
* @param {Number} row Visual Row index.
|
|
* @returns {Number} Physical row index.
|
|
*/
|
|
|
|
}, {
|
|
key: 'onModifyRow',
|
|
value: function onModifyRow(row, source) {
|
|
if (source !== this.pluginName) {
|
|
var rowInMapper = this.rowsMapper.getValueByIndex(row);
|
|
row = rowInMapper === null ? row : rowInMapper;
|
|
}
|
|
|
|
return row;
|
|
}
|
|
|
|
/**
|
|
* '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();
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
this.backlight.destroy();
|
|
this.guideline.destroy();
|
|
|
|
_get(ManualRowMove.prototype.__proto__ || Object.getPrototypeOf(ManualRowMove.prototype), 'destroy', this).call(this);
|
|
}
|
|
}]);
|
|
|
|
return ManualRowMove;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('ManualRowMove', ManualRowMove);
|
|
|
|
exports.default = ManualRowMove;
|
|
|
|
/***/ }),
|
|
/* 364 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _arrayMapper = __webpack_require__(265);
|
|
|
|
var _arrayMapper2 = _interopRequireDefault(_arrayMapper);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class RowsMapper
|
|
* @plugin ManualRowMove
|
|
*/
|
|
var RowsMapper = function () {
|
|
function RowsMapper(manualRowMove) {
|
|
_classCallCheck(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.
|
|
*/
|
|
|
|
|
|
_createClass(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, _arrayMapper2.default);
|
|
|
|
exports.default = RowsMapper;
|
|
|
|
/***/ }),
|
|
/* 365 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(267);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var CSS_CLASSNAME = 'ht__manualRowMove--backlight';
|
|
|
|
/**
|
|
* @class BacklightUI
|
|
* @util
|
|
*/
|
|
|
|
var BacklightUI = function (_BaseUI) {
|
|
_inherits(BacklightUI, _BaseUI);
|
|
|
|
function BacklightUI() {
|
|
_classCallCheck(this, BacklightUI);
|
|
|
|
return _possibleConstructorReturn(this, (BacklightUI.__proto__ || Object.getPrototypeOf(BacklightUI)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(BacklightUI, [{
|
|
key: 'build',
|
|
|
|
/**
|
|
* Custom className on build process.
|
|
*/
|
|
value: function build() {
|
|
_get(BacklightUI.prototype.__proto__ || Object.getPrototypeOf(BacklightUI.prototype), 'build', this).call(this);
|
|
|
|
(0, _element.addClass)(this._element, CSS_CLASSNAME);
|
|
}
|
|
}]);
|
|
|
|
return BacklightUI;
|
|
}(_base2.default);
|
|
|
|
exports.default = BacklightUI;
|
|
|
|
/***/ }),
|
|
/* 366 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(267);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var CSS_CLASSNAME = 'ht__manualRowMove--guideline';
|
|
|
|
/**
|
|
* @class GuidelineUI
|
|
* @util
|
|
*/
|
|
|
|
var GuidelineUI = function (_BaseUI) {
|
|
_inherits(GuidelineUI, _BaseUI);
|
|
|
|
function GuidelineUI() {
|
|
_classCallCheck(this, GuidelineUI);
|
|
|
|
return _possibleConstructorReturn(this, (GuidelineUI.__proto__ || Object.getPrototypeOf(GuidelineUI)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(GuidelineUI, [{
|
|
key: 'build',
|
|
|
|
/**
|
|
* Custom className on build process.
|
|
*/
|
|
value: function build() {
|
|
_get(GuidelineUI.prototype.__proto__ || Object.getPrototypeOf(GuidelineUI.prototype), 'build', this).call(this);
|
|
|
|
(0, _element.addClass)(this._element, CSS_CLASSNAME);
|
|
}
|
|
}]);
|
|
|
|
return GuidelineUI;
|
|
}(_base2.default);
|
|
|
|
exports.default = GuidelineUI;
|
|
|
|
/***/ }),
|
|
/* 367 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
// Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js
|
|
|
|
/**
|
|
* @description
|
|
* ManualRowResize Plugin.
|
|
*
|
|
* Has 2 UI components:
|
|
* - 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 = function (_BasePlugin) {
|
|
_inherits(ManualRowResize, _BasePlugin);
|
|
|
|
function ManualRowResize(hotInstance) {
|
|
_classCallCheck(this, ManualRowResize);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ManualRowResize.__proto__ || Object.getPrototypeOf(ManualRowResize)).call(this, hotInstance));
|
|
|
|
_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 = document.createElement('DIV');
|
|
_this.guide = document.createElement('DIV');
|
|
_this.eventManager = new _eventManager2.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;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ManualRowResize, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return this.hot.getSettings().manualRowResize;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin 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();
|
|
|
|
_get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Updates the plugin to use the latest options you have specified.
|
|
*/
|
|
|
|
}, {
|
|
key: 'updatePlugin',
|
|
value: function updatePlugin() {
|
|
var initialRowHeights = this.hot.getSettings().manualRowResize;
|
|
|
|
if (Array.isArray(initialRowHeights)) {
|
|
this.manualRowHeights = initialRowHeights;
|
|
} else if (!initialRowHeights) {
|
|
this.manualRowHeights = [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
_get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'disablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Save the current sizes using the persistentState plugin.
|
|
*/
|
|
|
|
}, {
|
|
key: 'saveManualRowHeights',
|
|
value: function saveManualRowHeights() {
|
|
this.hot.runHooks('persistentStateSave', 'manualRowHeights', this.manualRowHeights);
|
|
}
|
|
|
|
/**
|
|
* Load the previously saved sizes using the persistentState plugin.
|
|
*
|
|
* @returns {Array}
|
|
*/
|
|
|
|
}, {
|
|
key: 'loadManualRowHeights',
|
|
value: function loadManualRowHeights() {
|
|
var storedState = {};
|
|
|
|
this.hot.runHooks('persistentStateLoad', 'manualRowHeights', storedState);
|
|
|
|
return storedState.value;
|
|
}
|
|
|
|
/**
|
|
* Set the resize handle position.
|
|
*
|
|
* @param {HTMLCellElement} TH TH HTML element.
|
|
*/
|
|
|
|
}, {
|
|
key: 'setupHandlePosition',
|
|
value: function setupHandlePosition(TH) {
|
|
var _this3 = this;
|
|
|
|
this.currentTH = TH;
|
|
var row = this.hot.view.wt.wtTable.getCoords(TH).row; // getCoords returns CellCoords
|
|
var headerWidth = (0, _element.outerWidth)(this.currentTH);
|
|
|
|
if (row >= 0) {
|
|
// if not col header
|
|
var box = this.currentTH.getBoundingClientRect();
|
|
|
|
this.currentRow = row;
|
|
this.selectedRows = [];
|
|
|
|
if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.rows) {
|
|
var _hot$getSelectedRange = this.hot.getSelectedRange(),
|
|
from = _hot$getSelectedRange.from,
|
|
to = _hot$getSelectedRange.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 = box.top - 6;
|
|
this.startHeight = parseInt(box.height, 10);
|
|
this.handle.style.left = box.left + 'px';
|
|
this.handle.style.top = this.startOffset + this.startHeight + 'px';
|
|
this.handle.style.width = headerWidth + 'px';
|
|
this.hot.rootElement.appendChild(this.handle);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refresh the resize handle position.
|
|
*/
|
|
|
|
}, {
|
|
key: 'refreshHandlePosition',
|
|
value: function refreshHandlePosition() {
|
|
this.handle.style.top = this.startOffset + this.currentHeight + 'px';
|
|
}
|
|
|
|
/**
|
|
* Set the resize guide position.
|
|
*/
|
|
|
|
}, {
|
|
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 = handleRightPosition + 'px';
|
|
this.guide.style.width = maximumVisibleElementWidth - handleWidth + 'px';
|
|
this.hot.rootElement.appendChild(this.guide);
|
|
}
|
|
|
|
/**
|
|
* Refresh the resize guide position.
|
|
*/
|
|
|
|
}, {
|
|
key: 'refreshGuidePosition',
|
|
value: function refreshGuidePosition() {
|
|
this.guide.style.top = this.handle.style.top;
|
|
}
|
|
|
|
/**
|
|
* Hide both the resize handle and resize guide.
|
|
*/
|
|
|
|
}, {
|
|
key: 'hideHandleAndGuide',
|
|
value: function hideHandleAndGuide() {
|
|
(0, _element.removeClass)(this.handle, 'active');
|
|
(0, _element.removeClass)(this.guide, 'active');
|
|
}
|
|
|
|
/**
|
|
* Check if provided element is considered as a row header.
|
|
*
|
|
* @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;
|
|
}
|
|
|
|
/**
|
|
* Get the TH element from the provided element.
|
|
*
|
|
* @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
|
|
*/
|
|
|
|
}, {
|
|
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++;
|
|
|
|
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
|
|
* @param {MouseEvent} event
|
|
*/
|
|
|
|
}, {
|
|
key: 'onMouseUp',
|
|
value: function onMouseUp(event) {
|
|
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);
|
|
};
|
|
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);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bind the mouse events.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'bindEvents',
|
|
value: function bindEvents() {
|
|
var _this8 = this;
|
|
|
|
this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) {
|
|
return _this8.onMouseOver(e);
|
|
});
|
|
this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) {
|
|
return _this8.onMouseDown(e);
|
|
});
|
|
this.eventManager.addEventListener(window, 'mousemove', function (e) {
|
|
return _this8.onMouseMove(e);
|
|
});
|
|
this.eventManager.addEventListener(window, 'mouseup', function (e) {
|
|
return _this8.onMouseUp(e);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Cache the current row height.
|
|
*
|
|
* @param {Number} row Visual row index.
|
|
* @param {Number} height Row height.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'setManualSize',
|
|
value: function setManualSize(row, height) {
|
|
row = this.hot.runHooks('modifyRow', row);
|
|
this.manualRowHeights[row] = height;
|
|
|
|
return height;
|
|
}
|
|
|
|
/**
|
|
* Modify the provided row height, based on the plugin settings.
|
|
*
|
|
* @private
|
|
* @param {Number} height Row height.
|
|
* @param {Number} row Visual row index.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
}, {
|
|
key: 'onModifyRowHeight',
|
|
value: function onModifyRowHeight(height, row) {
|
|
if (this.enabled) {
|
|
var autoRowSizePlugin = this.hot.getPlugin('autoRowSize');
|
|
var autoRowHeightResult = autoRowSizePlugin ? autoRowSizePlugin.heights[row] : null;
|
|
|
|
row = this.hot.runHooks('modifyRow', row);
|
|
|
|
var manualRowHeight = this.manualRowHeights[row];
|
|
|
|
if (manualRowHeight !== void 0 && (manualRowHeight === autoRowHeightResult || manualRowHeight > (height || 0))) {
|
|
return manualRowHeight;
|
|
}
|
|
}
|
|
|
|
return height;
|
|
}
|
|
}]);
|
|
|
|
return ManualRowResize;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('manualRowResize', ManualRowResize);
|
|
|
|
exports.default = ManualRowResize;
|
|
|
|
/***/ }),
|
|
/* 368 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function CellInfoCollection() {
|
|
var collection = [];
|
|
|
|
collection.getInfo = function (row, col) {
|
|
for (var i = 0, ilen = this.length; i < ilen; i++) {
|
|
if (this[i].row <= row && this[i].row + this[i].rowspan - 1 >= row && this[i].col <= col && this[i].col + this[i].colspan - 1 >= col) {
|
|
return this[i];
|
|
}
|
|
}
|
|
};
|
|
|
|
collection.setInfo = function (info) {
|
|
for (var i = 0, ilen = this.length; i < ilen; i++) {
|
|
if (this[i].row === info.row && this[i].col === info.col) {
|
|
this[i] = info;
|
|
return;
|
|
}
|
|
}
|
|
this.push(info);
|
|
};
|
|
|
|
collection.removeInfo = function (row, col) {
|
|
for (var i = 0, ilen = this.length; i < ilen; i++) {
|
|
if (this[i].row === row && this[i].col === col) {
|
|
this.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
return collection;
|
|
}
|
|
|
|
/**
|
|
* Plugin used to merge cells in Handsontable.
|
|
*
|
|
* @private
|
|
* @plugin MergeCells
|
|
* @class MergeCells
|
|
*/
|
|
function MergeCells(mergeCellsSetting) {
|
|
this.mergedCellInfoCollection = new CellInfoCollection();
|
|
|
|
if (Array.isArray(mergeCellsSetting)) {
|
|
for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) {
|
|
this.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param cellRange (CellRange)
|
|
*/
|
|
MergeCells.prototype.canMergeRange = function (cellRange) {
|
|
// is more than one cell selected
|
|
return !cellRange.isSingle();
|
|
};
|
|
|
|
MergeCells.prototype.mergeRange = function (cellRange) {
|
|
if (!this.canMergeRange(cellRange)) {
|
|
return;
|
|
}
|
|
|
|
// normalize top left corner
|
|
var topLeft = cellRange.getTopLeftCorner();
|
|
var bottomRight = cellRange.getBottomRightCorner();
|
|
|
|
var mergeParent = {};
|
|
mergeParent.row = topLeft.row;
|
|
mergeParent.col = topLeft.col;
|
|
// TD has rowspan == 1 by default. rowspan == 2 means spread over 2 cells
|
|
mergeParent.rowspan = bottomRight.row - topLeft.row + 1;
|
|
mergeParent.colspan = bottomRight.col - topLeft.col + 1;
|
|
this.mergedCellInfoCollection.setInfo(mergeParent);
|
|
};
|
|
|
|
MergeCells.prototype.mergeOrUnmergeSelection = function (cellRange) {
|
|
var info = this.mergedCellInfoCollection.getInfo(cellRange.from.row, cellRange.from.col);
|
|
if (info) {
|
|
// unmerge
|
|
this.unmergeSelection(cellRange.from);
|
|
} else {
|
|
// merge
|
|
this.mergeSelection(cellRange);
|
|
}
|
|
};
|
|
|
|
MergeCells.prototype.mergeSelection = function (cellRange) {
|
|
this.mergeRange(cellRange);
|
|
};
|
|
|
|
MergeCells.prototype.unmergeSelection = function (cellRange) {
|
|
var info = this.mergedCellInfoCollection.getInfo(cellRange.row, cellRange.col);
|
|
this.mergedCellInfoCollection.removeInfo(info.row, info.col);
|
|
};
|
|
|
|
MergeCells.prototype.applySpanProperties = function (TD, row, col) {
|
|
var info = this.mergedCellInfoCollection.getInfo(row, col);
|
|
|
|
if (info) {
|
|
if (info.row === row && info.col === col) {
|
|
TD.setAttribute('rowspan', info.rowspan);
|
|
TD.setAttribute('colspan', info.colspan);
|
|
} else {
|
|
TD.removeAttribute('rowspan');
|
|
TD.removeAttribute('colspan');
|
|
|
|
TD.style.display = 'none';
|
|
}
|
|
} else {
|
|
TD.removeAttribute('rowspan');
|
|
TD.removeAttribute('colspan');
|
|
}
|
|
};
|
|
|
|
MergeCells.prototype.modifyTransform = function (hook, currentSelectedRange, delta) {
|
|
var sameRowspan = function sameRowspan(merged, coords) {
|
|
if (coords.row >= merged.row && coords.row <= merged.row + merged.rowspan - 1) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
sameColspan = function sameColspan(merged, coords) {
|
|
if (coords.col >= merged.col && coords.col <= merged.col + merged.colspan - 1) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
getNextPosition = function getNextPosition(newDelta) {
|
|
return new _src.CellCoords(currentSelectedRange.to.row + newDelta.row, currentSelectedRange.to.col + newDelta.col);
|
|
};
|
|
|
|
var newDelta = {
|
|
row: delta.row,
|
|
col: delta.col
|
|
};
|
|
|
|
if (hook == 'modifyTransformStart') {
|
|
/* eslint-disable block-scoped-var */
|
|
var nextPosition;
|
|
|
|
if (!this.lastDesiredCoords) {
|
|
this.lastDesiredCoords = new _src.CellCoords(null, null);
|
|
}
|
|
var currentPosition = new _src.CellCoords(currentSelectedRange.highlight.row, currentSelectedRange.highlight.col),
|
|
|
|
// if current position's parent is a merged range, returns it
|
|
mergedParent = this.mergedCellInfoCollection.getInfo(currentPosition.row, currentPosition.col),
|
|
currentRangeContainsMerge; // if current range contains a merged range
|
|
|
|
for (var i = 0, mergesLength = this.mergedCellInfoCollection.length; i < mergesLength; i++) {
|
|
var range = this.mergedCellInfoCollection[i];
|
|
range = new _src.CellCoords(range.row + range.rowspan - 1, range.col + range.colspan - 1);
|
|
if (currentSelectedRange.includes(range)) {
|
|
currentRangeContainsMerge = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
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(this.lastDesiredCoords)) {
|
|
this.lastDesiredCoords = new _src.CellCoords(null, null); // reset outdated version of lastDesiredCoords
|
|
}
|
|
|
|
newDelta.row = this.lastDesiredCoords.row ? this.lastDesiredCoords.row - currentPosition.row : newDelta.row;
|
|
newDelta.col = this.lastDesiredCoords.col ? this.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(currentSelectedRange.highlight.row + newDelta.row, currentSelectedRange.highlight.col + newDelta.col);
|
|
|
|
var nextParentIsMerged = this.mergedCellInfoCollection.getInfo(nextPosition.row, nextPosition.col);
|
|
|
|
if (nextParentIsMerged) {
|
|
// skipping the invisible cells in the merge range
|
|
this.lastDesiredCoords = nextPosition;
|
|
newDelta = {
|
|
row: nextParentIsMerged.row - currentPosition.row,
|
|
col: nextParentIsMerged.col - currentPosition.col
|
|
};
|
|
}
|
|
} else if (hook == 'modifyTransformEnd') {
|
|
for (var _i = 0, _mergesLength = this.mergedCellInfoCollection.length; _i < _mergesLength; _i++) {
|
|
var currentMerge = this.mergedCellInfoCollection[_i];
|
|
var _mergeTopLeft = new _src.CellCoords(currentMerge.row, currentMerge.col);
|
|
var _mergeBottomRight = new _src.CellCoords(currentMerge.row + currentMerge.rowspan - 1, currentMerge.col + currentMerge.colspan - 1);
|
|
var mergedRange = new _src.CellRange(_mergeTopLeft, _mergeTopLeft, _mergeBottomRight);
|
|
var sharedBorders = currentSelectedRange.getBordersSharedWith(mergedRange);
|
|
|
|
if (mergedRange.isEqual(currentSelectedRange)) {
|
|
// only the merged range is selected
|
|
currentSelectedRange.setDirection('NW-SE');
|
|
} else if (sharedBorders.length > 0) {
|
|
var mergeHighlighted = currentSelectedRange.highlight.isEqual(mergedRange.from);
|
|
|
|
if (sharedBorders.indexOf('top') > -1) {
|
|
// if range shares a border with the merged section, change range direction accordingly
|
|
if (currentSelectedRange.to.isSouthEastOf(mergedRange.from) && mergeHighlighted) {
|
|
currentSelectedRange.setDirection('NW-SE');
|
|
} else if (currentSelectedRange.to.isSouthWestOf(mergedRange.from) && mergeHighlighted) {
|
|
currentSelectedRange.setDirection('NE-SW');
|
|
}
|
|
} else if (sharedBorders.indexOf('bottom') > -1) {
|
|
if (currentSelectedRange.to.isNorthEastOf(mergedRange.from) && mergeHighlighted) {
|
|
currentSelectedRange.setDirection('SW-NE');
|
|
} else if (currentSelectedRange.to.isNorthWestOf(mergedRange.from) && mergeHighlighted) {
|
|
currentSelectedRange.setDirection('SE-NW');
|
|
}
|
|
}
|
|
}
|
|
|
|
nextPosition = getNextPosition(newDelta);
|
|
var withinRowspan = sameRowspan(currentMerge, nextPosition),
|
|
withinColspan = sameColspan(currentMerge, nextPosition);
|
|
|
|
if (currentSelectedRange.includesRange(mergedRange) && (mergedRange.includes(nextPosition) || withinRowspan || withinColspan)) {
|
|
// if next step overlaps a merged range, jump past it
|
|
if (withinRowspan) {
|
|
if (newDelta.row < 0) {
|
|
newDelta.row -= currentMerge.rowspan - 1;
|
|
} else if (newDelta.row > 0) {
|
|
newDelta.row += currentMerge.rowspan - 1;
|
|
}
|
|
}
|
|
if (withinColspan) {
|
|
if (newDelta.col < 0) {
|
|
newDelta.col -= currentMerge.colspan - 1;
|
|
} else if (newDelta.col > 0) {
|
|
newDelta.col += currentMerge.colspan - 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (newDelta.row !== 0) {
|
|
delta.row = newDelta.row;
|
|
}
|
|
if (newDelta.col !== 0) {
|
|
delta.col = newDelta.col;
|
|
}
|
|
};
|
|
|
|
MergeCells.prototype.shiftCollection = function (direction, index, count) {
|
|
var shiftVector = [0, 0];
|
|
|
|
switch (direction) {
|
|
case 'right':
|
|
shiftVector[0] += 1;
|
|
|
|
break;
|
|
case 'left':
|
|
shiftVector[0] -= 1;
|
|
|
|
break;
|
|
case 'down':
|
|
shiftVector[1] += 1;
|
|
|
|
break;
|
|
case 'up':
|
|
shiftVector[1] -= 1;
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
for (var i = 0; i < this.mergedCellInfoCollection.length; i++) {
|
|
var currentMerge = this.mergedCellInfoCollection[i];
|
|
|
|
if (direction === 'right' || direction === 'left') {
|
|
if (index <= currentMerge.col) {
|
|
currentMerge.col += shiftVector[0];
|
|
}
|
|
} else if (index <= currentMerge.row) {
|
|
currentMerge.row += shiftVector[1];
|
|
}
|
|
}
|
|
};
|
|
|
|
var beforeInit = function beforeInit() {
|
|
var instance = this;
|
|
var mergeCellsSetting = instance.getSettings().mergeCells;
|
|
|
|
if (mergeCellsSetting) {
|
|
if (!instance.mergeCells) {
|
|
instance.mergeCells = new MergeCells(mergeCellsSetting);
|
|
}
|
|
}
|
|
};
|
|
|
|
var afterInit = function afterInit() {
|
|
var instance = this;
|
|
if (instance.mergeCells) {
|
|
/**
|
|
* Monkey patch Table.prototype.getCell to return TD for merged cell parent if asked for TD of a cell that is
|
|
* invisible due to the merge. This is not the cleanest solution but there is a test case for it (merged cells scroll) so feel free to refactor it!
|
|
*/
|
|
instance.view.wt.wtTable.getCell = function (coords) {
|
|
if (instance.getSettings().mergeCells) {
|
|
var mergeParent = instance.mergeCells.mergedCellInfoCollection.getInfo(coords.row, coords.col);
|
|
if (mergeParent) {
|
|
coords = mergeParent;
|
|
}
|
|
}
|
|
return _src.Table.prototype.getCell.call(this, coords);
|
|
};
|
|
}
|
|
};
|
|
|
|
var afterUpdateSettings = function afterUpdateSettings() {
|
|
var instance = this;
|
|
var mergeCellsSetting = instance.getSettings().mergeCells;
|
|
|
|
if (mergeCellsSetting) {
|
|
if (instance.mergeCells) {
|
|
instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection();
|
|
|
|
if (Array.isArray(mergeCellsSetting)) {
|
|
for (var i = 0, ilen = mergeCellsSetting.length; i < ilen; i++) {
|
|
instance.mergeCells.mergedCellInfoCollection.setInfo(mergeCellsSetting[i]);
|
|
}
|
|
}
|
|
} else {
|
|
instance.mergeCells = new MergeCells(mergeCellsSetting);
|
|
}
|
|
} else if (instance.mergeCells) {
|
|
// it doesn't actually turn off the plugin, just resets the settings. Need to refactor.
|
|
instance.mergeCells.mergedCellInfoCollection = new CellInfoCollection();
|
|
}
|
|
};
|
|
|
|
var onBeforeKeyDown = function onBeforeKeyDown(event) {
|
|
if (!this.mergeCells) {
|
|
return;
|
|
}
|
|
|
|
var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
|
|
|
|
if (ctrlDown) {
|
|
if (event.keyCode === 77) {
|
|
// CTRL + M
|
|
this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange());
|
|
this.render();
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
}
|
|
}
|
|
};
|
|
|
|
var addMergeActionsToContextMenu = function addMergeActionsToContextMenu(defaultOptions) {
|
|
if (!this.getSettings().mergeCells) {
|
|
return;
|
|
}
|
|
|
|
defaultOptions.items.push({ name: '---------' });
|
|
defaultOptions.items.push({
|
|
key: 'mergeCells',
|
|
name: function name() {
|
|
var sel = this.getSelected();
|
|
var info = this.mergeCells.mergedCellInfoCollection.getInfo(sel[0], sel[1]);
|
|
if (info) {
|
|
return 'Unmerge cells';
|
|
}
|
|
return 'Merge cells';
|
|
},
|
|
callback: function callback() {
|
|
this.mergeCells.mergeOrUnmergeSelection(this.getSelectedRange());
|
|
this.render();
|
|
},
|
|
disabled: function disabled() {
|
|
return this.selection.selectedHeader.corner;
|
|
}
|
|
});
|
|
};
|
|
|
|
var afterRenderer = function afterRenderer(TD, row, col, prop, value, cellProperties) {
|
|
if (this.mergeCells) {
|
|
this.mergeCells.applySpanProperties(TD, row, col);
|
|
}
|
|
};
|
|
|
|
var modifyTransformFactory = function modifyTransformFactory(hook) {
|
|
return function (delta) {
|
|
var mergeCellsSetting = this.getSettings().mergeCells;
|
|
if (mergeCellsSetting) {
|
|
var currentSelectedRange = this.getSelectedRange();
|
|
this.mergeCells.modifyTransform(hook, currentSelectedRange, delta);
|
|
|
|
if (hook === 'modifyTransformEnd') {
|
|
// sanitize "from" (core.js will sanitize to)
|
|
var totalRows = this.countRows();
|
|
var totalCols = this.countCols();
|
|
if (currentSelectedRange.from.row < 0) {
|
|
currentSelectedRange.from.row = 0;
|
|
} else if (currentSelectedRange.from.row > 0 && currentSelectedRange.from.row >= totalRows) {
|
|
currentSelectedRange.from.row = currentSelectedRange.from - 1;
|
|
}
|
|
|
|
if (currentSelectedRange.from.col < 0) {
|
|
currentSelectedRange.from.col = 0;
|
|
} else if (currentSelectedRange.from.col > 0 && currentSelectedRange.from.col >= totalCols) {
|
|
currentSelectedRange.from.col = totalCols - 1;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell
|
|
* @param coords
|
|
*/
|
|
var beforeSetRangeEnd = function beforeSetRangeEnd(coords) {
|
|
|
|
this.lastDesiredCoords = null; // unset lastDesiredCoords when selection is changed with mouse
|
|
var mergeCellsSetting = this.getSettings().mergeCells;
|
|
if (mergeCellsSetting) {
|
|
var selRange = this.getSelectedRange();
|
|
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;
|
|
do {
|
|
rangeExpanded = false;
|
|
|
|
for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) {
|
|
var cellInfo = this.mergeCells.mergedCellInfoCollection[i];
|
|
var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col);
|
|
var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1);
|
|
|
|
var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight);
|
|
if (selRange.expandByRange(mergedCellRange)) {
|
|
coords.row = selRange.to.row;
|
|
coords.col = selRange.to.col;
|
|
|
|
rangeExpanded = true;
|
|
}
|
|
}
|
|
} while (rangeExpanded);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns correct coordinates for merged start / end cells in selection for area borders
|
|
* @param corners
|
|
* @param className
|
|
*/
|
|
var beforeDrawAreaBorders = function beforeDrawAreaBorders(corners, className) {
|
|
if (className && className == 'area') {
|
|
var mergeCellsSetting = this.getSettings().mergeCells;
|
|
if (mergeCellsSetting) {
|
|
var selRange = this.getSelectedRange();
|
|
var startRange = new _src.CellRange(selRange.from, selRange.from, selRange.from);
|
|
var stopRange = new _src.CellRange(selRange.to, selRange.to, selRange.to);
|
|
|
|
for (var i = 0, ilen = this.mergeCells.mergedCellInfoCollection.length; i < ilen; i++) {
|
|
var cellInfo = this.mergeCells.mergedCellInfoCollection[i];
|
|
var mergedCellTopLeft = new _src.CellCoords(cellInfo.row, cellInfo.col);
|
|
var mergedCellBottomRight = new _src.CellCoords(cellInfo.row + cellInfo.rowspan - 1, cellInfo.col + cellInfo.colspan - 1);
|
|
var mergedCellRange = new _src.CellRange(mergedCellTopLeft, mergedCellTopLeft, mergedCellBottomRight);
|
|
|
|
if (startRange.expandByRange(mergedCellRange)) {
|
|
corners[0] = startRange.from.row;
|
|
corners[1] = startRange.from.col;
|
|
}
|
|
|
|
if (stopRange.expandByRange(mergedCellRange)) {
|
|
corners[2] = stopRange.from.row;
|
|
corners[3] = stopRange.from.col;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
var afterGetCellMeta = function afterGetCellMeta(row, col, cellProperties) {
|
|
var mergeCellsSetting = this.getSettings().mergeCells;
|
|
if (mergeCellsSetting) {
|
|
var mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(row, col);
|
|
if (mergeParent && (mergeParent.row != row || mergeParent.col != col)) {
|
|
cellProperties.copyable = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
var afterViewportRowCalculatorOverride = function afterViewportRowCalculatorOverride(calc) {
|
|
var mergeCellsSetting = this.getSettings().mergeCells;
|
|
if (mergeCellsSetting) {
|
|
var colCount = this.countCols();
|
|
var mergeParent;
|
|
for (var c = 0; c < colCount; c++) {
|
|
mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.startRow, c);
|
|
if (mergeParent) {
|
|
if (mergeParent.row < calc.startRow) {
|
|
calc.startRow = mergeParent.row;
|
|
return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards
|
|
}
|
|
}
|
|
mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(calc.endRow, c);
|
|
if (mergeParent) {
|
|
var mergeEnd = mergeParent.row + mergeParent.rowspan - 1;
|
|
if (mergeEnd > calc.endRow) {
|
|
calc.endRow = mergeEnd;
|
|
return afterViewportRowCalculatorOverride.call(this, calc); // recursively search upwards
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
var afterViewportColumnCalculatorOverride = function afterViewportColumnCalculatorOverride(calc) {
|
|
var mergeCellsSetting = this.getSettings().mergeCells;
|
|
if (mergeCellsSetting) {
|
|
var rowCount = this.countRows();
|
|
var mergeParent;
|
|
for (var r = 0; r < rowCount; r++) {
|
|
mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.startColumn);
|
|
|
|
if (mergeParent) {
|
|
if (mergeParent.col < calc.startColumn) {
|
|
calc.startColumn = mergeParent.col;
|
|
return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards
|
|
}
|
|
}
|
|
mergeParent = this.mergeCells.mergedCellInfoCollection.getInfo(r, calc.endColumn);
|
|
if (mergeParent) {
|
|
var mergeEnd = mergeParent.col + mergeParent.colspan - 1;
|
|
if (mergeEnd > calc.endColumn) {
|
|
calc.endColumn = mergeEnd;
|
|
return afterViewportColumnCalculatorOverride.call(this, calc); // recursively search upwards
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
var isMultipleSelection = function isMultipleSelection(isMultiple) {
|
|
if (isMultiple && this.mergeCells) {
|
|
var mergedCells = this.mergeCells.mergedCellInfoCollection,
|
|
selectionRange = this.getSelectedRange();
|
|
|
|
for (var group in mergedCells) {
|
|
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;
|
|
};
|
|
|
|
function modifyAutofillRange(select, drag) {
|
|
var mergeCellsSetting = this.getSettings().mergeCells;
|
|
|
|
if (!mergeCellsSetting || this.selection.isMultiple()) {
|
|
return;
|
|
}
|
|
var info = this.mergeCells.mergedCellInfoCollection.getInfo(select[0], select[1]);
|
|
|
|
if (info) {
|
|
select[0] = info.row;
|
|
select[1] = info.col;
|
|
select[2] = info.row + info.rowspan - 1;
|
|
select[3] = info.col + info.colspan - 1;
|
|
}
|
|
}
|
|
|
|
function onAfterCreateCol(col, count) {
|
|
if (this.mergeCells) {
|
|
this.mergeCells.shiftCollection('right', col, count);
|
|
}
|
|
}
|
|
|
|
function onAfterRemoveCol(col, count) {
|
|
if (this.mergeCells) {
|
|
this.mergeCells.shiftCollection('left', col, count);
|
|
}
|
|
}
|
|
|
|
function onAfterCreateRow(row, count) {
|
|
if (this.mergeCells) {
|
|
this.mergeCells.shiftCollection('down', row, count);
|
|
}
|
|
}
|
|
|
|
function onAfterRemoveRow(row, count) {
|
|
if (this.mergeCells) {
|
|
this.mergeCells.shiftCollection('up', row, count);
|
|
}
|
|
}
|
|
|
|
var hook = _pluginHooks2.default.getSingleton();
|
|
|
|
hook.add('beforeInit', beforeInit);
|
|
hook.add('afterInit', afterInit);
|
|
hook.add('afterUpdateSettings', afterUpdateSettings);
|
|
hook.add('beforeKeyDown', onBeforeKeyDown);
|
|
hook.add('modifyTransformStart', modifyTransformFactory('modifyTransformStart'));
|
|
hook.add('modifyTransformEnd', modifyTransformFactory('modifyTransformEnd'));
|
|
hook.add('beforeSetRangeEnd', beforeSetRangeEnd);
|
|
hook.add('beforeDrawBorders', beforeDrawAreaBorders);
|
|
hook.add('afterIsMultipleSelection', isMultipleSelection);
|
|
hook.add('afterRenderer', afterRenderer);
|
|
hook.add('afterContextMenuDefaultOptions', addMergeActionsToContextMenu);
|
|
hook.add('afterGetCellMeta', afterGetCellMeta);
|
|
hook.add('afterViewportRowCalculatorOverride', afterViewportRowCalculatorOverride);
|
|
hook.add('afterViewportColumnCalculatorOverride', afterViewportColumnCalculatorOverride);
|
|
hook.add('modifyAutofillRange', modifyAutofillRange);
|
|
hook.add('afterCreateCol', onAfterCreateCol);
|
|
hook.add('afterRemoveCol', onAfterRemoveCol);
|
|
hook.add('afterCreateRow', onAfterCreateRow);
|
|
hook.add('afterRemoveRow', onAfterRemoveRow);
|
|
|
|
exports.default = MergeCells;
|
|
|
|
/***/ }),
|
|
/* 369 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @private
|
|
* @plugin MultipleSelectionHandles
|
|
*/
|
|
var MultipleSelectionHandles = function (_BasePlugin) {
|
|
_inherits(MultipleSelectionHandles, _BasePlugin);
|
|
|
|
/**
|
|
* @param {Object} hotInstance
|
|
*/
|
|
function MultipleSelectionHandles(hotInstance) {
|
|
_classCallCheck(this, MultipleSelectionHandles);
|
|
|
|
/**
|
|
* @type {Array}
|
|
*/
|
|
var _this2 = _possibleConstructorReturn(this, (MultipleSelectionHandles.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles)).call(this, hotInstance));
|
|
|
|
_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}
|
|
*/
|
|
|
|
|
|
_createClass(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 _eventManager2.default(this);
|
|
}
|
|
this.registerListeners();
|
|
_get(MultipleSelectionHandles.prototype.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Bind the touch events
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: 'registerListeners',
|
|
value: function registerListeners() {
|
|
var _this = this;
|
|
|
|
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(this.hot.rootElement, 'touchstart', function (event) {
|
|
var selectedRange = void 0;
|
|
|
|
if ((0, _element.hasClass)(event.target, 'topLeftSelectionHandle-HitArea')) {
|
|
selectedRange = _this.hot.getSelectedRange();
|
|
|
|
_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.getSelectedRange();
|
|
|
|
_this.dragged.push('bottomRight');
|
|
|
|
_this.touchStartRange = {
|
|
width: selectedRange.getWidth(),
|
|
height: selectedRange.getHeight(),
|
|
direction: selectedRange.getDirection()
|
|
};
|
|
|
|
event.preventDefault();
|
|
return false;
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(this.hot.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(this.hot.rootElement, 'touchmove', function (event) {
|
|
var scrollTop = (0, _element.getWindowScrollTop)(),
|
|
scrollLeft = (0, _element.getWindowScrollLeft)(),
|
|
endTarget = void 0,
|
|
targetCoords = void 0,
|
|
selectedRange = void 0,
|
|
rangeWidth = void 0,
|
|
rangeHeight = void 0,
|
|
rangeDirection = void 0,
|
|
newRangeCoords = void 0;
|
|
|
|
if (_this.dragged.length === 0) {
|
|
return;
|
|
}
|
|
|
|
endTarget = document.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.getSelectedRange();
|
|
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(),
|
|
bottomRightCorner = selectedRange.getBottomRightCorner(),
|
|
bottomLeftCorner = selectedRange.getBottomLeftCorner(),
|
|
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;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('multipleSelectionHandles', MultipleSelectionHandles);
|
|
|
|
exports.default = MultipleSelectionHandles;
|
|
|
|
/***/ }),
|
|
/* 370 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _jsonPatchDuplex = __webpack_require__(249);
|
|
|
|
var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex);
|
|
|
|
var _localHooks = __webpack_require__(70);
|
|
|
|
var _localHooks2 = _interopRequireDefault(_localHooks);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _utils = __webpack_require__(372);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class DataObserver
|
|
* @plugin ObserveChanges
|
|
*/
|
|
var DataObserver = function () {
|
|
function DataObserver(observedData) {
|
|
_classCallCheck(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
|
|
*/
|
|
|
|
|
|
_createClass(DataObserver, [{
|
|
key: 'setObservedData',
|
|
value: function setObservedData(observedData) {
|
|
var _this = this;
|
|
|
|
if (this.observer) {
|
|
_jsonPatchDuplex2.default.unobserve(this.observedData, this.observer);
|
|
}
|
|
this.observedData = observedData;
|
|
this.observer = _jsonPatchDuplex2.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() {
|
|
_jsonPatchDuplex2.default.unobserve(this.observedData, this.observer);
|
|
this.observedData = null;
|
|
this.observer = null;
|
|
}
|
|
}]);
|
|
|
|
return DataObserver;
|
|
}();
|
|
|
|
(0, _object.mixin)(DataObserver, _localHooks2.default);
|
|
|
|
exports.default = DataObserver;
|
|
|
|
/***/ }),
|
|
/* 371 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _jsonPatchDuplex = __webpack_require__(249);
|
|
|
|
var _jsonPatchDuplex2 = _interopRequireDefault(_jsonPatchDuplex);
|
|
|
|
var _dataObserver = __webpack_require__(370);
|
|
|
|
var _dataObserver2 = _interopRequireDefault(_dataObserver);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
// 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 = function (_BasePlugin) {
|
|
_inherits(ObserveChanges, _BasePlugin);
|
|
|
|
function ObserveChanges(hotInstance) {
|
|
_classCallCheck(this, ObserveChanges);
|
|
|
|
/**
|
|
* Instance of {@link DataObserver}.
|
|
*
|
|
* @type {DataObserver}
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (ObserveChanges.__proto__ || Object.getPrototypeOf(ObserveChanges)).call(this, hotInstance));
|
|
|
|
_this.observer = null;
|
|
return _this;
|
|
}
|
|
|
|
/**
|
|
* Check if the plugin is enabled in the handsontable settings.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
|
|
|
|
_createClass(ObserveChanges, [{
|
|
key: 'isEnabled',
|
|
value: function isEnabled() {
|
|
return this.hot.getSettings().observeChanges;
|
|
}
|
|
|
|
/**
|
|
* Enable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'enablePlugin',
|
|
value: function enablePlugin() {
|
|
var _this2 = this;
|
|
|
|
if (this.enabled) {
|
|
return;
|
|
}
|
|
if (!this.observer) {
|
|
this.observer = new _dataObserver2.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);
|
|
});
|
|
|
|
_get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(ObserveChanges.prototype), 'enablePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
if (this.observer) {
|
|
this.observer.destroy();
|
|
this.observer = null;
|
|
this._deletePublicApi();
|
|
}
|
|
|
|
_get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(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 = 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());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroy plugin instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'destroy',
|
|
value: function destroy() {
|
|
if (this.observer) {
|
|
this.observer.destroy();
|
|
this._deletePublicApi();
|
|
}
|
|
_get(ObserveChanges.prototype.__proto__ || Object.getPrototypeOf(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();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Delete 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;
|
|
}(_base2.default);
|
|
|
|
exports.default = ObserveChanges;
|
|
|
|
|
|
(0, _plugins.registerPlugin)('observeChanges', ObserveChanges);
|
|
|
|
/***/ }),
|
|
/* 372 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
|
|
|
exports.cleanPatches = cleanPatches;
|
|
exports.parsePath = parsePath;
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
patches = (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
|
|
*/
|
|
patches = (0, _array.arrayMap)(patches, 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.
|
|
*/
|
|
patches = (0, _array.arrayFilter)(patches, 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 patches;
|
|
}
|
|
|
|
/**
|
|
* 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 = _slicedToArray(match, 3),
|
|
row = _match[1],
|
|
column = _match[2];
|
|
|
|
return {
|
|
row: parseInt(row, 10),
|
|
col: /^\d*$/.test(column) ? parseInt(column, 10) : column
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 373 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function Storage(prefix) {
|
|
var savedKeys;
|
|
|
|
var saveSavedKeys = function saveSavedKeys() {
|
|
window.localStorage[prefix + '__persistentStateKeys'] = JSON.stringify(savedKeys);
|
|
};
|
|
|
|
var loadSavedKeys = function loadSavedKeys() {
|
|
var keysJSON = window.localStorage[prefix + '__persistentStateKeys'];
|
|
var keys = typeof keysJSON == 'string' ? JSON.parse(keysJSON) : void 0;
|
|
savedKeys = keys ? keys : [];
|
|
};
|
|
|
|
var clearSavedKeys = function clearSavedKeys() {
|
|
savedKeys = [];
|
|
saveSavedKeys();
|
|
};
|
|
|
|
loadSavedKeys();
|
|
|
|
this.saveValue = function (key, value) {
|
|
window.localStorage[prefix + '_' + key] = JSON.stringify(value);
|
|
if (savedKeys.indexOf(key) == -1) {
|
|
savedKeys.push(key);
|
|
saveSavedKeys();
|
|
}
|
|
};
|
|
|
|
this.loadValue = function (key, defaultValue) {
|
|
|
|
key = typeof key === 'undefined' ? defaultValue : key;
|
|
|
|
var value = window.localStorage[prefix + '_' + key];
|
|
|
|
return typeof value == 'undefined' ? void 0 : JSON.parse(value);
|
|
};
|
|
|
|
this.reset = function (key) {
|
|
window.localStorage.removeItem(prefix + '_' + key);
|
|
};
|
|
|
|
this.resetAll = function () {
|
|
for (var index = 0; index < savedKeys.length; index++) {
|
|
window.localStorage.removeItem(prefix + '_' + savedKeys[index]);
|
|
}
|
|
|
|
clearSavedKeys();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* @class PersistentState
|
|
* @plugin PersistentState
|
|
*/
|
|
function HandsontablePersistentState() {
|
|
var plugin = this;
|
|
|
|
this.init = function () {
|
|
var instance = this,
|
|
pluginSettings = instance.getSettings().persistentState;
|
|
|
|
plugin.enabled = !!pluginSettings;
|
|
|
|
if (!plugin.enabled) {
|
|
removeHooks.call(instance);
|
|
return;
|
|
}
|
|
|
|
if (!instance.storage) {
|
|
instance.storage = new Storage(instance.rootElement.id);
|
|
}
|
|
|
|
instance.resetState = plugin.resetValue;
|
|
|
|
addHooks.call(instance);
|
|
};
|
|
|
|
this.saveValue = function (key, value) {
|
|
var instance = this;
|
|
|
|
instance.storage.saveValue(key, value);
|
|
};
|
|
|
|
this.loadValue = function (key, saveTo) {
|
|
var instance = this;
|
|
|
|
saveTo.value = instance.storage.loadValue(key);
|
|
};
|
|
|
|
this.resetValue = function (key) {
|
|
var instance = this;
|
|
|
|
if (typeof key === 'undefined') {
|
|
instance.storage.resetAll();
|
|
} else {
|
|
instance.storage.reset(key);
|
|
}
|
|
};
|
|
|
|
var hooks = {
|
|
persistentStateSave: plugin.saveValue,
|
|
persistentStateLoad: plugin.loadValue,
|
|
persistentStateReset: plugin.resetValue
|
|
};
|
|
|
|
for (var hookName in hooks) {
|
|
if ((0, _object.hasOwnProperty)(hooks, hookName)) {
|
|
_pluginHooks2.default.getSingleton().register(hookName);
|
|
}
|
|
}
|
|
|
|
function addHooks() {
|
|
var instance = this;
|
|
|
|
for (var hookName in hooks) {
|
|
if ((0, _object.hasOwnProperty)(hooks, hookName)) {
|
|
instance.addHook(hookName, hooks[hookName]);
|
|
}
|
|
}
|
|
}
|
|
|
|
function removeHooks() {
|
|
var instance = this;
|
|
|
|
for (var hookName in hooks) {
|
|
if ((0, _object.hasOwnProperty)(hooks, hookName)) {
|
|
instance.removeHook(hookName, hooks[hookName]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var htPersistentState = new HandsontablePersistentState();
|
|
|
|
_pluginHooks2.default.getSingleton().add('beforeInit', htPersistentState.init);
|
|
_pluginHooks2.default.getSingleton().add('afterUpdateSettings', htPersistentState.init);
|
|
|
|
exports.default = HandsontablePersistentState;
|
|
|
|
/***/ }),
|
|
/* 374 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _renderers = __webpack_require__(9);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* @private
|
|
* @plugin Search
|
|
*/
|
|
function Search(instance) {
|
|
this.query = function (queryStr, callback, queryMethod) {
|
|
var rowCount = instance.countRows();
|
|
var colCount = instance.countCols();
|
|
var queryResult = [];
|
|
|
|
if (!callback) {
|
|
callback = Search.global.getDefaultCallback();
|
|
}
|
|
|
|
if (!queryMethod) {
|
|
queryMethod = Search.global.getDefaultQueryMethod();
|
|
}
|
|
|
|
for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
for (var colIndex = 0; colIndex < colCount; colIndex++) {
|
|
var cellData = instance.getDataAtCell(rowIndex, colIndex);
|
|
var cellProperties = instance.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;
|
|
};
|
|
};
|
|
|
|
Search.DEFAULT_CALLBACK = function (instance, row, col, data, testResult) {
|
|
instance.getCellMeta(row, col).isSearchResult = testResult;
|
|
};
|
|
|
|
Search.DEFAULT_QUERY_METHOD = function (query, value) {
|
|
if (typeof query == 'undefined' || query == null || !query.toLowerCase || query.length === 0) {
|
|
return false;
|
|
}
|
|
if (typeof value == 'undefined' || value == null) {
|
|
return false;
|
|
}
|
|
|
|
return value.toString().toLowerCase().indexOf(query.toLowerCase()) != -1;
|
|
};
|
|
|
|
Search.DEFAULT_SEARCH_RESULT_CLASS = 'htSearchResult';
|
|
|
|
Search.global = function () {
|
|
|
|
var defaultCallback = Search.DEFAULT_CALLBACK;
|
|
var defaultQueryMethod = Search.DEFAULT_QUERY_METHOD;
|
|
var defaultSearchResultClass = Search.DEFAULT_SEARCH_RESULT_CLASS;
|
|
|
|
return {
|
|
getDefaultCallback: function getDefaultCallback() {
|
|
return defaultCallback;
|
|
},
|
|
setDefaultCallback: function setDefaultCallback(newDefaultCallback) {
|
|
defaultCallback = newDefaultCallback;
|
|
},
|
|
getDefaultQueryMethod: function getDefaultQueryMethod() {
|
|
return defaultQueryMethod;
|
|
},
|
|
setDefaultQueryMethod: function setDefaultQueryMethod(newDefaultQueryMethod) {
|
|
defaultQueryMethod = newDefaultQueryMethod;
|
|
},
|
|
getDefaultSearchResultClass: function getDefaultSearchResultClass() {
|
|
return defaultSearchResultClass;
|
|
},
|
|
setDefaultSearchResultClass: function setDefaultSearchResultClass(newSearchResultClass) {
|
|
defaultSearchResultClass = newSearchResultClass;
|
|
}
|
|
};
|
|
}();
|
|
|
|
function SearchCellDecorator(instance, TD, row, col, prop, value, cellProperties) {
|
|
var searchResultClass = cellProperties.search !== null && _typeof(cellProperties.search) == 'object' && cellProperties.search.searchResultClass || Search.global.getDefaultSearchResultClass();
|
|
|
|
if (cellProperties.isSearchResult) {
|
|
(0, _element.addClass)(TD, searchResultClass);
|
|
} else {
|
|
(0, _element.removeClass)(TD, searchResultClass);
|
|
}
|
|
};
|
|
|
|
var originalBaseRenderer = (0, _renderers.getRenderer)('base');
|
|
|
|
(0, _renderers.registerRenderer)('base', function (instance, TD, row, col, prop, value, cellProperties) {
|
|
originalBaseRenderer.apply(this, arguments);
|
|
SearchCellDecorator.apply(this, arguments);
|
|
});
|
|
|
|
function init() {
|
|
var instance = this;
|
|
|
|
var pluginEnabled = !!instance.getSettings().search;
|
|
|
|
if (pluginEnabled) {
|
|
instance.search = new Search(instance);
|
|
} else {
|
|
delete instance.search;
|
|
}
|
|
}
|
|
|
|
_pluginHooks2.default.getSingleton().add('afterInit', init);
|
|
_pluginHooks2.default.getSingleton().add('afterUpdateSettings', init);
|
|
|
|
exports.default = Search;
|
|
|
|
/***/ }),
|
|
/* 375 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _base = __webpack_require__(12);
|
|
|
|
var _base2 = _interopRequireDefault(_base);
|
|
|
|
var _plugins = __webpack_require__(5);
|
|
|
|
var _feature = __webpack_require__(34);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
/**
|
|
* @private
|
|
* @plugin TouchScroll
|
|
* @class TouchScroll
|
|
*/
|
|
var TouchScroll = function (_BasePlugin) {
|
|
_inherits(TouchScroll, _BasePlugin);
|
|
|
|
function TouchScroll(hotInstance) {
|
|
_classCallCheck(this, TouchScroll);
|
|
|
|
/**
|
|
* Collection of scrollbars to update.
|
|
*
|
|
* @type {Array}
|
|
*/
|
|
var _this = _possibleConstructorReturn(this, (TouchScroll.__proto__ || Object.getPrototypeOf(TouchScroll)).call(this, hotInstance));
|
|
|
|
_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}
|
|
*/
|
|
|
|
|
|
_createClass(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();
|
|
|
|
_get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(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;
|
|
|
|
_get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(TouchScroll.prototype), 'updatePlugin', this).call(this);
|
|
}
|
|
|
|
/**
|
|
* Disable plugin for this Handsontable instance.
|
|
*/
|
|
|
|
}, {
|
|
key: 'disablePlugin',
|
|
value: function disablePlugin() {
|
|
_get(TouchScroll.prototype.__proto__ || Object.getPrototypeOf(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 _hot$view$wt$wtOverla = this.hot.view.wt.wtOverlays,
|
|
topOverlay = _hot$view$wt$wtOverla.topOverlay,
|
|
bottomOverlay = _hot$view$wt$wtOverla.bottomOverlay,
|
|
leftOverlay = _hot$view$wt$wtOverla.leftOverlay,
|
|
topLeftCornerOverlay = _hot$view$wt$wtOverla.topLeftCornerOverlay,
|
|
bottomLeftCornerOverlay = _hot$view$wt$wtOverla.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;
|
|
}(_base2.default);
|
|
|
|
(0, _plugins.registerPlugin)('touchScroll', TouchScroll);
|
|
|
|
exports.default = TouchScroll;
|
|
|
|
/***/ }),
|
|
/* 376 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _pluginHooks = __webpack_require__(8);
|
|
|
|
var _pluginHooks2 = _interopRequireDefault(_pluginHooks);
|
|
|
|
var _array = __webpack_require__(2);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
var _object = __webpack_require__(1);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* @description
|
|
* Handsontable UndoRedo plugin. It allows to undo and redo certain actions done in the table.
|
|
* Please note, that not all actions are currently undo-able.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* ...
|
|
* undo: true
|
|
* ...
|
|
* ```
|
|
* @class UndoRedo
|
|
* @plugin UndoRedo
|
|
*/
|
|
/**
|
|
* Handsontable UndoRedo class
|
|
*/
|
|
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') {
|
|
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();
|
|
|
|
index = (originalData.length + index) % originalData.length;
|
|
|
|
var removedData = (0, _object.deepClone)(originalData.slice(index, index + amount));
|
|
|
|
plugin.done(new UndoRedo.RemoveRowAction(index, 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();
|
|
|
|
index = (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)(index, index + (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', index + i));
|
|
});
|
|
|
|
if (Array.isArray(instance.getSettings().colHeaders)) {
|
|
(0, _number.rangeEach)(amount - 1, function (i) {
|
|
headers.push(instance.getSettings().colHeaders[instance.runHooks('modifyCol', index + i)] || null);
|
|
});
|
|
}
|
|
|
|
var manualColumnMovePlugin = plugin.instance.getPlugin('manualColumnMove');
|
|
|
|
var columnsMap = manualColumnMovePlugin.isEnabled() ? manualColumnMovePlugin.columnsMapper.__arrayMap : [];
|
|
var action = new UndoRedo.RemoveColumnAction(index, 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));
|
|
});
|
|
};
|
|
|
|
UndoRedo.prototype.done = function (action) {
|
|
if (!this.ignoreNewActions) {
|
|
this.doneActions.push(action);
|
|
this.undoneActions.length = 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Undo last edit.
|
|
*
|
|
* @function undo
|
|
* @memberof UndoRedo#
|
|
*/
|
|
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 edit (used to reverse an undo).
|
|
*
|
|
* @function redo
|
|
* @memberof UndoRedo#
|
|
*/
|
|
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);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Check 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;
|
|
};
|
|
|
|
/**
|
|
* Check 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.
|
|
*/
|
|
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),
|
|
emptyRowsAtTheEnd = instance.countEmptyRows(true),
|
|
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.
|
|
*/
|
|
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(),
|
|
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.
|
|
*/
|
|
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.
|
|
*/
|
|
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.
|
|
*/
|
|
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 = void 0;
|
|
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[this.indexes.length - 1], '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[this.indexes.length - 1], '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.
|
|
*/
|
|
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) {
|
|
if (!instance.getPlugin('contextMenu').isEnabled()) {
|
|
return;
|
|
}
|
|
for (var row = this.range.from.row; row <= this.range.to.row; row++) {
|
|
for (var col = this.range.from.col; col <= this.range.to.col; col++) {
|
|
instance.setCellMeta(row, col, 'className', this.stateBefore[row][col] || ' htLeft');
|
|
}
|
|
}
|
|
|
|
instance.addHookOnce('afterRender', undoneCallback);
|
|
instance.render();
|
|
};
|
|
UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback) {
|
|
if (!instance.getPlugin('contextMenu').isEnabled()) {
|
|
return;
|
|
}
|
|
instance.selectCell(this.range.from.row, this.range.from.col, this.range.to.row, this.range.to.col);
|
|
instance.getPlugin('contextMenu').executeCommand('alignment:' + this.alignment.replace('ht', '').toLowerCase());
|
|
|
|
instance.addHookOnce('afterRender', undoneCallback);
|
|
instance.render();
|
|
};
|
|
|
|
/**
|
|
* Filters action.
|
|
*/
|
|
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();
|
|
};
|
|
|
|
/**
|
|
* ManualRowMove action.
|
|
* @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++) {
|
|
newRows.push(this.target + i);
|
|
}
|
|
manualRowMove.moveRows(newRows.slice(), newTarget);
|
|
instance.render();
|
|
|
|
instance.selection.setRangeStartOnly(new _src.CellCoords(this.rows[0], 0));
|
|
instance.selection.setRangeEnd(new _src.CellCoords(this.rows[this.rows.length - 1], instance.countCols() - 1));
|
|
};
|
|
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.selection.setRangeStartOnly(new _src.CellCoords(startSelection, 0));
|
|
instance.selection.setRangeEnd(new _src.CellCoords(startSelection + this.rows.length - 1, instance.countCols() - 1));
|
|
};
|
|
|
|
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 = _pluginHooks2.default.getSingleton();
|
|
|
|
hook.add('afterInit', init);
|
|
hook.add('afterUpdateSettings', init);
|
|
|
|
hook.register('beforeUndo');
|
|
hook.register('afterUndo');
|
|
hook.register('beforeRedo');
|
|
hook.register('afterRedo');
|
|
|
|
/***/ }),
|
|
/* 377 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
function cellDecorator(instance, TD, row, col, prop, value, cellProperties) {
|
|
if (cellProperties.className) {
|
|
if (TD.className) {
|
|
TD.className = TD.className + ' ' + cellProperties.className;
|
|
} else {
|
|
TD.className = cellProperties.className;
|
|
}
|
|
}
|
|
|
|
if (cellProperties.readOnly) {
|
|
(0, _element.addClass)(TD, cellProperties.readOnlyCellClassName);
|
|
}
|
|
|
|
if (cellProperties.valid === false && cellProperties.invalidCellClassName) {
|
|
(0, _element.addClass)(TD, cellProperties.invalidCellClassName);
|
|
} else {
|
|
(0, _element.removeClass)(TD, cellProperties.invalidCellClassName);
|
|
}
|
|
|
|
if (cellProperties.wordWrap === false && cellProperties.noWordWrapClassName) {
|
|
(0, _element.addClass)(TD, cellProperties.noWordWrapClassName);
|
|
}
|
|
|
|
if (!value && cellProperties.placeholder) {
|
|
(0, _element.addClass)(TD, cellProperties.placeholderCellClassName);
|
|
}
|
|
} /**
|
|
* Adds appropriate CSS class to table cell, based on cellProperties
|
|
*/
|
|
exports.default = cellDecorator;
|
|
|
|
/***/ }),
|
|
/* 378 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _index = __webpack_require__(9);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var clonableWRAPPER = document.createElement('DIV');
|
|
clonableWRAPPER.className = 'htAutocompleteWrapper';
|
|
|
|
var clonableARROW = document.createElement('DIV');
|
|
clonableARROW.className = 'htAutocompleteArrow';
|
|
// workaround for https://github.com/handsontable/handsontable/issues/1946
|
|
// this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
|
|
clonableARROW.appendChild(document.createTextNode(String.fromCharCode(9660)));
|
|
|
|
var wrapTdContentWithWrapper = function wrapTdContentWithWrapper(TD, WRAPPER) {
|
|
WRAPPER.innerHTML = TD.innerHTML;
|
|
(0, _element.empty)(TD);
|
|
TD.appendChild(WRAPPER);
|
|
};
|
|
|
|
/**
|
|
* Autocomplete renderer
|
|
*
|
|
* @private
|
|
* @renderer AutocompleteRenderer
|
|
* @param {Object} instance Handsontable instance
|
|
* @param {Element} TD Table cell where to render
|
|
* @param {Number} row
|
|
* @param {Number} col
|
|
* @param {String|Number} prop Row object property name
|
|
* @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
|
|
* @param {Object} cellProperties Cell properites (shared by cell renderer and editor)
|
|
*/
|
|
function autocompleteRenderer(instance, TD, row, col, prop, value, cellProperties) {
|
|
var WRAPPER = clonableWRAPPER.cloneNode(true); // this is faster than createElement
|
|
var ARROW = clonableARROW.cloneNode(true); // this is faster than createElement
|
|
|
|
if (cellProperties.allowHtml) {
|
|
(0, _index.getRenderer)('html').apply(this, arguments);
|
|
} else {
|
|
(0, _index.getRenderer)('text').apply(this, arguments);
|
|
}
|
|
|
|
TD.appendChild(ARROW);
|
|
(0, _element.addClass)(TD, 'htAutocomplete');
|
|
|
|
if (!TD.firstChild) {
|
|
// http://jsperf.com/empty-node-if-needed
|
|
// otherwise empty fields appear borderless in demo/renderers.html (IE)
|
|
TD.appendChild(document.createTextNode(String.fromCharCode(160))); // workaround for https://github.com/handsontable/handsontable/issues/1946
|
|
// this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
|
|
}
|
|
|
|
if (!instance.acArrowListener) {
|
|
var eventManager = new _eventManager2.default(instance);
|
|
|
|
// not very elegant but easy and fast
|
|
instance.acArrowListener = function (event) {
|
|
if ((0, _element.hasClass)(event.target, 'htAutocompleteArrow')) {
|
|
instance.view.wt.getSetting('onCellDblClick', null, new _src.CellCoords(row, col), TD);
|
|
}
|
|
};
|
|
|
|
eventManager.addEventListener(instance.rootElement, 'mousedown', instance.acArrowListener);
|
|
|
|
// We need to unbind the listener after the table has been destroyed
|
|
instance.addHookOnce('afterDestroy', function () {
|
|
eventManager.destroy();
|
|
});
|
|
}
|
|
}
|
|
|
|
exports.default = autocompleteRenderer;
|
|
|
|
/***/ }),
|
|
/* 379 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _string = __webpack_require__(27);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _unicode = __webpack_require__(16);
|
|
|
|
var _function = __webpack_require__(35);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _index = __webpack_require__(9);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var isListeningKeyDownEvent = new WeakMap();
|
|
var isCheckboxListenerAdded = new WeakMap();
|
|
var BAD_VALUE_CLASS = 'htBadValue';
|
|
|
|
/**
|
|
* Checkbox renderer
|
|
*
|
|
* @private
|
|
* @param {Object} instance Handsontable instance
|
|
* @param {Element} TD Table cell where to render
|
|
* @param {Number} row
|
|
* @param {Number} col
|
|
* @param {String|Number} prop Row object property name
|
|
* @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
|
|
* @param {Object} cellProperties Cell properties (shared by cell renderer and editor)
|
|
*/
|
|
function checkboxRenderer(instance, TD, row, col, prop, value, cellProperties) {
|
|
(0, _index.getRenderer)('base').apply(this, arguments);
|
|
|
|
var eventManager = registerEvents(instance);
|
|
var input = createInput();
|
|
var labelOptions = cellProperties.label;
|
|
var badValue = false;
|
|
|
|
if (typeof cellProperties.checkedTemplate === 'undefined') {
|
|
cellProperties.checkedTemplate = true;
|
|
}
|
|
if (typeof cellProperties.uncheckedTemplate === 'undefined') {
|
|
cellProperties.uncheckedTemplate = false;
|
|
}
|
|
|
|
(0, _element.empty)(TD); // TODO identify under what circumstances this line can be removed
|
|
|
|
if (value === cellProperties.checkedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.checkedTemplate)) {
|
|
input.checked = true;
|
|
} else if (value === cellProperties.uncheckedTemplate || (0, _string.equalsIgnoreCase)(value, cellProperties.uncheckedTemplate)) {
|
|
input.checked = false;
|
|
} else if (value === null) {
|
|
// default value
|
|
(0, _element.addClass)(input, 'noValue');
|
|
} else {
|
|
input.style.display = 'none';
|
|
(0, _element.addClass)(input, BAD_VALUE_CLASS);
|
|
badValue = true;
|
|
}
|
|
|
|
input.setAttribute('data-row', row);
|
|
input.setAttribute('data-col', col);
|
|
|
|
if (!badValue && labelOptions) {
|
|
var labelText = '';
|
|
|
|
if (labelOptions.value) {
|
|
labelText = typeof labelOptions.value === 'function' ? labelOptions.value.call(this, row, col, prop, value) : labelOptions.value;
|
|
} else if (labelOptions.property) {
|
|
labelText = instance.getDataAtRowProp(row, labelOptions.property);
|
|
}
|
|
var label = createLabel(labelText);
|
|
|
|
if (labelOptions.position === 'before') {
|
|
label.appendChild(input);
|
|
} else {
|
|
label.insertBefore(input, label.firstChild);
|
|
}
|
|
input = label;
|
|
}
|
|
|
|
TD.appendChild(input);
|
|
|
|
if (badValue) {
|
|
TD.appendChild(document.createTextNode('#bad-value#'));
|
|
}
|
|
|
|
if (!isListeningKeyDownEvent.has(instance)) {
|
|
isListeningKeyDownEvent.set(instance, true);
|
|
instance.addHook('beforeKeyDown', onBeforeKeyDown);
|
|
}
|
|
|
|
/**
|
|
* On before key down DOM listener.
|
|
*
|
|
* @private
|
|
* @param {Event} event
|
|
*/
|
|
function onBeforeKeyDown(event) {
|
|
var toggleKeys = 'SPACE|ENTER';
|
|
var switchOffKeys = 'DELETE|BACKSPACE';
|
|
var isKeyCode = (0, _function.partial)(_unicode.isKey, event.keyCode);
|
|
|
|
if (isKeyCode(toggleKeys + '|' + switchOffKeys) && !(0, _event.isImmediatePropagationStopped)(event)) {
|
|
eachSelectedCheckboxCell(function () {
|
|
(0, _event.stopImmediatePropagation)(event);
|
|
event.preventDefault();
|
|
});
|
|
}
|
|
if (isKeyCode(toggleKeys)) {
|
|
changeSelectedCheckboxesState();
|
|
}
|
|
if (isKeyCode(switchOffKeys)) {
|
|
changeSelectedCheckboxesState(true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Change checkbox checked property
|
|
*
|
|
* @private
|
|
* @param {Boolean} [uncheckCheckbox=false]
|
|
*/
|
|
function changeSelectedCheckboxesState() {
|
|
var uncheckCheckbox = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
|
|
var selRange = instance.getSelectedRange();
|
|
|
|
if (!selRange) {
|
|
return;
|
|
}
|
|
|
|
var topLeft = selRange.getTopLeftCorner();
|
|
var bottomRight = selRange.getBottomRightCorner();
|
|
var changes = [];
|
|
|
|
for (var _row = topLeft.row; _row <= bottomRight.row; _row += 1) {
|
|
for (var _col = topLeft.col; _col <= bottomRight.col; _col += 1) {
|
|
var _cellProperties = instance.getCellMeta(_row, _col);
|
|
|
|
if (_cellProperties.type !== 'checkbox') {
|
|
return;
|
|
}
|
|
|
|
/* eslint-disable no-continue */
|
|
if (_cellProperties.readOnly === true) {
|
|
continue;
|
|
}
|
|
|
|
if (typeof _cellProperties.checkedTemplate === 'undefined') {
|
|
_cellProperties.checkedTemplate = true;
|
|
}
|
|
if (typeof _cellProperties.uncheckedTemplate === 'undefined') {
|
|
_cellProperties.uncheckedTemplate = false;
|
|
}
|
|
|
|
var dataAtCell = instance.getDataAtCell(_row, _col);
|
|
|
|
if (uncheckCheckbox === false) {
|
|
if (dataAtCell === _cellProperties.checkedTemplate) {
|
|
changes.push([_row, _col, _cellProperties.uncheckedTemplate]);
|
|
} else if ([_cellProperties.uncheckedTemplate, null, void 0].indexOf(dataAtCell) !== -1) {
|
|
changes.push([_row, _col, _cellProperties.checkedTemplate]);
|
|
}
|
|
} else {
|
|
changes.push([_row, _col, _cellProperties.uncheckedTemplate]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (changes.length > 0) {
|
|
instance.setDataAtCell(changes);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Call callback for each found selected cell with checkbox type.
|
|
*
|
|
* @private
|
|
* @param {Function} callback
|
|
*/
|
|
function eachSelectedCheckboxCell(callback) {
|
|
var selRange = instance.getSelectedRange();
|
|
|
|
if (!selRange) {
|
|
return;
|
|
}
|
|
var topLeft = selRange.getTopLeftCorner();
|
|
var bottomRight = selRange.getBottomRightCorner();
|
|
|
|
for (var _row2 = topLeft.row; _row2 <= bottomRight.row; _row2++) {
|
|
for (var _col2 = topLeft.col; _col2 <= bottomRight.col; _col2++) {
|
|
var _cellProperties2 = instance.getCellMeta(_row2, _col2);
|
|
|
|
if (_cellProperties2.type !== 'checkbox') {
|
|
return;
|
|
}
|
|
|
|
var cell = instance.getCell(_row2, _col2);
|
|
|
|
if (cell == null) {
|
|
|
|
callback(_row2, _col2, _cellProperties2);
|
|
} else {
|
|
var checkboxes = cell.querySelectorAll('input[type=checkbox]');
|
|
|
|
if (checkboxes.length > 0 && !_cellProperties2.readOnly) {
|
|
callback(checkboxes);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register checkbox listeners.
|
|
*
|
|
* @param {Handsontable} instance Handsontable instance.
|
|
* @returns {EventManager}
|
|
*/
|
|
function registerEvents(instance) {
|
|
var eventManager = isCheckboxListenerAdded.get(instance);
|
|
|
|
if (!eventManager) {
|
|
eventManager = new _eventManager2.default(instance);
|
|
eventManager.addEventListener(instance.rootElement, 'click', function (event) {
|
|
return onClick(event, instance);
|
|
});
|
|
eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) {
|
|
return onMouseUp(event, instance);
|
|
});
|
|
eventManager.addEventListener(instance.rootElement, 'change', function (event) {
|
|
return onChange(event, instance);
|
|
});
|
|
|
|
isCheckboxListenerAdded.set(instance, eventManager);
|
|
}
|
|
|
|
return eventManager;
|
|
}
|
|
|
|
/**
|
|
* Create input element.
|
|
*
|
|
* @returns {Node}
|
|
*/
|
|
function createInput() {
|
|
var input = document.createElement('input');
|
|
|
|
input.className = 'htCheckboxRendererInput';
|
|
input.type = 'checkbox';
|
|
input.setAttribute('autocomplete', 'off');
|
|
input.setAttribute('tabindex', '-1');
|
|
|
|
return input.cloneNode(false);
|
|
}
|
|
|
|
/**
|
|
* Create label element.
|
|
*
|
|
* @returns {Node}
|
|
*/
|
|
function createLabel(text) {
|
|
var label = document.createElement('label');
|
|
|
|
label.className = 'htCheckboxRendererLabel';
|
|
label.appendChild(document.createTextNode(text));
|
|
|
|
return label.cloneNode(true);
|
|
}
|
|
|
|
/**
|
|
* `mouseup` callback.
|
|
*
|
|
* @private
|
|
* @param {Event} event `mouseup` event.
|
|
* @param {Object} instance Handsontable instance.
|
|
*/
|
|
function onMouseUp(event, instance) {
|
|
if (!isCheckboxInput(event.target)) {
|
|
return;
|
|
}
|
|
setTimeout(instance.listen, 10);
|
|
}
|
|
|
|
/**
|
|
* `click` callback.
|
|
*
|
|
* @private
|
|
* @param {Event} event `click` event.
|
|
* @param {Object} instance Handsontable instance.
|
|
*/
|
|
function onClick(event, instance) {
|
|
if (!isCheckboxInput(event.target)) {
|
|
return false;
|
|
}
|
|
|
|
var row = parseInt(event.target.getAttribute('data-row'), 10);
|
|
var col = parseInt(event.target.getAttribute('data-col'), 10);
|
|
var cellProperties = instance.getCellMeta(row, col);
|
|
|
|
if (cellProperties.readOnly) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* `change` callback.
|
|
*
|
|
* @param {Event} event `change` event.
|
|
* @param {Object} instance Handsontable instance.
|
|
* @param {Object} cellProperties Reference to cell properties.
|
|
* @returns {Boolean}
|
|
*/
|
|
function onChange(event, instance) {
|
|
if (!isCheckboxInput(event.target)) {
|
|
return false;
|
|
}
|
|
|
|
var row = parseInt(event.target.getAttribute('data-row'), 10);
|
|
var col = parseInt(event.target.getAttribute('data-col'), 10);
|
|
var cellProperties = instance.getCellMeta(row, col);
|
|
|
|
if (!cellProperties.readOnly) {
|
|
var newCheckboxValue = null;
|
|
|
|
if (event.target.checked) {
|
|
newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? true : cellProperties.checkedTemplate;
|
|
} else {
|
|
newCheckboxValue = cellProperties.uncheckedTemplate === void 0 ? false : cellProperties.uncheckedTemplate;
|
|
}
|
|
|
|
instance.setDataAtCell(row, col, newCheckboxValue);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the provided element is the checkbox input.
|
|
*
|
|
* @private
|
|
* @param {HTMLElement} element The element in question.
|
|
* @returns {Boolean}
|
|
*/
|
|
function isCheckboxInput(element) {
|
|
return element.tagName === 'INPUT' && element.getAttribute('type') === 'checkbox';
|
|
}
|
|
|
|
exports.default = checkboxRenderer;
|
|
|
|
/***/ }),
|
|
/* 380 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _index = __webpack_require__(9);
|
|
|
|
/**
|
|
* @private
|
|
* @renderer HtmlRenderer
|
|
* @param instance
|
|
* @param TD
|
|
* @param row
|
|
* @param col
|
|
* @param prop
|
|
* @param value
|
|
* @param cellProperties
|
|
*/
|
|
function htmlRenderer(instance, TD, row, col, prop, value, cellProperties) {
|
|
(0, _index.getRenderer)('base').apply(this, arguments);
|
|
|
|
if (value === null || value === void 0) {
|
|
value = '';
|
|
}
|
|
|
|
(0, _element.fastInnerHTML)(TD, value);
|
|
}
|
|
|
|
exports.default = htmlRenderer;
|
|
|
|
/***/ }),
|
|
/* 381 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _numbro = __webpack_require__(51);
|
|
|
|
var _numbro2 = _interopRequireDefault(_numbro);
|
|
|
|
var _index = __webpack_require__(9);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* Numeric cell renderer
|
|
*
|
|
* @private
|
|
* @renderer NumericRenderer
|
|
* @dependencies numbro
|
|
* @param {Object} instance Handsontable instance
|
|
* @param {Element} TD Table cell where to render
|
|
* @param {Number} row
|
|
* @param {Number} col
|
|
* @param {String|Number} prop Row object property name
|
|
* @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
|
|
* @param {Object} cellProperties Cell properties (shared by cell renderer and editor)
|
|
*/
|
|
function numericRenderer(instance, TD, row, col, prop, value, cellProperties) {
|
|
if ((0, _number.isNumeric)(value)) {
|
|
if (typeof cellProperties.language !== 'undefined') {
|
|
_numbro2.default.culture(cellProperties.language);
|
|
}
|
|
|
|
value = (0, _numbro2.default)(value).format(cellProperties.format || '0');
|
|
|
|
var className = cellProperties.className || '';
|
|
|
|
var classArr = className.length ? className.split(' ') : [];
|
|
|
|
if (classArr.indexOf('htLeft') < 0 && classArr.indexOf('htCenter') < 0 && classArr.indexOf('htRight') < 0 && classArr.indexOf('htJustify') < 0) {
|
|
classArr.push('htRight');
|
|
}
|
|
|
|
if (classArr.indexOf('htNumeric') < 0) {
|
|
classArr.push('htNumeric');
|
|
}
|
|
|
|
cellProperties.className = classArr.join(' ');
|
|
}
|
|
|
|
(0, _index.getRenderer)('text')(instance, TD, row, col, prop, value, cellProperties);
|
|
}
|
|
|
|
exports.default = numericRenderer;
|
|
|
|
/***/ }),
|
|
/* 382 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _index = __webpack_require__(9);
|
|
|
|
var _number = __webpack_require__(6);
|
|
|
|
/**
|
|
* @private
|
|
* @renderer PasswordRenderer
|
|
* @param instance
|
|
* @param TD
|
|
* @param row
|
|
* @param col
|
|
* @param prop
|
|
* @param value
|
|
* @param cellProperties
|
|
*/
|
|
function passwordRenderer(instance, TD, row, col, prop, value, cellProperties) {
|
|
(0, _index.getRenderer)('text').apply(this, arguments);
|
|
|
|
value = TD.innerHTML;
|
|
|
|
var hashLength = cellProperties.hashLength || value.length;
|
|
var hashSymbol = cellProperties.hashSymbol || '*';
|
|
|
|
var hash = '';
|
|
|
|
(0, _number.rangeEach)(hashLength - 1, function () {
|
|
hash += hashSymbol;
|
|
});
|
|
(0, _element.fastInnerHTML)(TD, hash);
|
|
}
|
|
|
|
exports.default = passwordRenderer;
|
|
|
|
/***/ }),
|
|
/* 383 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _mixed = __webpack_require__(20);
|
|
|
|
var _index = __webpack_require__(9);
|
|
|
|
/**
|
|
* Default text renderer
|
|
*
|
|
* @private
|
|
* @renderer TextRenderer
|
|
* @param {Object} instance Handsontable instance
|
|
* @param {Element} TD Table cell where to render
|
|
* @param {Number} row
|
|
* @param {Number} col
|
|
* @param {String|Number} prop Row object property name
|
|
* @param value Value to render (remember to escape unsafe HTML before inserting to DOM!)
|
|
* @param {Object} cellProperties Cell properties (shared by cell renderer and editor)
|
|
*/
|
|
function textRenderer(instance, TD, row, col, prop, value, cellProperties) {
|
|
(0, _index.getRenderer)('base').apply(this, arguments);
|
|
|
|
if (!value && cellProperties.placeholder) {
|
|
value = cellProperties.placeholder;
|
|
}
|
|
|
|
var escaped = (0, _mixed.stringify)(value);
|
|
|
|
if (!instance.getSettings().trimWhitespace) {
|
|
escaped = escaped.replace(/ /g, String.fromCharCode(160));
|
|
}
|
|
|
|
if (cellProperties.rendererTemplate) {
|
|
(0, _element.empty)(TD);
|
|
var TEMPLATE = document.createElement('TEMPLATE');
|
|
TEMPLATE.setAttribute('bind', '{{}}');
|
|
TEMPLATE.innerHTML = cellProperties.rendererTemplate;
|
|
HTMLTemplateElement.decorate(TEMPLATE);
|
|
TEMPLATE.model = instance.getSourceDataAtRow(row);
|
|
TD.appendChild(TEMPLATE);
|
|
} else {
|
|
// this is faster than innerHTML. See: https://github.com/handsontable/handsontable/wiki/JavaScript-&-DOM-performance-tips
|
|
(0, _element.fastInnerText)(TD, escaped);
|
|
}
|
|
}
|
|
|
|
exports.default = textRenderer;
|
|
|
|
/***/ }),
|
|
/* 384 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
|
|
|
var _element = __webpack_require__(0);
|
|
|
|
var _browser = __webpack_require__(25);
|
|
|
|
var _eventManager = __webpack_require__(4);
|
|
|
|
var _eventManager2 = _interopRequireDefault(_eventManager);
|
|
|
|
var _event = __webpack_require__(7);
|
|
|
|
var _src = __webpack_require__(11);
|
|
|
|
var _src2 = _interopRequireDefault(_src);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* Handsontable TableView constructor
|
|
* @param {Object} instance
|
|
*/
|
|
function TableView(instance) {
|
|
var _this = this;
|
|
|
|
var that = this;
|
|
|
|
this.eventManager = new _eventManager2.default(instance);
|
|
this.instance = instance;
|
|
this.settings = instance.getSettings();
|
|
this.selectionMouseDown = false;
|
|
|
|
var originalStyle = instance.rootElement.getAttribute('style');
|
|
|
|
if (originalStyle) {
|
|
instance.rootElement.setAttribute('data-originalstyle', originalStyle); // needed to retrieve original style in jsFiddle link generator in HT examples. may be removed in future versions
|
|
}
|
|
|
|
(0, _element.addClass)(instance.rootElement, 'handsontable');
|
|
|
|
var table = document.createElement('TABLE');
|
|
(0, _element.addClass)(table, 'htCore');
|
|
|
|
if (instance.getSettings().tableClassName) {
|
|
(0, _element.addClass)(table, instance.getSettings().tableClassName);
|
|
}
|
|
this.THEAD = document.createElement('THEAD');
|
|
table.appendChild(this.THEAD);
|
|
this.TBODY = document.createElement('TBODY');
|
|
table.appendChild(this.TBODY);
|
|
|
|
instance.table = table;
|
|
|
|
instance.container.insertBefore(table, instance.container.firstChild);
|
|
|
|
this.eventManager.addEventListener(instance.rootElement, 'mousedown', function (event) {
|
|
this.selectionMouseDown = true;
|
|
|
|
if (!that.isTextSelectionAllowed(event.target)) {
|
|
clearTextSelection();
|
|
event.preventDefault();
|
|
window.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe.
|
|
}
|
|
});
|
|
this.eventManager.addEventListener(instance.rootElement, 'mouseup', function (event) {
|
|
this.selectionMouseDown = false;
|
|
});
|
|
this.eventManager.addEventListener(instance.rootElement, 'mousemove', function (event) {
|
|
if (this.selectionMouseDown && !that.isTextSelectionAllowed(event.target)) {
|
|
clearTextSelection();
|
|
event.preventDefault();
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'keyup', function (event) {
|
|
if (instance.selection.isInProgress() && !event.shiftKey) {
|
|
instance.selection.finish();
|
|
}
|
|
});
|
|
|
|
var isMouseDown;
|
|
this.isMouseDown = function () {
|
|
return isMouseDown;
|
|
};
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'mouseup', function (event) {
|
|
if (instance.selection.isInProgress() && event.which === 1) {
|
|
// is left mouse button
|
|
instance.selection.finish();
|
|
}
|
|
|
|
isMouseDown = false;
|
|
|
|
if ((0, _element.isOutsideInput)(document.activeElement) || !instance.selection.isSelected()) {
|
|
instance.unlisten();
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'mousedown', function (event) {
|
|
var originalTarget = event.target;
|
|
var next = event.target;
|
|
var eventX = event.x || event.clientX;
|
|
var eventY = event.y || event.clientY;
|
|
|
|
if (isMouseDown || !instance.rootElement) {
|
|
return; // it must have been started in a cell
|
|
}
|
|
|
|
// immediate click on "holder" means click on the right side of vertical scrollbar
|
|
if (next === instance.view.wt.wtTable.holder) {
|
|
var scrollbarWidth = (0, _element.getScrollbarWidth)();
|
|
|
|
if (document.elementFromPoint(eventX + scrollbarWidth, eventY) !== instance.view.wt.wtTable.holder || document.elementFromPoint(eventX, eventY + scrollbarWidth) !== instance.view.wt.wtTable.holder) {
|
|
return;
|
|
}
|
|
} else {
|
|
while (next !== document.documentElement) {
|
|
if (next === null) {
|
|
if (event.isTargetWebComponent) {
|
|
break;
|
|
}
|
|
// click on something that was a row but now is detached (possibly because your click triggered a rerender)
|
|
return;
|
|
}
|
|
if (next === instance.rootElement) {
|
|
// click inside container
|
|
return;
|
|
}
|
|
next = next.parentNode;
|
|
}
|
|
}
|
|
|
|
// function did not return until here, we have an outside click!
|
|
|
|
var outsideClickDeselects = typeof that.settings.outsideClickDeselects === 'function' ? that.settings.outsideClickDeselects(originalTarget) : that.settings.outsideClickDeselects;
|
|
|
|
if (outsideClickDeselects) {
|
|
instance.deselectCell();
|
|
} else {
|
|
instance.destroyEditor();
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(table, 'selectstart', function (event) {
|
|
if (that.settings.fragmentSelection || (0, _element.isInput)(event.target)) {
|
|
return;
|
|
}
|
|
// https://github.com/handsontable/handsontable/issues/160
|
|
// Prevent text from being selected when performing drag down.
|
|
event.preventDefault();
|
|
});
|
|
|
|
var clearTextSelection = function clearTextSelection() {
|
|
// http://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript
|
|
if (window.getSelection) {
|
|
if (window.getSelection().empty) {
|
|
// Chrome
|
|
window.getSelection().empty();
|
|
} else if (window.getSelection().removeAllRanges) {
|
|
// Firefox
|
|
window.getSelection().removeAllRanges();
|
|
}
|
|
} else if (document.selection) {
|
|
// IE?
|
|
document.selection.empty();
|
|
}
|
|
};
|
|
|
|
var selections = [new _src.Selection({
|
|
className: 'current',
|
|
border: {
|
|
width: 2,
|
|
color: '#5292F7',
|
|
// style: 'solid', // not used
|
|
cornerVisible: function cornerVisible() {
|
|
return that.settings.fillHandle && !that.isCellEdited() && !instance.selection.isMultiple();
|
|
},
|
|
multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() {
|
|
return !that.isCellEdited() && !instance.selection.isMultiple();
|
|
}
|
|
}
|
|
}), new _src.Selection({
|
|
className: 'area',
|
|
border: {
|
|
width: 1,
|
|
color: '#89AFF9',
|
|
// style: 'solid', // not used
|
|
cornerVisible: function cornerVisible() {
|
|
return that.settings.fillHandle && !that.isCellEdited() && instance.selection.isMultiple();
|
|
},
|
|
multipleSelectionHandlesVisible: function multipleSelectionHandlesVisible() {
|
|
return !that.isCellEdited() && instance.selection.isMultiple();
|
|
}
|
|
}
|
|
}), new _src.Selection({
|
|
className: 'highlight',
|
|
highlightHeaderClassName: that.settings.currentHeaderClassName,
|
|
highlightRowClassName: that.settings.currentRowClassName,
|
|
highlightColumnClassName: that.settings.currentColClassName
|
|
}), new _src.Selection({
|
|
className: 'fill',
|
|
border: {
|
|
width: 1,
|
|
color: 'red'
|
|
// style: 'solid' // not used
|
|
}
|
|
})];
|
|
selections.current = selections[0];
|
|
selections.area = selections[1];
|
|
selections.highlight = selections[2];
|
|
selections.fill = selections[3];
|
|
|
|
var walkontableConfig = {
|
|
debug: function debug() {
|
|
return that.settings.debug;
|
|
},
|
|
externalRowCalculator: this.instance.getPlugin('autoRowSize') && this.instance.getPlugin('autoRowSize').isEnabled(),
|
|
table: table,
|
|
preventOverflow: function preventOverflow() {
|
|
return _this.settings.preventOverflow;
|
|
},
|
|
stretchH: function stretchH() {
|
|
return that.settings.stretchH;
|
|
},
|
|
data: instance.getDataAtCell,
|
|
totalRows: function totalRows() {
|
|
return instance.countRows();
|
|
},
|
|
totalColumns: function totalColumns() {
|
|
return instance.countCols();
|
|
},
|
|
fixedColumnsLeft: function fixedColumnsLeft() {
|
|
return that.settings.fixedColumnsLeft;
|
|
},
|
|
fixedRowsTop: function fixedRowsTop() {
|
|
return that.settings.fixedRowsTop;
|
|
},
|
|
fixedRowsBottom: function fixedRowsBottom() {
|
|
return that.settings.fixedRowsBottom;
|
|
},
|
|
minSpareRows: function minSpareRows() {
|
|
return that.settings.minSpareRows;
|
|
},
|
|
renderAllRows: that.settings.renderAllRows,
|
|
rowHeaders: function rowHeaders() {
|
|
var headerRenderers = [];
|
|
|
|
if (instance.hasRowHeaders()) {
|
|
headerRenderers.push(function (row, TH) {
|
|
that.appendRowHeader(row, TH);
|
|
});
|
|
}
|
|
instance.runHooks('afterGetRowHeaderRenderers', headerRenderers);
|
|
|
|
return headerRenderers;
|
|
},
|
|
columnHeaders: function columnHeaders() {
|
|
var headerRenderers = [];
|
|
|
|
if (instance.hasColHeaders()) {
|
|
headerRenderers.push(function (column, TH) {
|
|
that.appendColHeader(column, TH);
|
|
});
|
|
}
|
|
instance.runHooks('afterGetColumnHeaderRenderers', headerRenderers);
|
|
|
|
return headerRenderers;
|
|
},
|
|
columnWidth: instance.getColWidth,
|
|
rowHeight: instance.getRowHeight,
|
|
cellRenderer: function cellRenderer(row, col, TD) {
|
|
var cellProperties = that.instance.getCellMeta(row, col);
|
|
var prop = that.instance.colToProp(col);
|
|
var value = that.instance.getDataAtRowProp(row, prop);
|
|
|
|
if (that.instance.hasHook('beforeValueRender')) {
|
|
value = that.instance.runHooks('beforeValueRender', value);
|
|
}
|
|
|
|
that.instance.runHooks('beforeRenderer', TD, row, col, prop, value, cellProperties);
|
|
that.instance.getCellRenderer(cellProperties)(that.instance, TD, row, col, prop, value, cellProperties);
|
|
that.instance.runHooks('afterRenderer', TD, row, col, prop, value, cellProperties);
|
|
},
|
|
selections: selections,
|
|
hideBorderOnMouseDownOver: function hideBorderOnMouseDownOver() {
|
|
return that.settings.fragmentSelection;
|
|
},
|
|
onCellMouseDown: function onCellMouseDown(event, coords, TD, wt) {
|
|
var blockCalculations = {
|
|
row: false,
|
|
column: false,
|
|
cells: false
|
|
};
|
|
|
|
instance.listen();
|
|
|
|
that.activeWt = wt;
|
|
isMouseDown = true;
|
|
|
|
instance.runHooks('beforeOnCellMouseDown', event, coords, TD, blockCalculations);
|
|
|
|
if ((0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
|
|
var actualSelection = instance.getSelectedRange();
|
|
var selection = instance.selection;
|
|
var selectedHeader = selection.selectedHeader;
|
|
|
|
if (event.shiftKey && actualSelection) {
|
|
if (coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) {
|
|
selection.setSelectedHeaders(false, false);
|
|
selection.setRangeEnd(coords);
|
|
} else if ((selectedHeader.cols || selectedHeader.rows) && coords.row >= 0 && coords.col >= 0 && !blockCalculations.cells) {
|
|
selection.setSelectedHeaders(false, false);
|
|
selection.setRangeEnd(new _src.CellCoords(coords.row, coords.col));
|
|
} else if (selectedHeader.cols && coords.row < 0 && !blockCalculations.column) {
|
|
selection.setRangeEnd(new _src.CellCoords(actualSelection.to.row, coords.col));
|
|
} else if (selectedHeader.rows && coords.col < 0 && !blockCalculations.row) {
|
|
selection.setRangeEnd(new _src.CellCoords(coords.row, actualSelection.to.col));
|
|
} else if ((!selectedHeader.cols && !selectedHeader.rows && coords.col < 0 || selectedHeader.cols && coords.col < 0) && !blockCalculations.row) {
|
|
selection.setSelectedHeaders(true, false);
|
|
selection.setRangeStartOnly(new _src.CellCoords(actualSelection.from.row, 0));
|
|
selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1));
|
|
} else if ((!selectedHeader.cols && !selectedHeader.rows && coords.row < 0 || selectedHeader.rows && coords.row < 0) && !blockCalculations.column) {
|
|
selection.setSelectedHeaders(false, true);
|
|
selection.setRangeStartOnly(new _src.CellCoords(0, actualSelection.from.col));
|
|
selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col));
|
|
}
|
|
} else {
|
|
var doNewSelection = true;
|
|
|
|
if (actualSelection) {
|
|
var from = actualSelection.from,
|
|
to = actualSelection.to;
|
|
|
|
var coordsNotInSelection = !selection.inInSelection(coords);
|
|
|
|
if (coords.row < 0 && selectedHeader.cols) {
|
|
var start = Math.min(from.col, to.col);
|
|
var end = Math.max(from.col, to.col);
|
|
|
|
doNewSelection = coords.col < start || coords.col > end;
|
|
} else if (coords.col < 0 && selectedHeader.rows) {
|
|
var _start = Math.min(from.row, to.row);
|
|
var _end = Math.max(from.row, to.row);
|
|
|
|
doNewSelection = coords.row < _start || coords.row > _end;
|
|
} else {
|
|
doNewSelection = coordsNotInSelection;
|
|
}
|
|
}
|
|
|
|
var rightClick = (0, _event.isRightClick)(event);
|
|
var leftClick = (0, _event.isLeftClick)(event) || event.type === 'touchstart';
|
|
|
|
// clicked row header and when some column was selected
|
|
if (coords.row < 0 && coords.col >= 0 && !blockCalculations.column) {
|
|
selection.setSelectedHeaders(false, true);
|
|
|
|
if (leftClick || rightClick && doNewSelection) {
|
|
selection.setRangeStartOnly(new _src.CellCoords(0, coords.col));
|
|
selection.setRangeEnd(new _src.CellCoords(Math.max(instance.countRows() - 1, 0), coords.col), false);
|
|
}
|
|
|
|
// clicked column header and when some row was selected
|
|
} else if (coords.col < 0 && coords.row >= 0 && !blockCalculations.row) {
|
|
selection.setSelectedHeaders(true, false);
|
|
|
|
if (leftClick || rightClick && doNewSelection) {
|
|
selection.setRangeStartOnly(new _src.CellCoords(coords.row, 0));
|
|
selection.setRangeEnd(new _src.CellCoords(coords.row, Math.max(instance.countCols() - 1, 0)), false);
|
|
}
|
|
} else if (coords.col >= 0 && coords.row >= 0 && !blockCalculations.cells) {
|
|
if (leftClick || rightClick && doNewSelection) {
|
|
selection.setSelectedHeaders(false, false);
|
|
selection.setRangeStart(coords);
|
|
}
|
|
} else if (coords.col < 0 && coords.row < 0) {
|
|
coords.row = 0;
|
|
coords.col = 0;
|
|
|
|
selection.setSelectedHeaders(false, false, true);
|
|
selection.setRangeStart(coords);
|
|
}
|
|
}
|
|
|
|
instance.runHooks('afterOnCellMouseDown', event, coords, TD);
|
|
that.activeWt = that.wt;
|
|
},
|
|
onCellMouseOut: function onCellMouseOut(event, coords, TD, wt) {
|
|
that.activeWt = wt;
|
|
instance.runHooks('beforeOnCellMouseOut', event, coords, TD);
|
|
|
|
if ((0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
|
|
instance.runHooks('afterOnCellMouseOut', event, coords, TD);
|
|
that.activeWt = that.wt;
|
|
},
|
|
onCellMouseOver: function onCellMouseOver(event, coords, TD, wt) {
|
|
var blockCalculations = {
|
|
row: false,
|
|
column: false,
|
|
cell: false
|
|
};
|
|
|
|
that.activeWt = wt;
|
|
instance.runHooks('beforeOnCellMouseOver', event, coords, TD, blockCalculations);
|
|
|
|
if ((0, _event.isImmediatePropagationStopped)(event)) {
|
|
return;
|
|
}
|
|
|
|
if (event.button === 0 && isMouseDown) {
|
|
if (coords.row >= 0 && coords.col >= 0) {
|
|
// is not a header
|
|
if (instance.selection.selectedHeader.cols && !blockCalculations.column) {
|
|
instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false);
|
|
} else if (instance.selection.selectedHeader.rows && !blockCalculations.row) {
|
|
instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false);
|
|
} else if (!blockCalculations.cell) {
|
|
instance.selection.setRangeEnd(coords);
|
|
}
|
|
} else {
|
|
/* eslint-disable no-lonely-if */
|
|
if (instance.selection.selectedHeader.cols && !blockCalculations.column) {
|
|
instance.selection.setRangeEnd(new _src.CellCoords(instance.countRows() - 1, coords.col), false);
|
|
} else if (instance.selection.selectedHeader.rows && !blockCalculations.row) {
|
|
instance.selection.setRangeEnd(new _src.CellCoords(coords.row, instance.countCols() - 1), false);
|
|
} else if (!blockCalculations.cell) {
|
|
instance.selection.setRangeEnd(coords);
|
|
}
|
|
}
|
|
}
|
|
|
|
instance.runHooks('afterOnCellMouseOver', event, coords, TD);
|
|
that.activeWt = that.wt;
|
|
},
|
|
onCellMouseUp: function onCellMouseUp(event, coords, TD, wt) {
|
|
that.activeWt = wt;
|
|
instance.runHooks('beforeOnCellMouseUp', event, coords, TD);
|
|
|
|
instance.runHooks('afterOnCellMouseUp', event, coords, TD);
|
|
that.activeWt = that.wt;
|
|
},
|
|
onCellCornerMouseDown: function onCellCornerMouseDown(event) {
|
|
event.preventDefault();
|
|
instance.runHooks('afterOnCellCornerMouseDown', event);
|
|
},
|
|
onCellCornerDblClick: function onCellCornerDblClick(event) {
|
|
event.preventDefault();
|
|
instance.runHooks('afterOnCellCornerDblClick', event);
|
|
},
|
|
beforeDraw: function beforeDraw(force, skipRender) {
|
|
that.beforeRender(force, skipRender);
|
|
},
|
|
onDraw: function onDraw(force) {
|
|
that.onDraw(force);
|
|
},
|
|
onScrollVertically: function onScrollVertically() {
|
|
instance.runHooks('afterScrollVertically');
|
|
},
|
|
onScrollHorizontally: function onScrollHorizontally() {
|
|
instance.runHooks('afterScrollHorizontally');
|
|
},
|
|
onBeforeDrawBorders: function onBeforeDrawBorders(corners, borderClassName) {
|
|
instance.runHooks('beforeDrawBorders', corners, borderClassName);
|
|
},
|
|
onBeforeTouchScroll: function onBeforeTouchScroll() {
|
|
instance.runHooks('beforeTouchScroll');
|
|
},
|
|
onAfterMomentumScroll: function onAfterMomentumScroll() {
|
|
instance.runHooks('afterMomentumScroll');
|
|
},
|
|
onBeforeStretchingColumnWidth: function onBeforeStretchingColumnWidth(stretchedWidth, column) {
|
|
return instance.runHooks('beforeStretchingColumnWidth', stretchedWidth, column);
|
|
},
|
|
onModifyRowHeaderWidth: function onModifyRowHeaderWidth(rowHeaderWidth) {
|
|
return instance.runHooks('modifyRowHeaderWidth', rowHeaderWidth);
|
|
},
|
|
viewportRowCalculatorOverride: function viewportRowCalculatorOverride(calc) {
|
|
var rows = instance.countRows();
|
|
var viewportOffset = that.settings.viewportRowRenderingOffset;
|
|
|
|
if (viewportOffset === 'auto' && that.settings.fixedRowsTop) {
|
|
viewportOffset = 10;
|
|
}
|
|
if (typeof viewportOffset === 'number') {
|
|
calc.startRow = Math.max(calc.startRow - viewportOffset, 0);
|
|
calc.endRow = Math.min(calc.endRow + viewportOffset, rows - 1);
|
|
}
|
|
if (viewportOffset === 'auto') {
|
|
var center = calc.startRow + calc.endRow - calc.startRow;
|
|
var offset = Math.ceil(center / rows * 12);
|
|
|
|
calc.startRow = Math.max(calc.startRow - offset, 0);
|
|
calc.endRow = Math.min(calc.endRow + offset, rows - 1);
|
|
}
|
|
instance.runHooks('afterViewportRowCalculatorOverride', calc);
|
|
},
|
|
viewportColumnCalculatorOverride: function viewportColumnCalculatorOverride(calc) {
|
|
var cols = instance.countCols();
|
|
var viewportOffset = that.settings.viewportColumnRenderingOffset;
|
|
|
|
if (viewportOffset === 'auto' && that.settings.fixedColumnsLeft) {
|
|
viewportOffset = 10;
|
|
}
|
|
if (typeof viewportOffset === 'number') {
|
|
calc.startColumn = Math.max(calc.startColumn - viewportOffset, 0);
|
|
calc.endColumn = Math.min(calc.endColumn + viewportOffset, cols - 1);
|
|
}
|
|
if (viewportOffset === 'auto') {
|
|
var center = calc.startColumn + calc.endColumn - calc.startColumn;
|
|
var offset = Math.ceil(center / cols * 12);
|
|
|
|
calc.startRow = Math.max(calc.startColumn - offset, 0);
|
|
calc.endColumn = Math.min(calc.endColumn + offset, cols - 1);
|
|
}
|
|
instance.runHooks('afterViewportColumnCalculatorOverride', calc);
|
|
},
|
|
rowHeaderWidth: function rowHeaderWidth() {
|
|
return that.settings.rowHeaderWidth;
|
|
},
|
|
columnHeaderHeight: function columnHeaderHeight() {
|
|
var columnHeaderHeight = instance.runHooks('modifyColumnHeaderHeight');
|
|
return that.settings.columnHeaderHeight || columnHeaderHeight;
|
|
}
|
|
};
|
|
|
|
instance.runHooks('beforeInitWalkontable', walkontableConfig);
|
|
|
|
this.wt = new _src2.default(walkontableConfig);
|
|
this.activeWt = this.wt;
|
|
|
|
if (!(0, _browser.isChrome)() && !(0, _browser.isSafari)()) {
|
|
this.eventManager.addEventListener(instance.rootElement, 'wheel', function (event) {
|
|
event.preventDefault();
|
|
|
|
var lineHeight = parseInt((0, _element.getComputedStyle)(document.body)['font-size'], 10);
|
|
var holder = that.wt.wtOverlays.scrollableElement;
|
|
|
|
var deltaY = event.wheelDeltaY || event.deltaY;
|
|
var deltaX = event.wheelDeltaX || event.deltaX;
|
|
|
|
switch (event.deltaMode) {
|
|
case 0:
|
|
holder.scrollLeft += deltaX;
|
|
holder.scrollTop += deltaY;
|
|
break;
|
|
|
|
case 1:
|
|
holder.scrollLeft += deltaX * lineHeight;
|
|
holder.scrollTop += deltaY * lineHeight;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
this.eventManager.addEventListener(that.wt.wtTable.spreader, 'mousedown', function (event) {
|
|
// right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
|
|
if (event.target === that.wt.wtTable.spreader && event.which === 3) {
|
|
(0, _event.stopPropagation)(event);
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(that.wt.wtTable.spreader, 'contextmenu', function (event) {
|
|
// right mouse button exactly on spreader means right click on the right hand side of vertical scrollbar
|
|
if (event.target === that.wt.wtTable.spreader && event.which === 3) {
|
|
(0, _event.stopPropagation)(event);
|
|
}
|
|
});
|
|
|
|
this.eventManager.addEventListener(document.documentElement, 'click', function () {
|
|
if (that.settings.observeDOMVisibility) {
|
|
if (that.wt.drawInterrupted) {
|
|
that.instance.forceFullRender = true;
|
|
that.render();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
TableView.prototype.isTextSelectionAllowed = function (el) {
|
|
if ((0, _element.isInput)(el)) {
|
|
return true;
|
|
}
|
|
var isChildOfTableBody = (0, _element.isChildOf)(el, this.instance.view.wt.wtTable.spreader);
|
|
|
|
if (this.settings.fragmentSelection === true && isChildOfTableBody) {
|
|
return true;
|
|
}
|
|
if (this.settings.fragmentSelection === 'cell' && this.isSelectedOnlyCell() && isChildOfTableBody) {
|
|
return true;
|
|
}
|
|
if (!this.settings.fragmentSelection && this.isCellEdited() && this.isSelectedOnlyCell()) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Check if selected only one cell.
|
|
*
|
|
* @returns {Boolean}
|
|
*/
|
|
TableView.prototype.isSelectedOnlyCell = function () {
|
|
var _ref = this.instance.getSelected() || [],
|
|
_ref2 = _slicedToArray(_ref, 4),
|
|
row = _ref2[0],
|
|
col = _ref2[1],
|
|
rowEnd = _ref2[2],
|
|
colEnd = _ref2[3];
|
|
|
|
return row !== void 0 && row === rowEnd && col === colEnd;
|
|
};
|
|
|
|
TableView.prototype.isCellEdited = function () {
|
|
var activeEditor = this.instance.getActiveEditor();
|
|
|
|
return activeEditor && activeEditor.isOpened();
|
|
};
|
|
|
|
TableView.prototype.beforeRender = function (force, skipRender) {
|
|
if (force) {
|
|
// this.instance.forceFullRender = did Handsontable request full render?
|
|
this.instance.runHooks('beforeRender', this.instance.forceFullRender, skipRender);
|
|
}
|
|
};
|
|
|
|
TableView.prototype.onDraw = function (force) {
|
|
if (force) {
|
|
// this.instance.forceFullRender = did Handsontable request full render?
|
|
this.instance.runHooks('afterRender', this.instance.forceFullRender);
|
|
}
|
|
};
|
|
|
|
TableView.prototype.render = function () {
|
|
this.wt.draw(!this.instance.forceFullRender);
|
|
this.instance.forceFullRender = false;
|
|
this.instance.renderCall = false;
|
|
};
|
|
|
|
/**
|
|
* Returns td object given coordinates
|
|
*
|
|
* @param {CellCoords} coords
|
|
* @param {Boolean} topmost
|
|
*/
|
|
TableView.prototype.getCellAtCoords = function (coords, topmost) {
|
|
var td = this.wt.getCell(coords, topmost);
|
|
|
|
if (td < 0) {
|
|
// there was an exit code (cell is out of bounds)
|
|
return null;
|
|
}
|
|
|
|
return td;
|
|
};
|
|
|
|
/**
|
|
* Scroll viewport to selection.
|
|
*
|
|
* @param {CellCoords} coords
|
|
*/
|
|
TableView.prototype.scrollViewport = function (coords) {
|
|
this.wt.scrollViewport(coords);
|
|
};
|
|
|
|
/**
|
|
* Append row header to a TH element
|
|
* @param row
|
|
* @param TH
|
|
*/
|
|
TableView.prototype.appendRowHeader = function (row, TH) {
|
|
if (TH.firstChild) {
|
|
var container = TH.firstChild;
|
|
|
|
if (!(0, _element.hasClass)(container, 'relative')) {
|
|
(0, _element.empty)(TH);
|
|
this.appendRowHeader(row, TH);
|
|
|
|
return;
|
|
}
|
|
this.updateCellHeader(container.querySelector('.rowHeader'), row, this.instance.getRowHeader);
|
|
} else {
|
|
var div = document.createElement('div');
|
|
var span = document.createElement('span');
|
|
|
|
div.className = 'relative';
|
|
span.className = 'rowHeader';
|
|
this.updateCellHeader(span, row, this.instance.getRowHeader);
|
|
|
|
div.appendChild(span);
|
|
TH.appendChild(div);
|
|
}
|
|
|
|
this.instance.runHooks('afterGetRowHeader', row, TH);
|
|
};
|
|
|
|
/**
|
|
* Append column header to a TH element
|
|
* @param col
|
|
* @param TH
|
|
*/
|
|
TableView.prototype.appendColHeader = function (col, TH) {
|
|
if (TH.firstChild) {
|
|
var container = TH.firstChild;
|
|
|
|
if ((0, _element.hasClass)(container, 'relative')) {
|
|
this.updateCellHeader(container.querySelector('.colHeader'), col, this.instance.getColHeader);
|
|
} else {
|
|
(0, _element.empty)(TH);
|
|
this.appendColHeader(col, TH);
|
|
}
|
|
} else {
|
|
var div = document.createElement('div');
|
|
var span = document.createElement('span');
|
|
|
|
div.className = 'relative';
|
|
span.className = 'colHeader';
|
|
this.updateCellHeader(span, col, this.instance.getColHeader);
|
|
|
|
div.appendChild(span);
|
|
TH.appendChild(div);
|
|
}
|
|
|
|
this.instance.runHooks('afterGetColHeader', col, TH);
|
|
};
|
|
|
|
/**
|
|
* Update header cell content
|
|
*
|
|
* @since 0.15.0-beta4
|
|
* @param {HTMLElement} element Element to update
|
|
* @param {Number} index Row index or column index
|
|
* @param {Function} content Function which should be returns content for this cell
|
|
*/
|
|
TableView.prototype.updateCellHeader = function (element, index, content) {
|
|
var renderedIndex = index;
|
|
var parentOverlay = this.wt.wtOverlays.getParentOverlay(element) || this.wt;
|
|
|
|
// prevent wrong calculations from SampleGenerator
|
|
if (element.parentNode) {
|
|
if ((0, _element.hasClass)(element, 'colHeader')) {
|
|
renderedIndex = parentOverlay.wtTable.columnFilter.sourceToRendered(index);
|
|
} else if ((0, _element.hasClass)(element, 'rowHeader')) {
|
|
renderedIndex = parentOverlay.wtTable.rowFilter.sourceToRendered(index);
|
|
}
|
|
}
|
|
|
|
if (renderedIndex > -1) {
|
|
(0, _element.fastInnerHTML)(element, content(index));
|
|
} else {
|
|
// workaround for https://github.com/handsontable/handsontable/issues/1946
|
|
(0, _element.fastInnerText)(element, String.fromCharCode(160));
|
|
(0, _element.addClass)(element, 'cornerHeader');
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Given a element's left position relative to the viewport, returns maximum element width until the right
|
|
* edge of the viewport (before scrollbar)
|
|
*
|
|
* @param {Number} leftOffset
|
|
* @return {Number}
|
|
*/
|
|
TableView.prototype.maximumVisibleElementWidth = function (leftOffset) {
|
|
var workspaceWidth = this.wt.wtViewport.getWorkspaceWidth();
|
|
var maxWidth = workspaceWidth - leftOffset;
|
|
return maxWidth > 0 ? maxWidth : 0;
|
|
};
|
|
|
|
/**
|
|
* Given a element's top position relative to the viewport, returns maximum element height until the bottom
|
|
* edge of the viewport (before scrollbar)
|
|
*
|
|
* @param {Number} topOffset
|
|
* @return {Number}
|
|
*/
|
|
TableView.prototype.maximumVisibleElementHeight = function (topOffset) {
|
|
var workspaceHeight = this.wt.wtViewport.getWorkspaceHeight();
|
|
var maxHeight = workspaceHeight - topOffset;
|
|
return maxHeight > 0 ? maxHeight : 0;
|
|
};
|
|
|
|
TableView.prototype.mainViewIsActive = function () {
|
|
return this.wt === this.activeWt;
|
|
};
|
|
|
|
TableView.prototype.destroy = function () {
|
|
this.wt.destroy();
|
|
this.eventManager.destroy();
|
|
};
|
|
|
|
exports.default = TableView;
|
|
|
|
/***/ }),
|
|
/* 385 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* Refactored implementation of LinkedList (part of javascript-algorithms project) by Github users:
|
|
* mgechev, AndriiHeonia, Microfed and Jakeh (part of javascript-algorithms project - all project contributors
|
|
* at repository website)
|
|
*
|
|
* Link to repository: https://github.com/mgechev/javascript-algorithms
|
|
*/
|
|
|
|
/**
|
|
* Linked list node.
|
|
*
|
|
* @class NodeStructure
|
|
* @util
|
|
*/
|
|
var NodeStructure = function NodeStructure(data) {
|
|
_classCallCheck(this, NodeStructure);
|
|
|
|
/**
|
|
* Data of the node.
|
|
* @member {Object}
|
|
*/
|
|
this.data = data;
|
|
/**
|
|
* Next node.
|
|
* @member {NodeStructure}
|
|
*/
|
|
this.next = null;
|
|
/**
|
|
* Previous node.
|
|
* @member {NodeStructure}
|
|
*/
|
|
this.prev = null;
|
|
};
|
|
|
|
/**
|
|
* Linked list.
|
|
*
|
|
* @class LinkedList
|
|
* @util
|
|
*/
|
|
|
|
|
|
var LinkedList = function () {
|
|
function LinkedList() {
|
|
_classCallCheck(this, LinkedList);
|
|
|
|
this.first = null;
|
|
this.last = null;
|
|
}
|
|
|
|
/**
|
|
* Add data to the end of linked list.
|
|
*
|
|
* @param {Object} data Data which should be added.
|
|
*/
|
|
|
|
|
|
_createClass(LinkedList, [{
|
|
key: "push",
|
|
value: function push(data) {
|
|
var node = new NodeStructure(data);
|
|
|
|
if (this.first === null) {
|
|
this.first = node;
|
|
this.last = node;
|
|
} else {
|
|
var temp = this.last;
|
|
|
|
this.last = node;
|
|
node.prev = temp;
|
|
temp.next = node;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add data to the beginning of linked list.
|
|
*
|
|
* @param {Object} data Data which should be added.
|
|
*/
|
|
|
|
}, {
|
|
key: "unshift",
|
|
value: function unshift(data) {
|
|
var node = new NodeStructure(data);
|
|
|
|
if (this.first === null) {
|
|
this.first = node;
|
|
this.last = node;
|
|
} else {
|
|
var temp = this.first;
|
|
|
|
this.first = node;
|
|
node.next = temp;
|
|
temp.prev = node;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* In order traversal of the linked list.
|
|
*
|
|
* @param {Function} callback Callback which should be executed on each node.
|
|
*/
|
|
|
|
}, {
|
|
key: "inorder",
|
|
value: function inorder(callback) {
|
|
var temp = this.first;
|
|
|
|
while (temp) {
|
|
callback(temp);
|
|
temp = temp.next;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove data from the linked list.
|
|
*
|
|
* @param {Object} data Data which should be removed.
|
|
* @returns {Boolean} Returns true if data has been removed.
|
|
*/
|
|
|
|
}, {
|
|
key: "remove",
|
|
value: function remove(data) {
|
|
if (this.first === null) {
|
|
return false;
|
|
}
|
|
|
|
var temp = this.first;
|
|
var next = void 0;
|
|
var prev = void 0;
|
|
|
|
while (temp) {
|
|
if (temp.data === data) {
|
|
next = temp.next;
|
|
prev = temp.prev;
|
|
|
|
if (next) {
|
|
next.prev = prev;
|
|
}
|
|
|
|
if (prev) {
|
|
prev.next = next;
|
|
}
|
|
|
|
if (temp === this.first) {
|
|
this.first = next;
|
|
}
|
|
|
|
if (temp === this.last) {
|
|
this.last = prev;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
temp = temp.next;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if linked list contains cycle.
|
|
*
|
|
* @returns {Boolean} Returns true if linked list contains cycle.
|
|
*/
|
|
|
|
}, {
|
|
key: "hasCycle",
|
|
value: function hasCycle() {
|
|
var fast = this.first;
|
|
var slow = this.first;
|
|
|
|
while (true) {
|
|
if (fast === null) {
|
|
return false;
|
|
}
|
|
|
|
fast = fast.next;
|
|
|
|
if (fast === null) {
|
|
return false;
|
|
}
|
|
|
|
fast = fast.next;
|
|
slow = slow.next;
|
|
|
|
if (fast === slow) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: "pop",
|
|
|
|
|
|
/**
|
|
* Return last node from the linked list.
|
|
*
|
|
* @returns {NodeStructure} Last node.
|
|
*/
|
|
value: function pop() {
|
|
if (this.last === null) {
|
|
return null;
|
|
}
|
|
|
|
var temp = this.last;
|
|
this.last = this.last.prev;
|
|
|
|
return temp;
|
|
}
|
|
}, {
|
|
key: "shift",
|
|
|
|
|
|
/**
|
|
* Return first node from the linked list.
|
|
*
|
|
* @returns {NodeStructure} First node.
|
|
*/
|
|
value: function shift() {
|
|
if (this.first === null) {
|
|
return null;
|
|
}
|
|
|
|
var temp = this.first;
|
|
this.first = this.first.next;
|
|
|
|
return temp;
|
|
}
|
|
}, {
|
|
key: "recursiveReverse",
|
|
|
|
|
|
/**
|
|
* Reverses the linked list recursively
|
|
*/
|
|
value: function recursiveReverse() {
|
|
function inverse(current, next) {
|
|
if (!next) {
|
|
return;
|
|
}
|
|
inverse(next, next.next);
|
|
next.next = current;
|
|
}
|
|
|
|
if (!this.first) {
|
|
return;
|
|
}
|
|
|
|
inverse(this.first, this.first.next);
|
|
|
|
this.first.next = null;
|
|
var temp = this.first;
|
|
this.first = this.last;
|
|
this.last = temp;
|
|
}
|
|
}, {
|
|
key: "reverse",
|
|
|
|
|
|
/**
|
|
* Reverses the linked list iteratively
|
|
*/
|
|
value: function reverse() {
|
|
if (!this.first || !this.first.next) {
|
|
return;
|
|
}
|
|
|
|
var current = this.first.next;
|
|
var prev = this.first;
|
|
var temp = void 0;
|
|
|
|
while (current) {
|
|
temp = current.next;
|
|
current.next = prev;
|
|
prev.prev = current;
|
|
prev = current;
|
|
current = temp;
|
|
}
|
|
|
|
this.first.next = null;
|
|
this.last.prev = null;
|
|
temp = this.first;
|
|
this.first = prev;
|
|
this.last = temp;
|
|
}
|
|
}]);
|
|
|
|
return LinkedList;
|
|
}();
|
|
|
|
;
|
|
|
|
exports.NodeStructure = NodeStructure;
|
|
exports.default = LinkedList;
|
|
|
|
/***/ }),
|
|
/* 386 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
exports.parseDelay = parseDelay;
|
|
|
|
var _feature = __webpack_require__(34);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
/**
|
|
* @class Interval
|
|
* @util
|
|
*/
|
|
var Interval = function () {
|
|
_createClass(Interval, null, [{
|
|
key: 'create',
|
|
value: function create(func, delay) {
|
|
return new Interval(func, delay);
|
|
}
|
|
}]);
|
|
|
|
function Interval(func, delay) {
|
|
var _this = this;
|
|
|
|
_classCallCheck(this, Interval);
|
|
|
|
/**
|
|
* Animation frame request id.
|
|
*
|
|
* @type {Number}
|
|
*/
|
|
this.timer = null;
|
|
/**
|
|
* Function to invoke repeatedly.
|
|
*
|
|
* @type {Function}
|
|
*/
|
|
this.func = func;
|
|
/**
|
|
* Number of milliseconds that function should wait before next call.
|
|
*/
|
|
this.delay = parseDelay(delay);
|
|
/**
|
|
* Flag which indicates if interval object was stopped.
|
|
*
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
this.stopped = true;
|
|
/**
|
|
* Interval time (in milliseconds) of the last callback call.
|
|
*
|
|
* @private
|
|
* @type {Number}
|
|
*/
|
|
this._then = null;
|
|
/**
|
|
* Bounded function `func`.
|
|
*
|
|
* @private
|
|
* @type {Function}
|
|
*/
|
|
this._callback = function () {
|
|
return _this.__callback();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Start loop.
|
|
*
|
|
* @returns {Interval}
|
|
*/
|
|
|
|
|
|
_createClass(Interval, [{
|
|
key: 'start',
|
|
value: function start() {
|
|
if (this.stopped) {
|
|
this._then = Date.now();
|
|
this.stopped = false;
|
|
this.timer = (0, _feature.requestAnimationFrame)(this._callback);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Stop looping.
|
|
*
|
|
* @returns {Interval}
|
|
*/
|
|
|
|
}, {
|
|
key: 'stop',
|
|
value: function stop() {
|
|
if (!this.stopped) {
|
|
this.stopped = true;
|
|
(0, _feature.cancelAnimationFrame)(this.timer);
|
|
this.timer = null;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Loop callback, fired on every animation frame.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
}, {
|
|
key: '__callback',
|
|
value: function __callback() {
|
|
this.timer = (0, _feature.requestAnimationFrame)(this._callback);
|
|
|
|
if (this.delay) {
|
|
var now = Date.now();
|
|
var elapsed = now - this._then;
|
|
|
|
if (elapsed > this.delay) {
|
|
this._then = now - elapsed % this.delay;
|
|
this.func();
|
|
}
|
|
} else {
|
|
this.func();
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return Interval;
|
|
}();
|
|
|
|
exports.default = Interval;
|
|
function parseDelay(delay) {
|
|
if (typeof delay === 'string' && /fps$/.test(delay)) {
|
|
delay = 1000 / parseInt(delay.replace('fps', '') || 0, 10);
|
|
}
|
|
|
|
return delay;
|
|
}
|
|
|
|
/***/ }),
|
|
/* 387 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = mergeSort;
|
|
exports.merge = merge;
|
|
|
|
var _linkedList = __webpack_require__(385);
|
|
|
|
var _linkedList2 = _interopRequireDefault(_linkedList);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* Refactored implementation of mergeSort (part of javascript-algorithms project) by Github users:
|
|
* mgechev, AndriiHeonia and lekkas (part of javascript-algorithms project - all project contributors
|
|
* at repository website)
|
|
*
|
|
* Link to repository: https://github.com/mgechev/javascript-algorithms
|
|
*/
|
|
|
|
/**
|
|
* Specifies a function that defines the sort order. The array is sorted according to each
|
|
* character's Unicode code point value, according to the string conversion of each element.
|
|
*
|
|
* @param a {*} first compared element.
|
|
* @param b {*} second compared element.
|
|
* @returns {Number}
|
|
*/
|
|
var defaultCompareFunction = function defaultCompareFunction(a, b) {
|
|
// sort lexically
|
|
|
|
var firstValue = a.toString();
|
|
var secondValue = b.toString();
|
|
|
|
if (firstValue === secondValue) {
|
|
return 0;
|
|
} else if (firstValue < secondValue) {
|
|
return -1;
|
|
}
|
|
return 1;
|
|
};
|
|
|
|
/**
|
|
* Mergesort method which is recursively called for sorting the input array.
|
|
*
|
|
* @param {Array} array The array which should be sorted.
|
|
* @param {Function} compareFunction Compares two items in an array. If compareFunction is not supplied,
|
|
* elements are sorted by converting them to strings and comparing strings in Unicode code point order.
|
|
* @param {Number} startIndex Left side of the subarray.
|
|
* @param {Number} endIndex Right side of the subarray.
|
|
* @returns {Array} Array with sorted subarray.
|
|
*/
|
|
function mergeSort(array) {
|
|
var compareFunction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultCompareFunction;
|
|
var startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
var endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length;
|
|
|
|
if (Math.abs(endIndex - startIndex) <= 1) {
|
|
return [];
|
|
}
|
|
|
|
var middleIndex = Math.ceil((startIndex + endIndex) / 2);
|
|
|
|
mergeSort(array, compareFunction, startIndex, middleIndex);
|
|
mergeSort(array, compareFunction, middleIndex, endIndex);
|
|
|
|
return merge(array, compareFunction, startIndex, middleIndex, endIndex);
|
|
}
|
|
|
|
/**
|
|
* Devides and sort merges two subarrays of given array
|
|
*
|
|
* @param {Array} array The array which subarrays should be sorted.
|
|
* @param {Number} startIndex The start of the first subarray.
|
|
* This subarray is with end middle - 1.
|
|
* @param {Number} middleIndex The start of the second array.
|
|
* @param {Number} endIndex end - 1 is the end of the second array.
|
|
* @returns {Array} The array with sorted subarray.
|
|
*/
|
|
function merge(array, compareFunction, startIndex, middleIndex, endIndex) {
|
|
var leftElements = new _linkedList2.default();
|
|
var rightElements = new _linkedList2.default();
|
|
var leftSize = middleIndex - startIndex;
|
|
var rightSize = endIndex - middleIndex;
|
|
var maxSize = Math.max(leftSize, rightSize);
|
|
var size = endIndex - startIndex;
|
|
|
|
for (var _i = 0; _i < maxSize; _i += 1) {
|
|
if (_i < leftSize) {
|
|
leftElements.push(array[startIndex + _i]);
|
|
}
|
|
|
|
if (_i < rightSize) {
|
|
rightElements.push(array[middleIndex + _i]);
|
|
}
|
|
}
|
|
|
|
var i = 0;
|
|
|
|
while (i < size) {
|
|
if (leftElements.first && rightElements.first) {
|
|
if (compareFunction(leftElements.first.data, rightElements.first.data) > 0) {
|
|
array[startIndex + i] = rightElements.shift().data;
|
|
} else {
|
|
array[startIndex + i] = leftElements.shift().data;
|
|
}
|
|
} else if (leftElements.first) {
|
|
|
|
array[startIndex + i] = leftElements.shift().data;
|
|
} else {
|
|
|
|
array[startIndex + i] = rightElements.shift().data;
|
|
}
|
|
|
|
i += 1;
|
|
}
|
|
|
|
return array;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 388 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = autocompleteValidator;
|
|
/**
|
|
* Autocomplete cell validator.
|
|
*
|
|
* @private
|
|
* @validator AutocompleteValidator
|
|
* @param {*} value - Value of edited cell
|
|
* @param {Function} callback - Callback called with validation result
|
|
*/
|
|
function autocompleteValidator(value, callback) {
|
|
if (value == null) {
|
|
value = '';
|
|
}
|
|
|
|
if (this.allowEmpty && value === '') {
|
|
callback(true);
|
|
|
|
return;
|
|
}
|
|
|
|
if (this.strict && this.source) {
|
|
if (typeof this.source === 'function') {
|
|
this.source(value, process(value, callback));
|
|
} else {
|
|
process(value, callback)(this.source);
|
|
}
|
|
} else {
|
|
callback(true);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Function responsible for validation of autocomplete value.
|
|
*
|
|
* @param {*} value - Value of edited cell
|
|
* @param {Function} callback - Callback called with validation result
|
|
*/
|
|
function process(value, callback) {
|
|
var originalVal = value;
|
|
|
|
return function (source) {
|
|
var found = false;
|
|
|
|
for (var s = 0, slen = source.length; s < slen; s++) {
|
|
if (originalVal === source[s]) {
|
|
found = true; // perfect match
|
|
break;
|
|
}
|
|
}
|
|
|
|
callback(found);
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 389 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = dateValidator;
|
|
exports.correctFormat = correctFormat;
|
|
|
|
var _moment = __webpack_require__(36);
|
|
|
|
var _moment2 = _interopRequireDefault(_moment);
|
|
|
|
var _date = __webpack_require__(89);
|
|
|
|
var _editors = __webpack_require__(14);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* Date cell validator
|
|
*
|
|
* @private
|
|
* @validator DateValidator
|
|
* @dependencies moment
|
|
* @param {*} value - Value of edited cell
|
|
* @param {Function} callback - Callback called with validation result
|
|
*/
|
|
function dateValidator(value, callback) {
|
|
var valid = true;
|
|
var dateEditor = (0, _editors.getEditorInstance)('date', this.instance);
|
|
|
|
if (value == null) {
|
|
value = '';
|
|
}
|
|
var isValidDate = (0, _moment2.default)(new Date(value)).isValid() || (0, _moment2.default)(value, dateEditor.defaultDateFormat).isValid();
|
|
// is it in the specified format
|
|
var isValidFormat = (0, _moment2.default)(value, this.dateFormat || dateEditor.defaultDateFormat, true).isValid();
|
|
|
|
if (this.allowEmpty && value === '') {
|
|
isValidDate = true;
|
|
isValidFormat = true;
|
|
}
|
|
if (!isValidDate) {
|
|
valid = false;
|
|
}
|
|
if (!isValidDate && isValidFormat) {
|
|
valid = true;
|
|
}
|
|
|
|
if (isValidDate && !isValidFormat) {
|
|
if (this.correctFormat === true) {
|
|
// if format correction is enabled
|
|
var correctedValue = correctFormat(value, this.dateFormat);
|
|
var row = this.instance.runHooks('unmodifyRow', this.row);
|
|
var column = this.instance.runHooks('unmodifyCol', this.col);
|
|
|
|
this.instance.setDataAtCell(row, column, correctedValue, 'dateValidator');
|
|
valid = true;
|
|
} else {
|
|
valid = false;
|
|
}
|
|
}
|
|
|
|
callback(valid);
|
|
};
|
|
|
|
/**
|
|
* Format the given string using moment.js' format feature
|
|
*
|
|
* @param {String} value
|
|
* @param {String} dateFormat
|
|
* @returns {String}
|
|
*/
|
|
function correctFormat(value, dateFormat) {
|
|
var dateFromDate = (0, _moment2.default)((0, _date.getNormalizedDate)(value));
|
|
var dateFromMoment = (0, _moment2.default)(value, dateFormat);
|
|
var isAlphanumeric = value.search(/[A-z]/g) > -1;
|
|
var date = void 0;
|
|
|
|
if (dateFromDate.isValid() && dateFromDate.format('x') === dateFromMoment.format('x') || !dateFromMoment.isValid() || isAlphanumeric) {
|
|
date = dateFromDate;
|
|
} else {
|
|
date = dateFromMoment;
|
|
}
|
|
|
|
return date.format(dateFormat);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 390 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = numericValidator;
|
|
/**
|
|
* Numeric cell validator
|
|
*
|
|
* @private
|
|
* @validator NumericValidator
|
|
* @param {*} value - Value of edited cell
|
|
* @param {*} callback - Callback called with validation result
|
|
*/
|
|
function numericValidator(value, callback) {
|
|
if (value == null) {
|
|
value = '';
|
|
}
|
|
if (this.allowEmpty && value === '') {
|
|
callback(true);
|
|
} else if (value === '') {
|
|
callback(false);
|
|
} else {
|
|
callback(/^-?\d*(\.|,)?\d*$/.test(value));
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 391 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
exports.__esModule = true;
|
|
exports.default = timeValidator;
|
|
|
|
var _moment = __webpack_require__(36);
|
|
|
|
var _moment2 = _interopRequireDefault(_moment);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
// Formats which are correctly parsed to time (supported by momentjs)
|
|
var STRICT_FORMATS = ['YYYY-MM-DDTHH:mm:ss.SSSZ', 'X', // Unix timestamp
|
|
'x' // Unix ms timestamp
|
|
];
|
|
|
|
/**
|
|
* Time cell validator
|
|
*
|
|
* @private
|
|
* @validator TimeValidator
|
|
* @dependencies moment
|
|
* @param {*} value - Value of edited cell
|
|
* @param {Function} callback - Callback called with validation result
|
|
*/
|
|
function timeValidator(value, callback) {
|
|
var valid = true;
|
|
var timeFormat = this.timeFormat || 'h:mm:ss a';
|
|
|
|
if (value === null) {
|
|
value = '';
|
|
}
|
|
|
|
value = /^\d{3,}$/.test(value) ? parseInt(value, 10) : value;
|
|
|
|
var twoDigitValue = /^\d{1,2}$/.test(value);
|
|
|
|
if (twoDigitValue) {
|
|
value += ':00';
|
|
}
|
|
|
|
var date = (0, _moment2.default)(value, STRICT_FORMATS, true).isValid() ? (0, _moment2.default)(value) : (0, _moment2.default)(value, timeFormat);
|
|
var isValidTime = date.isValid();
|
|
|
|
// is it in the specified format
|
|
var isValidFormat = (0, _moment2.default)(value, timeFormat, true).isValid() && !twoDigitValue;
|
|
|
|
if (this.allowEmpty && value === '') {
|
|
isValidTime = true;
|
|
isValidFormat = true;
|
|
}
|
|
if (!isValidTime) {
|
|
valid = false;
|
|
}
|
|
if (!isValidTime && isValidFormat) {
|
|
valid = true;
|
|
}
|
|
if (isValidTime && !isValidFormat) {
|
|
if (this.correctFormat === true) {
|
|
// if format correction is enabled
|
|
var correctedValue = date.format(timeFormat);
|
|
var row = this.instance.runHooks('unmodifyRow', this.row);
|
|
var column = this.instance.runHooks('unmodifyCol', this.col);
|
|
|
|
this.instance.setDataAtCell(row, column, correctedValue, 'timeValidator');
|
|
valid = true;
|
|
} else {
|
|
valid = false;
|
|
}
|
|
}
|
|
|
|
callback(valid);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 392 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
|
|
|
|
var toObject = __webpack_require__(42)
|
|
, toIndex = __webpack_require__(61)
|
|
, toLength = __webpack_require__(24);
|
|
|
|
module.exports = [].copyWithin || function copyWithin(target/*= 0*/, start/*= 0, end = @length*/){
|
|
var O = toObject(this)
|
|
, len = toLength(O.length)
|
|
, to = toIndex(target, len)
|
|
, from = toIndex(start, len)
|
|
, end = arguments.length > 2 ? arguments[2] : undefined
|
|
, count = Math.min((end === undefined ? len : toIndex(end, len)) - from, len - to)
|
|
, inc = 1;
|
|
if(from < to && to < from + count){
|
|
inc = -1;
|
|
from += count - 1;
|
|
to += count - 1;
|
|
}
|
|
while(count-- > 0){
|
|
if(from in O)O[to] = O[from];
|
|
else delete O[to];
|
|
to += inc;
|
|
from += inc;
|
|
} return O;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 393 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
|
|
|
|
var toObject = __webpack_require__(42)
|
|
, toIndex = __webpack_require__(61)
|
|
, toLength = __webpack_require__(24);
|
|
module.exports = function fill(value /*, start = 0, end = @length */){
|
|
var O = toObject(this)
|
|
, length = toLength(O.length)
|
|
, aLen = arguments.length
|
|
, index = toIndex(aLen > 1 ? arguments[1] : undefined, length)
|
|
, end = aLen > 2 ? arguments[2] : undefined
|
|
, endPos = end === undefined ? length : toIndex(end, length);
|
|
while(endPos > index)O[index++] = value;
|
|
return O;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 394 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(15)
|
|
, isArray = __webpack_require__(277)
|
|
, SPECIES = __webpack_require__(10)('species');
|
|
|
|
module.exports = function(original){
|
|
var C;
|
|
if(isArray(original)){
|
|
C = original.constructor;
|
|
// cross-realm fallback
|
|
if(typeof C == 'function' && (C === Array || isArray(C.prototype)))C = undefined;
|
|
if(isObject(C)){
|
|
C = C[SPECIES];
|
|
if(C === null)C = undefined;
|
|
}
|
|
} return C === undefined ? Array : C;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 395 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
|
|
var speciesConstructor = __webpack_require__(394);
|
|
|
|
module.exports = function(original, length){
|
|
return new (speciesConstructor(original))(length);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 396 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// all enumerable object keys, includes symbols
|
|
var getKeys = __webpack_require__(40)
|
|
, gOPS = __webpack_require__(59)
|
|
, pIE = __webpack_require__(48);
|
|
module.exports = function(it){
|
|
var result = getKeys(it)
|
|
, getSymbols = gOPS.f;
|
|
if(getSymbols){
|
|
var symbols = getSymbols(it)
|
|
, isEnum = pIE.f
|
|
, i = 0
|
|
, key;
|
|
while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key);
|
|
} return result;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 397 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
// 21.2.5.3 get RegExp.prototype.flags
|
|
var anObject = __webpack_require__(18);
|
|
module.exports = function(){
|
|
var that = anObject(this)
|
|
, result = '';
|
|
if(that.global) result += 'g';
|
|
if(that.ignoreCase) result += 'i';
|
|
if(that.multiline) result += 'm';
|
|
if(that.unicode) result += 'u';
|
|
if(that.sticky) result += 'y';
|
|
return result;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 398 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var isObject = __webpack_require__(15)
|
|
, setPrototypeOf = __webpack_require__(286).set;
|
|
module.exports = function(that, target, C){
|
|
var P, S = target.constructor;
|
|
if(S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf){
|
|
setPrototypeOf(that, P);
|
|
} return that;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 399 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// fast apply, http://jsperf.lnkit.com/fast-apply/5
|
|
module.exports = function(fn, args, that){
|
|
var un = that === undefined;
|
|
switch(args.length){
|
|
case 0: return un ? fn()
|
|
: fn.call(that);
|
|
case 1: return un ? fn(args[0])
|
|
: fn.call(that, args[0]);
|
|
case 2: return un ? fn(args[0], args[1])
|
|
: fn.call(that, args[0], args[1]);
|
|
case 3: return un ? fn(args[0], args[1], args[2])
|
|
: fn.call(that, args[0], args[1], args[2]);
|
|
case 4: return un ? fn(args[0], args[1], args[2], args[3])
|
|
: fn.call(that, args[0], args[1], args[2], args[3]);
|
|
} return fn.apply(that, args);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 400 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
var create = __webpack_require__(80)
|
|
, descriptor = __webpack_require__(41)
|
|
, setToStringTag = __webpack_require__(49)
|
|
, IteratorPrototype = {};
|
|
|
|
// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
|
|
__webpack_require__(32)(IteratorPrototype, __webpack_require__(10)('iterator'), function(){ return this; });
|
|
|
|
module.exports = function(Constructor, NAME, next){
|
|
Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});
|
|
setToStringTag(Constructor, NAME + ' Iterator');
|
|
};
|
|
|
|
/***/ }),
|
|
/* 401 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var getKeys = __webpack_require__(40)
|
|
, toIObject = __webpack_require__(23);
|
|
module.exports = function(object, el){
|
|
var O = toIObject(object)
|
|
, keys = getKeys(O)
|
|
, length = keys.length
|
|
, index = 0
|
|
, key;
|
|
while(length > index)if(O[key = keys[index++]] === el)return key;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 402 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var global = __webpack_require__(13)
|
|
, macrotask = __webpack_require__(86).set
|
|
, Observer = global.MutationObserver || global.WebKitMutationObserver
|
|
, process = global.process
|
|
, Promise = global.Promise
|
|
, isNode = __webpack_require__(39)(process) == 'process';
|
|
|
|
module.exports = function(){
|
|
var head, last, notify;
|
|
|
|
var flush = function(){
|
|
var parent, fn;
|
|
if(isNode && (parent = process.domain))parent.exit();
|
|
while(head){
|
|
fn = head.fn;
|
|
head = head.next;
|
|
try {
|
|
fn();
|
|
} catch(e){
|
|
if(head)notify();
|
|
else last = undefined;
|
|
throw e;
|
|
}
|
|
} last = undefined;
|
|
if(parent)parent.enter();
|
|
};
|
|
|
|
// Node.js
|
|
if(isNode){
|
|
notify = function(){
|
|
process.nextTick(flush);
|
|
};
|
|
// browsers with MutationObserver
|
|
} else if(Observer){
|
|
var toggle = true
|
|
, node = document.createTextNode('');
|
|
new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new
|
|
notify = function(){
|
|
node.data = toggle = !toggle;
|
|
};
|
|
// environments with maybe non-completely correct, but existent Promise
|
|
} else if(Promise && Promise.resolve){
|
|
var promise = Promise.resolve();
|
|
notify = function(){
|
|
promise.then(flush);
|
|
};
|
|
// for other environments - macrotask based on:
|
|
// - setImmediate
|
|
// - MessageChannel
|
|
// - window.postMessag
|
|
// - onreadystatechange
|
|
// - setTimeout
|
|
} else {
|
|
notify = function(){
|
|
// strange IE + webpack dev server bug - use .call(global)
|
|
macrotask.call(global, flush);
|
|
};
|
|
}
|
|
|
|
return function(fn){
|
|
var task = {fn: fn, next: undefined};
|
|
if(last)last.next = task;
|
|
if(!head){
|
|
head = task;
|
|
notify();
|
|
} last = task;
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 403 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var dP = __webpack_require__(19)
|
|
, anObject = __webpack_require__(18)
|
|
, getKeys = __webpack_require__(40);
|
|
|
|
module.exports = __webpack_require__(21) ? Object.defineProperties : function defineProperties(O, Properties){
|
|
anObject(O);
|
|
var keys = getKeys(Properties)
|
|
, length = keys.length
|
|
, i = 0
|
|
, P;
|
|
while(length > i)dP.f(O, P = keys[i++], Properties[P]);
|
|
return O;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 404 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
|
|
var toIObject = __webpack_require__(23)
|
|
, gOPN = __webpack_require__(82).f
|
|
, toString = {}.toString;
|
|
|
|
var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
|
|
? Object.getOwnPropertyNames(window) : [];
|
|
|
|
var getWindowNames = function(it){
|
|
try {
|
|
return gOPN(it);
|
|
} catch(e){
|
|
return windowNames.slice();
|
|
}
|
|
};
|
|
|
|
module.exports.f = function getOwnPropertyNames(it){
|
|
return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
/* 405 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
|
|
var has = __webpack_require__(22)
|
|
, toObject = __webpack_require__(42)
|
|
, IE_PROTO = __webpack_require__(83)('IE_PROTO')
|
|
, ObjectProto = Object.prototype;
|
|
|
|
module.exports = Object.getPrototypeOf || function(O){
|
|
O = toObject(O);
|
|
if(has(O, IE_PROTO))return O[IE_PROTO];
|
|
if(typeof O.constructor == 'function' && O instanceof O.constructor){
|
|
return O.constructor.prototype;
|
|
} return O instanceof Object ? ObjectProto : null;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 406 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// all object keys, includes non-enumerable and symbols
|
|
var gOPN = __webpack_require__(82)
|
|
, gOPS = __webpack_require__(59)
|
|
, anObject = __webpack_require__(18)
|
|
, Reflect = __webpack_require__(13).Reflect;
|
|
module.exports = Reflect && Reflect.ownKeys || function ownKeys(it){
|
|
var keys = gOPN.f(anObject(it))
|
|
, getSymbols = gOPS.f;
|
|
return getSymbols ? keys.concat(getSymbols(it)) : keys;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 407 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// 7.2.9 SameValue(x, y)
|
|
module.exports = Object.is || function is(x, y){
|
|
return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 408 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
// 7.3.20 SpeciesConstructor(O, defaultConstructor)
|
|
var anObject = __webpack_require__(18)
|
|
, aFunction = __webpack_require__(73)
|
|
, SPECIES = __webpack_require__(10)('species');
|
|
module.exports = function(O, D){
|
|
var C = anObject(O).constructor, S;
|
|
return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 409 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var toInteger = __webpack_require__(62)
|
|
, defined = __webpack_require__(30);
|
|
// true -> String#at
|
|
// false -> String#codePointAt
|
|
module.exports = function(TO_STRING){
|
|
return function(that, pos){
|
|
var s = String(defined(that))
|
|
, i = toInteger(pos)
|
|
, l = s.length
|
|
, a, b;
|
|
if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
|
|
a = s.charCodeAt(i);
|
|
return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
|
|
? TO_STRING ? s.charAt(i) : a
|
|
: TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 410 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var global = __webpack_require__(13)
|
|
, core = __webpack_require__(45)
|
|
, LIBRARY = __webpack_require__(58)
|
|
, wksExt = __webpack_require__(290)
|
|
, defineProperty = __webpack_require__(19).f;
|
|
module.exports = function(name){
|
|
var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});
|
|
if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 411 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 412 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 413 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 414 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 415 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 416 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 417 */
|
|
/***/ (function(module, exports) {
|
|
|
|
// removed by extract-text-webpack-plugin
|
|
|
|
/***/ }),
|
|
/* 418 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
var map = {
|
|
"./af": 133,
|
|
"./af.js": 133,
|
|
"./ar": 140,
|
|
"./ar-dz": 134,
|
|
"./ar-dz.js": 134,
|
|
"./ar-kw": 135,
|
|
"./ar-kw.js": 135,
|
|
"./ar-ly": 136,
|
|
"./ar-ly.js": 136,
|
|
"./ar-ma": 137,
|
|
"./ar-ma.js": 137,
|
|
"./ar-sa": 138,
|
|
"./ar-sa.js": 138,
|
|
"./ar-tn": 139,
|
|
"./ar-tn.js": 139,
|
|
"./ar.js": 140,
|
|
"./az": 141,
|
|
"./az.js": 141,
|
|
"./be": 142,
|
|
"./be.js": 142,
|
|
"./bg": 143,
|
|
"./bg.js": 143,
|
|
"./bn": 144,
|
|
"./bn.js": 144,
|
|
"./bo": 145,
|
|
"./bo.js": 145,
|
|
"./br": 146,
|
|
"./br.js": 146,
|
|
"./bs": 147,
|
|
"./bs.js": 147,
|
|
"./ca": 148,
|
|
"./ca.js": 148,
|
|
"./cs": 149,
|
|
"./cs.js": 149,
|
|
"./cv": 150,
|
|
"./cv.js": 150,
|
|
"./cy": 151,
|
|
"./cy.js": 151,
|
|
"./da": 152,
|
|
"./da.js": 152,
|
|
"./de": 155,
|
|
"./de-at": 153,
|
|
"./de-at.js": 153,
|
|
"./de-ch": 154,
|
|
"./de-ch.js": 154,
|
|
"./de.js": 155,
|
|
"./dv": 156,
|
|
"./dv.js": 156,
|
|
"./el": 157,
|
|
"./el.js": 157,
|
|
"./en-au": 158,
|
|
"./en-au.js": 158,
|
|
"./en-ca": 159,
|
|
"./en-ca.js": 159,
|
|
"./en-gb": 160,
|
|
"./en-gb.js": 160,
|
|
"./en-ie": 161,
|
|
"./en-ie.js": 161,
|
|
"./en-nz": 162,
|
|
"./en-nz.js": 162,
|
|
"./eo": 163,
|
|
"./eo.js": 163,
|
|
"./es": 165,
|
|
"./es-do": 164,
|
|
"./es-do.js": 164,
|
|
"./es.js": 165,
|
|
"./et": 166,
|
|
"./et.js": 166,
|
|
"./eu": 167,
|
|
"./eu.js": 167,
|
|
"./fa": 168,
|
|
"./fa.js": 168,
|
|
"./fi": 169,
|
|
"./fi.js": 169,
|
|
"./fo": 170,
|
|
"./fo.js": 170,
|
|
"./fr": 173,
|
|
"./fr-ca": 171,
|
|
"./fr-ca.js": 171,
|
|
"./fr-ch": 172,
|
|
"./fr-ch.js": 172,
|
|
"./fr.js": 173,
|
|
"./fy": 174,
|
|
"./fy.js": 174,
|
|
"./gd": 175,
|
|
"./gd.js": 175,
|
|
"./gl": 176,
|
|
"./gl.js": 176,
|
|
"./gom-latn": 177,
|
|
"./gom-latn.js": 177,
|
|
"./he": 178,
|
|
"./he.js": 178,
|
|
"./hi": 179,
|
|
"./hi.js": 179,
|
|
"./hr": 180,
|
|
"./hr.js": 180,
|
|
"./hu": 181,
|
|
"./hu.js": 181,
|
|
"./hy-am": 182,
|
|
"./hy-am.js": 182,
|
|
"./id": 183,
|
|
"./id.js": 183,
|
|
"./is": 184,
|
|
"./is.js": 184,
|
|
"./it": 185,
|
|
"./it.js": 185,
|
|
"./ja": 186,
|
|
"./ja.js": 186,
|
|
"./jv": 187,
|
|
"./jv.js": 187,
|
|
"./ka": 188,
|
|
"./ka.js": 188,
|
|
"./kk": 189,
|
|
"./kk.js": 189,
|
|
"./km": 190,
|
|
"./km.js": 190,
|
|
"./kn": 191,
|
|
"./kn.js": 191,
|
|
"./ko": 192,
|
|
"./ko.js": 192,
|
|
"./ky": 193,
|
|
"./ky.js": 193,
|
|
"./lb": 194,
|
|
"./lb.js": 194,
|
|
"./lo": 195,
|
|
"./lo.js": 195,
|
|
"./lt": 196,
|
|
"./lt.js": 196,
|
|
"./lv": 197,
|
|
"./lv.js": 197,
|
|
"./me": 198,
|
|
"./me.js": 198,
|
|
"./mi": 199,
|
|
"./mi.js": 199,
|
|
"./mk": 200,
|
|
"./mk.js": 200,
|
|
"./ml": 201,
|
|
"./ml.js": 201,
|
|
"./mr": 202,
|
|
"./mr.js": 202,
|
|
"./ms": 204,
|
|
"./ms-my": 203,
|
|
"./ms-my.js": 203,
|
|
"./ms.js": 204,
|
|
"./my": 205,
|
|
"./my.js": 205,
|
|
"./nb": 206,
|
|
"./nb.js": 206,
|
|
"./ne": 207,
|
|
"./ne.js": 207,
|
|
"./nl": 209,
|
|
"./nl-be": 208,
|
|
"./nl-be.js": 208,
|
|
"./nl.js": 209,
|
|
"./nn": 210,
|
|
"./nn.js": 210,
|
|
"./pa-in": 211,
|
|
"./pa-in.js": 211,
|
|
"./pl": 212,
|
|
"./pl.js": 212,
|
|
"./pt": 214,
|
|
"./pt-br": 213,
|
|
"./pt-br.js": 213,
|
|
"./pt.js": 214,
|
|
"./ro": 215,
|
|
"./ro.js": 215,
|
|
"./ru": 216,
|
|
"./ru.js": 216,
|
|
"./sd": 217,
|
|
"./sd.js": 217,
|
|
"./se": 218,
|
|
"./se.js": 218,
|
|
"./si": 219,
|
|
"./si.js": 219,
|
|
"./sk": 220,
|
|
"./sk.js": 220,
|
|
"./sl": 221,
|
|
"./sl.js": 221,
|
|
"./sq": 222,
|
|
"./sq.js": 222,
|
|
"./sr": 224,
|
|
"./sr-cyrl": 223,
|
|
"./sr-cyrl.js": 223,
|
|
"./sr.js": 224,
|
|
"./ss": 225,
|
|
"./ss.js": 225,
|
|
"./sv": 226,
|
|
"./sv.js": 226,
|
|
"./sw": 227,
|
|
"./sw.js": 227,
|
|
"./ta": 228,
|
|
"./ta.js": 228,
|
|
"./te": 229,
|
|
"./te.js": 229,
|
|
"./tet": 230,
|
|
"./tet.js": 230,
|
|
"./th": 231,
|
|
"./th.js": 231,
|
|
"./tl-ph": 232,
|
|
"./tl-ph.js": 232,
|
|
"./tlh": 233,
|
|
"./tlh.js": 233,
|
|
"./tr": 234,
|
|
"./tr.js": 234,
|
|
"./tzl": 235,
|
|
"./tzl.js": 235,
|
|
"./tzm": 237,
|
|
"./tzm-latn": 236,
|
|
"./tzm-latn.js": 236,
|
|
"./tzm.js": 237,
|
|
"./uk": 238,
|
|
"./uk.js": 238,
|
|
"./ur": 239,
|
|
"./ur.js": 239,
|
|
"./uz": 241,
|
|
"./uz-latn": 240,
|
|
"./uz-latn.js": 240,
|
|
"./uz.js": 241,
|
|
"./vi": 242,
|
|
"./vi.js": 242,
|
|
"./x-pseudo": 243,
|
|
"./x-pseudo.js": 243,
|
|
"./yo": 244,
|
|
"./yo.js": 244,
|
|
"./zh-cn": 245,
|
|
"./zh-cn.js": 245,
|
|
"./zh-hk": 246,
|
|
"./zh-hk.js": 246,
|
|
"./zh-tw": 247,
|
|
"./zh-tw.js": 247
|
|
};
|
|
function webpackContext(req) {
|
|
return __webpack_require__(webpackContextResolve(req));
|
|
};
|
|
function webpackContextResolve(req) {
|
|
var id = map[req];
|
|
if(!(id + 1)) // check for number or string
|
|
throw new Error("Cannot find module '" + req + "'.");
|
|
return id;
|
|
};
|
|
webpackContext.keys = function webpackContextKeys() {
|
|
return Object.keys(map);
|
|
};
|
|
webpackContext.resolve = webpackContextResolve;
|
|
module.exports = webpackContext;
|
|
webpackContext.id = 418;
|
|
|
|
/***/ }),
|
|
/* 419 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/*!
|
|
* Pikaday
|
|
*
|
|
* Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday
|
|
*/
|
|
|
|
(function (root, factory)
|
|
{
|
|
'use strict';
|
|
|
|
var moment;
|
|
if (true) {
|
|
// CommonJS module
|
|
// Load moment.js as an optional dependency
|
|
try { moment = __webpack_require__(36); } catch (e) {}
|
|
module.exports = factory(moment);
|
|
} else if (typeof define === 'function' && define.amd) {
|
|
// AMD. Register as an anonymous module.
|
|
define(function (req)
|
|
{
|
|
// Load moment.js as an optional dependency
|
|
var id = 'moment';
|
|
try { moment = req(id); } catch (e) {}
|
|
return factory(moment);
|
|
});
|
|
} else {
|
|
root.Pikaday = factory(root.moment);
|
|
}
|
|
}(this, function (moment)
|
|
{
|
|
'use strict';
|
|
|
|
/**
|
|
* feature detection and helper functions
|
|
*/
|
|
var hasMoment = typeof moment === 'function',
|
|
|
|
hasEventListeners = !!window.addEventListener,
|
|
|
|
document = window.document,
|
|
|
|
sto = window.setTimeout,
|
|
|
|
addEvent = function(el, e, callback, capture)
|
|
{
|
|
if (hasEventListeners) {
|
|
el.addEventListener(e, callback, !!capture);
|
|
} else {
|
|
el.attachEvent('on' + e, callback);
|
|
}
|
|
},
|
|
|
|
removeEvent = function(el, e, callback, capture)
|
|
{
|
|
if (hasEventListeners) {
|
|
el.removeEventListener(e, callback, !!capture);
|
|
} else {
|
|
el.detachEvent('on' + e, callback);
|
|
}
|
|
},
|
|
|
|
fireEvent = function(el, eventName, data)
|
|
{
|
|
var ev;
|
|
|
|
if (document.createEvent) {
|
|
ev = document.createEvent('HTMLEvents');
|
|
ev.initEvent(eventName, true, false);
|
|
ev = extend(ev, data);
|
|
el.dispatchEvent(ev);
|
|
} else if (document.createEventObject) {
|
|
ev = document.createEventObject();
|
|
ev = extend(ev, data);
|
|
el.fireEvent('on' + eventName, ev);
|
|
}
|
|
},
|
|
|
|
trim = function(str)
|
|
{
|
|
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
|
|
},
|
|
|
|
hasClass = function(el, cn)
|
|
{
|
|
return (' ' + el.className + ' ').indexOf(' ' + cn + ' ') !== -1;
|
|
},
|
|
|
|
addClass = function(el, cn)
|
|
{
|
|
if (!hasClass(el, cn)) {
|
|
el.className = (el.className === '') ? cn : el.className + ' ' + cn;
|
|
}
|
|
},
|
|
|
|
removeClass = function(el, cn)
|
|
{
|
|
el.className = trim((' ' + el.className + ' ').replace(' ' + cn + ' ', ' '));
|
|
},
|
|
|
|
isArray = function(obj)
|
|
{
|
|
return (/Array/).test(Object.prototype.toString.call(obj));
|
|
},
|
|
|
|
isDate = function(obj)
|
|
{
|
|
return (/Date/).test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
|
|
},
|
|
|
|
isWeekend = function(date)
|
|
{
|
|
var day = date.getDay();
|
|
return day === 0 || day === 6;
|
|
},
|
|
|
|
isLeapYear = function(year)
|
|
{
|
|
// solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
|
|
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
|
|
},
|
|
|
|
getDaysInMonth = function(year, month)
|
|
{
|
|
return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
|
|
},
|
|
|
|
setToStartOfDay = function(date)
|
|
{
|
|
if (isDate(date)) date.setHours(0,0,0,0);
|
|
},
|
|
|
|
compareDates = function(a,b)
|
|
{
|
|
// weak date comparison (use setToStartOfDay(date) to ensure correct result)
|
|
return a.getTime() === b.getTime();
|
|
},
|
|
|
|
extend = function(to, from, overwrite)
|
|
{
|
|
var prop, hasProp;
|
|
for (prop in from) {
|
|
hasProp = to[prop] !== undefined;
|
|
if (hasProp && typeof from[prop] === 'object' && from[prop] !== null && from[prop].nodeName === undefined) {
|
|
if (isDate(from[prop])) {
|
|
if (overwrite) {
|
|
to[prop] = new Date(from[prop].getTime());
|
|
}
|
|
}
|
|
else if (isArray(from[prop])) {
|
|
if (overwrite) {
|
|
to[prop] = from[prop].slice(0);
|
|
}
|
|
} else {
|
|
to[prop] = extend({}, from[prop], overwrite);
|
|
}
|
|
} else if (overwrite || !hasProp) {
|
|
to[prop] = from[prop];
|
|
}
|
|
}
|
|
return to;
|
|
},
|
|
|
|
adjustCalendar = function(calendar) {
|
|
if (calendar.month < 0) {
|
|
calendar.year -= Math.ceil(Math.abs(calendar.month)/12);
|
|
calendar.month += 12;
|
|
}
|
|
if (calendar.month > 11) {
|
|
calendar.year += Math.floor(Math.abs(calendar.month)/12);
|
|
calendar.month -= 12;
|
|
}
|
|
return calendar;
|
|
},
|
|
|
|
/**
|
|
* defaults and localisation
|
|
*/
|
|
defaults = {
|
|
|
|
// bind the picker to a form field
|
|
field: null,
|
|
|
|
// automatically show/hide the picker on `field` focus (default `true` if `field` is set)
|
|
bound: undefined,
|
|
|
|
// position of the datepicker, relative to the field (default to bottom & left)
|
|
// ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
|
|
position: 'bottom left',
|
|
|
|
// automatically fit in the viewport even if it means repositioning from the position option
|
|
reposition: true,
|
|
|
|
// the default output format for `.toString()` and `field` value
|
|
format: 'YYYY-MM-DD',
|
|
|
|
// the initial date to view when first opened
|
|
defaultDate: null,
|
|
|
|
// make the `defaultDate` the initial selected value
|
|
setDefaultDate: false,
|
|
|
|
// first day of week (0: Sunday, 1: Monday etc)
|
|
firstDay: 0,
|
|
|
|
// the default flag for moment's strict date parsing
|
|
formatStrict: false,
|
|
|
|
// the minimum/earliest date that can be selected
|
|
minDate: null,
|
|
// the maximum/latest date that can be selected
|
|
maxDate: null,
|
|
|
|
// number of years either side, or array of upper/lower range
|
|
yearRange: 10,
|
|
|
|
// show week numbers at head of row
|
|
showWeekNumber: false,
|
|
|
|
// used internally (don't config outside)
|
|
minYear: 0,
|
|
maxYear: 9999,
|
|
minMonth: undefined,
|
|
maxMonth: undefined,
|
|
|
|
startRange: null,
|
|
endRange: null,
|
|
|
|
isRTL: false,
|
|
|
|
// Additional text to append to the year in the calendar title
|
|
yearSuffix: '',
|
|
|
|
// Render the month after year in the calendar title
|
|
showMonthAfterYear: false,
|
|
|
|
// Render days of the calendar grid that fall in the next or previous month
|
|
showDaysInNextAndPreviousMonths: false,
|
|
|
|
// how many months are visible
|
|
numberOfMonths: 1,
|
|
|
|
// when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
|
|
// only used for the first display or when a selected date is not visible
|
|
mainCalendar: 'left',
|
|
|
|
// Specify a DOM element to render the calendar in
|
|
container: undefined,
|
|
|
|
// internationalization
|
|
i18n: {
|
|
previousMonth : 'Previous Month',
|
|
nextMonth : 'Next Month',
|
|
months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
|
weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
|
|
weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
|
|
},
|
|
|
|
// Theme Classname
|
|
theme: null,
|
|
|
|
// callback function
|
|
onSelect: null,
|
|
onOpen: null,
|
|
onClose: null,
|
|
onDraw: null
|
|
},
|
|
|
|
|
|
/**
|
|
* templating functions to abstract HTML rendering
|
|
*/
|
|
renderDayName = function(opts, day, abbr)
|
|
{
|
|
day += opts.firstDay;
|
|
while (day >= 7) {
|
|
day -= 7;
|
|
}
|
|
return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
|
|
},
|
|
|
|
renderDay = function(opts)
|
|
{
|
|
var arr = [];
|
|
var ariaSelected = 'false';
|
|
if (opts.isEmpty) {
|
|
if (opts.showDaysInNextAndPreviousMonths) {
|
|
arr.push('is-outside-current-month');
|
|
} else {
|
|
return '<td class="is-empty"></td>';
|
|
}
|
|
}
|
|
if (opts.isDisabled) {
|
|
arr.push('is-disabled');
|
|
}
|
|
if (opts.isToday) {
|
|
arr.push('is-today');
|
|
}
|
|
if (opts.isSelected) {
|
|
arr.push('is-selected');
|
|
ariaSelected = 'true';
|
|
}
|
|
if (opts.isInRange) {
|
|
arr.push('is-inrange');
|
|
}
|
|
if (opts.isStartRange) {
|
|
arr.push('is-startrange');
|
|
}
|
|
if (opts.isEndRange) {
|
|
arr.push('is-endrange');
|
|
}
|
|
return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '" aria-selected="' + ariaSelected + '">' +
|
|
'<button class="pika-button pika-day" type="button" ' +
|
|
'data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' +
|
|
opts.day +
|
|
'</button>' +
|
|
'</td>';
|
|
},
|
|
|
|
renderWeek = function (d, m, y) {
|
|
// Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
|
|
var onejan = new Date(y, 0, 1),
|
|
weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay()+1)/7);
|
|
return '<td class="pika-week">' + weekNum + '</td>';
|
|
},
|
|
|
|
renderRow = function(days, isRTL)
|
|
{
|
|
return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>';
|
|
},
|
|
|
|
renderBody = function(rows)
|
|
{
|
|
return '<tbody>' + rows.join('') + '</tbody>';
|
|
},
|
|
|
|
renderHead = function(opts)
|
|
{
|
|
var i, arr = [];
|
|
if (opts.showWeekNumber) {
|
|
arr.push('<th></th>');
|
|
}
|
|
for (i = 0; i < 7; i++) {
|
|
arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
|
|
}
|
|
return '<thead><tr>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</tr></thead>';
|
|
},
|
|
|
|
renderTitle = function(instance, c, year, month, refYear, randId)
|
|
{
|
|
var i, j, arr,
|
|
opts = instance._o,
|
|
isMinYear = year === opts.minYear,
|
|
isMaxYear = year === opts.maxYear,
|
|
html = '<div id="' + randId + '" class="pika-title" role="heading" aria-live="assertive">',
|
|
monthHtml,
|
|
yearHtml,
|
|
prev = true,
|
|
next = true;
|
|
|
|
for (arr = [], i = 0; i < 12; i++) {
|
|
arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' +
|
|
(i === month ? ' selected="selected"': '') +
|
|
((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled="disabled"' : '') + '>' +
|
|
opts.i18n.months[i] + '</option>');
|
|
}
|
|
|
|
monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join('') + '</select></div>';
|
|
|
|
if (isArray(opts.yearRange)) {
|
|
i = opts.yearRange[0];
|
|
j = opts.yearRange[1] + 1;
|
|
} else {
|
|
i = year - opts.yearRange;
|
|
j = 1 + year + opts.yearRange;
|
|
}
|
|
|
|
for (arr = []; i < j && i <= opts.maxYear; i++) {
|
|
if (i >= opts.minYear) {
|
|
arr.push('<option value="' + i + '"' + (i === year ? ' selected="selected"': '') + '>' + (i) + '</option>');
|
|
}
|
|
}
|
|
yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join('') + '</select></div>';
|
|
|
|
if (opts.showMonthAfterYear) {
|
|
html += yearHtml + monthHtml;
|
|
} else {
|
|
html += monthHtml + yearHtml;
|
|
}
|
|
|
|
if (isMinYear && (month === 0 || opts.minMonth >= month)) {
|
|
prev = false;
|
|
}
|
|
|
|
if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
|
|
next = false;
|
|
}
|
|
|
|
if (c === 0) {
|
|
html += '<button class="pika-prev' + (prev ? '' : ' is-disabled') + '" type="button">' + opts.i18n.previousMonth + '</button>';
|
|
}
|
|
if (c === (instance._o.numberOfMonths - 1) ) {
|
|
html += '<button class="pika-next' + (next ? '' : ' is-disabled') + '" type="button">' + opts.i18n.nextMonth + '</button>';
|
|
}
|
|
|
|
return html += '</div>';
|
|
},
|
|
|
|
renderTable = function(opts, data, randId)
|
|
{
|
|
return '<table cellpadding="0" cellspacing="0" class="pika-table" role="grid" aria-labelledby="' + randId + '">' + renderHead(opts) + renderBody(data) + '</table>';
|
|
},
|
|
|
|
|
|
/**
|
|
* Pikaday constructor
|
|
*/
|
|
Pikaday = function(options)
|
|
{
|
|
var self = this,
|
|
opts = self.config(options);
|
|
|
|
self._onMouseDown = function(e)
|
|
{
|
|
if (!self._v) {
|
|
return;
|
|
}
|
|
e = e || window.event;
|
|
var target = e.target || e.srcElement;
|
|
if (!target) {
|
|
return;
|
|
}
|
|
|
|
if (!hasClass(target, 'is-disabled')) {
|
|
if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty') && !hasClass(target.parentNode, 'is-disabled')) {
|
|
self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
|
|
if (opts.bound) {
|
|
sto(function() {
|
|
self.hide();
|
|
if (opts.field) {
|
|
opts.field.blur();
|
|
}
|
|
}, 100);
|
|
}
|
|
}
|
|
else if (hasClass(target, 'pika-prev')) {
|
|
self.prevMonth();
|
|
}
|
|
else if (hasClass(target, 'pika-next')) {
|
|
self.nextMonth();
|
|
}
|
|
}
|
|
if (!hasClass(target, 'pika-select')) {
|
|
// if this is touch event prevent mouse events emulation
|
|
if (e.preventDefault) {
|
|
e.preventDefault();
|
|
} else {
|
|
e.returnValue = false;
|
|
return false;
|
|
}
|
|
} else {
|
|
self._c = true;
|
|
}
|
|
};
|
|
|
|
self._onChange = function(e)
|
|
{
|
|
e = e || window.event;
|
|
var target = e.target || e.srcElement;
|
|
if (!target) {
|
|
return;
|
|
}
|
|
if (hasClass(target, 'pika-select-month')) {
|
|
self.gotoMonth(target.value);
|
|
}
|
|
else if (hasClass(target, 'pika-select-year')) {
|
|
self.gotoYear(target.value);
|
|
}
|
|
};
|
|
|
|
self._onKeyChange = function(e)
|
|
{
|
|
e = e || window.event;
|
|
|
|
if (self.isVisible()) {
|
|
|
|
switch(e.keyCode){
|
|
case 13:
|
|
case 27:
|
|
opts.field.blur();
|
|
break;
|
|
case 37:
|
|
e.preventDefault();
|
|
self.adjustDate('subtract', 1);
|
|
break;
|
|
case 38:
|
|
self.adjustDate('subtract', 7);
|
|
break;
|
|
case 39:
|
|
self.adjustDate('add', 1);
|
|
break;
|
|
case 40:
|
|
self.adjustDate('add', 7);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
self._onInputChange = function(e)
|
|
{
|
|
var date;
|
|
|
|
if (e.firedBy === self) {
|
|
return;
|
|
}
|
|
if (hasMoment) {
|
|
date = moment(opts.field.value, opts.format, opts.formatStrict);
|
|
date = (date && date.isValid()) ? date.toDate() : null;
|
|
}
|
|
else {
|
|
date = new Date(Date.parse(opts.field.value));
|
|
}
|
|
if (isDate(date)) {
|
|
self.setDate(date);
|
|
}
|
|
if (!self._v) {
|
|
self.show();
|
|
}
|
|
};
|
|
|
|
self._onInputFocus = function()
|
|
{
|
|
self.show();
|
|
};
|
|
|
|
self._onInputClick = function()
|
|
{
|
|
self.show();
|
|
};
|
|
|
|
self._onInputBlur = function()
|
|
{
|
|
// IE allows pika div to gain focus; catch blur the input field
|
|
var pEl = document.activeElement;
|
|
do {
|
|
if (hasClass(pEl, 'pika-single')) {
|
|
return;
|
|
}
|
|
}
|
|
while ((pEl = pEl.parentNode));
|
|
|
|
if (!self._c) {
|
|
self._b = sto(function() {
|
|
self.hide();
|
|
}, 50);
|
|
}
|
|
self._c = false;
|
|
};
|
|
|
|
self._onClick = function(e)
|
|
{
|
|
e = e || window.event;
|
|
var target = e.target || e.srcElement,
|
|
pEl = target;
|
|
if (!target) {
|
|
return;
|
|
}
|
|
if (!hasEventListeners && hasClass(target, 'pika-select')) {
|
|
if (!target.onchange) {
|
|
target.setAttribute('onchange', 'return;');
|
|
addEvent(target, 'change', self._onChange);
|
|
}
|
|
}
|
|
do {
|
|
if (hasClass(pEl, 'pika-single') || pEl === opts.trigger) {
|
|
return;
|
|
}
|
|
}
|
|
while ((pEl = pEl.parentNode));
|
|
if (self._v && target !== opts.trigger && pEl !== opts.trigger) {
|
|
self.hide();
|
|
}
|
|
};
|
|
|
|
self.el = document.createElement('div');
|
|
self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : '');
|
|
|
|
addEvent(self.el, 'mousedown', self._onMouseDown, true);
|
|
addEvent(self.el, 'touchend', self._onMouseDown, true);
|
|
addEvent(self.el, 'change', self._onChange);
|
|
addEvent(document, 'keydown', self._onKeyChange);
|
|
|
|
if (opts.field) {
|
|
if (opts.container) {
|
|
opts.container.appendChild(self.el);
|
|
} else if (opts.bound) {
|
|
document.body.appendChild(self.el);
|
|
} else {
|
|
opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
|
|
}
|
|
addEvent(opts.field, 'change', self._onInputChange);
|
|
|
|
if (!opts.defaultDate) {
|
|
if (hasMoment && opts.field.value) {
|
|
opts.defaultDate = moment(opts.field.value, opts.format).toDate();
|
|
} else {
|
|
opts.defaultDate = new Date(Date.parse(opts.field.value));
|
|
}
|
|
opts.setDefaultDate = true;
|
|
}
|
|
}
|
|
|
|
var defDate = opts.defaultDate;
|
|
|
|
if (isDate(defDate)) {
|
|
if (opts.setDefaultDate) {
|
|
self.setDate(defDate, true);
|
|
} else {
|
|
self.gotoDate(defDate);
|
|
}
|
|
} else {
|
|
self.gotoDate(new Date());
|
|
}
|
|
|
|
if (opts.bound) {
|
|
this.hide();
|
|
self.el.className += ' is-bound';
|
|
addEvent(opts.trigger, 'click', self._onInputClick);
|
|
addEvent(opts.trigger, 'focus', self._onInputFocus);
|
|
addEvent(opts.trigger, 'blur', self._onInputBlur);
|
|
} else {
|
|
this.show();
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* public Pikaday API
|
|
*/
|
|
Pikaday.prototype = {
|
|
|
|
|
|
/**
|
|
* configure functionality
|
|
*/
|
|
config: function(options)
|
|
{
|
|
if (!this._o) {
|
|
this._o = extend({}, defaults, true);
|
|
}
|
|
|
|
var opts = extend(this._o, options, true);
|
|
|
|
opts.isRTL = !!opts.isRTL;
|
|
|
|
opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;
|
|
|
|
opts.theme = (typeof opts.theme) === 'string' && opts.theme ? opts.theme : null;
|
|
|
|
opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);
|
|
|
|
opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field;
|
|
|
|
opts.disableWeekends = !!opts.disableWeekends;
|
|
|
|
opts.disableDayFn = (typeof opts.disableDayFn) === 'function' ? opts.disableDayFn : null;
|
|
|
|
var nom = parseInt(opts.numberOfMonths, 10) || 1;
|
|
opts.numberOfMonths = nom > 4 ? 4 : nom;
|
|
|
|
if (!isDate(opts.minDate)) {
|
|
opts.minDate = false;
|
|
}
|
|
if (!isDate(opts.maxDate)) {
|
|
opts.maxDate = false;
|
|
}
|
|
if ((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate) {
|
|
opts.maxDate = opts.minDate = false;
|
|
}
|
|
if (opts.minDate) {
|
|
this.setMinDate(opts.minDate);
|
|
}
|
|
if (opts.maxDate) {
|
|
this.setMaxDate(opts.maxDate);
|
|
}
|
|
|
|
if (isArray(opts.yearRange)) {
|
|
var fallback = new Date().getFullYear() - 10;
|
|
opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
|
|
opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
|
|
} else {
|
|
opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
|
|
if (opts.yearRange > 100) {
|
|
opts.yearRange = 100;
|
|
}
|
|
}
|
|
|
|
return opts;
|
|
},
|
|
|
|
/**
|
|
* return a formatted string of the current selection (using Moment.js if available)
|
|
*/
|
|
toString: function(format)
|
|
{
|
|
return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._d.toDateString();
|
|
},
|
|
|
|
/**
|
|
* return a Moment.js object of the current selection (if available)
|
|
*/
|
|
getMoment: function()
|
|
{
|
|
return hasMoment ? moment(this._d) : null;
|
|
},
|
|
|
|
/**
|
|
* set the current selection from a Moment.js object (if available)
|
|
*/
|
|
setMoment: function(date, preventOnSelect)
|
|
{
|
|
if (hasMoment && moment.isMoment(date)) {
|
|
this.setDate(date.toDate(), preventOnSelect);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* return a Date object of the current selection with fallback for the current date
|
|
*/
|
|
getDate: function()
|
|
{
|
|
return isDate(this._d) ? new Date(this._d.getTime()) : new Date();
|
|
},
|
|
|
|
/**
|
|
* set the current selection
|
|
*/
|
|
setDate: function(date, preventOnSelect)
|
|
{
|
|
if (!date) {
|
|
this._d = null;
|
|
|
|
if (this._o.field) {
|
|
this._o.field.value = '';
|
|
fireEvent(this._o.field, 'change', { firedBy: this });
|
|
}
|
|
|
|
return this.draw();
|
|
}
|
|
if (typeof date === 'string') {
|
|
date = new Date(Date.parse(date));
|
|
}
|
|
if (!isDate(date)) {
|
|
return;
|
|
}
|
|
|
|
var min = this._o.minDate,
|
|
max = this._o.maxDate;
|
|
|
|
if (isDate(min) && date < min) {
|
|
date = min;
|
|
} else if (isDate(max) && date > max) {
|
|
date = max;
|
|
}
|
|
|
|
this._d = new Date(date.getTime());
|
|
setToStartOfDay(this._d);
|
|
this.gotoDate(this._d);
|
|
|
|
if (this._o.field) {
|
|
this._o.field.value = this.toString();
|
|
fireEvent(this._o.field, 'change', { firedBy: this });
|
|
}
|
|
if (!preventOnSelect && typeof this._o.onSelect === 'function') {
|
|
this._o.onSelect.call(this, this.getDate());
|
|
}
|
|
},
|
|
|
|
/**
|
|
* change view to a specific date
|
|
*/
|
|
gotoDate: function(date)
|
|
{
|
|
var newCalendar = true;
|
|
|
|
if (!isDate(date)) {
|
|
return;
|
|
}
|
|
|
|
if (this.calendars) {
|
|
var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
|
|
lastVisibleDate = new Date(this.calendars[this.calendars.length-1].year, this.calendars[this.calendars.length-1].month, 1),
|
|
visibleDate = date.getTime();
|
|
// get the end of the month
|
|
lastVisibleDate.setMonth(lastVisibleDate.getMonth()+1);
|
|
lastVisibleDate.setDate(lastVisibleDate.getDate()-1);
|
|
newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate);
|
|
}
|
|
|
|
if (newCalendar) {
|
|
this.calendars = [{
|
|
month: date.getMonth(),
|
|
year: date.getFullYear()
|
|
}];
|
|
if (this._o.mainCalendar === 'right') {
|
|
this.calendars[0].month += 1 - this._o.numberOfMonths;
|
|
}
|
|
}
|
|
|
|
this.adjustCalendars();
|
|
},
|
|
|
|
adjustDate: function(sign, days) {
|
|
|
|
var day = this.getDate();
|
|
var difference = parseInt(days)*24*60*60*1000;
|
|
|
|
var newDay;
|
|
|
|
if (sign === 'add') {
|
|
newDay = new Date(day.valueOf() + difference);
|
|
} else if (sign === 'subtract') {
|
|
newDay = new Date(day.valueOf() - difference);
|
|
}
|
|
|
|
if (hasMoment) {
|
|
if (sign === 'add') {
|
|
newDay = moment(day).add(days, "days").toDate();
|
|
} else if (sign === 'subtract') {
|
|
newDay = moment(day).subtract(days, "days").toDate();
|
|
}
|
|
}
|
|
|
|
this.setDate(newDay);
|
|
},
|
|
|
|
adjustCalendars: function() {
|
|
this.calendars[0] = adjustCalendar(this.calendars[0]);
|
|
for (var c = 1; c < this._o.numberOfMonths; c++) {
|
|
this.calendars[c] = adjustCalendar({
|
|
month: this.calendars[0].month + c,
|
|
year: this.calendars[0].year
|
|
});
|
|
}
|
|
this.draw();
|
|
},
|
|
|
|
gotoToday: function()
|
|
{
|
|
this.gotoDate(new Date());
|
|
},
|
|
|
|
/**
|
|
* change view to a specific month (zero-index, e.g. 0: January)
|
|
*/
|
|
gotoMonth: function(month)
|
|
{
|
|
if (!isNaN(month)) {
|
|
this.calendars[0].month = parseInt(month, 10);
|
|
this.adjustCalendars();
|
|
}
|
|
},
|
|
|
|
nextMonth: function()
|
|
{
|
|
this.calendars[0].month++;
|
|
this.adjustCalendars();
|
|
},
|
|
|
|
prevMonth: function()
|
|
{
|
|
this.calendars[0].month--;
|
|
this.adjustCalendars();
|
|
},
|
|
|
|
/**
|
|
* change view to a specific full year (e.g. "2012")
|
|
*/
|
|
gotoYear: function(year)
|
|
{
|
|
if (!isNaN(year)) {
|
|
this.calendars[0].year = parseInt(year, 10);
|
|
this.adjustCalendars();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* change the minDate
|
|
*/
|
|
setMinDate: function(value)
|
|
{
|
|
if(value instanceof Date) {
|
|
setToStartOfDay(value);
|
|
this._o.minDate = value;
|
|
this._o.minYear = value.getFullYear();
|
|
this._o.minMonth = value.getMonth();
|
|
} else {
|
|
this._o.minDate = defaults.minDate;
|
|
this._o.minYear = defaults.minYear;
|
|
this._o.minMonth = defaults.minMonth;
|
|
this._o.startRange = defaults.startRange;
|
|
}
|
|
|
|
this.draw();
|
|
},
|
|
|
|
/**
|
|
* change the maxDate
|
|
*/
|
|
setMaxDate: function(value)
|
|
{
|
|
if(value instanceof Date) {
|
|
setToStartOfDay(value);
|
|
this._o.maxDate = value;
|
|
this._o.maxYear = value.getFullYear();
|
|
this._o.maxMonth = value.getMonth();
|
|
} else {
|
|
this._o.maxDate = defaults.maxDate;
|
|
this._o.maxYear = defaults.maxYear;
|
|
this._o.maxMonth = defaults.maxMonth;
|
|
this._o.endRange = defaults.endRange;
|
|
}
|
|
|
|
this.draw();
|
|
},
|
|
|
|
setStartRange: function(value)
|
|
{
|
|
this._o.startRange = value;
|
|
},
|
|
|
|
setEndRange: function(value)
|
|
{
|
|
this._o.endRange = value;
|
|
},
|
|
|
|
/**
|
|
* refresh the HTML
|
|
*/
|
|
draw: function(force)
|
|
{
|
|
if (!this._v && !force) {
|
|
return;
|
|
}
|
|
var opts = this._o,
|
|
minYear = opts.minYear,
|
|
maxYear = opts.maxYear,
|
|
minMonth = opts.minMonth,
|
|
maxMonth = opts.maxMonth,
|
|
html = '',
|
|
randId;
|
|
|
|
if (this._y <= minYear) {
|
|
this._y = minYear;
|
|
if (!isNaN(minMonth) && this._m < minMonth) {
|
|
this._m = minMonth;
|
|
}
|
|
}
|
|
if (this._y >= maxYear) {
|
|
this._y = maxYear;
|
|
if (!isNaN(maxMonth) && this._m > maxMonth) {
|
|
this._m = maxMonth;
|
|
}
|
|
}
|
|
|
|
randId = 'pika-title-' + Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 2);
|
|
|
|
for (var c = 0; c < opts.numberOfMonths; c++) {
|
|
html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId) + '</div>';
|
|
}
|
|
|
|
this.el.innerHTML = html;
|
|
|
|
if (opts.bound) {
|
|
if(opts.field.type !== 'hidden') {
|
|
sto(function() {
|
|
opts.trigger.focus();
|
|
}, 1);
|
|
}
|
|
}
|
|
|
|
if (typeof this._o.onDraw === 'function') {
|
|
this._o.onDraw(this);
|
|
}
|
|
|
|
if (opts.bound) {
|
|
// let the screen reader user know to use arrow keys
|
|
opts.field.setAttribute('aria-label', 'Use the arrow keys to pick a date');
|
|
}
|
|
},
|
|
|
|
adjustPosition: function()
|
|
{
|
|
var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect;
|
|
|
|
if (this._o.container) return;
|
|
|
|
this.el.style.position = 'absolute';
|
|
|
|
field = this._o.trigger;
|
|
pEl = field;
|
|
width = this.el.offsetWidth;
|
|
height = this.el.offsetHeight;
|
|
viewportWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
|
|
|
|
if (typeof field.getBoundingClientRect === 'function') {
|
|
clientRect = field.getBoundingClientRect();
|
|
left = clientRect.left + window.pageXOffset;
|
|
top = clientRect.bottom + window.pageYOffset;
|
|
} else {
|
|
left = pEl.offsetLeft;
|
|
top = pEl.offsetTop + pEl.offsetHeight;
|
|
while((pEl = pEl.offsetParent)) {
|
|
left += pEl.offsetLeft;
|
|
top += pEl.offsetTop;
|
|
}
|
|
}
|
|
|
|
// default position is bottom & left
|
|
if ((this._o.reposition && left + width > viewportWidth) ||
|
|
(
|
|
this._o.position.indexOf('right') > -1 &&
|
|
left - width + field.offsetWidth > 0
|
|
)
|
|
) {
|
|
left = left - width + field.offsetWidth;
|
|
}
|
|
if ((this._o.reposition && top + height > viewportHeight + scrollTop) ||
|
|
(
|
|
this._o.position.indexOf('top') > -1 &&
|
|
top - height - field.offsetHeight > 0
|
|
)
|
|
) {
|
|
top = top - height - field.offsetHeight;
|
|
}
|
|
|
|
this.el.style.left = left + 'px';
|
|
this.el.style.top = top + 'px';
|
|
},
|
|
|
|
/**
|
|
* render HTML for a particular month
|
|
*/
|
|
render: function(year, month, randId)
|
|
{
|
|
var opts = this._o,
|
|
now = new Date(),
|
|
days = getDaysInMonth(year, month),
|
|
before = new Date(year, month, 1).getDay(),
|
|
data = [],
|
|
row = [];
|
|
setToStartOfDay(now);
|
|
if (opts.firstDay > 0) {
|
|
before -= opts.firstDay;
|
|
if (before < 0) {
|
|
before += 7;
|
|
}
|
|
}
|
|
var previousMonth = month === 0 ? 11 : month - 1,
|
|
nextMonth = month === 11 ? 0 : month + 1,
|
|
yearOfPreviousMonth = month === 0 ? year - 1 : year,
|
|
yearOfNextMonth = month === 11 ? year + 1 : year,
|
|
daysInPreviousMonth = getDaysInMonth(yearOfPreviousMonth, previousMonth);
|
|
var cells = days + before,
|
|
after = cells;
|
|
while(after > 7) {
|
|
after -= 7;
|
|
}
|
|
cells += 7 - after;
|
|
for (var i = 0, r = 0; i < cells; i++)
|
|
{
|
|
var day = new Date(year, month, 1 + (i - before)),
|
|
isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
|
|
isToday = compareDates(day, now),
|
|
isEmpty = i < before || i >= (days + before),
|
|
dayNumber = 1 + (i - before),
|
|
monthNumber = month,
|
|
yearNumber = year,
|
|
isStartRange = opts.startRange && compareDates(opts.startRange, day),
|
|
isEndRange = opts.endRange && compareDates(opts.endRange, day),
|
|
isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
|
|
isDisabled = (opts.minDate && day < opts.minDate) ||
|
|
(opts.maxDate && day > opts.maxDate) ||
|
|
(opts.disableWeekends && isWeekend(day)) ||
|
|
(opts.disableDayFn && opts.disableDayFn(day));
|
|
|
|
if (isEmpty) {
|
|
if (i < before) {
|
|
dayNumber = daysInPreviousMonth + dayNumber;
|
|
monthNumber = previousMonth;
|
|
yearNumber = yearOfPreviousMonth;
|
|
} else {
|
|
dayNumber = dayNumber - days;
|
|
monthNumber = nextMonth;
|
|
yearNumber = yearOfNextMonth;
|
|
}
|
|
}
|
|
|
|
var dayConfig = {
|
|
day: dayNumber,
|
|
month: monthNumber,
|
|
year: yearNumber,
|
|
isSelected: isSelected,
|
|
isToday: isToday,
|
|
isDisabled: isDisabled,
|
|
isEmpty: isEmpty,
|
|
isStartRange: isStartRange,
|
|
isEndRange: isEndRange,
|
|
isInRange: isInRange,
|
|
showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths
|
|
};
|
|
|
|
row.push(renderDay(dayConfig));
|
|
|
|
if (++r === 7) {
|
|
if (opts.showWeekNumber) {
|
|
row.unshift(renderWeek(i - before, month, year));
|
|
}
|
|
data.push(renderRow(row, opts.isRTL));
|
|
row = [];
|
|
r = 0;
|
|
}
|
|
}
|
|
return renderTable(opts, data, randId);
|
|
},
|
|
|
|
isVisible: function()
|
|
{
|
|
return this._v;
|
|
},
|
|
|
|
show: function()
|
|
{
|
|
if (!this.isVisible()) {
|
|
removeClass(this.el, 'is-hidden');
|
|
this._v = true;
|
|
this.draw();
|
|
if (this._o.bound) {
|
|
addEvent(document, 'click', this._onClick);
|
|
this.adjustPosition();
|
|
}
|
|
if (typeof this._o.onOpen === 'function') {
|
|
this._o.onOpen.call(this);
|
|
}
|
|
}
|
|
},
|
|
|
|
hide: function()
|
|
{
|
|
var v = this._v;
|
|
if (v !== false) {
|
|
if (this._o.bound) {
|
|
removeEvent(document, 'click', this._onClick);
|
|
}
|
|
this.el.style.position = 'static'; // reset
|
|
this.el.style.left = 'auto';
|
|
this.el.style.top = 'auto';
|
|
addClass(this.el, 'is-hidden');
|
|
this._v = false;
|
|
if (v !== undefined && typeof this._o.onClose === 'function') {
|
|
this._o.onClose.call(this);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* GAME OVER
|
|
*/
|
|
destroy: function()
|
|
{
|
|
this.hide();
|
|
removeEvent(this.el, 'mousedown', this._onMouseDown, true);
|
|
removeEvent(this.el, 'touchend', this._onMouseDown, true);
|
|
removeEvent(this.el, 'change', this._onChange);
|
|
if (this._o.field) {
|
|
removeEvent(this._o.field, 'change', this._onInputChange);
|
|
if (this._o.bound) {
|
|
removeEvent(this._o.trigger, 'click', this._onInputClick);
|
|
removeEvent(this._o.trigger, 'focus', this._onInputFocus);
|
|
removeEvent(this._o.trigger, 'blur', this._onInputBlur);
|
|
}
|
|
}
|
|
if (this.el.parentNode) {
|
|
this.el.parentNode.removeChild(this.el);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
return Pikaday;
|
|
|
|
}));
|
|
|
|
|
|
/***/ }),
|
|
/* 420 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function(module) {
|
|
if(!module.webpackPolyfill) {
|
|
module.deprecate = function() {};
|
|
module.paths = [];
|
|
// module.parent = undefined by default
|
|
if(!module.children) module.children = [];
|
|
Object.defineProperty(module, "loaded", {
|
|
enumerable: true,
|
|
get: function() {
|
|
return module.l;
|
|
}
|
|
});
|
|
Object.defineProperty(module, "id", {
|
|
enumerable: true,
|
|
get: function() {
|
|
return module.i;
|
|
}
|
|
});
|
|
module.webpackPolyfill = 1;
|
|
}
|
|
return module;
|
|
};
|
|
|
|
|
|
/***/ })
|
|
/******/ ]);
|
|
});
|