]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(cssVars): use css vars work with vapor mode
authordaiwei <daiwei521@126.com>
Thu, 26 Dec 2024 13:44:59 +0000 (21:44 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 26 Dec 2024 13:44:59 +0000 (21:44 +0800)
packages/compiler-sfc/src/compileScript.ts
packages/compiler-sfc/src/style/cssVars.ts
packages/runtime-dom/src/helpers/useCssVars.ts
packages/runtime-dom/src/index.ts
packages/runtime-vapor/src/index.ts
packages/runtime-vapor/src/useCssVars.ts [new file with mode: 0644]

index 0d1dc0976f4aa12fc9e5a48a0f32f95bf3ca3185..798e7465071cdc5e51c55c7519ee4236ab24095a 100644 (file)
@@ -29,7 +29,7 @@ import {
   normalScriptDefaultVar,
   processNormalScript,
 } from './script/normalScript'
-import { CSS_VARS_HELPER, genCssVarsCode } from './style/cssVars'
+import { genCssVarsCode, getCssVarsHelper } from './style/cssVars'
 import {
   type SFCTemplateCompileOptions,
   compileTemplate,
@@ -759,7 +759,7 @@ export function compileScript(
     // no need to do this when targeting SSR
     !options.templateOptions?.ssr
   ) {
-    ctx.helperImports.add(CSS_VARS_HELPER)
+    ctx.helperImports.add(getCssVarsHelper(vapor))
     ctx.helperImports.add('unref')
     ctx.s.prependLeft(
       startOffset,
@@ -768,6 +768,7 @@ export function compileScript(
         ctx.bindingMetadata,
         scopeId,
         !!options.isProd,
+        vapor,
       )}\n`,
     )
   }
index 0397c7d790a4bb40098693ce6061d0e70de8f8a0..95a7d53c8ae2ca8e15db011401595a74857999ac 100644 (file)
@@ -10,10 +10,14 @@ import {
 import type { SFCDescriptor } from '../parse'
 import type { PluginCreator } from 'postcss'
 import hash from 'hash-sum'
-import { getEscapedCssVarName } from '@vue/shared'
+import { capitalize, getEscapedCssVarName } from '@vue/shared'
 
 export const CSS_VARS_HELPER = `useCssVars`
 
+export function getCssVarsHelper(vapor: boolean | undefined): string {
+  return vapor ? `vapor${capitalize(CSS_VARS_HELPER)}` : CSS_VARS_HELPER
+}
+
 export function genCssVarsFromList(
   vars: string[],
   id: string,
@@ -162,6 +166,7 @@ export function genCssVarsCode(
   bindings: BindingMetadata,
   id: string,
   isProd: boolean,
+  vapor?: boolean,
 ) {
   const varsExp = genCssVarsFromList(vars, id, isProd)
   const exp = createSimpleExpression(varsExp, false)
@@ -182,7 +187,7 @@ export function genCssVarsCode(
           })
           .join('')
 
-  return `_${CSS_VARS_HELPER}(_ctx => (${transformedString}))`
+  return `_${getCssVarsHelper(vapor)}(_ctx => (${transformedString}))`
 }
 
 // <script setup> already gets the calls injected as part of the transform
index e2bc6de92781cd046ef087e9ced48d3633be2bbc..b25be09d212915e437dde4d069c312e1827041de 100644 (file)
@@ -49,19 +49,7 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>): void {
     updateTeleports(vars)
   }
 
-  // handle cases where child component root is affected
-  // and triggers reflow in onMounted
-  onBeforeUpdate(() => {
-    queuePostFlushCb(setVars)
-  })
-
-  onMounted(() => {
-    // run setVars synchronously here, but run as post-effect on changes
-    watch(setVars, NOOP, { flush: 'post' })
-    const ob = new MutationObserver(setVars)
-    ob.observe(instance.subTree.el!.parentNode, { childList: true })
-    onUnmounted(() => ob.disconnect())
-  })
+  applyCssVars(() => instance.subTree.el!.parentNode!, setVars)
 }
 
 function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
@@ -94,7 +82,26 @@ function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
   }
 }
 
-function setVarsOnNode(el: Node, vars: Record<string, string>) {
+export function applyCssVars(
+  getParentNode: () => Node,
+  setVars: () => void,
+): void {
+  // handle cases where child component root is affected
+  // and triggers reflow in onMounted
+  onBeforeUpdate(() => {
+    queuePostFlushCb(setVars)
+  })
+
+  onMounted(() => {
+    // run setVars synchronously here, but run as post-effect on changes
+    watch(setVars, NOOP, { flush: 'post' })
+    const ob = new MutationObserver(setVars)
+    ob.observe(getParentNode(), { childList: true })
+    onUnmounted(() => ob.disconnect())
+  })
+}
+
+export function setVarsOnNode(el: Node, vars: Record<string, string>): void {
   if (el.nodeType === 1) {
     const style = (el as HTMLElement).style
     let cssText = ''
index 60c32ce5d309b600f1e8fc582ffb9f086a45a0d3..66c69d374a789247fc4a91ad236abb6198a56351 100644 (file)
@@ -322,3 +322,7 @@ export { patchStyle } from './modules/style'
  * @internal
  */
 export { shouldSetAsProp } from './patchProp'
+/**
+ * @internal
+ */
+export { applyCssVars, setVarsOnNode } from './helpers/useCssVars'
index f081ecf2abf358a2e1c9a0b251997b835ba3e7db..3df99253f020cdb79d73534b8da67afc543d4890 100644 (file)
@@ -24,3 +24,4 @@ export { on, delegate, delegateEvents, setDynamicEvents } from './dom/event'
 export { createIf } from './apiCreateIf'
 export { createFor } from './apiCreateFor'
 export { createTemplateRefSetter } from './apiTemplateRef'
+export { vaporUseCssVars } from './useCssVars'
diff --git a/packages/runtime-vapor/src/useCssVars.ts b/packages/runtime-vapor/src/useCssVars.ts
new file mode 100644 (file)
index 0000000..c405b3a
--- /dev/null
@@ -0,0 +1,51 @@
+import {
+  applyCssVars,
+  currentInstance,
+  setVarsOnNode,
+  warn,
+} from '@vue/runtime-dom'
+import { type VaporComponentInstance, isVaporComponent } from './component'
+import { isArray } from '@vue/shared'
+import type { Block } from './block'
+
+export function vaporUseCssVars(getter: () => Record<string, string>): void {
+  if (!__BROWSER__ && !__TEST__) return
+
+  const instance = currentInstance as VaporComponentInstance
+  /* v8 ignore start */
+  if (!instance) {
+    __DEV__ &&
+      warn(`useCssVars is called without current active component instance.`)
+    return
+  }
+  /* v8 ignore stop */
+
+  applyCssVars(
+    () => resolveParentNode(instance.block),
+    () => setVarsOnBlock(instance.block, getter()),
+  )
+}
+
+function resolveParentNode(block: Block): Node {
+  if (block instanceof Node) {
+    return block.parentNode!
+  } else if (isVaporComponent(block)) {
+    return resolveParentNode(block.block!)
+  } else if (isArray(block)) {
+    return resolveParentNode(block[0])
+  } else {
+    return resolveParentNode(block.nodes)
+  }
+}
+
+function setVarsOnBlock(block: Block, vars: Record<string, string>): void {
+  if (block instanceof Node) {
+    setVarsOnNode(block, vars)
+  } else if (isArray(block)) {
+    block.forEach(child => setVarsOnBlock(child, vars))
+  } else if (isVaporComponent(block)) {
+    setVarsOnBlock(block.block!, vars)
+  } else {
+    setVarsOnBlock(block.nodes, vars)
+  }
+}