]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): fix svg with directives being incorrectly hoisted (#5919)
authorTravis <godxiaoji@163.com>
Mon, 23 May 2022 01:40:53 +0000 (09:40 +0800)
committerGitHub <noreply@github.com>
Mon, 23 May 2022 01:40:53 +0000 (21:40 -0400)
fix #5289

packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap
packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
packages/compiler-core/src/transforms/hoistStatic.ts

index 73c714d837eb8132b24388b46ace69e9a41dfc19..15b5cf4c309d745d14ab048a423dd27a9341864a 100644 (file)
@@ -211,6 +211,30 @@ return function render(_ctx, _cache) {
 }"
 `;
 
+exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist SVG with directives 1`] = `
+"const _Vue = Vue
+const { createElementVNode: _createElementVNode } = _Vue
+
+const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"path\\", { d: \\"M2,3H5.5L12\\" }, null, -1 /* HOISTED */)
+const _hoisted_2 = [
+  _hoisted_1
+]
+
+return function render(_ctx, _cache) {
+  with (_ctx) {
+    const { createElementVNode: _createElementVNode, resolveDirective: _resolveDirective, openBlock: _openBlock, createElementBlock: _createElementBlock, withDirectives: _withDirectives } = _Vue
+
+    const _directive_foo = _resolveDirective(\\"foo\\")
+
+    return (_openBlock(), _createElementBlock(\\"div\\", null, [
+      _withDirectives((_openBlock(), _createElementBlock(\\"svg\\", null, _hoisted_2)), [
+        [_directive_foo]
+      ])
+    ]))
+  }
+}"
+`;
+
 exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers + other bindings 1`] = `
 "import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
 
index 0cbd4910a303488eabdec6625ecaa1e6f2f5cf9b..2c4421aeb3b42e973cff7531037d76e65142eb7d 100644 (file)
@@ -616,5 +616,11 @@ describe('compiler: hoistStatic transform', () => {
       expect(root.hoists.length).toBe(0)
       expect(generate(root).code).toMatchSnapshot()
     })
+
+    test('should NOT hoist SVG with directives', () => {
+      const root = transformWithHoist(`<div><svg v-foo><path d="M2,3H5.5L12"/></svg></div>`)
+      expect(root.hoists.length).toBe(2)
+      expect(generate(root).code).toMatchSnapshot()
+    })
   })
 })
index ae95eadb6830017c3d3b6d133f09e988ecb60bc7..848052581ed7dd134aa42d89f362874e450b897b 100644 (file)
@@ -230,6 +230,15 @@ export function getConstantType(
         // static then they don't need to be blocks since there will be no
         // nested updates.
         if (codegenNode.isBlock) {
+          // except set custom directives.
+          for (let i = 0; i < node.props.length; i++) {
+            const p = node.props[i]
+            if (p.type === NodeTypes.DIRECTIVE) {
+              constantCache.set(node, ConstantTypes.NOT_CONSTANT)
+              return ConstantTypes.NOT_CONSTANT
+            }
+          }
+
           context.removeHelper(OPEN_BLOCK)
           context.removeHelper(
             getVNodeBlockHelper(context.inSSR, codegenNode.isComponent)