64e9978cb8ccdb0dd1614509f4b906635e5ed4148b47e1a8b2fd461b81f1dc87ca3ad0404056a9f51979bb83cc8c318def249d87739953663a55c2fb76b4d2 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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. 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; }
  4. 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; }
  5. import { addClass, getScrollbarWidth, getScrollTop, getWindowScrollLeft, hasClass, outerHeight, innerWidth, removeClass, setOverlayPosition, resetCssTransform } from './../../../../helpers/dom/element';
  6. import Overlay from './_base';
  7. /**
  8. * @class TopOverlay
  9. */
  10. var TopOverlay = function (_Overlay) {
  11. _inherits(TopOverlay, _Overlay);
  12. /**
  13. * @param {Walkontable} wotInstance
  14. */
  15. function TopOverlay(wotInstance) {
  16. _classCallCheck(this, TopOverlay);
  17. var _this = _possibleConstructorReturn(this, (TopOverlay.__proto__ || Object.getPrototypeOf(TopOverlay)).call(this, wotInstance));
  18. _this.clone = _this.makeClone(Overlay.CLONE_TOP);
  19. return _this;
  20. }
  21. /**
  22. * Checks if overlay should be fully rendered
  23. *
  24. * @returns {Boolean}
  25. */
  26. _createClass(TopOverlay, [{
  27. key: 'shouldBeRendered',
  28. value: function shouldBeRendered() {
  29. return !!(this.wot.getSetting('fixedRowsTop') || this.wot.getSetting('columnHeaders').length);
  30. }
  31. /**
  32. * Updates the top overlay position
  33. */
  34. }, {
  35. key: 'resetFixedPosition',
  36. value: function resetFixedPosition() {
  37. if (!this.needFullRender || !this.wot.wtTable.holder.parentNode) {
  38. // removed from DOM
  39. return;
  40. }
  41. var overlayRoot = this.clone.wtTable.holder.parentNode;
  42. var headerPosition = 0;
  43. var preventOverflow = this.wot.getSetting('preventOverflow');
  44. if (this.trimmingContainer === window && (!preventOverflow || preventOverflow !== 'vertical')) {
  45. var box = this.wot.wtTable.hider.getBoundingClientRect();
  46. var top = Math.ceil(box.top);
  47. var bottom = Math.ceil(box.bottom);
  48. var finalLeft = void 0;
  49. var finalTop = void 0;
  50. finalLeft = this.wot.wtTable.hider.style.left;
  51. finalLeft = finalLeft === '' ? 0 : finalLeft;
  52. if (top < 0 && bottom - overlayRoot.offsetHeight > 0) {
  53. finalTop = -top;
  54. } else {
  55. finalTop = 0;
  56. }
  57. headerPosition = finalTop;
  58. finalTop += 'px';
  59. setOverlayPosition(overlayRoot, finalLeft, finalTop);
  60. } else {
  61. headerPosition = this.getScrollPosition();
  62. resetCssTransform(overlayRoot);
  63. }
  64. this.adjustHeaderBordersPosition(headerPosition);
  65. this.adjustElementsSize();
  66. }
  67. /**
  68. * Sets the main overlay's vertical scroll position
  69. *
  70. * @param {Number} pos
  71. */
  72. }, {
  73. key: 'setScrollPosition',
  74. value: function setScrollPosition(pos) {
  75. if (this.mainTableScrollableElement === window) {
  76. window.scrollTo(getWindowScrollLeft(), pos);
  77. } else {
  78. this.mainTableScrollableElement.scrollTop = pos;
  79. }
  80. }
  81. /**
  82. * Triggers onScroll hook callback
  83. */
  84. }, {
  85. key: 'onScroll',
  86. value: function onScroll() {
  87. this.wot.getSetting('onScrollHorizontally');
  88. }
  89. /**
  90. * Calculates total sum cells height
  91. *
  92. * @param {Number} from Row index which calculates started from
  93. * @param {Number} to Row index where calculation is finished
  94. * @returns {Number} Height sum
  95. */
  96. }, {
  97. key: 'sumCellSizes',
  98. value: function sumCellSizes(from, to) {
  99. var sum = 0;
  100. var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight;
  101. while (from < to) {
  102. var height = this.wot.wtTable.getRowHeight(from);
  103. sum += height === void 0 ? defaultRowHeight : height;
  104. from++;
  105. }
  106. return sum;
  107. }
  108. /**
  109. * Adjust overlay root element, childs and master table element sizes (width, height).
  110. *
  111. * @param {Boolean} [force=false]
  112. */
  113. }, {
  114. key: 'adjustElementsSize',
  115. value: function adjustElementsSize() {
  116. var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  117. this.updateTrimmingContainer();
  118. if (this.needFullRender || force) {
  119. this.adjustRootElementSize();
  120. this.adjustRootChildrenSize();
  121. if (!force) {
  122. this.areElementSizesAdjusted = true;
  123. }
  124. }
  125. }
  126. /**
  127. * Adjust overlay root element size (width and height).
  128. */
  129. }, {
  130. key: 'adjustRootElementSize',
  131. value: function adjustRootElementSize() {
  132. var masterHolder = this.wot.wtTable.holder;
  133. var scrollbarWidth = masterHolder.clientWidth === masterHolder.offsetWidth ? 0 : getScrollbarWidth();
  134. var overlayRoot = this.clone.wtTable.holder.parentNode;
  135. var overlayRootStyle = overlayRoot.style;
  136. var preventOverflow = this.wot.getSetting('preventOverflow');
  137. var tableHeight = void 0;
  138. if (this.trimmingContainer !== window || preventOverflow === 'horizontal') {
  139. var width = this.wot.wtViewport.getWorkspaceWidth() - scrollbarWidth;
  140. width = Math.min(width, innerWidth(this.wot.wtTable.wtRootElement));
  141. overlayRootStyle.width = width + 'px';
  142. } else {
  143. overlayRootStyle.width = '';
  144. }
  145. this.clone.wtTable.holder.style.width = overlayRootStyle.width;
  146. tableHeight = outerHeight(this.clone.wtTable.TABLE);
  147. overlayRootStyle.height = (tableHeight === 0 ? tableHeight : tableHeight + 4) + 'px';
  148. }
  149. /**
  150. * Adjust overlay root childs size
  151. */
  152. }, {
  153. key: 'adjustRootChildrenSize',
  154. value: function adjustRootChildrenSize() {
  155. var scrollbarWidth = getScrollbarWidth();
  156. this.clone.wtTable.hider.style.width = this.hider.style.width;
  157. this.clone.wtTable.holder.style.width = this.clone.wtTable.holder.parentNode.style.width;
  158. if (scrollbarWidth === 0) {
  159. scrollbarWidth = 30;
  160. }
  161. this.clone.wtTable.holder.style.height = parseInt(this.clone.wtTable.holder.parentNode.style.height, 10) + scrollbarWidth + 'px';
  162. }
  163. /**
  164. * Adjust the overlay dimensions and position
  165. */
  166. }, {
  167. key: 'applyToDOM',
  168. value: function applyToDOM() {
  169. var total = this.wot.getSetting('totalRows');
  170. if (!this.areElementSizesAdjusted) {
  171. this.adjustElementsSize();
  172. }
  173. if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') {
  174. this.spreader.style.top = this.wot.wtViewport.rowsRenderCalculator.startPosition + 'px';
  175. } else if (total === 0) {
  176. // can happen if there are 0 rows
  177. this.spreader.style.top = '0';
  178. } else {
  179. throw new Error('Incorrect value of the rowsRenderCalculator');
  180. }
  181. this.spreader.style.bottom = '';
  182. if (this.needFullRender) {
  183. this.syncOverlayOffset();
  184. }
  185. }
  186. /**
  187. * Synchronize calculated left position to an element
  188. */
  189. }, {
  190. key: 'syncOverlayOffset',
  191. value: function syncOverlayOffset() {
  192. if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') {
  193. this.clone.wtTable.spreader.style.left = this.wot.wtViewport.columnsRenderCalculator.startPosition + 'px';
  194. } else {
  195. this.clone.wtTable.spreader.style.left = '';
  196. }
  197. }
  198. /**
  199. * Scrolls vertically to a row
  200. *
  201. * @param sourceRow {Number} Row index which you want to scroll to
  202. * @param [bottomEdge=false] {Boolean} if `true`, scrolls according to the bottom edge (top edge is by default)
  203. */
  204. }, {
  205. key: 'scrollTo',
  206. value: function scrollTo(sourceRow, bottomEdge) {
  207. var newY = this.getTableParentOffset();
  208. var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
  209. var mainHolder = sourceInstance.wtTable.holder;
  210. var scrollbarCompensation = 0;
  211. if (bottomEdge && mainHolder.offsetHeight !== mainHolder.clientHeight) {
  212. scrollbarCompensation = getScrollbarWidth();
  213. }
  214. if (bottomEdge) {
  215. var fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
  216. var fixedRowsTop = this.wot.getSetting('fixedRowsTop');
  217. var totalRows = this.wot.getSetting('totalRows');
  218. newY += this.sumCellSizes(0, sourceRow + 1);
  219. newY -= this.wot.wtViewport.getViewportHeight() - this.sumCellSizes(totalRows - fixedRowsBottom, totalRows);
  220. // Fix 1 pixel offset when cell is selected
  221. newY += 1;
  222. } else {
  223. newY += this.sumCellSizes(this.wot.getSetting('fixedRowsTop'), sourceRow);
  224. }
  225. newY += scrollbarCompensation;
  226. this.setScrollPosition(newY);
  227. }
  228. /**
  229. * Gets table parent top position
  230. *
  231. * @returns {Number}
  232. */
  233. }, {
  234. key: 'getTableParentOffset',
  235. value: function getTableParentOffset() {
  236. if (this.mainTableScrollableElement === window) {
  237. return this.wot.wtTable.holderOffset.top;
  238. }
  239. return 0;
  240. }
  241. /**
  242. * Gets the main overlay's vertical scroll position
  243. *
  244. * @returns {Number} Main table's vertical scroll position
  245. */
  246. }, {
  247. key: 'getScrollPosition',
  248. value: function getScrollPosition() {
  249. return getScrollTop(this.mainTableScrollableElement);
  250. }
  251. /**
  252. * Redraw borders of selection
  253. *
  254. * @param {WalkontableSelection} selection Selection for redraw
  255. */
  256. }, {
  257. key: 'redrawSelectionBorders',
  258. value: function redrawSelectionBorders(selection) {
  259. if (selection && selection.cellRange) {
  260. var border = selection.getBorder(this.wot);
  261. if (border) {
  262. var corners = selection.getCorners();
  263. border.disappear();
  264. border.appear(corners);
  265. }
  266. }
  267. }
  268. /**
  269. * Redrawing borders of all selections
  270. */
  271. }, {
  272. key: 'redrawAllSelectionsBorders',
  273. value: function redrawAllSelectionsBorders() {
  274. var selections = this.wot.selections;
  275. this.redrawSelectionBorders(selections.current);
  276. this.redrawSelectionBorders(selections.area);
  277. this.redrawSelectionBorders(selections.fill);
  278. this.wot.wtTable.wot.wtOverlays.leftOverlay.refresh();
  279. }
  280. /**
  281. * Adds css classes to hide the header border's header (cell-selection border hiding issue)
  282. *
  283. * @param {Number} position Header Y position if trimming container is window or scroll top if not
  284. */
  285. }, {
  286. key: 'adjustHeaderBordersPosition',
  287. value: function adjustHeaderBordersPosition(position) {
  288. var masterParent = this.wot.wtTable.holder.parentNode;
  289. var totalColumns = this.wot.getSetting('totalColumns');
  290. if (totalColumns) {
  291. removeClass(masterParent, 'emptyColumns');
  292. } else {
  293. addClass(masterParent, 'emptyColumns');
  294. }
  295. if (this.wot.getSetting('fixedRowsTop') === 0 && this.wot.getSetting('columnHeaders').length > 0) {
  296. var previousState = hasClass(masterParent, 'innerBorderTop');
  297. if (position || this.wot.getSetting('totalRows') === 0) {
  298. addClass(masterParent, 'innerBorderTop');
  299. } else {
  300. removeClass(masterParent, 'innerBorderTop');
  301. }
  302. if (!previousState && position || previousState && !position) {
  303. this.wot.wtOverlays.adjustElementsSize();
  304. // cell borders should be positioned once again,
  305. // because we added / removed 1px border from table header
  306. this.redrawAllSelectionsBorders();
  307. }
  308. }
  309. // nasty workaround for double border in the header, TODO: find a pure-css solution
  310. if (this.wot.getSetting('rowHeaders').length === 0) {
  311. var secondHeaderCell = this.clone.wtTable.THEAD.querySelectorAll('th:nth-of-type(2)');
  312. if (secondHeaderCell) {
  313. for (var i = 0; i < secondHeaderCell.length; i++) {
  314. secondHeaderCell[i].style['border-left-width'] = 0;
  315. }
  316. }
  317. }
  318. }
  319. }]);
  320. return TopOverlay;
  321. }(Overlay);
  322. Overlay.registerOverlay(Overlay.CLONE_TOP, TopOverlay);
  323. export default TopOverlay;