]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: shorten scoped css var / animation prefix
authorEvan You <yyx990803@gmail.com>
Fri, 10 Jul 2020 22:47:31 +0000 (18:47 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 10 Jul 2020 22:47:31 +0000 (18:47 -0400)
packages/compiler-sfc/__tests__/compileStyle.spec.ts
packages/compiler-sfc/src/stylePluginScoped.ts
packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts
packages/runtime-dom/src/helpers/useCssVars.ts

index d21b99ad02e279d39b3934ff423001bf20206cef..94443f197c6e87cec9cf598daa36c84aff9e93ff 100644 (file)
@@ -155,7 +155,8 @@ describe('SFC scoped CSS', () => {
   })
 
   test('scoped keyframes', () => {
-    const style = compileScoped(`
+    const style = compileScoped(
+      `
 .anim {
   animation: color 5s infinite, other 5s;
 }
@@ -190,23 +191,27 @@ describe('SFC scoped CSS', () => {
   from { opacity: 0; }
   to { opacity: 1; }
 }
-    `)
+    `,
+      { id: 'data-v-test' }
+    )
 
     expect(style).toContain(
-      `.anim[test] {\n  animation: color-test 5s infinite, other 5s;`
+      `.anim[data-v-test] {\n  animation: color-test 5s infinite, other 5s;`
+    )
+    expect(style).toContain(
+      `.anim-2[data-v-test] {\n  animation-name: color-test`
     )
-    expect(style).toContain(`.anim-2[test] {\n  animation-name: color-test`)
     expect(style).toContain(
-      `.anim-3[test] {\n  animation: 5s color-test infinite, 5s other;`
+      `.anim-3[data-v-test] {\n  animation: 5s color-test infinite, 5s other;`
     )
     expect(style).toContain(`@keyframes color-test {`)
     expect(style).toContain(`@-webkit-keyframes color-test {`)
 
     expect(style).toContain(
-      `.anim-multiple[test] {\n  animation: color-test 5s infinite,opacity-test 2s;`
+      `.anim-multiple[data-v-test] {\n  animation: color-test 5s infinite,opacity-test 2s;`
     )
     expect(style).toContain(
-      `.anim-multiple-2[test] {\n  animation-name: color-test,opacity-test;`
+      `.anim-multiple-2[data-v-test] {\n  animation-name: color-test,opacity-test;`
     )
     expect(style).toContain(`@keyframes opacity-test {`)
     expect(style).toContain(`@-webkit-keyframes opacity-test {`)
@@ -268,11 +273,12 @@ describe('SFC scoped CSS', () => {
         font-size: var(--global:font);
       }`,
         {
+          id: 'data-v-test',
           vars: true
         }
       )
       expect(code).toMatchInlineSnapshot(`
-        ".foo[test] {
+        ".foo[data-v-test] {
                 color: var(--test-color);
                 font-size: var(--font);
         }"
index 2b02c55826ea1515a24ec4a429afe384cb6cde1f..ad90bf5c1bc1cc8f3f7f129952e187ce60c83356 100644 (file)
@@ -8,6 +8,7 @@ const cssVarRE = /\bvar\(--(global:)?([^)]+)\)/g
 export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
   const { id, vars: hasInjectedVars } = options as { id: string; vars: boolean }
   const keyframes = Object.create(null)
+  const shortId = id.replace(/^data-v-/, '')
 
   root.each(function rewriteSelectors(node) {
     if (node.type !== 'rule') {
@@ -17,7 +18,7 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
           node.each(rewriteSelectors)
         } else if (/-?keyframes$/.test(node.name)) {
           // register keyframes
-          keyframes[node.params] = node.params = node.params + '-' + id
+          keyframes[node.params] = node.params = node.params + '-' + shortId
         }
       }
       return
@@ -170,7 +171,7 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
       // rewrite CSS variables
       if (hasInjectedVars && cssVarRE.test(decl.value)) {
         decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
-          return $1 ? `var(--${$2})` : `var(--${id}-${$2})`
+          return $1 ? `var(--${$2})` : `var(--${shortId}-${$2})`
         })
       }
     })
index 6c4176864b93c29d064f8456c8b14f83059cfad3..a7d8e8e8603a64170b1a93e854a2c4194aa3c419 100644 (file)
@@ -15,17 +15,21 @@ describe('useCssVars', () => {
     const state = reactive({ color: 'red' })
     const App = getApp(state)
     const root = document.createElement('div')
-    const prefix = scopeId ? `${scopeId}-` : ``
+    const prefix = scopeId ? `${scopeId.replace(/^data-v-/, '')}-` : ``
 
     render(h(App), root)
     for (const c of [].slice.call(root.children as any)) {
-      expect((c as HTMLElement).style.getPropertyValue(`--${prefix}color`))
+      expect(
+        (c as HTMLElement).style.getPropertyValue(`--${prefix}color`)
+      ).toBe(`red`)
     }
 
     state.color = 'green'
     await nextTick()
     for (const c of [].slice.call(root.children as any)) {
-      expect((c as HTMLElement).style.getPropertyValue(`--${prefix}color`))
+      expect(
+        (c as HTMLElement).style.getPropertyValue(`--${prefix}color`)
+      ).toBe('green')
     }
   }
 
@@ -65,7 +69,7 @@ describe('useCssVars', () => {
   })
 
   test('with <style scoped>', async () => {
-    const id = 'v-12345'
+    const id = 'data-v-12345'
 
     await assertCssVars(
       state => ({
index 631cb20b7e9455e7977c30ed252591a58d215015..6c45894fe3b97404bdbb048a20fd14cfe6c9c0fe 100644 (file)
@@ -5,8 +5,7 @@ import {
   watchEffect,
   warn,
   VNode,
-  Fragment,
-  ComponentInternalInstance
+  Fragment
 } from '@vue/runtime-core'
 import { ShapeFlags } from '@vue/shared/src'
 
@@ -20,14 +19,15 @@ export function useCSSVars(
       warn(`useCssVars is called without current active component instance.`)
     return
   }
+
+  const prefix =
+    scoped && instance.type.__scopeId
+      ? `${instance.type.__scopeId.replace(/^data-v-/, '')}-`
+      : ``
+
   onMounted(() => {
     watchEffect(() => {
-      setVarsOnVNode(
-        instance.subTree,
-        getter(instance.proxy!),
-        instance,
-        scoped
-      )
+      setVarsOnVNode(instance.subTree, getter(instance.proxy!), prefix)
     })
   })
 }
@@ -35,8 +35,7 @@ export function useCSSVars(
 function setVarsOnVNode(
   vnode: VNode,
   vars: Record<string, string>,
-  owner: ComponentInternalInstance,
-  scoped: boolean
+  prefix: string
 ) {
   // drill down HOCs until it's a non-component vnode
   while (vnode.component) {
@@ -44,14 +43,10 @@ function setVarsOnVNode(
   }
   if (vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.el) {
     const style = vnode.el.style
-    const prefix =
-      scoped && owner.type.__scopeId ? `${owner.type.__scopeId}-` : ``
     for (const key in vars) {
       style.setProperty(`--${prefix}${key}`, vars[key])
     }
   } else if (vnode.type === Fragment) {
-    ;(vnode.children as VNode[]).forEach(c =>
-      setVarsOnVNode(c, vars, owner, scoped)
-    )
+    ;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars, prefix))
   }
 }