UNPKG

handsontable

Version:

Handsontable is a JavaScript Data Grid available for React, Angular and Vue.

152 lines (146 loc) 5.51 kB
"use strict"; exports.__esModule = true; require("core-js/modules/es.error.cause.js"); var _element = require("../../../helpers/dom/element"); function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /** * The class generates the nested headers structure in the DOM and reads the column width for * each column. The hierarchy is built only for visible, non-hidden columns. Each time the * column is shown or hidden, the structure is rebuilt, and the width of the columns in the * map updated. * * @private */ class GhostTable { constructor(hot, nestedHeaderSettingsGetter) { /** * Reference to the Handsontable instance. * * @private * @type {Handsontable} */ _defineProperty(this, "hot", void 0); /** * The function for retrieving the nested headers settings. * * @private * @type {Function} */ _defineProperty(this, "nestedHeaderSettingsGetter", void 0); /** * The value that holds information about the number of the nested header layers (header rows). * * @private * @type {number} */ _defineProperty(this, "layersCount", 0); /** * Temporary element created to get minimal headers widths. * * @private * @type {*} */ _defineProperty(this, "container", void 0); /** * PhysicalIndexToValueMap to keep and track of the columns' widths. * * @private * @type {PhysicalIndexToValueMap} */ _defineProperty(this, "widthsMap", void 0); this.hot = hot; this.nestedHeaderSettingsGetter = nestedHeaderSettingsGetter; this.widthsMap = this.hot.columnIndexMapper.createAndRegisterIndexMap('nestedHeaders.widthsMap', 'physicalIndexToValue'); } /** * Sets the number of nested headers layers count. * * @param {number} layersCount Total number of headers levels. * @returns {GhostTable} */ setLayersCount(layersCount) { this.layersCount = layersCount; return this; } /** * Gets the column width based on the visual column index. * * @param {number} visualColumn Visual column index. * @returns {number|null} */ getWidth(visualColumn) { return this.widthsMap.getValueAtIndex(this.hot.toPhysicalColumn(visualColumn)); } /** * Build cache of the headers widths. */ buildWidthsMap() { const currentThemeName = this.hot.getCurrentThemeName(); this.container = this.hot.rootDocument.createElement('div'); this.container.classList.add('handsontable', 'htGhostTable', 'htAutoSize'); if (currentThemeName) { this.container.classList.add(currentThemeName); } this._buildGhostTable(this.container); this.hot.rootDocument.body.appendChild(this.container); const columns = this.container.querySelectorAll('tr:last-of-type th'); const maxColumns = columns.length; this.widthsMap.clear(); for (let column = 0; column < maxColumns; column++) { const visualColumnsIndex = this.hot.columnIndexMapper.getVisualFromRenderableIndex(column); const physicalColumnIndex = this.hot.toPhysicalColumn(visualColumnsIndex); this.widthsMap.setValueAtIndex(physicalColumnIndex, columns[column].offsetWidth); } this.container.parentNode.removeChild(this.container); this.container = null; } /** * Build temporary table for getting minimal columns widths. * * @private * @param {HTMLElement} container The element where the DOM nodes are injected. */ _buildGhostTable(container) { const { rootDocument, columnIndexMapper } = this.hot; const fragment = rootDocument.createDocumentFragment(); const table = rootDocument.createElement('table'); const isDropdownEnabled = !!this.hot.getSettings().dropdownMenu; const maxRenderedCols = columnIndexMapper.getRenderableIndexesLength(); for (let row = 0; row < this.layersCount; row++) { const tr = rootDocument.createElement('tr'); for (let col = 0; col < maxRenderedCols; col++) { let visualColumnsIndex = columnIndexMapper.getVisualFromRenderableIndex(col); if (visualColumnsIndex === null) { visualColumnsIndex = col; } const th = rootDocument.createElement('th'); const headerSettings = this.nestedHeaderSettingsGetter(row, visualColumnsIndex); if (headerSettings && (!headerSettings.isPlaceholder || headerSettings.isHidden)) { let label = headerSettings.label; if (isDropdownEnabled) { label += '<button class="changeType"></button>'; } (0, _element.fastInnerHTML)(th, label); th.colSpan = headerSettings.colspan; tr.appendChild(th); } } table.appendChild(tr); } fragment.appendChild(table); container.appendChild(fragment); } /** * Clear the widths cache. */ clear() { this.widthsMap.clear(); this.container = null; } } var _default = exports.default = GhostTable;