useCacheToken.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. var _typeof = require("@babel/runtime/helpers/typeof");
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.TOKEN_PREFIX = void 0;
  8. exports.default = useCacheToken;
  9. exports.getComputedToken = exports.extract = void 0;
  10. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  11. var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
  12. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  13. var _hash = _interopRequireDefault(require("@emotion/hash"));
  14. var _dynamicCSS = require("rc-util/lib/Dom/dynamicCSS");
  15. var _react = require("react");
  16. var _StyleContext = _interopRequireWildcard(require("../StyleContext"));
  17. var _util = require("../util");
  18. var _cssVariables = require("../util/css-variables");
  19. var _useGlobalCache = _interopRequireDefault(require("./useGlobalCache"));
  20. function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
  21. 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; }
  22. var EMPTY_OVERRIDE = {};
  23. // Generate different prefix to make user selector break in production env.
  24. // This helps developer not to do style override directly on the hash id.
  25. var hashPrefix = process.env.NODE_ENV !== 'production' ? 'css-dev-only-do-not-override' : 'css';
  26. var tokenKeys = new Map();
  27. function recordCleanToken(tokenKey) {
  28. tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) + 1);
  29. }
  30. function removeStyleTags(key, instanceId) {
  31. if (typeof document !== 'undefined') {
  32. var styles = document.querySelectorAll("style[".concat(_StyleContext.ATTR_TOKEN, "=\"").concat(key, "\"]"));
  33. styles.forEach(function (style) {
  34. if (style[_StyleContext.CSS_IN_JS_INSTANCE] === instanceId) {
  35. var _style$parentNode;
  36. (_style$parentNode = style.parentNode) === null || _style$parentNode === void 0 || _style$parentNode.removeChild(style);
  37. }
  38. });
  39. }
  40. }
  41. var TOKEN_THRESHOLD = 0;
  42. // Remove will check current keys first
  43. function cleanTokenStyle(tokenKey, instanceId) {
  44. tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) - 1);
  45. var cleanableKeyList = new Set();
  46. tokenKeys.forEach(function (value, key) {
  47. if (value <= 0) cleanableKeyList.add(key);
  48. });
  49. // Should keep tokens under threshold for not to insert style too often
  50. if (tokenKeys.size - cleanableKeyList.size > TOKEN_THRESHOLD) {
  51. cleanableKeyList.forEach(function (key) {
  52. removeStyleTags(key, instanceId);
  53. tokenKeys.delete(key);
  54. });
  55. }
  56. }
  57. var getComputedToken = exports.getComputedToken = function getComputedToken(originToken, overrideToken, theme, format) {
  58. var derivativeToken = theme.getDerivativeToken(originToken);
  59. // Merge with override
  60. var mergedDerivativeToken = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, derivativeToken), overrideToken);
  61. // Format if needed
  62. if (format) {
  63. mergedDerivativeToken = format(mergedDerivativeToken);
  64. }
  65. return mergedDerivativeToken;
  66. };
  67. var TOKEN_PREFIX = exports.TOKEN_PREFIX = 'token';
  68. /**
  69. * Cache theme derivative token as global shared one
  70. * @param theme Theme entity
  71. * @param tokens List of tokens, used for cache. Please do not dynamic generate object directly
  72. * @param option Additional config
  73. * @returns Call Theme.getDerivativeToken(tokenObject) to get token
  74. */
  75. function useCacheToken(theme, tokens) {
  76. var option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  77. var _useContext = (0, _react.useContext)(_StyleContext.default),
  78. instanceId = _useContext.cache.instanceId,
  79. container = _useContext.container;
  80. var _option$salt = option.salt,
  81. salt = _option$salt === void 0 ? '' : _option$salt,
  82. _option$override = option.override,
  83. override = _option$override === void 0 ? EMPTY_OVERRIDE : _option$override,
  84. formatToken = option.formatToken,
  85. compute = option.getComputedToken,
  86. cssVar = option.cssVar;
  87. // Basic - We do basic cache here
  88. var mergedToken = (0, _util.memoResult)(function () {
  89. return Object.assign.apply(Object, [{}].concat((0, _toConsumableArray2.default)(tokens)));
  90. }, tokens);
  91. var tokenStr = (0, _util.flattenToken)(mergedToken);
  92. var overrideTokenStr = (0, _util.flattenToken)(override);
  93. var cssVarStr = cssVar ? (0, _util.flattenToken)(cssVar) : '';
  94. var cachedToken = (0, _useGlobalCache.default)(TOKEN_PREFIX, [salt, theme.id, tokenStr, overrideTokenStr, cssVarStr], function () {
  95. var _cssVar$key;
  96. var mergedDerivativeToken = compute ? compute(mergedToken, override, theme) : getComputedToken(mergedToken, override, theme, formatToken);
  97. // Replace token value with css variables
  98. var actualToken = (0, _objectSpread2.default)({}, mergedDerivativeToken);
  99. var cssVarsStr = '';
  100. if (!!cssVar) {
  101. var _transformToken = (0, _cssVariables.transformToken)(mergedDerivativeToken, cssVar.key, {
  102. prefix: cssVar.prefix,
  103. ignore: cssVar.ignore,
  104. unitless: cssVar.unitless,
  105. preserve: cssVar.preserve
  106. });
  107. var _transformToken2 = (0, _slicedToArray2.default)(_transformToken, 2);
  108. mergedDerivativeToken = _transformToken2[0];
  109. cssVarsStr = _transformToken2[1];
  110. }
  111. // Optimize for `useStyleRegister` performance
  112. var tokenKey = (0, _util.token2key)(mergedDerivativeToken, salt);
  113. mergedDerivativeToken._tokenKey = tokenKey;
  114. actualToken._tokenKey = (0, _util.token2key)(actualToken, salt);
  115. var themeKey = (_cssVar$key = cssVar === null || cssVar === void 0 ? void 0 : cssVar.key) !== null && _cssVar$key !== void 0 ? _cssVar$key : tokenKey;
  116. mergedDerivativeToken._themeKey = themeKey;
  117. recordCleanToken(themeKey);
  118. var hashId = "".concat(hashPrefix, "-").concat((0, _hash.default)(tokenKey));
  119. mergedDerivativeToken._hashId = hashId; // Not used
  120. return [mergedDerivativeToken, hashId, actualToken, cssVarsStr, (cssVar === null || cssVar === void 0 ? void 0 : cssVar.key) || ''];
  121. }, function (cache) {
  122. // Remove token will remove all related style
  123. cleanTokenStyle(cache[0]._themeKey, instanceId);
  124. }, function (_ref) {
  125. var _ref2 = (0, _slicedToArray2.default)(_ref, 4),
  126. token = _ref2[0],
  127. cssVarsStr = _ref2[3];
  128. if (cssVar && cssVarsStr) {
  129. var style = (0, _dynamicCSS.updateCSS)(cssVarsStr, (0, _hash.default)("css-variables-".concat(token._themeKey)), {
  130. mark: _StyleContext.ATTR_MARK,
  131. prepend: 'queue',
  132. attachTo: container,
  133. priority: -999
  134. });
  135. style[_StyleContext.CSS_IN_JS_INSTANCE] = instanceId;
  136. // Used for `useCacheToken` to remove on batch when token removed
  137. style.setAttribute(_StyleContext.ATTR_TOKEN, token._themeKey);
  138. }
  139. });
  140. return cachedToken;
  141. }
  142. var extract = exports.extract = function extract(cache, effectStyles, options) {
  143. var _cache = (0, _slicedToArray2.default)(cache, 5),
  144. realToken = _cache[2],
  145. styleStr = _cache[3],
  146. cssVarKey = _cache[4];
  147. var _ref3 = options || {},
  148. plain = _ref3.plain;
  149. if (!styleStr) {
  150. return null;
  151. }
  152. var styleId = realToken._tokenKey;
  153. var order = -999;
  154. // ====================== Style ======================
  155. // Used for rc-util
  156. var sharedAttrs = {
  157. 'data-rc-order': 'prependQueue',
  158. 'data-rc-priority': "".concat(order)
  159. };
  160. var styleText = (0, _util.toStyleStr)(styleStr, cssVarKey, styleId, sharedAttrs, plain);
  161. return [order, styleId, styleText];
  162. };