UNPKG

handsontable

Version:

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

292 lines (284 loc) • 11.8 kB
import "core-js/modules/es.error.cause.js"; import "core-js/modules/esnext.iterator.constructor.js"; import "core-js/modules/esnext.iterator.for-each.js"; function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); } function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); } function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); } function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; } function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } import { warn } from "../helpers/console.mjs"; const CLASSIC_THEME_DEFAULT_HEIGHT = 23; /** * Handles the theme-related style operations. */ var _themeName = /*#__PURE__*/new WeakMap(); var _rootElement = /*#__PURE__*/new WeakMap(); var _rootComputedStyle = /*#__PURE__*/new WeakMap(); var _rootDocument = /*#__PURE__*/new WeakMap(); var _isClassicTheme = /*#__PURE__*/new WeakMap(); var _cssVars = /*#__PURE__*/new WeakMap(); var _computedStyles = /*#__PURE__*/new WeakMap(); var _onThemeChange = /*#__PURE__*/new WeakMap(); var _StylesHandler_brand = /*#__PURE__*/new WeakSet(); export class StylesHandler { /** * Initializes a new instance of the `StylesHandler` class. * * @param {object} options The options for the `StylesHandler` instance. * @param {HTMLElement} options.rootElement The root element of the instance. * @param {Document} options.rootDocument The root document of the instance. * @param {function(string)} options.onThemeChange The callback function to be called when the theme changes. */ constructor(_ref) { let { rootElement: _rootElement2, rootDocument: _rootDocument2, onThemeChange = () => {} } = _ref; /** * Calculates the row height based on the current theme and CSS variables. * * @returns {number|null} The calculated row height, or `null` if any required CSS variable is not found. */ _classPrivateMethodInitSpec(this, _StylesHandler_brand); /** * The name of the theme. * * @type {string|undefined} */ _classPrivateFieldInitSpec(this, _themeName, void 0); /** * The instance's root element. * * @type {HTMLElement} */ _classPrivateFieldInitSpec(this, _rootElement, void 0); /** * The computed style of the root element. * * @type {CSSStyleDeclaration} * @private */ _classPrivateFieldInitSpec(this, _rootComputedStyle, void 0); /** * The root document of the instance. * * @type {Document} */ _classPrivateFieldInitSpec(this, _rootDocument, void 0); /** * `true` if the classic theme is enabled, `false` otherwise. * * @type {boolean} */ _classPrivateFieldInitSpec(this, _isClassicTheme, true); /** * An object to store CSS variable values. * * @type {object} */ _classPrivateFieldInitSpec(this, _cssVars, {}); /** * Stores the computed styles for various elements. * * @type {object} - An object containing the computed styles if a nested structure of `element: { [element type]: {property: value} }`. */ _classPrivateFieldInitSpec(this, _computedStyles, {}); /** * The callback function to be called when the theme changes. * * @type {function(string)} */ _classPrivateFieldInitSpec(this, _onThemeChange, void 0); _classPrivateFieldSet(_rootElement, this, _rootElement2); _classPrivateFieldSet(_rootDocument, this, _rootDocument2); _classPrivateFieldSet(_onThemeChange, this, onThemeChange); } /** * Gets the value indicating whether the classic theme is enabled. * * @returns {boolean} `true` if the classic theme is enabled, `false` otherwise. */ isClassicTheme() { return _classPrivateFieldGet(_isClassicTheme, this); } /** * Retrieves the value of a specified CSS variable. * * @param {string} variableName - The name of the CSS variable to retrieve. * @returns {number|null|undefined} The value of the specified CSS variable, or `undefined` if not found. */ getCSSVariableValue(variableName) { var _assertClassBrand$cal; if (_classPrivateFieldGet(_isClassicTheme, this)) { return null; } if (_classPrivateFieldGet(_cssVars, this)[`--ht-${variableName}`]) { return _classPrivateFieldGet(_cssVars, this)[`--ht-${variableName}`]; } const acquiredValue = (_assertClassBrand$cal = _assertClassBrand(_StylesHandler_brand, this, _getParsedNumericCSSValue).call(this, `--ht-${variableName}`)) !== null && _assertClassBrand$cal !== void 0 ? _assertClassBrand$cal : _assertClassBrand(_StylesHandler_brand, this, _getCSSValue).call(this, `--ht-${variableName}`); if (acquiredValue !== null) { _classPrivateFieldGet(_cssVars, this)[`--ht-${variableName}`] = acquiredValue; return acquiredValue; } } /** * Retrieves the computed style value for a specified CSS property of a `td` element. * * @param {string} cssProperty - The CSS property to retrieve the value for. * @returns {number|string|undefined} The value of the specified CSS property, or `undefined` if not found. */ getStyleForTD(cssProperty) { var _classPrivateFieldGet2; return (_classPrivateFieldGet2 = _classPrivateFieldGet(_computedStyles, this)) === null || _classPrivateFieldGet2 === void 0 ? void 0 : _classPrivateFieldGet2.td[cssProperty]; } /** * Calculates the row height based on the current theme and CSS variables. * * @returns {number} The calculated row height. */ getDefaultRowHeight() { if (_classPrivateFieldGet(_isClassicTheme, this)) { return CLASSIC_THEME_DEFAULT_HEIGHT; } const calculatedRowHeight = _assertClassBrand(_StylesHandler_brand, this, _calculateRowHeight).call(this); if (!calculatedRowHeight) { return CLASSIC_THEME_DEFAULT_HEIGHT; } return calculatedRowHeight; } /** * Checks if the cells are using the `border-box` box-sizing model. * * @returns {boolean} */ areCellsBorderBox() { return this.getStyleForTD('box-sizing') === 'border-box'; } /** * Applies the specified theme to the instance. * * @param {string|undefined|boolean} [themeName] - The name of the theme to apply. */ useTheme(themeName) { if (!themeName) { _classPrivateFieldSet(_themeName, this, undefined); _classPrivateFieldSet(_isClassicTheme, this, true); _classPrivateFieldGet(_onThemeChange, this).call(this, _classPrivateFieldGet(_themeName, this)); _assertClassBrand(_StylesHandler_brand, this, _cacheStylesheetValues).call(this); return; } if (themeName && themeName !== _classPrivateFieldGet(_themeName, this)) { if (!/ht-theme-.*/.test(themeName)) { warn(`Invalid theme name: ${themeName}. Please provide a valid theme name.`); _classPrivateFieldSet(_themeName, this, undefined); _classPrivateFieldSet(_isClassicTheme, this, false); _classPrivateFieldGet(_onThemeChange, this).call(this, _classPrivateFieldGet(_themeName, this)); _assertClassBrand(_StylesHandler_brand, this, _cacheStylesheetValues).call(this); return; } if (_classPrivateFieldGet(_themeName, this)) { _assertClassBrand(_StylesHandler_brand, this, _clearCachedValues).call(this); } _classPrivateFieldSet(_themeName, this, themeName); _classPrivateFieldSet(_isClassicTheme, this, false); _classPrivateFieldGet(_onThemeChange, this).call(this, _classPrivateFieldGet(_themeName, this)); _assertClassBrand(_StylesHandler_brand, this, _cacheStylesheetValues).call(this); } } /** * Gets the name of the theme. * * @returns {string|undefined} */ getThemeName() { return _classPrivateFieldGet(_themeName, this); } } function _calculateRowHeight() { const lineHeightVarValue = this.getCSSVariableValue('line-height'); const verticalPaddingVarValue = this.getCSSVariableValue('cell-vertical-padding'); const bottomBorderWidth = Math.ceil(parseFloat(this.getStyleForTD('border-bottom-width'))); if (lineHeightVarValue === null || verticalPaddingVarValue === null || isNaN(bottomBorderWidth)) { return null; } return lineHeightVarValue + 2 * verticalPaddingVarValue + bottomBorderWidth; } /** * Caches the computed style values for the root element and `td` element. */ function _cacheStylesheetValues() { if (!this.isClassicTheme()) { _classPrivateFieldSet(_rootComputedStyle, this, getComputedStyle(_classPrivateFieldGet(_rootElement, this))); } const stylesForTD = _assertClassBrand(_StylesHandler_brand, this, _getStylesForTD).call(this, ['box-sizing', 'border-bottom-width']); _classPrivateFieldGet(_computedStyles, this).td = { ..._classPrivateFieldGet(_computedStyles, this).td, ...{ 'box-sizing': stylesForTD['box-sizing'], 'border-bottom-width': stylesForTD['border-bottom-width'] } }; } /** * Retrieves and processes the computed styles for a `td` element. * * This method creates a temporary table structure, appends it to the root element, * retrieves the computed styles for the `td` element, and then removes the table * from the DOM. The computed styles are passed to the provided callback function. * * @param {Array} cssProps - An array of CSS properties to retrieve. * @returns {object} An object containing the requested computed styles for the `td` element. * @private */ function _getStylesForTD(cssProps) { const rootDocument = _classPrivateFieldGet(_rootDocument, this); const rootElement = _classPrivateFieldGet(_rootElement, this); const table = rootDocument.createElement('table'); const tbody = rootDocument.createElement('tbody'); const tr = rootDocument.createElement('tr'); // This needs not to be the first row in order to get "regular" values. const tr2 = rootDocument.createElement('tr'); const td = rootDocument.createElement('td'); tr2.appendChild(td); tbody.appendChild(tr); tbody.appendChild(tr2); table.appendChild(tbody); rootElement.appendChild(table); const computedStyle = getComputedStyle(td); const returnObject = {}; cssProps.forEach(prop => { returnObject[prop] = computedStyle.getPropertyValue(prop); }); rootElement.removeChild(table); return returnObject; } /** * Parses the numeric value of a specified CSS property from the root element's computed style. * * @param {string} property - The CSS property to retrieve and parse. * @returns {number|null} The parsed value of the CSS property or `null` if non-existent. */ function _getParsedNumericCSSValue(property) { const parsedValue = Math.ceil(parseFloat(_assertClassBrand(_StylesHandler_brand, this, _getCSSValue).call(this, property))); return Number.isNaN(parsedValue) ? null : parsedValue; } /** * Retrieves the non-numeric value of a specified CSS property from the root element's computed style. * * @param {string} property - The CSS property to retrieve. * @returns {string|null} The value of the specified CSS property or `null` if non-existent. */ function _getCSSValue(property) { const acquiredValue = _classPrivateFieldGet(_rootComputedStyle, this).getPropertyValue(property); return acquiredValue === '' ? null : acquiredValue; } /** * Clears the cached values. */ function _clearCachedValues() { _classPrivateFieldSet(_computedStyles, this, {}); _classPrivateFieldSet(_cssVars, this, {}); _classPrivateFieldSet(_isClassicTheme, this, true); }