]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: only rewrite css varaiable in `<style scoped>` when vars is present
authorEvan You <yyx990803@gmail.com>
Fri, 10 Jul 2020 21:10:48 +0000 (17:10 -0400)
committerEvan You <yyx990803@gmail.com>
Fri, 10 Jul 2020 21:10:48 +0000 (17:10 -0400)
packages/compiler-sfc/__tests__/compileStyle.spec.ts
packages/compiler-sfc/src/compileScript.ts
packages/compiler-sfc/src/compileStyle.ts
packages/compiler-sfc/src/parse.ts
packages/compiler-sfc/src/stylePluginScoped.ts

index b1bd2ee012962d0570d18cbd2049c77a4d62d3bf..d21b99ad02e279d39b3934ff423001bf20206cef 100644 (file)
@@ -1,15 +1,23 @@
-import { compileStyle, compileStyleAsync } from '../src/compileStyle'
+import {
+  compileStyle,
+  compileStyleAsync,
+  SFCStyleCompileOptions
+} from '../src/compileStyle'
 import { mockWarn } from '@vue/shared'
 
 describe('SFC scoped CSS', () => {
   mockWarn()
 
-  function compileScoped(source: string): string {
+  function compileScoped(
+    source: string,
+    options?: Partial<SFCStyleCompileOptions>
+  ): string {
     const res = compileStyle({
       source,
       filename: 'test.css',
       id: 'test',
-      scoped: true
+      scoped: true,
+      ...options
     })
     if (res.errors.length) {
       res.errors.forEach(err => {
@@ -254,10 +262,15 @@ describe('SFC scoped CSS', () => {
 
   describe('<style vars>', () => {
     test('should rewrite CSS vars in scoped mode', () => {
-      const code = compileScoped(`.foo {
+      const code = compileScoped(
+        `.foo {
         color: var(--color);
         font-size: var(--global:font);
-      }`)
+      }`,
+        {
+          vars: true
+        }
+      )
       expect(code).toMatchInlineSnapshot(`
         ".foo[test] {
                 color: var(--test-color);
index 8b7711e2df447e23045c973a690e137e9a149d0f..33d3c40f47b5418b1e1df08891cc36d348b4db7b 100644 (file)
@@ -174,7 +174,7 @@ export function compileScript(
   }
 
   // 2. check <script setup="xxx"> function signature
-  const setupValue = scriptSetup.attrs.setup
+  const setupValue = scriptSetup.setup
   const hasExplicitSignature = typeof setupValue === 'string'
 
   let propsVar: string | undefined
index ded5f0bf6e62d591749de1104e8170007d1b355e..eab0456b6527d2c7572da7c10fa4abfd6c3b9907 100644 (file)
@@ -15,6 +15,7 @@ export interface SFCStyleCompileOptions {
   id: string
   map?: RawSourceMap
   scoped?: boolean
+  vars?: boolean
   trim?: boolean
   preprocessLang?: PreprocessLang
   preprocessOptions?: any
@@ -73,6 +74,7 @@ export function doCompileStyle(
     filename,
     id,
     scoped = false,
+    vars = false,
     trim = true,
     modules = false,
     modulesOptions = {},
@@ -90,7 +92,7 @@ export function doCompileStyle(
     plugins.push(trimPlugin())
   }
   if (scoped) {
-    plugins.push(scopedPlugin(id))
+    plugins.push(scopedPlugin({ id, vars }))
   }
   let cssModules: Record<string, string> | undefined
   if (modules) {
index 0fd3896eb3f25952e9a93acce7c682f62ca10945..e3291df5a34e69d5ff1640d03826759edb3e2a52 100644 (file)
@@ -40,12 +40,14 @@ export interface SFCTemplateBlock extends SFCBlock {
 
 export interface SFCScriptBlock extends SFCBlock {
   type: 'script'
+  setup?: string | boolean
   bindings?: BindingMetadata
 }
 
 export interface SFCStyleBlock extends SFCBlock {
   type: 'style'
   scoped?: boolean
+  vars?: string
   module?: string | boolean
 }
 
@@ -266,11 +268,15 @@ function createBlock(
       } else if (type === 'style') {
         if (p.name === 'scoped') {
           ;(block as SFCStyleBlock).scoped = true
+        } else if (p.name === 'vars' && typeof attrs.vars === 'string') {
+          ;(block as SFCStyleBlock).vars = attrs.vars
         } else if (p.name === 'module') {
           ;(block as SFCStyleBlock).module = attrs[p.name]
         }
       } else if (type === 'template' && p.name === 'functional') {
         ;(block as SFCTemplateBlock).functional = true
+      } else if (type === 'script' && p.name === 'setup') {
+        ;(block as SFCScriptBlock).setup = attrs.setup
       }
     }
   })
index ef4664fd7b27bbb71eaaee1cd37dff4488c948af..2b02c55826ea1515a24ec4a429afe384cb6cde1f 100644 (file)
@@ -6,7 +6,7 @@ const animationRE = /^(-\w+-)?animation$/
 const cssVarRE = /\bvar\(--(global:)?([^)]+)\)/g
 
 export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
-  const id: string = options
+  const { id, vars: hasInjectedVars } = options as { id: string; vars: boolean }
   const keyframes = Object.create(null)
 
   root.each(function rewriteSelectors(node) {
@@ -135,44 +135,45 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
   })
 
   const hasKeyframes = Object.keys(keyframes).length
-  root.walkDecls(decl => {
-    // If keyframes are found in this <style>, find and rewrite animation names
-    // in declarations.
-    // Caveat: this only works for keyframes and animation rules in the same
-    // <style> element.
-    if (hasKeyframes) {
-      // individual animation-name declaration
-      if (animationNameRE.test(decl.prop)) {
-        decl.value = decl.value
-          .split(',')
-          .map(v => keyframes[v.trim()] || v.trim())
-          .join(',')
-      }
-      // shorthand
-      if (animationRE.test(decl.prop)) {
-        decl.value = decl.value
-          .split(',')
-          .map(v => {
-            const vals = v.trim().split(/\s+/)
-            const i = vals.findIndex(val => keyframes[val])
-            if (i !== -1) {
-              vals.splice(i, 1, keyframes[vals[i]])
-              return vals.join(' ')
-            } else {
-              return v
-            }
-          })
-          .join(',')
+  if (hasKeyframes || hasInjectedVars)
+    root.walkDecls(decl => {
+      // If keyframes are found in this <style>, find and rewrite animation names
+      // in declarations.
+      // Caveat: this only works for keyframes and animation rules in the same
+      // <style> element.
+      if (hasKeyframes) {
+        // individual animation-name declaration
+        if (animationNameRE.test(decl.prop)) {
+          decl.value = decl.value
+            .split(',')
+            .map(v => keyframes[v.trim()] || v.trim())
+            .join(',')
+        }
+        // shorthand
+        if (animationRE.test(decl.prop)) {
+          decl.value = decl.value
+            .split(',')
+            .map(v => {
+              const vals = v.trim().split(/\s+/)
+              const i = vals.findIndex(val => keyframes[val])
+              if (i !== -1) {
+                vals.splice(i, 1, keyframes[vals[i]])
+                return vals.join(' ')
+              } else {
+                return v
+              }
+            })
+            .join(',')
+        }
       }
-    }
 
-    // rewrite CSS variables
-    if (cssVarRE.test(decl.value)) {
-      decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
-        return $1 ? `var(--${$2})` : `var(--${id}-${$2})`
-      })
-    }
-  })
+      // rewrite CSS variables
+      if (hasInjectedVars && cssVarRE.test(decl.value)) {
+        decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
+          return $1 ? `var(--${$2})` : `var(--${id}-${$2})`
+        })
+      }
+    })
 })
 
 function isSpaceCombinator(node: Node) {