multipleSelectionHandles.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. 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; }; }();
  2. 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); } };
  3. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4. 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; }
  5. 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; }
  6. import Hooks from './../../pluginHooks';
  7. import { getWindowScrollTop, hasClass, getWindowScrollLeft } from './../../helpers/dom/element';
  8. import { isMobileBrowser } from './../../helpers/browser';
  9. import BasePlugin from './../_base';
  10. import EventManager from './../../eventManager';
  11. import { registerPlugin } from './../../plugins';
  12. import { CellCoords } from './../../3rdparty/walkontable/src';
  13. /**
  14. * @private
  15. * @plugin MultipleSelectionHandles
  16. */
  17. var MultipleSelectionHandles = function (_BasePlugin) {
  18. _inherits(MultipleSelectionHandles, _BasePlugin);
  19. /**
  20. * @param {Object} hotInstance
  21. */
  22. function MultipleSelectionHandles(hotInstance) {
  23. _classCallCheck(this, MultipleSelectionHandles);
  24. /**
  25. * @type {Array}
  26. */
  27. var _this2 = _possibleConstructorReturn(this, (MultipleSelectionHandles.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles)).call(this, hotInstance));
  28. _this2.dragged = [];
  29. /**
  30. * Instance of EventManager.
  31. *
  32. * @type {EventManager}
  33. */
  34. _this2.eventManager = null;
  35. /**
  36. * @type {null}
  37. */
  38. _this2.lastSetCell = null;
  39. return _this2;
  40. }
  41. /**
  42. * Check if the plugin is enabled in the handsontable settings.
  43. *
  44. * @returns {Boolean}
  45. */
  46. _createClass(MultipleSelectionHandles, [{
  47. key: 'isEnabled',
  48. value: function isEnabled() {
  49. return isMobileBrowser();
  50. }
  51. /**
  52. * Enable plugin for this Handsontable instance.
  53. */
  54. }, {
  55. key: 'enablePlugin',
  56. value: function enablePlugin() {
  57. if (this.enabled) {
  58. return;
  59. }
  60. if (!this.eventManager) {
  61. this.eventManager = new EventManager(this);
  62. }
  63. this.registerListeners();
  64. _get(MultipleSelectionHandles.prototype.__proto__ || Object.getPrototypeOf(MultipleSelectionHandles.prototype), 'enablePlugin', this).call(this);
  65. }
  66. /**
  67. * Bind the touch events
  68. * @private
  69. */
  70. }, {
  71. key: 'registerListeners',
  72. value: function registerListeners() {
  73. var _this = this;
  74. function removeFromDragged(query) {
  75. if (_this.dragged.length === 1) {
  76. // clear array
  77. _this.dragged.splice(0, _this.dragged.length);
  78. return true;
  79. }
  80. var entryPosition = _this.dragged.indexOf(query);
  81. if (entryPosition == -1) {
  82. return false;
  83. } else if (entryPosition === 0) {
  84. _this.dragged = _this.dragged.slice(0, 1);
  85. } else if (entryPosition == 1) {
  86. _this.dragged = _this.dragged.slice(-1);
  87. }
  88. }
  89. this.eventManager.addEventListener(this.hot.rootElement, 'touchstart', function (event) {
  90. var selectedRange = void 0;
  91. if (hasClass(event.target, 'topLeftSelectionHandle-HitArea')) {
  92. selectedRange = _this.hot.getSelectedRange();
  93. _this.dragged.push('topLeft');
  94. _this.touchStartRange = {
  95. width: selectedRange.getWidth(),
  96. height: selectedRange.getHeight(),
  97. direction: selectedRange.getDirection()
  98. };
  99. event.preventDefault();
  100. return false;
  101. } else if (hasClass(event.target, 'bottomRightSelectionHandle-HitArea')) {
  102. selectedRange = _this.hot.getSelectedRange();
  103. _this.dragged.push('bottomRight');
  104. _this.touchStartRange = {
  105. width: selectedRange.getWidth(),
  106. height: selectedRange.getHeight(),
  107. direction: selectedRange.getDirection()
  108. };
  109. event.preventDefault();
  110. return false;
  111. }
  112. });
  113. this.eventManager.addEventListener(this.hot.rootElement, 'touchend', function (event) {
  114. if (hasClass(event.target, 'topLeftSelectionHandle-HitArea')) {
  115. removeFromDragged.call(_this, 'topLeft');
  116. _this.touchStartRange = void 0;
  117. event.preventDefault();
  118. return false;
  119. } else if (hasClass(event.target, 'bottomRightSelectionHandle-HitArea')) {
  120. removeFromDragged.call(_this, 'bottomRight');
  121. _this.touchStartRange = void 0;
  122. event.preventDefault();
  123. return false;
  124. }
  125. });
  126. this.eventManager.addEventListener(this.hot.rootElement, 'touchmove', function (event) {
  127. var scrollTop = getWindowScrollTop(),
  128. scrollLeft = getWindowScrollLeft(),
  129. endTarget = void 0,
  130. targetCoords = void 0,
  131. selectedRange = void 0,
  132. rangeWidth = void 0,
  133. rangeHeight = void 0,
  134. rangeDirection = void 0,
  135. newRangeCoords = void 0;
  136. if (_this.dragged.length === 0) {
  137. return;
  138. }
  139. endTarget = document.elementFromPoint(event.touches[0].screenX - scrollLeft, event.touches[0].screenY - scrollTop);
  140. if (!endTarget || endTarget === _this.lastSetCell) {
  141. return;
  142. }
  143. if (endTarget.nodeName == 'TD' || endTarget.nodeName == 'TH') {
  144. targetCoords = _this.hot.getCoords(endTarget);
  145. if (targetCoords.col == -1) {
  146. targetCoords.col = 0;
  147. }
  148. selectedRange = _this.hot.getSelectedRange();
  149. rangeWidth = selectedRange.getWidth();
  150. rangeHeight = selectedRange.getHeight();
  151. rangeDirection = selectedRange.getDirection();
  152. if (rangeWidth == 1 && rangeHeight == 1) {
  153. _this.hot.selection.setRangeEnd(targetCoords);
  154. }
  155. newRangeCoords = _this.getCurrentRangeCoords(selectedRange, targetCoords, _this.touchStartRange.direction, rangeDirection, _this.dragged[0]);
  156. if (newRangeCoords.start !== null) {
  157. _this.hot.selection.setRangeStart(newRangeCoords.start);
  158. }
  159. _this.hot.selection.setRangeEnd(newRangeCoords.end);
  160. _this.lastSetCell = endTarget;
  161. }
  162. event.preventDefault();
  163. });
  164. }
  165. }, {
  166. key: 'getCurrentRangeCoords',
  167. value: function getCurrentRangeCoords(selectedRange, currentTouch, touchStartDirection, currentDirection, draggedHandle) {
  168. var topLeftCorner = selectedRange.getTopLeftCorner(),
  169. bottomRightCorner = selectedRange.getBottomRightCorner(),
  170. bottomLeftCorner = selectedRange.getBottomLeftCorner(),
  171. topRightCorner = selectedRange.getTopRightCorner();
  172. var newCoords = {
  173. start: null,
  174. end: null
  175. };
  176. switch (touchStartDirection) {
  177. case 'NE-SW':
  178. switch (currentDirection) {
  179. case 'NE-SW':
  180. case 'NW-SE':
  181. if (draggedHandle == 'topLeft') {
  182. newCoords = {
  183. start: new CellCoords(currentTouch.row, selectedRange.highlight.col),
  184. end: new CellCoords(bottomLeftCorner.row, currentTouch.col)
  185. };
  186. } else {
  187. newCoords = {
  188. start: new CellCoords(selectedRange.highlight.row, currentTouch.col),
  189. end: new CellCoords(currentTouch.row, topLeftCorner.col)
  190. };
  191. }
  192. break;
  193. case 'SE-NW':
  194. if (draggedHandle == 'bottomRight') {
  195. newCoords = {
  196. start: new CellCoords(bottomRightCorner.row, currentTouch.col),
  197. end: new CellCoords(currentTouch.row, topLeftCorner.col)
  198. };
  199. }
  200. break;
  201. default:
  202. break;
  203. }
  204. break;
  205. case 'NW-SE':
  206. switch (currentDirection) {
  207. case 'NE-SW':
  208. if (draggedHandle == 'topLeft') {
  209. newCoords = {
  210. start: currentTouch,
  211. end: bottomLeftCorner
  212. };
  213. } else {
  214. newCoords.end = currentTouch;
  215. }
  216. break;
  217. case 'NW-SE':
  218. if (draggedHandle == 'topLeft') {
  219. newCoords = {
  220. start: currentTouch,
  221. end: bottomRightCorner
  222. };
  223. } else {
  224. newCoords.end = currentTouch;
  225. }
  226. break;
  227. case 'SE-NW':
  228. if (draggedHandle == 'topLeft') {
  229. newCoords = {
  230. start: currentTouch,
  231. end: topLeftCorner
  232. };
  233. } else {
  234. newCoords.end = currentTouch;
  235. }
  236. break;
  237. case 'SW-NE':
  238. if (draggedHandle == 'topLeft') {
  239. newCoords = {
  240. start: currentTouch,
  241. end: topRightCorner
  242. };
  243. } else {
  244. newCoords.end = currentTouch;
  245. }
  246. break;
  247. default:
  248. break;
  249. }
  250. break;
  251. case 'SW-NE':
  252. switch (currentDirection) {
  253. case 'NW-SE':
  254. if (draggedHandle == 'bottomRight') {
  255. newCoords = {
  256. start: new CellCoords(currentTouch.row, topLeftCorner.col),
  257. end: new CellCoords(bottomLeftCorner.row, currentTouch.col)
  258. };
  259. } else {
  260. newCoords = {
  261. start: new CellCoords(topLeftCorner.row, currentTouch.col),
  262. end: new CellCoords(currentTouch.row, bottomRightCorner.col)
  263. };
  264. }
  265. break;
  266. // case 'NE-SW':
  267. //
  268. // break;
  269. case 'SW-NE':
  270. if (draggedHandle == 'topLeft') {
  271. newCoords = {
  272. start: new CellCoords(selectedRange.highlight.row, currentTouch.col),
  273. end: new CellCoords(currentTouch.row, bottomRightCorner.col)
  274. };
  275. } else {
  276. newCoords = {
  277. start: new CellCoords(currentTouch.row, topLeftCorner.col),
  278. end: new CellCoords(topLeftCorner.row, currentTouch.col)
  279. };
  280. }
  281. break;
  282. case 'SE-NW':
  283. if (draggedHandle == 'bottomRight') {
  284. newCoords = {
  285. start: new CellCoords(currentTouch.row, topRightCorner.col),
  286. end: new CellCoords(topLeftCorner.row, currentTouch.col)
  287. };
  288. } else if (draggedHandle == 'topLeft') {
  289. newCoords = {
  290. start: bottomLeftCorner,
  291. end: currentTouch
  292. };
  293. }
  294. break;
  295. default:
  296. break;
  297. }
  298. break;
  299. case 'SE-NW':
  300. switch (currentDirection) {
  301. case 'NW-SE':
  302. case 'NE-SW':
  303. case 'SW-NE':
  304. if (draggedHandle == 'topLeft') {
  305. newCoords.end = currentTouch;
  306. }
  307. break;
  308. case 'SE-NW':
  309. if (draggedHandle == 'topLeft') {
  310. newCoords.end = currentTouch;
  311. } else {
  312. newCoords = {
  313. start: currentTouch,
  314. end: topLeftCorner
  315. };
  316. }
  317. break;
  318. default:
  319. break;
  320. }
  321. break;
  322. default:
  323. break;
  324. }
  325. return newCoords;
  326. }
  327. /**
  328. * Check if user is currently dragging the handle.
  329. *
  330. * @returns {boolean} Dragging state
  331. */
  332. }, {
  333. key: 'isDragged',
  334. value: function isDragged() {
  335. return this.dragged.length > 0;
  336. }
  337. }]);
  338. return MultipleSelectionHandles;
  339. }(BasePlugin);
  340. registerPlugin('multipleSelectionHandles', MultipleSelectionHandles);
  341. export default MultipleSelectionHandles;