dc662b00f8b6024ddcf37ada33f878aa871c6d5c3c4001d59e6071d4130706becd7aa18662bea6a9b5d58cfa77cbf65b0de8c88879f8e7b93cdd022d54ccc4 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import {
  2. closestDown,
  3. hasClass,
  4. isChildOf,
  5. getParent,
  6. } from './../../../helpers/dom/element';
  7. import {partial} from './../../../helpers/function';
  8. import {isMobileBrowser} from './../../../helpers/browser';
  9. import EventManager from './../../../eventManager';
  10. /**
  11. *
  12. */
  13. function Event(instance) {
  14. const that = this;
  15. const eventManager = new EventManager(instance);
  16. this.instance = instance;
  17. var dblClickOrigin = [null, null];
  18. this.dblClickTimeout = [null, null];
  19. var onMouseDown = function(event) {
  20. const activeElement = document.activeElement;
  21. const getParentNode = partial(getParent, event.realTarget);
  22. const realTarget = event.realTarget;
  23. // ignore focusable element from mouse down processing (https://github.com/handsontable/handsontable/issues/3555)
  24. if (realTarget === activeElement ||
  25. getParentNode(0) === activeElement ||
  26. getParentNode(1) === activeElement) {
  27. return;
  28. }
  29. var cell = that.parentCell(realTarget);
  30. if (hasClass(realTarget, 'corner')) {
  31. that.instance.getSetting('onCellCornerMouseDown', event, realTarget);
  32. } else if (cell.TD) {
  33. if (that.instance.hasSetting('onCellMouseDown')) {
  34. that.instance.getSetting('onCellMouseDown', event, cell.coords, cell.TD, that.instance);
  35. }
  36. }
  37. if (event.button !== 2) { // if not right mouse button
  38. if (cell.TD) {
  39. dblClickOrigin[0] = cell.TD;
  40. clearTimeout(that.dblClickTimeout[0]);
  41. that.dblClickTimeout[0] = setTimeout(() => {
  42. dblClickOrigin[0] = null;
  43. }, 1000);
  44. }
  45. }
  46. };
  47. var onTouchMove = function(event) {
  48. that.instance.touchMoving = true;
  49. };
  50. var longTouchTimeout;
  51. var onTouchStart = function(event) {
  52. var container = this;
  53. eventManager.addEventListener(this, 'touchmove', onTouchMove);
  54. // Prevent cell selection when scrolling with touch event - not the best solution performance-wise
  55. that.checkIfTouchMove = setTimeout(() => {
  56. if (that.instance.touchMoving === true) {
  57. that.instance.touchMoving = void 0;
  58. eventManager.removeEventListener('touchmove', onTouchMove, false);
  59. }
  60. onMouseDown(event);
  61. }, 30);
  62. };
  63. var onMouseOver = function(event) {
  64. var table,
  65. td,
  66. mainWOT;
  67. if (that.instance.hasSetting('onCellMouseOver')) {
  68. table = that.instance.wtTable.TABLE;
  69. td = closestDown(event.realTarget, ['TD', 'TH'], table);
  70. mainWOT = that.instance.cloneSource || that.instance;
  71. if (td && td !== mainWOT.lastMouseOver && isChildOf(td, table)) {
  72. mainWOT.lastMouseOver = td;
  73. that.instance.getSetting('onCellMouseOver', event, that.instance.wtTable.getCoords(td), td, that.instance);
  74. }
  75. }
  76. };
  77. var onMouseOut = function(event) {
  78. let table;
  79. let lastTD;
  80. let nextTD;
  81. if (that.instance.hasSetting('onCellMouseOut')) {
  82. table = that.instance.wtTable.TABLE;
  83. lastTD = closestDown(event.realTarget, ['TD', 'TH'], table);
  84. nextTD = closestDown(event.relatedTarget, ['TD', 'TH'], table);
  85. if (lastTD && lastTD !== nextTD && isChildOf(lastTD, table)) {
  86. that.instance.getSetting('onCellMouseOut', event, that.instance.wtTable.getCoords(lastTD), lastTD, that.instance);
  87. }
  88. }
  89. };
  90. var onMouseUp = function(event) {
  91. if (event.button !== 2) { // if not right mouse button
  92. var cell = that.parentCell(event.realTarget);
  93. if (cell.TD === dblClickOrigin[0] && cell.TD === dblClickOrigin[1]) {
  94. if (hasClass(event.realTarget, 'corner')) {
  95. that.instance.getSetting('onCellCornerDblClick', event, cell.coords, cell.TD, that.instance);
  96. } else {
  97. that.instance.getSetting('onCellDblClick', event, cell.coords, cell.TD, that.instance);
  98. }
  99. dblClickOrigin[0] = null;
  100. dblClickOrigin[1] = null;
  101. } else if (cell.TD === dblClickOrigin[0]) {
  102. that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance);
  103. dblClickOrigin[1] = cell.TD;
  104. clearTimeout(that.dblClickTimeout[1]);
  105. that.dblClickTimeout[1] = setTimeout(() => {
  106. dblClickOrigin[1] = null;
  107. }, 500);
  108. } else if (cell.TD && that.instance.hasSetting('onCellMouseUp')) {
  109. that.instance.getSetting('onCellMouseUp', event, cell.coords, cell.TD, that.instance);
  110. }
  111. }
  112. };
  113. var onTouchEnd = function(event) {
  114. clearTimeout(longTouchTimeout);
  115. // that.instance.longTouch == void 0;
  116. event.preventDefault();
  117. onMouseUp(event);
  118. // eventManager.removeEventListener(that.instance.wtTable.holder, "mouseup", onMouseUp);
  119. };
  120. eventManager.addEventListener(this.instance.wtTable.holder, 'mousedown', onMouseDown);
  121. eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseover', onMouseOver);
  122. eventManager.addEventListener(this.instance.wtTable.TABLE, 'mouseout', onMouseOut);
  123. eventManager.addEventListener(this.instance.wtTable.holder, 'mouseup', onMouseUp);
  124. // check if full HOT instance, or detached WOT AND run on mobile device
  125. if (this.instance.wtTable.holder.parentNode.parentNode && isMobileBrowser() && !that.instance.wtTable.isWorkingOnClone()) {
  126. var classSelector = `.${this.instance.wtTable.holder.parentNode.className.split(' ').join('.')}`;
  127. eventManager.addEventListener(this.instance.wtTable.holder, 'touchstart', (event) => {
  128. that.instance.touchApplied = true;
  129. if (isChildOf(event.target, classSelector)) {
  130. onTouchStart.call(event.target, event);
  131. }
  132. });
  133. eventManager.addEventListener(this.instance.wtTable.holder, 'touchend', (event) => {
  134. that.instance.touchApplied = false;
  135. if (isChildOf(event.target, classSelector)) {
  136. onTouchEnd.call(event.target, event);
  137. }
  138. });
  139. if (!that.instance.momentumScrolling) {
  140. that.instance.momentumScrolling = {};
  141. }
  142. eventManager.addEventListener(this.instance.wtTable.holder, 'scroll', (event) => {
  143. clearTimeout(that.instance.momentumScrolling._timeout);
  144. if (!that.instance.momentumScrolling.ongoing) {
  145. that.instance.getSetting('onBeforeTouchScroll');
  146. }
  147. that.instance.momentumScrolling.ongoing = true;
  148. that.instance.momentumScrolling._timeout = setTimeout(() => {
  149. if (!that.instance.touchApplied) {
  150. that.instance.momentumScrolling.ongoing = false;
  151. that.instance.getSetting('onAfterMomentumScroll');
  152. }
  153. }, 200);
  154. });
  155. }
  156. eventManager.addEventListener(window, 'resize', () => {
  157. if (that.instance.getSetting('stretchH') !== 'none') {
  158. that.instance.draw();
  159. }
  160. });
  161. this.destroy = function() {
  162. clearTimeout(this.dblClickTimeout[0]);
  163. clearTimeout(this.dblClickTimeout[1]);
  164. eventManager.destroy();
  165. };
  166. }
  167. Event.prototype.parentCell = function(elem) {
  168. var cell = {};
  169. var TABLE = this.instance.wtTable.TABLE;
  170. var TD = closestDown(elem, ['TD', 'TH'], TABLE);
  171. if (TD) {
  172. cell.coords = this.instance.wtTable.getCoords(TD);
  173. cell.TD = TD;
  174. } else if (hasClass(elem, 'wtBorder') && hasClass(elem, 'current')) {
  175. cell.coords = this.instance.selections.current.cellRange.highlight; // selections.current is current selected cell
  176. cell.TD = this.instance.wtTable.getCell(cell.coords);
  177. } else if (hasClass(elem, 'wtBorder') && hasClass(elem, 'area')) {
  178. if (this.instance.selections.area.cellRange) {
  179. cell.coords = this.instance.selections.area.cellRange.to; // selections.area is area selected cells
  180. cell.TD = this.instance.wtTable.getCell(cell.coords);
  181. }
  182. }
  183. return cell;
  184. };
  185. export default Event;