"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.TOKEN_PREFIX = void 0; exports.default = useCacheToken; exports.getComputedToken = exports.extract = void 0; var _hash = _interopRequireDefault(require("@emotion/hash")); var _dynamicCSS = require("@rc-component/util/lib/Dom/dynamicCSS"); var _react = require("react"); var _StyleContext = _interopRequireWildcard(require("../StyleContext")); var _util = require("../util"); var _cssVariables = require("../util/css-variables"); var _useGlobalCache = _interopRequireDefault(require("./useGlobalCache")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const EMPTY_OVERRIDE = {}; // Generate different prefix to make user selector break in production env. // This helps developer not to do style override directly on the hash id. const hashPrefix = process.env.NODE_ENV !== 'production' ? 'css-dev-only-do-not-override' : 'css'; const tokenKeys = new Map(); function recordCleanToken(tokenKey) { tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) + 1); } function removeStyleTags(key, instanceId) { if (typeof document !== 'undefined') { const styles = document.querySelectorAll(`style[${_StyleContext.ATTR_TOKEN}="${key}"]`); styles.forEach(style => { if (style[_StyleContext.CSS_IN_JS_INSTANCE] === instanceId) { style.parentNode?.removeChild(style); } }); } } const TOKEN_THRESHOLD = -1; // Remove will check current keys first function cleanTokenStyle(tokenKey, instanceId) { tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) - 1); const cleanableKeyList = new Set(); tokenKeys.forEach((value, key) => { if (value <= 0) cleanableKeyList.add(key); }); // Should keep tokens under threshold for not to insert style too often if (tokenKeys.size - cleanableKeyList.size > TOKEN_THRESHOLD) { cleanableKeyList.forEach(key => { removeStyleTags(key, instanceId); tokenKeys.delete(key); }); } } const getComputedToken = (originToken, overrideToken, theme, format) => { const derivativeToken = theme.getDerivativeToken(originToken); // Merge with override let mergedDerivativeToken = { ...derivativeToken, ...overrideToken }; // Format if needed if (format) { mergedDerivativeToken = format(mergedDerivativeToken); } return mergedDerivativeToken; }; exports.getComputedToken = getComputedToken; const TOKEN_PREFIX = exports.TOKEN_PREFIX = 'token'; /** * Cache theme derivative token as global shared one * @param theme Theme entity * @param tokens List of tokens, used for cache. Please do not dynamic generate object directly * @param option Additional config * @returns Call Theme.getDerivativeToken(tokenObject) to get token */ function useCacheToken(theme, tokens, option) { const { cache: { instanceId }, container, hashPriority } = (0, _react.useContext)(_StyleContext.default); const { salt = '', override = EMPTY_OVERRIDE, formatToken, getComputedToken: compute, cssVar, nonce } = option; // Basic - We do basic cache here const mergedToken = (0, _util.memoResult)(() => Object.assign({}, ...tokens), tokens); const tokenStr = (0, _util.flattenToken)(mergedToken); const overrideTokenStr = (0, _util.flattenToken)(override); const cssVarStr = (0, _util.flattenToken)(cssVar); const cachedToken = (0, _useGlobalCache.default)(TOKEN_PREFIX, [salt, theme.id, tokenStr, overrideTokenStr, cssVarStr], () => { const mergedDerivativeToken = compute ? compute(mergedToken, override, theme) : getComputedToken(mergedToken, override, theme, formatToken); const actualToken = { ...mergedDerivativeToken }; // Optimize for `useStyleRegister` performance const mergedSalt = `${salt}_${cssVar.prefix}`; const hashId = (0, _hash.default)(mergedSalt); const hashCls = `${hashPrefix}-${hashId}`; actualToken._tokenKey = (0, _util.token2key)(actualToken, mergedSalt); // Replace token value with css variables const [tokenWithCssVar, cssVarsStr] = (0, _cssVariables.transformToken)(mergedDerivativeToken, cssVar.key, { prefix: cssVar.prefix, ignore: cssVar.ignore, unitless: cssVar.unitless, preserve: cssVar.preserve, hashPriority, hashCls: cssVar.hashed ? hashCls : undefined }); tokenWithCssVar._hashId = hashId; recordCleanToken(cssVar.key); return [tokenWithCssVar, hashCls, actualToken, cssVarsStr, cssVar.key]; }, ([,,,, themeKey]) => { // Remove token will remove all related style cleanTokenStyle(themeKey, instanceId); }, ([,,, cssVarsStr, themeKey]) => { if (!cssVarsStr) { return; } let mergedCSSConfig = { mark: _StyleContext.ATTR_MARK, prepend: 'queue', attachTo: container, priority: -999 }; mergedCSSConfig = (0, _util.injectCSPNonce)(mergedCSSConfig, nonce); const style = (0, _dynamicCSS.updateCSS)(cssVarsStr, (0, _hash.default)(`css-var-${themeKey}`), mergedCSSConfig); style[_StyleContext.CSS_IN_JS_INSTANCE] = instanceId; // Used for `useCacheToken` to remove on batch when token removed style.setAttribute(_StyleContext.ATTR_TOKEN, themeKey); }); return cachedToken; } const extract = (cache, effectStyles, options) => { const [,, realToken, styleStr, cssVarKey] = cache; const { plain } = options || {}; if (!styleStr) { return null; } const styleId = realToken._tokenKey; const order = -999; // ====================== Style ====================== // Used for @rc-component/util const sharedAttrs = { 'data-rc-order': 'prependQueue', 'data-rc-priority': `${order}` }; const styleText = (0, _util.toStyleStr)(styleStr, cssVarKey, styleId, sharedAttrs, plain); return [order, styleId, styleText]; }; exports.extract = extract;