94e6186bb919eabd3e0adb932e9c08b687b382a893ecbc3c101cb86b68ada8f87f2219dc6e49e54c03ecc2d44c62a9f2f7825859a7b33385c55f7caa026663 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. 'use strict';
  2. exports.__esModule = true;
  3. 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; }; }();
  4. 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); } };
  5. var _base = require('./../_base');
  6. var _base2 = _interopRequireDefault(_base);
  7. var _element = require('./../../helpers/dom/element');
  8. var _eventManager = require('./../../eventManager');
  9. var _eventManager2 = _interopRequireDefault(_eventManager);
  10. var _event = require('./../../helpers/dom/event');
  11. var _array = require('./../../helpers/array');
  12. var _number = require('./../../helpers/number');
  13. var _plugins = require('./../../plugins');
  14. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  15. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16. 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; }
  17. 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; }
  18. // Developer note! Whenever you make a change in this file, make an analogous change in manualRowResize.js
  19. /**
  20. * @description
  21. * ManualRowResize Plugin.
  22. *
  23. * Has 2 UI components:
  24. * - handle - the draggable element that sets the desired height of the row.
  25. * - guide - the helper guide that shows the desired height as a horizontal guide.
  26. *
  27. * @plugin ManualRowResize
  28. */
  29. var ManualRowResize = function (_BasePlugin) {
  30. _inherits(ManualRowResize, _BasePlugin);
  31. function ManualRowResize(hotInstance) {
  32. _classCallCheck(this, ManualRowResize);
  33. var _this = _possibleConstructorReturn(this, (ManualRowResize.__proto__ || Object.getPrototypeOf(ManualRowResize)).call(this, hotInstance));
  34. _this.currentTH = null;
  35. _this.currentRow = null;
  36. _this.selectedRows = [];
  37. _this.currentHeight = null;
  38. _this.newSize = null;
  39. _this.startY = null;
  40. _this.startHeight = null;
  41. _this.startOffset = null;
  42. _this.handle = document.createElement('DIV');
  43. _this.guide = document.createElement('DIV');
  44. _this.eventManager = new _eventManager2.default(_this);
  45. _this.pressed = null;
  46. _this.dblclick = 0;
  47. _this.autoresizeTimeout = null;
  48. _this.manualRowHeights = [];
  49. (0, _element.addClass)(_this.handle, 'manualRowResizer');
  50. (0, _element.addClass)(_this.guide, 'manualRowResizerGuide');
  51. return _this;
  52. }
  53. /**
  54. * Check if the plugin is enabled in the handsontable settings.
  55. *
  56. * @returns {Boolean}
  57. */
  58. _createClass(ManualRowResize, [{
  59. key: 'isEnabled',
  60. value: function isEnabled() {
  61. return this.hot.getSettings().manualRowResize;
  62. }
  63. /**
  64. * Enable plugin for this Handsontable instance.
  65. */
  66. }, {
  67. key: 'enablePlugin',
  68. value: function enablePlugin() {
  69. var _this2 = this;
  70. if (this.enabled) {
  71. return;
  72. }
  73. this.manualRowHeights = [];
  74. var initialRowHeights = this.hot.getSettings().manualRowResize;
  75. var loadedManualRowHeights = this.loadManualRowHeights();
  76. if (typeof loadedManualRowHeights != 'undefined') {
  77. this.manualRowHeights = loadedManualRowHeights;
  78. } else if (Array.isArray(initialRowHeights)) {
  79. this.manualRowHeights = initialRowHeights;
  80. } else {
  81. this.manualRowHeights = [];
  82. }
  83. this.addHook('modifyRowHeight', function (height, row) {
  84. return _this2.onModifyRowHeight(height, row);
  85. });
  86. // Handsontable.hooks.register('beforeRowResize');
  87. // Handsontable.hooks.register('afterRowResize');
  88. this.bindEvents();
  89. _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'enablePlugin', this).call(this);
  90. }
  91. /**
  92. * Updates the plugin to use the latest options you have specified.
  93. */
  94. }, {
  95. key: 'updatePlugin',
  96. value: function updatePlugin() {
  97. var initialRowHeights = this.hot.getSettings().manualRowResize;
  98. if (Array.isArray(initialRowHeights)) {
  99. this.manualRowHeights = initialRowHeights;
  100. } else if (!initialRowHeights) {
  101. this.manualRowHeights = [];
  102. }
  103. }
  104. /**
  105. * Disable plugin for this Handsontable instance.
  106. */
  107. }, {
  108. key: 'disablePlugin',
  109. value: function disablePlugin() {
  110. _get(ManualRowResize.prototype.__proto__ || Object.getPrototypeOf(ManualRowResize.prototype), 'disablePlugin', this).call(this);
  111. }
  112. /**
  113. * Save the current sizes using the persistentState plugin.
  114. */
  115. }, {
  116. key: 'saveManualRowHeights',
  117. value: function saveManualRowHeights() {
  118. this.hot.runHooks('persistentStateSave', 'manualRowHeights', this.manualRowHeights);
  119. }
  120. /**
  121. * Load the previously saved sizes using the persistentState plugin.
  122. *
  123. * @returns {Array}
  124. */
  125. }, {
  126. key: 'loadManualRowHeights',
  127. value: function loadManualRowHeights() {
  128. var storedState = {};
  129. this.hot.runHooks('persistentStateLoad', 'manualRowHeights', storedState);
  130. return storedState.value;
  131. }
  132. /**
  133. * Set the resize handle position.
  134. *
  135. * @param {HTMLCellElement} TH TH HTML element.
  136. */
  137. }, {
  138. key: 'setupHandlePosition',
  139. value: function setupHandlePosition(TH) {
  140. var _this3 = this;
  141. this.currentTH = TH;
  142. var row = this.hot.view.wt.wtTable.getCoords(TH).row; // getCoords returns CellCoords
  143. var headerWidth = (0, _element.outerWidth)(this.currentTH);
  144. if (row >= 0) {
  145. // if not col header
  146. var box = this.currentTH.getBoundingClientRect();
  147. this.currentRow = row;
  148. this.selectedRows = [];
  149. if (this.hot.selection.isSelected() && this.hot.selection.selectedHeader.rows) {
  150. var _hot$getSelectedRange = this.hot.getSelectedRange(),
  151. from = _hot$getSelectedRange.from,
  152. to = _hot$getSelectedRange.to;
  153. var start = from.row;
  154. var end = to.row;
  155. if (start >= end) {
  156. start = to.row;
  157. end = from.row;
  158. }
  159. if (this.currentRow >= start && this.currentRow <= end) {
  160. (0, _number.rangeEach)(start, end, function (i) {
  161. return _this3.selectedRows.push(i);
  162. });
  163. } else {
  164. this.selectedRows.push(this.currentRow);
  165. }
  166. } else {
  167. this.selectedRows.push(this.currentRow);
  168. }
  169. this.startOffset = box.top - 6;
  170. this.startHeight = parseInt(box.height, 10);
  171. this.handle.style.left = box.left + 'px';
  172. this.handle.style.top = this.startOffset + this.startHeight + 'px';
  173. this.handle.style.width = headerWidth + 'px';
  174. this.hot.rootElement.appendChild(this.handle);
  175. }
  176. }
  177. /**
  178. * Refresh the resize handle position.
  179. */
  180. }, {
  181. key: 'refreshHandlePosition',
  182. value: function refreshHandlePosition() {
  183. this.handle.style.top = this.startOffset + this.currentHeight + 'px';
  184. }
  185. /**
  186. * Set the resize guide position.
  187. */
  188. }, {
  189. key: 'setupGuidePosition',
  190. value: function setupGuidePosition() {
  191. var handleWidth = parseInt((0, _element.outerWidth)(this.handle), 10);
  192. var handleRightPosition = parseInt(this.handle.style.left, 10) + handleWidth;
  193. var maximumVisibleElementWidth = parseInt(this.hot.view.maximumVisibleElementWidth(0), 10);
  194. (0, _element.addClass)(this.handle, 'active');
  195. (0, _element.addClass)(this.guide, 'active');
  196. this.guide.style.top = this.handle.style.top;
  197. this.guide.style.left = handleRightPosition + 'px';
  198. this.guide.style.width = maximumVisibleElementWidth - handleWidth + 'px';
  199. this.hot.rootElement.appendChild(this.guide);
  200. }
  201. /**
  202. * Refresh the resize guide position.
  203. */
  204. }, {
  205. key: 'refreshGuidePosition',
  206. value: function refreshGuidePosition() {
  207. this.guide.style.top = this.handle.style.top;
  208. }
  209. /**
  210. * Hide both the resize handle and resize guide.
  211. */
  212. }, {
  213. key: 'hideHandleAndGuide',
  214. value: function hideHandleAndGuide() {
  215. (0, _element.removeClass)(this.handle, 'active');
  216. (0, _element.removeClass)(this.guide, 'active');
  217. }
  218. /**
  219. * Check if provided element is considered as a row header.
  220. *
  221. * @param {HTMLElement} element HTML element.
  222. * @returns {Boolean}
  223. */
  224. }, {
  225. key: 'checkIfRowHeader',
  226. value: function checkIfRowHeader(element) {
  227. if (element != this.hot.rootElement) {
  228. var parent = element.parentNode;
  229. if (parent.tagName === 'TBODY') {
  230. return true;
  231. }
  232. return this.checkIfRowHeader(parent);
  233. }
  234. return false;
  235. }
  236. /**
  237. * Get the TH element from the provided element.
  238. *
  239. * @param {HTMLElement} element HTML element.
  240. * @returns {HTMLElement}
  241. */
  242. }, {
  243. key: 'getTHFromTargetElement',
  244. value: function getTHFromTargetElement(element) {
  245. if (element.tagName != 'TABLE') {
  246. if (element.tagName == 'TH') {
  247. return element;
  248. }
  249. return this.getTHFromTargetElement(element.parentNode);
  250. }
  251. return null;
  252. }
  253. /**
  254. * 'mouseover' event callback - set the handle position.
  255. *
  256. * @private
  257. * @param {MouseEvent} event
  258. */
  259. }, {
  260. key: 'onMouseOver',
  261. value: function onMouseOver(event) {
  262. if (this.checkIfRowHeader(event.target)) {
  263. var th = this.getTHFromTargetElement(event.target);
  264. if (th) {
  265. if (!this.pressed) {
  266. this.setupHandlePosition(th);
  267. }
  268. }
  269. }
  270. }
  271. /**
  272. * Auto-size row after doubleclick - callback.
  273. *
  274. * @private
  275. */
  276. }, {
  277. key: 'afterMouseDownTimeout',
  278. value: function afterMouseDownTimeout() {
  279. var _this4 = this;
  280. var render = function render() {
  281. _this4.hot.forceFullRender = true;
  282. _this4.hot.view.render(); // updates all
  283. _this4.hot.view.wt.wtOverlays.adjustElementsSize(true);
  284. };
  285. var resize = function resize(selectedRow, forceRender) {
  286. var hookNewSize = _this4.hot.runHooks('beforeRowResize', selectedRow, _this4.newSize, true);
  287. if (hookNewSize !== void 0) {
  288. _this4.newSize = hookNewSize;
  289. }
  290. _this4.setManualSize(selectedRow, _this4.newSize); // double click sets auto row size
  291. if (forceRender) {
  292. render();
  293. }
  294. _this4.hot.runHooks('afterRowResize', selectedRow, _this4.newSize, true);
  295. };
  296. if (this.dblclick >= 2) {
  297. var selectedRowsLength = this.selectedRows.length;
  298. if (selectedRowsLength > 1) {
  299. (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
  300. resize(selectedRow);
  301. });
  302. render();
  303. } else {
  304. (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
  305. resize(selectedRow, true);
  306. });
  307. }
  308. }
  309. this.dblclick = 0;
  310. this.autoresizeTimeout = null;
  311. }
  312. /**
  313. * 'mousedown' event callback.
  314. *
  315. * @private
  316. * @param {MouseEvent} event
  317. */
  318. }, {
  319. key: 'onMouseDown',
  320. value: function onMouseDown(event) {
  321. var _this5 = this;
  322. if ((0, _element.hasClass)(event.target, 'manualRowResizer')) {
  323. this.setupGuidePosition();
  324. this.pressed = this.hot;
  325. if (this.autoresizeTimeout == null) {
  326. this.autoresizeTimeout = setTimeout(function () {
  327. return _this5.afterMouseDownTimeout();
  328. }, 500);
  329. this.hot._registerTimeout(this.autoresizeTimeout);
  330. }
  331. this.dblclick++;
  332. this.startY = (0, _event.pageY)(event);
  333. this.newSize = this.startHeight;
  334. }
  335. }
  336. /**
  337. * 'mousemove' event callback - refresh the handle and guide positions, cache the new row height.
  338. *
  339. * @private
  340. * @param {MouseEvent} event
  341. */
  342. }, {
  343. key: 'onMouseMove',
  344. value: function onMouseMove(event) {
  345. var _this6 = this;
  346. if (this.pressed) {
  347. this.currentHeight = this.startHeight + ((0, _event.pageY)(event) - this.startY);
  348. (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
  349. _this6.newSize = _this6.setManualSize(selectedRow, _this6.currentHeight);
  350. });
  351. this.refreshHandlePosition();
  352. this.refreshGuidePosition();
  353. }
  354. }
  355. /**
  356. * 'mouseup' event callback - apply the row resizing.
  357. *
  358. * @private
  359. * @param {MouseEvent} event
  360. */
  361. }, {
  362. key: 'onMouseUp',
  363. value: function onMouseUp(event) {
  364. var _this7 = this;
  365. var render = function render() {
  366. _this7.hot.forceFullRender = true;
  367. _this7.hot.view.render(); // updates all
  368. _this7.hot.view.wt.wtOverlays.adjustElementsSize(true);
  369. };
  370. var runHooks = function runHooks(selectedRow, forceRender) {
  371. _this7.hot.runHooks('beforeRowResize', selectedRow, _this7.newSize);
  372. if (forceRender) {
  373. render();
  374. }
  375. _this7.saveManualRowHeights();
  376. _this7.hot.runHooks('afterRowResize', selectedRow, _this7.newSize);
  377. };
  378. if (this.pressed) {
  379. this.hideHandleAndGuide();
  380. this.pressed = false;
  381. if (this.newSize != this.startHeight) {
  382. var selectedRowsLength = this.selectedRows.length;
  383. if (selectedRowsLength > 1) {
  384. (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
  385. runHooks(selectedRow);
  386. });
  387. render();
  388. } else {
  389. (0, _array.arrayEach)(this.selectedRows, function (selectedRow) {
  390. runHooks(selectedRow, true);
  391. });
  392. }
  393. }
  394. this.setupHandlePosition(this.currentTH);
  395. }
  396. }
  397. /**
  398. * Bind the mouse events.
  399. *
  400. * @private
  401. */
  402. }, {
  403. key: 'bindEvents',
  404. value: function bindEvents() {
  405. var _this8 = this;
  406. this.eventManager.addEventListener(this.hot.rootElement, 'mouseover', function (e) {
  407. return _this8.onMouseOver(e);
  408. });
  409. this.eventManager.addEventListener(this.hot.rootElement, 'mousedown', function (e) {
  410. return _this8.onMouseDown(e);
  411. });
  412. this.eventManager.addEventListener(window, 'mousemove', function (e) {
  413. return _this8.onMouseMove(e);
  414. });
  415. this.eventManager.addEventListener(window, 'mouseup', function (e) {
  416. return _this8.onMouseUp(e);
  417. });
  418. }
  419. /**
  420. * Cache the current row height.
  421. *
  422. * @param {Number} row Row index.
  423. * @param {Number} height Row height.
  424. * @returns {Number}
  425. */
  426. }, {
  427. key: 'setManualSize',
  428. value: function setManualSize(row, height) {
  429. row = this.hot.runHooks('modifyRow', row);
  430. this.manualRowHeights[row] = height;
  431. return height;
  432. }
  433. /**
  434. * Modify the provided row height, based on the plugin settings.
  435. *
  436. * @private
  437. * @param {Number} height Row height.
  438. * @param {Number} row Row index.
  439. * @returns {Number}
  440. */
  441. }, {
  442. key: 'onModifyRowHeight',
  443. value: function onModifyRowHeight(height, row) {
  444. if (this.enabled) {
  445. var autoRowSizePlugin = this.hot.getPlugin('autoRowSize');
  446. var autoRowHeightResult = autoRowSizePlugin ? autoRowSizePlugin.heights[row] : null;
  447. row = this.hot.runHooks('modifyRow', row);
  448. var manualRowHeight = this.manualRowHeights[row];
  449. if (manualRowHeight !== void 0 && (manualRowHeight === autoRowHeightResult || manualRowHeight > (height || 0))) {
  450. return manualRowHeight;
  451. }
  452. }
  453. return height;
  454. }
  455. }]);
  456. return ManualRowResize;
  457. }(_base2.default);
  458. (0, _plugins.registerPlugin)('manualRowResize', ManualRowResize);
  459. exports.default = ManualRowResize;