123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- export function sleep(delay = 100) {
- return Promise.resolve({
- then: function(resolve) {
- setTimeout(resolve, delay);
- }
- });
- };
- export function hot() {
- return spec().$container.data('handsontable');
- };
- export function handsontable(options) {
- var 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 getTopClone() {
- return spec().$container.find('.ht_clone_top');
- };
- export function getTopLeftClone() {
- return spec().$container.find('.ht_clone_top_left_corner');
- };
- // for compatybility
- // var 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() {
- return !!(keyProxy().is(':visible') && keyProxy().parent().is(':visible') && !keyProxy().parent().is('.htHidden'));
- };
- export function isFillHandleVisible() {
- return !!spec().$container.find('.wtBorder.corner:visible').length;
- };
- export function getCorrespondingOverlay(cell, container) {
- var overlay = $(cell).parents('.handsontable');
- if (overlay[0] == container[0]) {
- return $('.ht_master');
- }
- return $(overlay[0]);
- };
- /**
- * Shows context menu
- */
- export function contextMenu(cell) {
- var hot = spec().$container.data('handsontable');
- var selected = hot.getSelected();
- if (!selected) {
- hot.selectCell(0, 0);
- selected = hot.getSelected();
- }
- if (!cell) {
- cell = getCell(selected[0], selected[1]);
- }
- var cellOffset = $(cell).offset();
- $(cell).simulate('contextmenu', {
- clientX: cellOffset.left - Handsontable.dom.getWindowScrollLeft(),
- clientY: cellOffset.top - Handsontable.dom.getWindowScrollTop(),
- });
- };
- export function closeContextMenu() {
- $(document).simulate('mousedown');
- // $(document).trigger('mousedown');
- };
- /**
- * Shows dropdown menu
- */
- export function dropdownMenu(columnIndex) {
- var hot = spec().$container.data('handsontable');
- var th = hot.view.wt.wtTable.getColumnHeader(columnIndex || 0);
- var button = th.querySelector('.changeType');
- if (button) {
- $(button).simulate('mousedown');
- $(button).simulate('click');
- }
- };
- export function closeDropdownMenu() {
- $(document).simulate('mousedown');
- };
- export function dropdownMenuRootElement() {
- var plugin = hot().getPlugin('dropdownMenu');
- var 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) {
- if (!(element instanceof jQuery)) {
- element = $(element);
- }
- var ev = $.Event(type);
- ev.which = button || 1; // left click by default
- element.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) {
- var ev = {}; // $.Event(type);
- if (typeof key === 'string') {
- if (key.indexOf('shift+') > -1) {
- key = key.substring(6);
- ev.shiftKey = true;
- }
- if (key.indexOf('ctrl+') > -1) {
- key = key.substring(5);
- ev.ctrlKey = true;
- ev.metaKey = true;
- }
- switch (key) {
- 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':
- 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;
- default:
- throw new Error(`Unrecognised key name: ${key}`);
- }
- } else if (typeof key === 'number') {
- ev.keyCode = key;
- }
- // 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.isImmediatePropagationEnabled == null) {
- 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) {
- var el = keyProxy()[0];
- if (el.setSelectionRange) {
- el.focus();
- el.setSelectionRange(pos, pos);
- } else if (el.createTextRange) {
- var 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').copyPaste.triggerPaste(null, str);
- };
- /**
- * Calls a method in current Handsontable instance, returns its output
- * @param method
- * @return {Function}
- */
- export function handsontableMethodFactory(method) {
- return function() {
- var instance;
- try {
- instance = spec().$container.handsontable('getInstance');
- } catch (err) {
- console.error(err);
- }
- 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](...arguments);
- };
- };
- export const addHook = handsontableMethodFactory('addHook');
- export const alter = handsontableMethodFactory('alter');
- export const colToProp = handsontableMethodFactory('colToProp');
- export const countCols = handsontableMethodFactory('countCols');
- export const countRows = handsontableMethodFactory('countRows');
- export const deselectCell = handsontableMethodFactory('deselectCell');
- export const destroy = handsontableMethodFactory('destroy');
- export const destroyEditor = handsontableMethodFactory('destroyEditor');
- 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 getRowHeader = handsontableMethodFactory('getRowHeader');
- export const getSelected = handsontableMethodFactory('getSelected');
- 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 selectCell = handsontableMethodFactory('selectCell');
- 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 countSourceRows = handsontableMethodFactory('countSourceRows');
- export const countSourceCols = handsontableMethodFactory('countSourceCols');
- export const countEmptyRows = handsontableMethodFactory('countEmptyRows');
- export const countEmptyCols = handsontableMethodFactory('countEmptyCols');
- /**
- * Returns column width for HOT container
- * @param $elem
- * @param col
- * @returns {Number}
- */
- export function colWidth($elem, col) {
- var TR = $elem[0].querySelector('TBODY TR');
- var 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) {
- var 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) {
- rowCount = typeof rowCount === 'number' ? rowCount : 100;
- colCount = typeof colCount === 'number' ? colCount : 4;
- var
- rows = [],
- i,
- j;
- for (i = 0; i < rowCount; i++) {
- var row = [];
- for (j = 0; j < colCount; 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) {
- var obj = {};
- var _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) {
- var $container = spec().$container;
- var $th = $container.find(`thead tr:eq(0) th:eq(${displayedColumnIndex})`);
- $th.simulate('mouseover');
- var $resizer = $container.find('.manualColumnResizer');
- var resizerPosition = $resizer.position();
- $resizer.simulate('mousedown', {
- clientX: resizerPosition.left,
- });
- var delta = width - $th.width() - 2;
- var newPosition = resizerPosition.left + delta;
- $resizer.simulate('mousemove', {
- clientX: newPosition
- });
- $resizer.simulate('mouseup');
- }
- export function resizeRow(displayedRowIndex, height) {
- var $container = spec().$container;
- var $th = $container.find(`tbody tr:eq(${displayedRowIndex}) th:eq(0)`);
- $th.simulate('mouseover');
- var $resizer = $container.find('.manualRowResizer');
- var resizerPosition = $resizer.position();
- $resizer.simulate('mousedown', {
- clientY: resizerPosition.top
- });
- var 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) {
- var
- $mainContainer = container.parents('.handsontable').not('[class*=clone]').not('[class*=master]').first(),
- $rowHeaders = container.find('tbody tr th'),
- $firstRowHeader = $rowHeaders.eq(secondDisplayedRowIndex - 1),
- $secondRowHeader = $rowHeaders.eq(secondDisplayedRowIndex);
- $secondRowHeader.simulate('mouseover');
- var $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) {
- var
- $mainContainer = container.parents('.handsontable').not('[class*=clone]').not('[class*=master]').first(),
- $rowHeaders = container.find('tbody tr th'),
- $firstRowHeader = $rowHeaders.eq(firstDisplayedRowIndex),
- $secondRowHeader = $rowHeaders.eq(firstDisplayedRowIndex + 1);
- $secondRowHeader.simulate('mouseover');
- var $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) {
- var $mainContainer = container.parents('.handsontable').not('[class*=clone]').not('[class*=master]').first();
- var $colHeaders = container.find('thead tr:eq(0) th');
- var $to = $colHeaders.eq(to);
- var $from = $colHeaders.eq(from);
- // Enter the second column header
- $from.simulate('mouseover');
- var $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) {
- var e = document.createEvent('TouchEvent');
- var targetCoords = target.getBoundingClientRect();
- var touches;
- var targetTouches;
- var changedTouches;
- if (!pageX && !pageY) {
- pageX = parseInt(targetCoords.left + 3, 10);
- pageY = parseInt(targetCoords.top + 3, 10);
- }
- var touch = document.createTouch(window, target, 0, pageX, pageY, pageX, pageY);
- 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);
- };
|