| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776 |
- export function sleep(delay = 100) {
- return Promise.resolve({
- then(resolve) {
- setTimeout(resolve, delay);
- }
- });
- }
- export function promisfy(fn) {
- return new Promise((resolve, reject) => fn(resolve, reject));
- }
- /**
- * Calls a method in current Handsontable instance, returns its output
- * @param method
- * @return {Function}
- */
- export function handsontableMethodFactory(method) {
- return function(...args) {
- let instance;
- try {
- instance = spec().$container.handsontable('getInstance');
- } catch (err) {
- /* eslint-disable */
- console.error(err);
- /* eslint-enable */
- }
- if (instance) {
- if (method === 'destroy') {
- spec().$container.removeData();
- }
- } else {
- if (method === 'destroy') {
- return; // we can forgive this... maybe it was destroyed in the test
- }
- throw new Error('Something wrong with the test spec: Handsontable instance not found');
- }
- return instance[method](...args);
- };
- }
- export const addHook = handsontableMethodFactory('addHook');
- export const alter = handsontableMethodFactory('alter');
- export const colToProp = handsontableMethodFactory('colToProp');
- export const countCols = handsontableMethodFactory('countCols');
- export const countEmptyCols = handsontableMethodFactory('countEmptyCols');
- export const countEmptyRows = handsontableMethodFactory('countEmptyRows');
- export const countRows = handsontableMethodFactory('countRows');
- export const countSourceCols = handsontableMethodFactory('countSourceCols');
- export const countSourceRows = handsontableMethodFactory('countSourceRows');
- export const deselectCell = handsontableMethodFactory('deselectCell');
- export const destroy = handsontableMethodFactory('destroy');
- export const destroyEditor = handsontableMethodFactory('destroyEditor');
- export const emptySelectedCells = handsontableMethodFactory('emptySelectedCells');
- export const getActiveEditor = handsontableMethodFactory('getActiveEditor');
- export const getCell = handsontableMethodFactory('getCell');
- export const getCellEditor = handsontableMethodFactory('getCellEditor');
- export const getCellMeta = handsontableMethodFactory('getCellMeta');
- export const getCellMetaAtRow = handsontableMethodFactory('getCellMetaAtRow');
- export const getCellRenderer = handsontableMethodFactory('getCellRenderer');
- export const getCellsMeta = handsontableMethodFactory('getCellsMeta');
- export const getCellValidator = handsontableMethodFactory('getCellValidator');
- export const getColHeader = handsontableMethodFactory('getColHeader');
- export const getCopyableData = handsontableMethodFactory('getCopyableData');
- export const getCopyableText = handsontableMethodFactory('getCopyableText');
- export const getData = handsontableMethodFactory('getData');
- export const getDataAtCell = handsontableMethodFactory('getDataAtCell');
- export const getDataAtCol = handsontableMethodFactory('getDataAtCol');
- export const getDataAtRow = handsontableMethodFactory('getDataAtRow');
- export const getDataAtRowProp = handsontableMethodFactory('getDataAtRowProp');
- export const getDataType = handsontableMethodFactory('getDataType');
- export const getInstance = handsontableMethodFactory('getInstance');
- export const getPlugin = handsontableMethodFactory('getPlugin');
- export const getRowHeader = handsontableMethodFactory('getRowHeader');
- export const getSelected = handsontableMethodFactory('getSelected');
- export const getSelectedLast = handsontableMethodFactory('getSelectedLast');
- export const getSelectedRange = handsontableMethodFactory('getSelectedRange');
- export const getSelectedRangeLast = handsontableMethodFactory('getSelectedRangeLast');
- export const getSourceData = handsontableMethodFactory('getSourceData');
- export const getSourceDataArray = handsontableMethodFactory('getSourceDataArray');
- export const getSourceDataAtCell = handsontableMethodFactory('getSourceDataAtCell');
- export const getSourceDataAtCol = handsontableMethodFactory('getSourceDataAtCol');
- export const getSourceDataAtRow = handsontableMethodFactory('getSourceDataAtRow');
- export const getValue = handsontableMethodFactory('getValue');
- export const loadData = handsontableMethodFactory('loadData');
- export const populateFromArray = handsontableMethodFactory('populateFromArray');
- export const propToCol = handsontableMethodFactory('propToCol');
- export const removeCellMeta = handsontableMethodFactory('removeCellMeta');
- export const render = handsontableMethodFactory('render');
- export const selectAll = handsontableMethodFactory('selectAll');
- export const selectCell = handsontableMethodFactory('selectCell');
- export const selectCells = handsontableMethodFactory('selectCells');
- export const selectColumns = handsontableMethodFactory('selectColumns');
- export const selectRows = handsontableMethodFactory('selectRows');
- export const setCellMeta = handsontableMethodFactory('setCellMeta');
- export const setDataAtCell = handsontableMethodFactory('setDataAtCell');
- export const setDataAtRowProp = handsontableMethodFactory('setDataAtRowProp');
- export const spliceCellsMeta = handsontableMethodFactory('spliceCellsMeta');
- export const spliceCol = handsontableMethodFactory('spliceCol');
- export const spliceRow = handsontableMethodFactory('spliceRow');
- export const updateSettings = handsontableMethodFactory('updateSettings');
- export const undo = handsontableMethodFactory('undo');
- const specContext = {};
- beforeEach(function() {
- specContext.spec = this;
- });
- afterEach(() => {
- specContext.spec = null;
- });
- export function spec() {
- return specContext.spec;
- }
- export function hot() {
- return spec().$container.data('handsontable');
- }
- export function handsontable(options) {
- const currentSpec = spec();
- currentSpec.$container.handsontable(options);
- currentSpec.$container[0].focus(); // otherwise TextEditor tests do not pass in IE8
- return currentSpec.$container.data('handsontable');
- }
- /**
- * As for v. 0.11 the only scrolling method is native scroll, which creates copies of main htCore table inside of the container.
- * Therefore, simple $(".htCore") will return more than one object. Most of the time, you're interested in the original
- * htCore, not the copies made by native scroll.
- *
- * This method returns the original htCore object
- *
- * @returns {jqObject} reference to the original htCore
- */
- export function getHtCore() {
- return spec().$container.find('.htCore').first();
- }
- export function getMaster() {
- return spec().$container.find('.ht_master');
- }
- export function getTopClone() {
- return spec().$container.find('.ht_clone_top');
- }
- export function getTopLeftClone() {
- return spec().$container.find('.ht_clone_top_left_corner');
- }
- // for compatybility
- // const getCornerClone = getTopLeftClone;
- export function getLeftClone() {
- return spec().$container.find('.ht_clone_left');
- }
- export function getBottomClone() {
- return spec().$container.find('.ht_clone_bottom');
- }
- export function getBottomLeftClone() {
- return spec().$container.find('.ht_clone_bottom_left_corner');
- }
- // Rename me to countTD
- export function countCells() {
- return getHtCore().find('tbody td').length;
- }
- export function isEditorVisible(editableElement) {
- if (editableElement && !(editableElement.hasClass('handsontableInput') || editableElement.hasClass('handsontableEditor'))) {
- throw new Error('Editable element of the editor was not found.');
- }
- const keyProxyHolder = (editableElement || keyProxy()).parent();
- if (keyProxyHolder.size() === 0) {
- return false;
- }
- const css = cssProp => keyProxyHolder.css(cssProp);
- return css('z-index') !== '-1' && css('top') !== '-9999px' && css('left') !== '-9999px';
- }
- export function isFillHandleVisible() {
- return !!spec().$container.find('.wtBorder.corner:visible').length;
- }
- export function getCorrespondingOverlay(cell, container) {
- const overlay = $(cell).parents('.handsontable');
- if (overlay[0] === container[0]) {
- return $('.ht_master');
- }
- return $(overlay[0]);
- }
- /**
- * Shows context menu
- */
- export function contextMenu(cell) {
- const hotInstance = spec().$container.data('handsontable');
- let clickedCell = cell;
- let selected = hotInstance.getSelectedLast();
- if (!selected) {
- hotInstance.selectCell(0, 0);
- selected = hotInstance.getSelectedLast();
- }
- if (!clickedCell) {
- clickedCell = getCell(selected[0], selected[1]);
- }
- const cellOffset = $(clickedCell).offset();
- $(clickedCell).simulate('mousedown', { button: 2 });
- $(clickedCell).simulate('contextmenu', {
- clientX: cellOffset.left - Handsontable.dom.getWindowScrollLeft(),
- clientY: cellOffset.top - Handsontable.dom.getWindowScrollTop(),
- });
- // Chrome doesn't call `mouseup`.
- // $(cell).simulate('mouseup', { button: 2 });
- }
- export function closeContextMenu() {
- $(document).simulate('mousedown');
- // $(document).trigger('mousedown');
- }
- /**
- * Shows dropdown menu
- */
- export function dropdownMenu(columnIndex) {
- const hotInstance = spec().$container.data('handsontable');
- const th = hotInstance.view.wt.wtTable.getColumnHeader(columnIndex || 0);
- const button = th.querySelector('.changeType');
- if (button) {
- $(button).simulate('mousedown');
- $(button).simulate('click');
- }
- }
- export function closeDropdownMenu() {
- $(document).simulate('mousedown');
- }
- export function dropdownMenuRootElement() {
- const plugin = hot().getPlugin('dropdownMenu');
- let root;
- if (plugin && plugin.menu) {
- root = plugin.menu.container;
- }
- return root;
- }
- /**
- * Returns a function that triggers a mouse event
- * @param {String} type Event type
- * @return {Function}
- */
- export function handsontableMouseTriggerFactory(type, button) {
- return function(element) {
- let handsontableElement = element;
- if (!(handsontableElement instanceof jQuery)) {
- handsontableElement = $(handsontableElement);
- }
- const ev = $.Event(type);
- ev.which = button || 1; // left click by default
- handsontableElement.simulate(type, ev);
- };
- }
- export const mouseDown = handsontableMouseTriggerFactory('mousedown');
- export const mouseMove = handsontableMouseTriggerFactory('mousemove');
- export const mouseOver = handsontableMouseTriggerFactory('mouseover');
- export const mouseUp = handsontableMouseTriggerFactory('mouseup');
- export function mouseDoubleClick(element) {
- mouseDown(element);
- mouseUp(element);
- mouseDown(element);
- mouseUp(element);
- }
- export const mouseRightDown = handsontableMouseTriggerFactory('mousedown', 3);
- export const mouseRightUp = handsontableMouseTriggerFactory('mouseup', 3);
- /**
- * Returns a function that triggers a key event
- * @param {String} type Event type
- * @return {Function}
- */
- export function handsontableKeyTriggerFactory(type) {
- return function(key, extend) {
- const ev = {}; // $.Event(type);
- let keyToTrigger = key;
- if (typeof keyToTrigger === 'string') {
- if (keyToTrigger.indexOf('shift+') > -1) {
- keyToTrigger = keyToTrigger.substring(6);
- ev.shiftKey = true;
- }
- if (keyToTrigger.indexOf('ctrl+') > -1) {
- keyToTrigger = keyToTrigger.substring(5);
- ev.ctrlKey = true;
- ev.metaKey = true;
- }
- switch (keyToTrigger) {
- case 'tab':
- ev.keyCode = 9;
- break;
- case 'enter':
- ev.keyCode = 13;
- break;
- case 'esc':
- ev.keyCode = 27;
- break;
- case 'f2':
- ev.keyCode = 113;
- break;
- case 'arrow_left':
- ev.keyCode = 37;
- break;
- case 'arrow_up':
- ev.keyCode = 38;
- break;
- case 'arrow_right':
- ev.keyCode = 39;
- break;
- case 'arrow_down':
- ev.keyCode = 40;
- break;
- case 'ctrl':
- if (window.navigator.platform.includes('Mac')) {
- ev.keyCode = 91;
- } else {
- ev.keyCode = 17;
- }
- break;
- case 'shift':
- ev.keyCode = 16;
- break;
- case 'backspace':
- ev.keyCode = 8;
- break;
- case 'delete':
- ev.keyCode = 46;
- break;
- case 'space':
- ev.keyCode = 32;
- break;
- case 'x':
- ev.keyCode = 88;
- break;
- case 'c':
- ev.keyCode = 67;
- break;
- case 'v':
- ev.keyCode = 86;
- break;
- case 'a':
- ev.keyCode = 65;
- break;
- default:
- throw new Error(`Unrecognised key name: ${keyToTrigger}`);
- }
- } else if (typeof keyToTrigger === 'number') {
- ev.keyCode = keyToTrigger;
- }
- // ev.originalEvent = {}; //needed as long Handsontable searches for event.originalEvent
- $.extend(ev, extend);
- $(document.activeElement).simulate(type, ev);
- };
- }
- export const keyDown = handsontableKeyTriggerFactory('keydown');
- export const keyUp = handsontableKeyTriggerFactory('keyup');
- /**
- * Presses keyDown, then keyUp
- */
- export function keyDownUp(key, extend) {
- if (typeof key === 'string' && key.indexOf('shift+') > -1) {
- keyDown('shift');
- }
- keyDown(key, extend);
- keyUp(key, extend);
- if (typeof key === 'string' && key.indexOf('shift+') > -1) {
- keyUp('shift');
- }
- }
- /**
- * Returns current value of the keyboard proxy textarea
- * @return {String}
- */
- export function keyProxy() {
- return spec().$container.find('textarea.handsontableInput');
- }
- export function serveImmediatePropagation(event) {
- if ((event !== null || event !== void 0)
- && (event.isImmediatePropagationEnabled === null || event.isImmediatePropagationEnabled === void 0)) {
- event.stopImmediatePropagation = function() {
- this.isImmediatePropagationEnabled = false;
- this.cancelBubble = true;
- };
- event.isImmediatePropagationEnabled = true;
- event.isImmediatePropagationStopped = function() {
- return !this.isImmediatePropagationEnabled;
- };
- }
- return event;
- }
- export function autocompleteEditor() {
- return spec().$container.find('.handsontableInput');
- }
- /**
- * Sets text cursor inside keyboard proxy
- */
- export function setCaretPosition(pos) {
- const el = keyProxy()[0];
- if (el.setSelectionRange) {
- el.focus();
- el.setSelectionRange(pos, pos);
- } else if (el.createTextRange) {
- const range = el.createTextRange();
- range.collapse(true);
- range.moveEnd('character', pos);
- range.moveStart('character', pos);
- range.select();
- }
- }
- /**
- * Returns autocomplete instance
- */
- export function autocomplete() {
- return spec().$container.find('.autocompleteEditor');
- }
- /**
- * Triggers paste string on current selection
- */
- export function triggerPaste(str) {
- spec().$container.data('handsontable').getPlugin('CopyPaste').paste(str);
- }
- /**
- * Returns column width for HOT container
- * @param $elem
- * @param col
- * @returns {Number}
- */
- export function colWidth($elem, col) {
- const TR = $elem[0].querySelector('TBODY TR');
- let cell;
- if (TR) {
- cell = TR.querySelectorAll('TD')[col];
- } else {
- cell = $elem[0].querySelector('THEAD TR').querySelectorAll('TH')[col];
- }
- if (!cell) {
- throw new Error(`Cannot find table column of index '${col}'`);
- }
- return cell.offsetWidth;
- }
- /**
- * Returns row height for HOT container
- * @param $elem
- * @param row
- * @returns {Number}
- */
- export function rowHeight($elem, row) {
- let TD;
- if (row >= 0) {
- TD = $elem[0].querySelector(`tbody tr:nth-child(${row + 1}) td`);
- } else {
- TD = $elem[0].querySelector(`thead tr:nth-child(${Math.abs(row)})`);
- }
- if (!TD) {
- throw new Error(`Cannot find table row of index '${row}'`);
- }
- return Handsontable.dom.outerHeight(TD);
- }
- /**
- * Returns value that has been rendered in table cell
- * @param {Number} trIndex
- * @param {Number} tdIndex
- * @returns {String}
- */
- export function getRenderedValue(trIndex, tdIndex) {
- return spec().$container.find('tbody tr').eq(trIndex).find('td').eq(tdIndex).html();
- }
- /**
- * Returns nodes that have been rendered in table cell
- * @param {Number} trIndex
- * @param {Number} tdIndex
- * @returns {String}
- */
- export function getRenderedContent(trIndex, tdIndex) {
- return spec().$container.find('tbody tr').eq(trIndex).find('td').eq(tdIndex).children();
- }
- /**
- * Create numerical data values for the table
- * @param rowCount
- * @param colCount
- * @returns {Array}
- */
- export function createNumericData(rowCount, colCount) {
- const rowsMax = typeof rowCount === 'number' ? rowCount : 100;
- const columnsMax = typeof colCount === 'number' ? colCount : 4;
- const rows = [];
- let i;
- let j;
- for (i = 0; i < rowsMax; i++) {
- const row = [];
- for (j = 0; j < columnsMax; j++) {
- row.push((i + 1));
- }
- rows.push(row);
- }
- return rows;
- }
- /**
- * Model factory, which creates object with private properties, accessible by setters and getters.
- * Created for the purpose of testing HOT with Backbone-like Models
- * @param opts
- * @returns {{}}
- * @constructor
- */
- export function Model(opts) {
- const obj = {};
- const _data = $.extend({
- id: undefined,
- name: undefined,
- address: undefined
- }, opts);
- obj.attr = function(name, value) {
- if (typeof value === 'undefined') {
- return this.get(name);
- }
- return this.set(name, value);
- };
- obj.get = function(name) {
- return _data[name];
- };
- obj.set = function(name, value) {
- _data[name] = value;
- return this;
- };
- return obj;
- }
- /**
- * Factory which produces an accessor for objects of type "Model" (see above).
- * This function should be used to create accessor for a given property name and pass it as `data` option in column
- * configuration.
- *
- * @param name - name of the property for which an accessor function will be created
- * @returns {Function}
- */
- export function createAccessorForProperty(name) {
- return function(obj, value) {
- return obj.attr(name, value);
- };
- }
- export function resizeColumn(displayedColumnIndex, width) {
- const $container = spec().$container;
- const $th = $container.find(`thead tr:eq(0) th:eq(${displayedColumnIndex})`);
- $th.simulate('mouseover');
- const $resizer = $container.find('.manualColumnResizer');
- const resizerPosition = $resizer.position();
- $resizer.simulate('mousedown', {
- clientX: resizerPosition.left,
- });
- const delta = width - $th.width() - 2;
- const newPosition = resizerPosition.left + delta;
- $resizer.simulate('mousemove', {
- clientX: newPosition
- });
- $resizer.simulate('mouseup');
- }
- export function resizeRow(displayedRowIndex, height) {
- const $container = spec().$container;
- const $th = $container.find(`tbody tr:eq(${displayedRowIndex}) th:eq(0)`);
- $th.simulate('mouseover');
- const $resizer = $container.find('.manualRowResizer');
- const resizerPosition = $resizer.position();
- $resizer.simulate('mousedown', {
- clientY: resizerPosition.top
- });
- let delta = height - $th.height() - 2;
- if (delta < 0) {
- delta = 0;
- }
- $resizer.simulate('mousemove', {
- clientY: resizerPosition.top + delta
- });
- $resizer.simulate('mouseup');
- }
- export function moveSecondDisplayedRowBeforeFirstRow(container, secondDisplayedRowIndex) {
- const $mainContainer = container.parents('.handsontable').not('[class*=clone]').not('[class*=master]').first();
- const $rowHeaders = container.find('tbody tr th');
- const $firstRowHeader = $rowHeaders.eq(secondDisplayedRowIndex - 1);
- const $secondRowHeader = $rowHeaders.eq(secondDisplayedRowIndex);
- $secondRowHeader.simulate('mouseover');
- const $manualRowMover = $mainContainer.find('.manualRowMover');
- if ($manualRowMover.length) {
- $manualRowMover.simulate('mousedown', {
- clientY: $manualRowMover[0].getBoundingClientRect().top
- });
- $manualRowMover.simulate('mousemove', {
- clientY: $manualRowMover[0].getBoundingClientRect().top - 20
- });
- $firstRowHeader.simulate('mouseover');
- $secondRowHeader.simulate('mouseup');
- }
- }
- export function moveFirstDisplayedRowAfterSecondRow(container, firstDisplayedRowIndex) {
- const $mainContainer = container.parents('.handsontable').not('[class*=clone]').not('[class*=master]').first();
- const $rowHeaders = container.find('tbody tr th');
- const $firstRowHeader = $rowHeaders.eq(firstDisplayedRowIndex);
- const $secondRowHeader = $rowHeaders.eq(firstDisplayedRowIndex + 1);
- $secondRowHeader.simulate('mouseover');
- const $manualRowMover = $mainContainer.find('.manualRowMover');
- if ($manualRowMover.length) {
- $manualRowMover.simulate('mousedown', {
- clientY: $manualRowMover[0].getBoundingClientRect().top
- });
- $manualRowMover.simulate('mousemove', {
- clientY: $manualRowMover[0].getBoundingClientRect().top + 20
- });
- $firstRowHeader.simulate('mouseover');
- $secondRowHeader.simulate('mouseup');
- }
- }
- export function swapDisplayedColumns(container, from, to) {
- const $mainContainer = container.parents('.handsontable').not('[class*=clone]').not('[class*=master]').first();
- const $colHeaders = container.find('thead tr:eq(0) th');
- const $to = $colHeaders.eq(to);
- const $from = $colHeaders.eq(from);
- // Enter the second column header
- $from.simulate('mouseover');
- const $manualColumnMover = $mainContainer.find('.manualColumnMover');
- // Grab the second column
- $manualColumnMover.simulate('mousedown', {
- pageX: $manualColumnMover[0].getBoundingClientRect().left,
- });
- // Drag the second column over the first column
- $manualColumnMover.simulate('mousemove', {
- pageX: $manualColumnMover[0].getBoundingClientRect().left - 20,
- });
- $to.simulate('mouseover');
- // Drop the second column
- $from.simulate('mouseup');
- }
- export function triggerTouchEvent(type, target, pageX, pageY) {
- const e = document.createEvent('TouchEvent');
- const targetCoords = target.getBoundingClientRect();
- const targetPageX = pageX || parseInt(targetCoords.left + 3, 10);
- const targetPageY = pageY || parseInt(targetCoords.top + 3, 10);
- let touches;
- let targetTouches;
- let changedTouches;
- const touch = document.createTouch(window, target, 0, targetPageX, targetPageY, targetPageX, targetPageY);
- if (type === 'touchend') {
- touches = document.createTouchList();
- targetTouches = document.createTouchList();
- changedTouches = document.createTouchList(touch);
- } else {
- touches = document.createTouchList(touch);
- targetTouches = document.createTouchList(touch);
- changedTouches = document.createTouchList(touch);
- }
- e.initTouchEvent(type, true, true, window, null, 0, 0, 0, 0, false, false, false, false, touches, targetTouches, changedTouches, 1, 0);
- target.dispatchEvent(e);
- }
- export function createSpreadsheetData(...args) {
- return Handsontable.helper.createSpreadsheetData(...args);
- }
|