c933584df8f8b6c19fd2b2677c98dd2928e8b72d3b48a05ef687668f3bc8b8869b0ff47a962fcc3fa45f688e909447e33abbe3c8330b525dbefa465c6e0826 13 KB

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