index.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // src/helper/css/index.ts
  2. import { raw } from "../../helper/html/index.js";
  3. import { DOM_RENDERER } from "../../jsx/constants.js";
  4. import { createCssJsxDomObjects } from "../../jsx/dom/css.js";
  5. import {
  6. CLASS_NAME,
  7. DEFAULT_STYLE_ID,
  8. PSEUDO_GLOBAL_SELECTOR,
  9. SELECTOR,
  10. SELECTORS,
  11. STYLE_STRING,
  12. cssCommon,
  13. cxCommon,
  14. keyframesCommon,
  15. viewTransitionCommon
  16. } from "./common.js";
  17. import { rawCssString } from "./common.js";
  18. var createCssContext = ({
  19. id,
  20. classNameSlug,
  21. onInvalidSlug
  22. }) => {
  23. const [cssJsxDomObject, StyleRenderToDom] = createCssJsxDomObjects({ id });
  24. const contextMap = /* @__PURE__ */ new WeakMap();
  25. const nonceMap = /* @__PURE__ */ new WeakMap();
  26. const replaceStyleRe = new RegExp(`(<style id="${id}"(?: nonce="[^"]*")?>.*?)(</style>)`);
  27. const newCssClassNameObject = (cssClassName) => {
  28. const appendStyle = ({ buffer, context }) => {
  29. const [toAdd, added] = contextMap.get(context);
  30. const names = Object.keys(toAdd);
  31. if (!names.length) {
  32. return;
  33. }
  34. let stylesStr = "";
  35. names.forEach((className2) => {
  36. added[className2] = true;
  37. stylesStr += className2.startsWith(PSEUDO_GLOBAL_SELECTOR) ? toAdd[className2] : `${className2[0] === "@" ? "" : "."}${className2}{${toAdd[className2]}}`;
  38. });
  39. contextMap.set(context, [{}, added]);
  40. if (buffer && replaceStyleRe.test(buffer[0])) {
  41. buffer[0] = buffer[0].replace(replaceStyleRe, (_, pre, post) => `${pre}${stylesStr}${post}`);
  42. return;
  43. }
  44. const nonce = nonceMap.get(context);
  45. const appendStyleScript = `<script${nonce ? ` nonce="${nonce}"` : ""}>document.querySelector('#${id}').textContent+=${JSON.stringify(stylesStr)}</script>`;
  46. if (buffer) {
  47. buffer[0] = `${appendStyleScript}${buffer[0]}`;
  48. return;
  49. }
  50. return Promise.resolve(appendStyleScript);
  51. };
  52. const addClassNameToContext = ({ context }) => {
  53. if (!contextMap.has(context)) {
  54. contextMap.set(context, [{}, {}]);
  55. }
  56. const [toAdd, added] = contextMap.get(context);
  57. let allAdded = true;
  58. if (!added[cssClassName[SELECTOR]]) {
  59. allAdded = false;
  60. toAdd[cssClassName[SELECTOR]] = cssClassName[STYLE_STRING];
  61. }
  62. cssClassName[SELECTORS].forEach(
  63. ({ [CLASS_NAME]: className2, [STYLE_STRING]: styleString }) => {
  64. if (!added[className2]) {
  65. allAdded = false;
  66. toAdd[className2] = styleString;
  67. }
  68. }
  69. );
  70. if (allAdded) {
  71. return;
  72. }
  73. return Promise.resolve(raw("", [appendStyle]));
  74. };
  75. const className = new String(cssClassName[CLASS_NAME]);
  76. Object.assign(className, cssClassName);
  77. className.isEscaped = true;
  78. className.callbacks = [addClassNameToContext];
  79. const promise = Promise.resolve(className);
  80. Object.assign(promise, cssClassName);
  81. promise.toString = cssJsxDomObject.toString;
  82. return promise;
  83. };
  84. const css2 = (strings, ...values) => {
  85. return newCssClassNameObject(cssCommon(strings, values, classNameSlug, onInvalidSlug));
  86. };
  87. const cx2 = (...args) => {
  88. args = cxCommon(args);
  89. return css2(Array(args.length).fill(""), ...args);
  90. };
  91. const keyframes2 = (strings, ...values) => keyframesCommon(strings, values, classNameSlug, onInvalidSlug);
  92. const viewTransition2 = ((strings, ...values) => {
  93. return newCssClassNameObject(
  94. viewTransitionCommon(strings, values, classNameSlug, onInvalidSlug)
  95. // eslint-disable-line @typescript-eslint/no-explicit-any
  96. );
  97. });
  98. const Style2 = ({ children, nonce } = {}) => raw(
  99. `<style id="${id}"${nonce ? ` nonce="${nonce}"` : ""}>${children ? children[STYLE_STRING] : ""}</style>`,
  100. [
  101. ({ context }) => {
  102. nonceMap.set(context, nonce);
  103. return void 0;
  104. }
  105. ]
  106. );
  107. Style2[DOM_RENDERER] = StyleRenderToDom;
  108. return {
  109. css: css2,
  110. cx: cx2,
  111. keyframes: keyframes2,
  112. viewTransition: viewTransition2,
  113. Style: Style2
  114. };
  115. };
  116. var defaultContext = createCssContext({
  117. id: DEFAULT_STYLE_ID
  118. });
  119. var css = defaultContext.css;
  120. var cx = defaultContext.cx;
  121. var keyframes = defaultContext.keyframes;
  122. var viewTransition = defaultContext.viewTransition;
  123. var Style = defaultContext.Style;
  124. export {
  125. Style,
  126. createCssContext,
  127. css,
  128. cx,
  129. keyframes,
  130. rawCssString,
  131. viewTransition
  132. };