0cc42c4a28b1e734ac73dc67396ad44d38ebfa266744ee84d175f67d5e669faa5c003b7802b42ba252c03cd7d773609db6fbe501c87fc486d2c4d48b6083f6 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  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('./overlay/_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. var performanceWarningAppeared = false;
  10. /**
  11. * @class TableRenderer
  12. */
  13. var TableRenderer = function () {
  14. /**
  15. * @param {WalkontableTable} wtTable
  16. */
  17. function TableRenderer(wtTable) {
  18. _classCallCheck(this, TableRenderer);
  19. this.wtTable = wtTable;
  20. this.wot = wtTable.instance;
  21. // legacy support
  22. this.instance = wtTable.instance;
  23. this.rowFilter = wtTable.rowFilter;
  24. this.columnFilter = wtTable.columnFilter;
  25. this.TABLE = wtTable.TABLE;
  26. this.THEAD = wtTable.THEAD;
  27. this.TBODY = wtTable.TBODY;
  28. this.COLGROUP = wtTable.COLGROUP;
  29. this.rowHeaders = [];
  30. this.rowHeaderCount = 0;
  31. this.columnHeaders = [];
  32. this.columnHeaderCount = 0;
  33. this.fixedRowsTop = 0;
  34. this.fixedRowsBottom = 0;
  35. }
  36. /**
  37. *
  38. */
  39. _createClass(TableRenderer, [{
  40. key: 'render',
  41. value: function render() {
  42. if (!this.wtTable.isWorkingOnClone()) {
  43. var skipRender = {};
  44. this.wot.getSetting('beforeDraw', true, skipRender);
  45. if (skipRender.skipRender === true) {
  46. return;
  47. }
  48. }
  49. this.rowHeaders = this.wot.getSetting('rowHeaders');
  50. this.rowHeaderCount = this.rowHeaders.length;
  51. this.fixedRowsTop = this.wot.getSetting('fixedRowsTop');
  52. this.fixedRowsBottom = this.wot.getSetting('fixedRowsBottom');
  53. this.columnHeaders = this.wot.getSetting('columnHeaders');
  54. this.columnHeaderCount = this.columnHeaders.length;
  55. var columnsToRender = this.wtTable.getRenderedColumnsCount();
  56. var rowsToRender = this.wtTable.getRenderedRowsCount();
  57. var totalColumns = this.wot.getSetting('totalColumns');
  58. var totalRows = this.wot.getSetting('totalRows');
  59. var workspaceWidth = void 0;
  60. var adjusted = false;
  61. if (_base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM) || _base2.default.isOverlayTypeOf(this.wot.cloneOverlay, _base2.default.CLONE_BOTTOM_LEFT_CORNER)) {
  62. // do NOT render headers on the bottom or bottom-left corner overlay
  63. this.columnHeaders = [];
  64. this.columnHeaderCount = 0;
  65. }
  66. if (totalColumns >= 0) {
  67. // prepare COL and TH elements for rendering
  68. this.adjustAvailableNodes();
  69. adjusted = true;
  70. // adjust column widths according to user widths settings
  71. this.renderColumnHeaders();
  72. // Render table rows
  73. this.renderRows(totalRows, rowsToRender, columnsToRender);
  74. if (!this.wtTable.isWorkingOnClone()) {
  75. workspaceWidth = this.wot.wtViewport.getWorkspaceWidth();
  76. this.wot.wtViewport.containerWidth = null;
  77. }
  78. this.adjustColumnWidths(columnsToRender);
  79. this.markOversizedColumnHeaders();
  80. this.adjustColumnHeaderHeights();
  81. }
  82. if (!adjusted) {
  83. this.adjustAvailableNodes();
  84. }
  85. this.removeRedundantRows(rowsToRender);
  86. if (!this.wtTable.isWorkingOnClone() || this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) {
  87. this.markOversizedRows();
  88. }
  89. if (!this.wtTable.isWorkingOnClone()) {
  90. this.wot.wtViewport.createVisibleCalculators();
  91. this.wot.wtOverlays.refresh(false);
  92. this.wot.wtOverlays.applyToDOM();
  93. var hiderWidth = (0, _element.outerWidth)(this.wtTable.hider);
  94. var tableWidth = (0, _element.outerWidth)(this.wtTable.TABLE);
  95. if (hiderWidth !== 0 && tableWidth !== hiderWidth) {
  96. // Recalculate the column widths, if width changes made in the overlays removed the scrollbar, thus changing the viewport width.
  97. this.adjustColumnWidths(columnsToRender);
  98. }
  99. if (workspaceWidth !== this.wot.wtViewport.getWorkspaceWidth()) {
  100. // workspace width changed though to shown/hidden vertical scrollbar. Let's reapply stretching
  101. this.wot.wtViewport.containerWidth = null;
  102. var firstRendered = this.wtTable.getFirstRenderedColumn();
  103. var lastRendered = this.wtTable.getLastRenderedColumn();
  104. var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth');
  105. var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth');
  106. rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);
  107. if (rowHeaderWidthSetting != null) {
  108. for (var i = 0; i < this.rowHeaderCount; i++) {
  109. var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
  110. width = width == null ? defaultColumnWidth : width;
  111. this.COLGROUP.childNodes[i].style.width = width + 'px';
  112. }
  113. }
  114. for (var _i = firstRendered; _i < lastRendered; _i++) {
  115. var _width = this.wtTable.getStretchedColumnWidth(_i);
  116. var renderedIndex = this.columnFilter.sourceToRendered(_i);
  117. this.COLGROUP.childNodes[renderedIndex + this.rowHeaderCount].style.width = _width + 'px';
  118. }
  119. }
  120. this.wot.getSetting('onDraw', true);
  121. } else if (this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) {
  122. this.wot.cloneSource.wtOverlays.adjustElementsSize();
  123. }
  124. }
  125. /**
  126. * @param {Number} renderedRowsCount
  127. */
  128. }, {
  129. key: 'removeRedundantRows',
  130. value: function removeRedundantRows(renderedRowsCount) {
  131. while (this.wtTable.tbodyChildrenLength > renderedRowsCount) {
  132. this.TBODY.removeChild(this.TBODY.lastChild);
  133. this.wtTable.tbodyChildrenLength--;
  134. }
  135. }
  136. /**
  137. * @param {Number} totalRows
  138. * @param {Number} rowsToRender
  139. * @param {Number} columnsToRender
  140. */
  141. }, {
  142. key: 'renderRows',
  143. value: function renderRows(totalRows, rowsToRender, columnsToRender) {
  144. var lastTD = void 0,
  145. TR = void 0;
  146. var visibleRowIndex = 0;
  147. var sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex);
  148. var isWorkingOnClone = this.wtTable.isWorkingOnClone();
  149. while (sourceRowIndex < totalRows && sourceRowIndex >= 0) {
  150. if (!performanceWarningAppeared && visibleRowIndex > 1000) {
  151. performanceWarningAppeared = true;
  152. console.warn('Performance tip: Handsontable rendered more than 1000 visible rows. Consider limiting the number ' + 'of rendered rows by specifying the table height and/or turning off the "renderAllRows" option.');
  153. }
  154. if (rowsToRender !== void 0 && visibleRowIndex === rowsToRender) {
  155. // We have as much rows as needed for this clone
  156. break;
  157. }
  158. TR = this.getOrCreateTrForRow(visibleRowIndex, TR);
  159. // Render row headers
  160. this.renderRowHeaders(sourceRowIndex, TR);
  161. // Add and/or remove TDs to TR to match the desired number
  162. this.adjustColumns(TR, columnsToRender + this.rowHeaderCount);
  163. lastTD = this.renderCells(sourceRowIndex, TR, columnsToRender);
  164. if (!isWorkingOnClone ||
  165. // Necessary to refresh oversized row heights after editing cell in overlays
  166. this.wot.isOverlayName(_base2.default.CLONE_BOTTOM)) {
  167. // Reset the oversized row cache for this row
  168. this.resetOversizedRow(sourceRowIndex);
  169. }
  170. if (TR.firstChild) {
  171. // if I have 2 fixed columns with one-line content and the 3rd column has a multiline content, this is
  172. // the way to make sure that the overlay will has same row height
  173. var height = this.wot.wtTable.getRowHeight(sourceRowIndex);
  174. if (height) {
  175. // Decrease height. 1 pixel will be "replaced" by 1px border top
  176. height--;
  177. TR.firstChild.style.height = height + 'px';
  178. } else {
  179. TR.firstChild.style.height = '';
  180. }
  181. }
  182. visibleRowIndex++;
  183. sourceRowIndex = this.rowFilter.renderedToSource(visibleRowIndex);
  184. }
  185. }
  186. /**
  187. * Reset the oversized row cache for the provided index
  188. *
  189. * @param {Number} sourceRow Row index
  190. */
  191. }, {
  192. key: 'resetOversizedRow',
  193. value: function resetOversizedRow(sourceRow) {
  194. if (this.wot.getSetting('externalRowCalculator')) {
  195. return;
  196. }
  197. if (this.wot.wtViewport.oversizedRows && this.wot.wtViewport.oversizedRows[sourceRow]) {
  198. this.wot.wtViewport.oversizedRows[sourceRow] = void 0;
  199. }
  200. }
  201. /**
  202. * Check if any of the rendered rows is higher than expected, and if so, cache them
  203. */
  204. }, {
  205. key: 'markOversizedRows',
  206. value: function markOversizedRows() {
  207. if (this.wot.getSetting('externalRowCalculator')) {
  208. return;
  209. }
  210. var rowCount = this.instance.wtTable.TBODY.childNodes.length;
  211. var expectedTableHeight = rowCount * this.instance.wtSettings.settings.defaultRowHeight;
  212. var actualTableHeight = (0, _element.innerHeight)(this.instance.wtTable.TBODY) - 1;
  213. var previousRowHeight = void 0;
  214. var rowInnerHeight = void 0;
  215. var sourceRowIndex = void 0;
  216. var currentTr = void 0;
  217. var rowHeader = void 0;
  218. var totalRows = this.instance.getSetting('totalRows');
  219. if (expectedTableHeight === actualTableHeight && !this.instance.getSetting('fixedRowsBottom')) {
  220. // If the actual table height equals rowCount * default single row height, no row is oversized -> no need to iterate over them
  221. return;
  222. }
  223. while (rowCount) {
  224. rowCount--;
  225. sourceRowIndex = this.instance.wtTable.rowFilter.renderedToSource(rowCount);
  226. previousRowHeight = this.instance.wtTable.getRowHeight(sourceRowIndex);
  227. currentTr = this.instance.wtTable.getTrForRow(sourceRowIndex);
  228. rowHeader = currentTr.querySelector('th');
  229. if (rowHeader) {
  230. rowInnerHeight = (0, _element.innerHeight)(rowHeader);
  231. } else {
  232. rowInnerHeight = (0, _element.innerHeight)(currentTr) - 1;
  233. }
  234. if (!previousRowHeight && this.instance.wtSettings.settings.defaultRowHeight < rowInnerHeight || previousRowHeight < rowInnerHeight) {
  235. this.instance.wtViewport.oversizedRows[sourceRowIndex] = ++rowInnerHeight;
  236. }
  237. }
  238. }
  239. /**
  240. * Check if any of the rendered columns is higher than expected, and if so, cache them.
  241. */
  242. }, {
  243. key: 'markOversizedColumnHeaders',
  244. value: function markOversizedColumnHeaders() {
  245. var overlayName = this.wot.getOverlayName();
  246. if (!this.columnHeaderCount || this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] || this.wtTable.isWorkingOnClone()) {
  247. return;
  248. }
  249. var columnCount = this.wtTable.getRenderedColumnsCount();
  250. for (var i = 0; i < this.columnHeaderCount; i++) {
  251. for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) {
  252. this.markIfOversizedColumnHeader(renderedColumnIndex);
  253. }
  254. }
  255. this.wot.wtViewport.hasOversizedColumnHeadersMarked[overlayName] = true;
  256. }
  257. /**
  258. *
  259. */
  260. }, {
  261. key: 'adjustColumnHeaderHeights',
  262. value: function adjustColumnHeaderHeights() {
  263. var columnHeaders = this.wot.getSetting('columnHeaders');
  264. var children = this.wot.wtTable.THEAD.childNodes;
  265. var oversizedColumnHeaders = this.wot.wtViewport.oversizedColumnHeaders;
  266. for (var i = 0, len = columnHeaders.length; i < len; i++) {
  267. if (oversizedColumnHeaders[i]) {
  268. if (!children[i] || children[i].childNodes.length === 0) {
  269. return;
  270. }
  271. children[i].childNodes[0].style.height = oversizedColumnHeaders[i] + 'px';
  272. }
  273. }
  274. }
  275. /**
  276. * Check if column header for the specified column is higher than expected, and if so, cache it
  277. *
  278. * @param {Number} col Index of column
  279. */
  280. }, {
  281. key: 'markIfOversizedColumnHeader',
  282. value: function markIfOversizedColumnHeader(col) {
  283. var sourceColIndex = this.wot.wtTable.columnFilter.renderedToSource(col);
  284. var level = this.columnHeaderCount;
  285. var defaultRowHeight = this.wot.wtSettings.settings.defaultRowHeight;
  286. var previousColHeaderHeight = void 0;
  287. var currentHeader = void 0;
  288. var currentHeaderHeight = void 0;
  289. var columnHeaderHeightSetting = this.wot.getSetting('columnHeaderHeight') || [];
  290. while (level) {
  291. level--;
  292. previousColHeaderHeight = this.wot.wtTable.getColumnHeaderHeight(level);
  293. currentHeader = this.wot.wtTable.getColumnHeader(sourceColIndex, level);
  294. if (!currentHeader) {
  295. /* eslint-disable no-continue */
  296. continue;
  297. }
  298. currentHeaderHeight = (0, _element.innerHeight)(currentHeader);
  299. if (!previousColHeaderHeight && defaultRowHeight < currentHeaderHeight || previousColHeaderHeight < currentHeaderHeight) {
  300. this.wot.wtViewport.oversizedColumnHeaders[level] = currentHeaderHeight;
  301. }
  302. if (Array.isArray(columnHeaderHeightSetting)) {
  303. if (columnHeaderHeightSetting[level] != null) {
  304. this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level];
  305. }
  306. } else if (!isNaN(columnHeaderHeightSetting)) {
  307. this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting;
  308. }
  309. if (this.wot.wtViewport.oversizedColumnHeaders[level] < (columnHeaderHeightSetting[level] || columnHeaderHeightSetting)) {
  310. this.wot.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level] || columnHeaderHeightSetting;
  311. }
  312. }
  313. }
  314. /**
  315. * @param {Number} sourceRowIndex
  316. * @param {HTMLTableRowElement} TR
  317. * @param {Number} columnsToRender
  318. * @returns {HTMLTableCellElement}
  319. */
  320. }, {
  321. key: 'renderCells',
  322. value: function renderCells(sourceRowIndex, TR, columnsToRender) {
  323. var TD = void 0;
  324. var sourceColIndex = void 0;
  325. for (var visibleColIndex = 0; visibleColIndex < columnsToRender; visibleColIndex++) {
  326. sourceColIndex = this.columnFilter.renderedToSource(visibleColIndex);
  327. if (visibleColIndex === 0) {
  328. TD = TR.childNodes[this.columnFilter.sourceColumnToVisibleRowHeadedColumn(sourceColIndex)];
  329. } else {
  330. TD = TD.nextSibling; // http://jsperf.com/nextsibling-vs-indexed-childnodes
  331. }
  332. // If the number of headers has been reduced, we need to replace excess TH with TD
  333. if (TD.nodeName == 'TH') {
  334. TD = replaceThWithTd(TD, TR);
  335. }
  336. if (!(0, _element.hasClass)(TD, 'hide')) {
  337. TD.className = '';
  338. }
  339. TD.removeAttribute('style');
  340. this.wot.wtSettings.settings.cellRenderer(sourceRowIndex, sourceColIndex, TD);
  341. }
  342. return TD;
  343. }
  344. /**
  345. * @param {Number} columnsToRender Number of columns to render.
  346. */
  347. }, {
  348. key: 'adjustColumnWidths',
  349. value: function adjustColumnWidths(columnsToRender) {
  350. var scrollbarCompensation = 0;
  351. var sourceInstance = this.wot.cloneSource ? this.wot.cloneSource : this.wot;
  352. var mainHolder = sourceInstance.wtTable.holder;
  353. var defaultColumnWidth = this.wot.getSetting('defaultColumnWidth');
  354. var rowHeaderWidthSetting = this.wot.getSetting('rowHeaderWidth');
  355. if (mainHolder.offsetHeight < mainHolder.scrollHeight) {
  356. scrollbarCompensation = (0, _element.getScrollbarWidth)();
  357. }
  358. this.wot.wtViewport.columnsRenderCalculator.refreshStretching(this.wot.wtViewport.getViewportWidth() - scrollbarCompensation);
  359. rowHeaderWidthSetting = this.instance.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);
  360. if (rowHeaderWidthSetting != null) {
  361. for (var i = 0; i < this.rowHeaderCount; i++) {
  362. var width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[i] : rowHeaderWidthSetting;
  363. width = width == null ? defaultColumnWidth : width;
  364. this.COLGROUP.childNodes[i].style.width = width + 'px';
  365. }
  366. }
  367. for (var renderedColIndex = 0; renderedColIndex < columnsToRender; renderedColIndex++) {
  368. var _width2 = this.wtTable.getStretchedColumnWidth(this.columnFilter.renderedToSource(renderedColIndex));
  369. this.COLGROUP.childNodes[renderedColIndex + this.rowHeaderCount].style.width = _width2 + 'px';
  370. }
  371. }
  372. /**
  373. * @param {HTMLTableCellElement} TR
  374. */
  375. }, {
  376. key: 'appendToTbody',
  377. value: function appendToTbody(TR) {
  378. this.TBODY.appendChild(TR);
  379. this.wtTable.tbodyChildrenLength++;
  380. }
  381. /**
  382. * @param {Number} rowIndex
  383. * @param {HTMLTableRowElement} currentTr
  384. * @returns {HTMLTableCellElement}
  385. */
  386. }, {
  387. key: 'getOrCreateTrForRow',
  388. value: function getOrCreateTrForRow(rowIndex, currentTr) {
  389. var TR = void 0;
  390. if (rowIndex >= this.wtTable.tbodyChildrenLength) {
  391. TR = this.createRow();
  392. this.appendToTbody(TR);
  393. } else if (rowIndex === 0) {
  394. TR = this.TBODY.firstChild;
  395. } else {
  396. // http://jsperf.com/nextsibling-vs-indexed-childnodes
  397. TR = currentTr.nextSibling;
  398. }
  399. if (TR.className) {
  400. TR.removeAttribute('class');
  401. }
  402. return TR;
  403. }
  404. /**
  405. * @returns {HTMLTableCellElement}
  406. */
  407. }, {
  408. key: 'createRow',
  409. value: function createRow() {
  410. var TR = document.createElement('TR');
  411. for (var visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) {
  412. TR.appendChild(document.createElement('TH'));
  413. }
  414. return TR;
  415. }
  416. /**
  417. * @param {Number} row
  418. * @param {Number} col
  419. * @param {HTMLTableCellElement} TH
  420. */
  421. }, {
  422. key: 'renderRowHeader',
  423. value: function renderRowHeader(row, col, TH) {
  424. TH.className = '';
  425. TH.removeAttribute('style');
  426. this.rowHeaders[col](row, TH, col);
  427. }
  428. /**
  429. * @param {Number} row
  430. * @param {HTMLTableCellElement} TR
  431. */
  432. }, {
  433. key: 'renderRowHeaders',
  434. value: function renderRowHeaders(row, TR) {
  435. for (var TH = TR.firstChild, visibleColIndex = 0; visibleColIndex < this.rowHeaderCount; visibleColIndex++) {
  436. // If the number of row headers increased we need to create TH or replace an existing TD node with TH
  437. if (!TH) {
  438. TH = document.createElement('TH');
  439. TR.appendChild(TH);
  440. } else if (TH.nodeName == 'TD') {
  441. TH = replaceTdWithTh(TH, TR);
  442. }
  443. this.renderRowHeader(row, visibleColIndex, TH);
  444. // http://jsperf.com/nextsibling-vs-indexed-childnodes
  445. TH = TH.nextSibling;
  446. }
  447. }
  448. /**
  449. * Adjust the number of COL and TH elements to match the number of columns and headers that need to be rendered
  450. */
  451. }, {
  452. key: 'adjustAvailableNodes',
  453. value: function adjustAvailableNodes() {
  454. this.adjustColGroups();
  455. this.adjustThead();
  456. }
  457. /**
  458. * Renders the column headers
  459. */
  460. }, {
  461. key: 'renderColumnHeaders',
  462. value: function renderColumnHeaders() {
  463. if (!this.columnHeaderCount) {
  464. return;
  465. }
  466. var columnCount = this.wtTable.getRenderedColumnsCount();
  467. for (var i = 0; i < this.columnHeaderCount; i++) {
  468. var TR = this.getTrForColumnHeaders(i);
  469. for (var renderedColumnIndex = -1 * this.rowHeaderCount; renderedColumnIndex < columnCount; renderedColumnIndex++) {
  470. var sourceCol = this.columnFilter.renderedToSource(renderedColumnIndex);
  471. this.renderColumnHeader(i, sourceCol, TR.childNodes[renderedColumnIndex + this.rowHeaderCount]);
  472. }
  473. }
  474. }
  475. /**
  476. * Adjusts the number of COL elements to match the number of columns that need to be rendered
  477. */
  478. }, {
  479. key: 'adjustColGroups',
  480. value: function adjustColGroups() {
  481. var columnCount = this.wtTable.getRenderedColumnsCount();
  482. while (this.wtTable.colgroupChildrenLength < columnCount + this.rowHeaderCount) {
  483. this.COLGROUP.appendChild(document.createElement('COL'));
  484. this.wtTable.colgroupChildrenLength++;
  485. }
  486. while (this.wtTable.colgroupChildrenLength > columnCount + this.rowHeaderCount) {
  487. this.COLGROUP.removeChild(this.COLGROUP.lastChild);
  488. this.wtTable.colgroupChildrenLength--;
  489. }
  490. if (this.rowHeaderCount) {
  491. (0, _element.addClass)(this.COLGROUP.childNodes[0], 'rowHeader');
  492. }
  493. }
  494. /**
  495. * Adjusts the number of TH elements in THEAD to match the number of headers and columns that need to be rendered
  496. */
  497. }, {
  498. key: 'adjustThead',
  499. value: function adjustThead() {
  500. var columnCount = this.wtTable.getRenderedColumnsCount();
  501. var TR = this.THEAD.firstChild;
  502. if (this.columnHeaders.length) {
  503. for (var i = 0, len = this.columnHeaders.length; i < len; i++) {
  504. TR = this.THEAD.childNodes[i];
  505. if (!TR) {
  506. TR = document.createElement('TR');
  507. this.THEAD.appendChild(TR);
  508. }
  509. this.theadChildrenLength = TR.childNodes.length;
  510. while (this.theadChildrenLength < columnCount + this.rowHeaderCount) {
  511. TR.appendChild(document.createElement('TH'));
  512. this.theadChildrenLength++;
  513. }
  514. while (this.theadChildrenLength > columnCount + this.rowHeaderCount) {
  515. TR.removeChild(TR.lastChild);
  516. this.theadChildrenLength--;
  517. }
  518. }
  519. var theadChildrenLength = this.THEAD.childNodes.length;
  520. if (theadChildrenLength > this.columnHeaders.length) {
  521. for (var _i2 = this.columnHeaders.length; _i2 < theadChildrenLength; _i2++) {
  522. this.THEAD.removeChild(this.THEAD.lastChild);
  523. }
  524. }
  525. } else if (TR) {
  526. (0, _element.empty)(TR);
  527. }
  528. }
  529. /**
  530. * @param {Number} index
  531. * @returns {HTMLTableCellElement}
  532. */
  533. }, {
  534. key: 'getTrForColumnHeaders',
  535. value: function getTrForColumnHeaders(index) {
  536. return this.THEAD.childNodes[index];
  537. }
  538. /**
  539. * @param {Number} row
  540. * @param {Number} col
  541. * @param {HTMLTableCellElement} TH
  542. * @returns {*}
  543. */
  544. }, {
  545. key: 'renderColumnHeader',
  546. value: function renderColumnHeader(row, col, TH) {
  547. TH.className = '';
  548. TH.removeAttribute('style');
  549. return this.columnHeaders[row](col, TH, row);
  550. }
  551. /**
  552. * Add and/or remove the TDs to match the desired number
  553. *
  554. * @param {HTMLTableCellElement} TR Table row in question
  555. * @param {Number} desiredCount The desired number of TDs in the TR
  556. */
  557. }, {
  558. key: 'adjustColumns',
  559. value: function adjustColumns(TR, desiredCount) {
  560. var count = TR.childNodes.length;
  561. while (count < desiredCount) {
  562. var TD = document.createElement('TD');
  563. TR.appendChild(TD);
  564. count++;
  565. }
  566. while (count > desiredCount) {
  567. TR.removeChild(TR.lastChild);
  568. count--;
  569. }
  570. }
  571. /**
  572. * @param {Number} columnsToRender
  573. */
  574. }, {
  575. key: 'removeRedundantColumns',
  576. value: function removeRedundantColumns(columnsToRender) {
  577. while (this.wtTable.tbodyChildrenLength > columnsToRender) {
  578. this.TBODY.removeChild(this.TBODY.lastChild);
  579. this.wtTable.tbodyChildrenLength--;
  580. }
  581. }
  582. }]);
  583. return TableRenderer;
  584. }();
  585. function replaceTdWithTh(TD, TR) {
  586. var TH = document.createElement('TH');
  587. TR.insertBefore(TH, TD);
  588. TR.removeChild(TD);
  589. return TH;
  590. }
  591. function replaceThWithTd(TH, TR) {
  592. var TD = document.createElement('TD');
  593. TR.insertBefore(TD, TH);
  594. TR.removeChild(TH);
  595. return TD;
  596. }
  597. exports.default = TableRenderer;