]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): `<style vars scoped>` prefixing should only apply to pre-transform...
authorEvan You <yyx990803@gmail.com>
Tue, 21 Jul 2020 19:05:28 +0000 (15:05 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 21 Jul 2020 19:05:28 +0000 (15:05 -0400)
fix #1623

packages/compiler-sfc/src/compileStyle.ts
packages/compiler-sfc/src/stylePluginScoped.ts
packages/compiler-sfc/src/stylePluginScopedVars.ts [new file with mode: 0644]

index b0aa484cd2379954a95e386796c77d5ffe00d90c..cf0761ffc0904550b44fc0fb81115828f45cb435 100644 (file)
@@ -7,6 +7,7 @@ import postcss, {
 } from 'postcss'
 import trimPlugin from './stylePluginTrim'
 import scopedPlugin from './stylePluginScoped'
+import scopedVarsPlugin from './stylePluginScopedVars'
 import {
   processors,
   StylePreprocessor,
@@ -95,11 +96,16 @@ export function doCompileStyle(
   const source = preProcessedSource ? preProcessedSource.code : options.source
 
   const plugins = (postcssPlugins || []).slice()
+  if (vars && scoped) {
+    // vars + scoped, only applies to raw source before other transforms
+    // #1623
+    plugins.unshift(scopedVarsPlugin(id))
+  }
   if (trim) {
     plugins.push(trimPlugin())
   }
   if (scoped) {
-    plugins.push(scopedPlugin({ id, vars }))
+    plugins.push(scopedPlugin(id))
   }
   let cssModules: Record<string, string> | undefined
   if (modules) {
index ad90bf5c1bc1cc8f3f7f129952e187ce60c83356..6274da818a6883154f7fcf7fcc189ff737793195 100644 (file)
@@ -3,10 +3,8 @@ import selectorParser, { Node, Selector } from 'postcss-selector-parser'
 
 const animationNameRE = /^(-\w+-)?animation-name$/
 const animationRE = /^(-\w+-)?animation$/
-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 }
+export default postcss.plugin('vue-scoped', (id: any) => (root: Root) => {
   const keyframes = Object.create(null)
   const shortId = id.replace(/^data-v-/, '')
 
@@ -135,46 +133,37 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
     }).processSync(node.selector)
   })
 
-  const hasKeyframes = Object.keys(keyframes).length
-  if (hasKeyframes || hasInjectedVars)
+  if (Object.keys(keyframes).length) {
+    // 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.
+    // individual animation-name declaration
     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 (animationNameRE.test(decl.prop)) {
+        decl.value = decl.value
+          .split(',')
+          .map(v => keyframes[v.trim()] || v.trim())
+          .join(',')
       }
-
-      // rewrite CSS variables
-      if (hasInjectedVars && cssVarRE.test(decl.value)) {
-        decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
-          return $1 ? `var(--${$2})` : `var(--${shortId}-${$2})`
-        })
+      // 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(',')
       }
     })
+  }
 })
 
 function isSpaceCombinator(node: Node) {
diff --git a/packages/compiler-sfc/src/stylePluginScopedVars.ts b/packages/compiler-sfc/src/stylePluginScopedVars.ts
new file mode 100644 (file)
index 0000000..c56c8ba
--- /dev/null
@@ -0,0 +1,15 @@
+import postcss, { Root } from 'postcss'
+
+const cssVarRE = /\bvar\(--(global:)?([^)]+)\)/g
+
+export default postcss.plugin('vue-scoped', (id: any) => (root: Root) => {
+  const shortId = id.replace(/^data-v-/, '')
+  root.walkDecls(decl => {
+    // rewrite CSS variables
+    if (cssVarRE.test(decl.value)) {
+      decl.value = decl.value.replace(cssVarRE, (_, $1, $2) => {
+        return $1 ? `var(--${$2})` : `var(--${shortId}-${$2})`
+      })
+    }
+  })
+})