ebf375c3bb6cabb5dc8e20b50abae5bc8f6101b3ac36fdbe7312ca792e10fd4a7f12493964af37b190ec31b874fe3ca66e7180aa84f44f004a2c5b5fa7e3f6 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  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. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. import { getScrollableElement, getScrollbarWidth, getScrollLeft, getScrollTop } from './../../../helpers/dom/element';
  4. import { arrayEach } from './../../../helpers/array';
  5. import { isKey } from './../../../helpers/unicode';
  6. import { isMobileBrowser } from './../../../helpers/browser';
  7. import EventManager from './../../../eventManager';
  8. import Overlay from './overlay/_base.js';
  9. /**
  10. * @class Overlays
  11. */
  12. var Overlays = function () {
  13. /**
  14. * @param {Walkontable} wotInstance
  15. */
  16. function Overlays(wotInstance) {
  17. _classCallCheck(this, Overlays);
  18. this.wot = wotInstance;
  19. // legacy support
  20. this.instance = this.wot;
  21. this.eventManager = new EventManager(this.wot);
  22. this.wot.update('scrollbarWidth', getScrollbarWidth());
  23. this.wot.update('scrollbarHeight', getScrollbarWidth());
  24. this.scrollableElement = getScrollableElement(this.wot.wtTable.TABLE);
  25. this.prepareOverlays();
  26. this.destroyed = false;
  27. this.keyPressed = false;
  28. this.spreaderLastSize = {
  29. width: null,
  30. height: null
  31. };
  32. this.overlayScrollPositions = {
  33. master: {
  34. top: 0,
  35. left: 0
  36. },
  37. top: {
  38. top: null,
  39. left: 0
  40. },
  41. bottom: {
  42. top: null,
  43. left: 0
  44. },
  45. left: {
  46. top: 0,
  47. left: null
  48. }
  49. };
  50. this.pendingScrollCallbacks = {
  51. master: {
  52. top: 0,
  53. left: 0
  54. },
  55. top: {
  56. left: 0
  57. },
  58. bottom: {
  59. left: 0
  60. },
  61. left: {
  62. top: 0
  63. }
  64. };
  65. this.verticalScrolling = false;
  66. this.horizontalScrolling = false;
  67. this.delegatedScrollCallback = false;
  68. this.registeredListeners = [];
  69. this.registerListeners();
  70. }
  71. /**
  72. * Prepare overlays based on user settings.
  73. *
  74. * @returns {Boolean} Returns `true` if changes applied to overlay needs scroll synchronization.
  75. */
  76. _createClass(Overlays, [{
  77. key: 'prepareOverlays',
  78. value: function prepareOverlays() {
  79. var syncScroll = false;
  80. if (this.topOverlay) {
  81. syncScroll = this.topOverlay.updateStateOfRendering() || syncScroll;
  82. } else {
  83. this.topOverlay = Overlay.createOverlay(Overlay.CLONE_TOP, this.wot);
  84. }
  85. if (!Overlay.hasOverlay(Overlay.CLONE_BOTTOM)) {
  86. this.bottomOverlay = {
  87. needFullRender: false,
  88. updateStateOfRendering: function updateStateOfRendering() {
  89. return false;
  90. }
  91. };
  92. }
  93. if (!Overlay.hasOverlay(Overlay.CLONE_BOTTOM_LEFT_CORNER)) {
  94. this.bottomLeftCornerOverlay = {
  95. needFullRender: false,
  96. updateStateOfRendering: function updateStateOfRendering() {
  97. return false;
  98. }
  99. };
  100. }
  101. if (this.bottomOverlay) {
  102. syncScroll = this.bottomOverlay.updateStateOfRendering() || syncScroll;
  103. } else {
  104. this.bottomOverlay = Overlay.createOverlay(Overlay.CLONE_BOTTOM, this.wot);
  105. }
  106. if (this.leftOverlay) {
  107. syncScroll = this.leftOverlay.updateStateOfRendering() || syncScroll;
  108. } else {
  109. this.leftOverlay = Overlay.createOverlay(Overlay.CLONE_LEFT, this.wot);
  110. }
  111. if (this.topOverlay.needFullRender && this.leftOverlay.needFullRender) {
  112. if (this.topLeftCornerOverlay) {
  113. syncScroll = this.topLeftCornerOverlay.updateStateOfRendering() || syncScroll;
  114. } else {
  115. this.topLeftCornerOverlay = Overlay.createOverlay(Overlay.CLONE_TOP_LEFT_CORNER, this.wot);
  116. }
  117. }
  118. if (this.bottomOverlay.needFullRender && this.leftOverlay.needFullRender) {
  119. if (this.bottomLeftCornerOverlay) {
  120. syncScroll = this.bottomLeftCornerOverlay.updateStateOfRendering() || syncScroll;
  121. } else {
  122. this.bottomLeftCornerOverlay = Overlay.createOverlay(Overlay.CLONE_BOTTOM_LEFT_CORNER, this.wot);
  123. }
  124. }
  125. if (this.wot.getSetting('debug') && !this.debug) {
  126. this.debug = Overlay.createOverlay(Overlay.CLONE_DEBUG, this.wot);
  127. }
  128. return syncScroll;
  129. }
  130. /**
  131. * Refresh and redraw table
  132. */
  133. }, {
  134. key: 'refreshAll',
  135. value: function refreshAll() {
  136. if (!this.wot.drawn) {
  137. return;
  138. }
  139. if (!this.wot.wtTable.holder.parentNode) {
  140. // Walkontable was detached from DOM, but this handler was not removed
  141. this.destroy();
  142. return;
  143. }
  144. this.wot.draw(true);
  145. if (this.verticalScrolling) {
  146. this.leftOverlay.onScroll();
  147. }
  148. if (this.horizontalScrolling) {
  149. this.topOverlay.onScroll();
  150. }
  151. this.verticalScrolling = false;
  152. this.horizontalScrolling = false;
  153. }
  154. /**
  155. * Register all necessary event listeners.
  156. */
  157. }, {
  158. key: 'registerListeners',
  159. value: function registerListeners() {
  160. var _this = this;
  161. var topOverlayScrollable = this.topOverlay.mainTableScrollableElement;
  162. var leftOverlayScrollable = this.leftOverlay.mainTableScrollableElement;
  163. var listenersToRegister = [];
  164. listenersToRegister.push([document.documentElement, 'keydown', function (event) {
  165. return _this.onKeyDown(event);
  166. }]);
  167. listenersToRegister.push([document.documentElement, 'keyup', function () {
  168. return _this.onKeyUp();
  169. }]);
  170. listenersToRegister.push([document, 'visibilitychange', function () {
  171. return _this.onKeyUp();
  172. }]);
  173. listenersToRegister.push([topOverlayScrollable, 'scroll', function (event) {
  174. return _this.onTableScroll(event);
  175. }]);
  176. if (topOverlayScrollable !== leftOverlayScrollable) {
  177. listenersToRegister.push([leftOverlayScrollable, 'scroll', function (event) {
  178. return _this.onTableScroll(event);
  179. }]);
  180. }
  181. if (this.topOverlay.needFullRender) {
  182. listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'scroll', function (event) {
  183. return _this.onTableScroll(event);
  184. }]);
  185. listenersToRegister.push([this.topOverlay.clone.wtTable.holder, 'wheel', function (event) {
  186. return _this.onTableScroll(event);
  187. }]);
  188. }
  189. if (this.bottomOverlay.needFullRender) {
  190. listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'scroll', function (event) {
  191. return _this.onTableScroll(event);
  192. }]);
  193. listenersToRegister.push([this.bottomOverlay.clone.wtTable.holder, 'wheel', function (event) {
  194. return _this.onTableScroll(event);
  195. }]);
  196. }
  197. if (this.leftOverlay.needFullRender) {
  198. listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'scroll', function (event) {
  199. return _this.onTableScroll(event);
  200. }]);
  201. listenersToRegister.push([this.leftOverlay.clone.wtTable.holder, 'wheel', function (event) {
  202. return _this.onTableScroll(event);
  203. }]);
  204. }
  205. if (this.topLeftCornerOverlay && this.topLeftCornerOverlay.needFullRender) {
  206. listenersToRegister.push([this.topLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
  207. return _this.onTableScroll(event);
  208. }]);
  209. }
  210. if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.needFullRender) {
  211. listenersToRegister.push([this.bottomLeftCornerOverlay.clone.wtTable.holder, 'wheel', function (event) {
  212. return _this.onTableScroll(event);
  213. }]);
  214. }
  215. if (this.topOverlay.trimmingContainer !== window && this.leftOverlay.trimmingContainer !== window) {
  216. // This is necessary?
  217. // eventManager.addEventListener(window, 'scroll', (event) => this.refreshAll(event));
  218. listenersToRegister.push([window, 'wheel', function (event) {
  219. var overlay = void 0;
  220. var deltaY = event.wheelDeltaY || event.deltaY;
  221. var deltaX = event.wheelDeltaX || event.deltaX;
  222. if (_this.topOverlay.clone.wtTable.holder.contains(event.realTarget)) {
  223. overlay = 'top';
  224. } else if (_this.bottomOverlay.clone && _this.bottomOverlay.clone.wtTable.holder.contains(event.realTarget)) {
  225. overlay = 'bottom';
  226. } else if (_this.leftOverlay.clone.wtTable.holder.contains(event.realTarget)) {
  227. overlay = 'left';
  228. } else if (_this.topLeftCornerOverlay && _this.topLeftCornerOverlay.clone && _this.topLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) {
  229. overlay = 'topLeft';
  230. } else if (_this.bottomLeftCornerOverlay && _this.bottomLeftCornerOverlay.clone && _this.bottomLeftCornerOverlay.clone.wtTable.holder.contains(event.realTarget)) {
  231. overlay = 'bottomLeft';
  232. }
  233. if (overlay == 'top' && deltaY !== 0 || overlay == 'left' && deltaX !== 0 || overlay == 'bottom' && deltaY !== 0 || (overlay === 'topLeft' || overlay === 'bottomLeft') && (deltaY !== 0 || deltaX !== 0)) {
  234. event.preventDefault();
  235. }
  236. }]);
  237. }
  238. while (listenersToRegister.length) {
  239. var listener = listenersToRegister.pop();
  240. this.eventManager.addEventListener(listener[0], listener[1], listener[2]);
  241. this.registeredListeners.push(listener);
  242. }
  243. }
  244. /**
  245. * Deregister all previously registered listeners.
  246. */
  247. }, {
  248. key: 'deregisterListeners',
  249. value: function deregisterListeners() {
  250. while (this.registeredListeners.length) {
  251. var listener = this.registeredListeners.pop();
  252. this.eventManager.removeEventListener(listener[0], listener[1], listener[2]);
  253. }
  254. }
  255. /**
  256. * Scroll listener
  257. *
  258. * @param {Event} event
  259. */
  260. }, {
  261. key: 'onTableScroll',
  262. value: function onTableScroll(event) {
  263. // if mobile browser, do not update scroll positions, as the overlays are hidden during the scroll
  264. if (isMobileBrowser()) {
  265. return;
  266. }
  267. var masterHorizontal = this.leftOverlay.mainTableScrollableElement;
  268. var masterVertical = this.topOverlay.mainTableScrollableElement;
  269. var target = event.target;
  270. // For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
  271. // by hot.refreshBorder
  272. if (this.keyPressed) {
  273. if (masterVertical !== window && target !== window && !event.target.contains(masterVertical) || masterHorizontal !== window && target !== window && !event.target.contains(masterHorizontal)) {
  274. return;
  275. }
  276. }
  277. if (event.type === 'scroll') {
  278. this.syncScrollPositions(event);
  279. } else {
  280. this.translateMouseWheelToScroll(event);
  281. }
  282. }
  283. /**
  284. * Key down listener
  285. */
  286. }, {
  287. key: 'onKeyDown',
  288. value: function onKeyDown(event) {
  289. this.keyPressed = isKey(event.keyCode, 'ARROW_UP|ARROW_RIGHT|ARROW_DOWN|ARROW_LEFT');
  290. }
  291. /**
  292. * Key up listener
  293. */
  294. }, {
  295. key: 'onKeyUp',
  296. value: function onKeyUp() {
  297. this.keyPressed = false;
  298. }
  299. /**
  300. * Translate wheel event into scroll event and sync scroll overlays position
  301. *
  302. * @private
  303. * @param {Event} event
  304. * @returns {Boolean}
  305. */
  306. }, {
  307. key: 'translateMouseWheelToScroll',
  308. value: function translateMouseWheelToScroll(event) {
  309. var topOverlay = this.topOverlay.clone.wtTable.holder;
  310. var bottomOverlay = this.bottomOverlay.clone ? this.bottomOverlay.clone.wtTable.holder : null;
  311. var leftOverlay = this.leftOverlay.clone.wtTable.holder;
  312. var topLeftCornerOverlay = this.topLeftCornerOverlay && this.topLeftCornerOverlay.clone ? this.topLeftCornerOverlay.clone.wtTable.holder : null;
  313. var bottomLeftCornerOverlay = this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone ? this.bottomLeftCornerOverlay.clone.wtTable.holder : null;
  314. var mouseWheelSpeedRatio = -0.2;
  315. var deltaY = event.wheelDeltaY || -1 * event.deltaY;
  316. var deltaX = event.wheelDeltaX || -1 * event.deltaX;
  317. var parentHolder = null;
  318. var eventMockup = { type: 'wheel' };
  319. var tempElem = event.target;
  320. var delta = null;
  321. // Fix for extremely slow header scrolling with a mousewheel on Firefox
  322. if (event.deltaMode === 1) {
  323. deltaY *= 120;
  324. deltaX *= 120;
  325. }
  326. while (tempElem != document && tempElem != null) {
  327. if (tempElem.className.indexOf('wtHolder') > -1) {
  328. parentHolder = tempElem;
  329. break;
  330. }
  331. tempElem = tempElem.parentNode;
  332. }
  333. eventMockup.target = parentHolder;
  334. if (parentHolder === topLeftCornerOverlay || parentHolder === bottomLeftCornerOverlay) {
  335. this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaX, 'x');
  336. this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * deltaY, 'y');
  337. } else {
  338. if (parentHolder === topOverlay || parentHolder === bottomOverlay) {
  339. delta = deltaY;
  340. } else if (parentHolder === leftOverlay) {
  341. delta = deltaX;
  342. }
  343. this.syncScrollPositions(eventMockup, mouseWheelSpeedRatio * delta);
  344. }
  345. return false;
  346. }
  347. /**
  348. * Synchronize scroll position between master table and overlay table.
  349. *
  350. * @private
  351. * @param {Event|Object} event
  352. * @param {Number} [fakeScrollValue=null]
  353. * @param {String} [fakeScrollDirection=null] `x` or `y`.
  354. */
  355. }, {
  356. key: 'syncScrollPositions',
  357. value: function syncScrollPositions(event) {
  358. var fakeScrollValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  359. var fakeScrollDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
  360. if (this.destroyed) {
  361. return;
  362. }
  363. if (arguments.length === 0) {
  364. this.syncScrollWithMaster();
  365. return;
  366. }
  367. var masterHorizontal = this.leftOverlay.mainTableScrollableElement;
  368. var masterVertical = this.topOverlay.mainTableScrollableElement;
  369. var target = event.target;
  370. var tempScrollValue = 0;
  371. var scrollValueChanged = false;
  372. var topOverlay = void 0;
  373. var leftOverlay = void 0;
  374. var topLeftCornerOverlay = void 0;
  375. var bottomLeftCornerOverlay = void 0;
  376. var bottomOverlay = void 0;
  377. var delegatedScroll = false;
  378. var preventOverflow = this.wot.getSetting('preventOverflow');
  379. if (this.topOverlay.needFullRender) {
  380. topOverlay = this.topOverlay.clone.wtTable.holder;
  381. }
  382. if (this.bottomOverlay.needFullRender) {
  383. bottomOverlay = this.bottomOverlay.clone.wtTable.holder;
  384. }
  385. if (this.leftOverlay.needFullRender) {
  386. leftOverlay = this.leftOverlay.clone.wtTable.holder;
  387. }
  388. if (this.leftOverlay.needFullRender && this.topOverlay.needFullRender) {
  389. topLeftCornerOverlay = this.topLeftCornerOverlay.clone.wtTable.holder;
  390. }
  391. if (this.leftOverlay.needFullRender && this.bottomOverlay.needFullRender) {
  392. bottomLeftCornerOverlay = this.bottomLeftCornerOverlay.clone.wtTable.holder;
  393. }
  394. if (target === document) {
  395. target = window;
  396. }
  397. if (target === masterHorizontal || target === masterVertical) {
  398. if (preventOverflow) {
  399. tempScrollValue = getScrollLeft(this.scrollableElement);
  400. } else {
  401. tempScrollValue = getScrollLeft(target);
  402. }
  403. // if scrolling the master table - populate the scroll values to both top and left overlays
  404. this.horizontalScrolling = true;
  405. this.overlayScrollPositions.master.left = tempScrollValue;
  406. scrollValueChanged = true;
  407. if (this.pendingScrollCallbacks.master.left > 0) {
  408. this.pendingScrollCallbacks.master.left--;
  409. } else {
  410. if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) {
  411. if (fakeScrollValue == null) {
  412. this.pendingScrollCallbacks.top.left++;
  413. }
  414. topOverlay.scrollLeft = tempScrollValue;
  415. delegatedScroll = masterHorizontal !== window;
  416. }
  417. if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) {
  418. if (fakeScrollValue == null) {
  419. this.pendingScrollCallbacks.bottom.left++;
  420. }
  421. bottomOverlay.scrollLeft = tempScrollValue;
  422. delegatedScroll = masterHorizontal !== window;
  423. }
  424. }
  425. tempScrollValue = getScrollTop(target);
  426. this.verticalScrolling = true;
  427. this.overlayScrollPositions.master.top = tempScrollValue;
  428. scrollValueChanged = true;
  429. if (this.pendingScrollCallbacks.master.top > 0) {
  430. this.pendingScrollCallbacks.master.top--;
  431. } else if (leftOverlay && leftOverlay.scrollTop !== tempScrollValue) {
  432. if (fakeScrollValue == null) {
  433. this.pendingScrollCallbacks.left.top++;
  434. }
  435. leftOverlay.scrollTop = tempScrollValue;
  436. delegatedScroll = masterVertical !== window;
  437. }
  438. } else if (target === bottomOverlay) {
  439. tempScrollValue = getScrollLeft(target);
  440. // if scrolling the bottom overlay - populate the horizontal scroll to the master table
  441. this.horizontalScrolling = true;
  442. this.overlayScrollPositions.bottom.left = tempScrollValue;
  443. scrollValueChanged = true;
  444. if (this.pendingScrollCallbacks.bottom.left > 0) {
  445. this.pendingScrollCallbacks.bottom.left--;
  446. } else {
  447. if (fakeScrollValue == null) {
  448. this.pendingScrollCallbacks.master.left++;
  449. }
  450. masterHorizontal.scrollLeft = tempScrollValue;
  451. if (topOverlay && topOverlay.scrollLeft !== tempScrollValue) {
  452. if (fakeScrollValue == null) {
  453. this.pendingScrollCallbacks.top.left++;
  454. }
  455. topOverlay.scrollLeft = tempScrollValue;
  456. delegatedScroll = masterVertical !== window;
  457. }
  458. }
  459. // "fake" scroll value calculated from the mousewheel event
  460. if (fakeScrollValue !== null) {
  461. scrollValueChanged = true;
  462. masterVertical.scrollTop += fakeScrollValue;
  463. }
  464. } else if (target === topOverlay) {
  465. tempScrollValue = getScrollLeft(target);
  466. // if scrolling the top overlay - populate the horizontal scroll to the master table
  467. this.horizontalScrolling = true;
  468. this.overlayScrollPositions.top.left = tempScrollValue;
  469. scrollValueChanged = true;
  470. if (this.pendingScrollCallbacks.top.left > 0) {
  471. this.pendingScrollCallbacks.top.left--;
  472. } else {
  473. if (fakeScrollValue == null) {
  474. this.pendingScrollCallbacks.master.left++;
  475. }
  476. masterHorizontal.scrollLeft = tempScrollValue;
  477. }
  478. // "fake" scroll value calculated from the mousewheel event
  479. if (fakeScrollValue !== null) {
  480. scrollValueChanged = true;
  481. masterVertical.scrollTop += fakeScrollValue;
  482. }
  483. if (bottomOverlay && bottomOverlay.scrollLeft !== tempScrollValue) {
  484. if (fakeScrollValue == null) {
  485. this.pendingScrollCallbacks.bottom.left++;
  486. }
  487. bottomOverlay.scrollLeft = tempScrollValue;
  488. delegatedScroll = masterVertical !== window;
  489. }
  490. } else if (target === leftOverlay) {
  491. tempScrollValue = getScrollTop(target);
  492. // if scrolling the left overlay - populate the vertical scroll to the master table
  493. if (this.overlayScrollPositions.left.top !== tempScrollValue) {
  494. this.verticalScrolling = true;
  495. this.overlayScrollPositions.left.top = tempScrollValue;
  496. scrollValueChanged = true;
  497. if (this.pendingScrollCallbacks.left.top > 0) {
  498. this.pendingScrollCallbacks.left.top--;
  499. } else {
  500. if (fakeScrollValue == null) {
  501. this.pendingScrollCallbacks.master.top++;
  502. }
  503. masterVertical.scrollTop = tempScrollValue;
  504. }
  505. }
  506. // "fake" scroll value calculated from the mousewheel event
  507. if (fakeScrollValue !== null) {
  508. scrollValueChanged = true;
  509. masterVertical.scrollLeft += fakeScrollValue;
  510. }
  511. } else if (target === topLeftCornerOverlay || target === bottomLeftCornerOverlay) {
  512. if (fakeScrollValue !== null) {
  513. scrollValueChanged = true;
  514. if (fakeScrollDirection === 'x') {
  515. masterVertical.scrollLeft += fakeScrollValue;
  516. } else if (fakeScrollDirection === 'y') {
  517. masterVertical.scrollTop += fakeScrollValue;
  518. }
  519. }
  520. }
  521. if (!this.keyPressed && scrollValueChanged && event.type === 'scroll') {
  522. if (this.delegatedScrollCallback) {
  523. this.delegatedScrollCallback = false;
  524. } else {
  525. this.refreshAll();
  526. }
  527. if (delegatedScroll) {
  528. this.delegatedScrollCallback = true;
  529. }
  530. }
  531. }
  532. /**
  533. * Synchronize overlay scrollbars with the master scrollbar
  534. */
  535. }, {
  536. key: 'syncScrollWithMaster',
  537. value: function syncScrollWithMaster() {
  538. var master = this.topOverlay.mainTableScrollableElement;
  539. var scrollLeft = master.scrollLeft,
  540. scrollTop = master.scrollTop;
  541. if (this.topOverlay.needFullRender) {
  542. this.topOverlay.clone.wtTable.holder.scrollLeft = scrollLeft;
  543. }
  544. if (this.bottomOverlay.needFullRender) {
  545. this.bottomOverlay.clone.wtTable.holder.scrollLeft = scrollLeft;
  546. }
  547. if (this.leftOverlay.needFullRender) {
  548. this.leftOverlay.clone.wtTable.holder.scrollTop = scrollTop;
  549. }
  550. }
  551. /**
  552. * Update the main scrollable elements for all the overlays.
  553. */
  554. }, {
  555. key: 'updateMainScrollableElements',
  556. value: function updateMainScrollableElements() {
  557. this.deregisterListeners();
  558. this.leftOverlay.updateMainScrollableElement();
  559. this.topOverlay.updateMainScrollableElement();
  560. if (this.bottomOverlay.needFullRender) {
  561. this.bottomOverlay.updateMainScrollableElement();
  562. }
  563. this.scrollableElement = getScrollableElement(this.wot.wtTable.TABLE);
  564. this.registerListeners();
  565. }
  566. /**
  567. *
  568. */
  569. }, {
  570. key: 'destroy',
  571. value: function destroy() {
  572. this.eventManager.destroy();
  573. this.topOverlay.destroy();
  574. if (this.bottomOverlay.clone) {
  575. this.bottomOverlay.destroy();
  576. }
  577. this.leftOverlay.destroy();
  578. if (this.topLeftCornerOverlay) {
  579. this.topLeftCornerOverlay.destroy();
  580. }
  581. if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) {
  582. this.bottomLeftCornerOverlay.destroy();
  583. }
  584. if (this.debug) {
  585. this.debug.destroy();
  586. }
  587. this.destroyed = true;
  588. }
  589. /**
  590. * @param {Boolean} [fastDraw=false]
  591. */
  592. }, {
  593. key: 'refresh',
  594. value: function refresh() {
  595. var fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  596. if (this.topOverlay.areElementSizesAdjusted && this.leftOverlay.areElementSizesAdjusted) {
  597. var container = this.wot.wtTable.wtRootElement.parentNode || this.wot.wtTable.wtRootElement;
  598. var width = container.clientWidth;
  599. var height = container.clientHeight;
  600. if (width !== this.spreaderLastSize.width || height !== this.spreaderLastSize.height) {
  601. this.spreaderLastSize.width = width;
  602. this.spreaderLastSize.height = height;
  603. this.adjustElementsSize();
  604. }
  605. }
  606. if (this.bottomOverlay.clone) {
  607. this.bottomOverlay.refresh(fastDraw);
  608. }
  609. this.leftOverlay.refresh(fastDraw);
  610. this.topOverlay.refresh(fastDraw);
  611. if (this.topLeftCornerOverlay) {
  612. this.topLeftCornerOverlay.refresh(fastDraw);
  613. }
  614. if (this.bottomLeftCornerOverlay && this.bottomLeftCornerOverlay.clone) {
  615. this.bottomLeftCornerOverlay.refresh(fastDraw);
  616. }
  617. if (this.debug) {
  618. this.debug.refresh(fastDraw);
  619. }
  620. }
  621. /**
  622. * Adjust overlays elements size and master table size
  623. *
  624. * @param {Boolean} [force=false]
  625. */
  626. }, {
  627. key: 'adjustElementsSize',
  628. value: function adjustElementsSize() {
  629. var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  630. var totalColumns = this.wot.getSetting('totalColumns');
  631. var totalRows = this.wot.getSetting('totalRows');
  632. var headerRowSize = this.wot.wtViewport.getRowHeaderWidth();
  633. var headerColumnSize = this.wot.wtViewport.getColumnHeaderHeight();
  634. var hiderStyle = this.wot.wtTable.hider.style;
  635. hiderStyle.width = headerRowSize + this.leftOverlay.sumCellSizes(0, totalColumns) + 'px';
  636. hiderStyle.height = headerColumnSize + this.topOverlay.sumCellSizes(0, totalRows) + 1 + 'px';
  637. this.topOverlay.adjustElementsSize(force);
  638. this.leftOverlay.adjustElementsSize(force);
  639. if (this.bottomOverlay.clone) {
  640. this.bottomOverlay.adjustElementsSize(force);
  641. }
  642. }
  643. /**
  644. *
  645. */
  646. }, {
  647. key: 'applyToDOM',
  648. value: function applyToDOM() {
  649. if (!this.topOverlay.areElementSizesAdjusted || !this.leftOverlay.areElementSizesAdjusted) {
  650. this.adjustElementsSize();
  651. }
  652. this.topOverlay.applyToDOM();
  653. if (this.bottomOverlay.clone) {
  654. this.bottomOverlay.applyToDOM();
  655. }
  656. this.leftOverlay.applyToDOM();
  657. }
  658. /**
  659. * Get the parent overlay of the provided element.
  660. *
  661. * @param {HTMLElement} element
  662. * @returns {Object|null}
  663. */
  664. }, {
  665. key: 'getParentOverlay',
  666. value: function getParentOverlay(element) {
  667. if (!element) {
  668. return null;
  669. }
  670. var overlays = [this.topOverlay, this.leftOverlay, this.bottomOverlay, this.topLeftCornerOverlay, this.bottomLeftCornerOverlay];
  671. var result = null;
  672. arrayEach(overlays, function (elem, i) {
  673. if (!elem) {
  674. return;
  675. }
  676. if (elem.clone && elem.clone.wtTable.TABLE.contains(element)) {
  677. result = elem.clone;
  678. }
  679. });
  680. return result;
  681. }
  682. }]);
  683. return Overlays;
  684. }();
  685. export default Overlays;