Skip to content

Commit

Permalink
fix(compiler-core): force <svg> into blocks for correct runtime isSVG
Browse files Browse the repository at this point in the history
state during patch
  • Loading branch information
yyx990803 committed Jan 20, 2020
1 parent 0c42a6d commit f2ac28b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import {
RESOLVE_DYNAMIC_COMPONENT,
SUSPENSE,
KEEP_ALIVE,
BASE_TRANSITION
BASE_TRANSITION,
OPEN_BLOCK,
CREATE_BLOCK
} from '../../src/runtimeHelpers'
import {
CallExpression,
Expand Down Expand Up @@ -821,4 +823,25 @@ describe('compiler: element transform', () => {
])
})
})

test('<svg> should be forced into blocks', () => {
const ast = parse(`<div><svg/></div>`)
transform(ast, {
nodeTransforms: [transformElement]
})
expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
expressions: [
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK
},
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_BLOCK,
arguments: [`"svg"`]
}
]
})
})
})
9 changes: 7 additions & 2 deletions packages/compiler-core/src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,21 +118,26 @@ export interface BaseElementNode extends Node {
| CallExpression
| SimpleExpressionNode
| CacheExpression
| SequenceExpression
| undefined
}

export interface PlainElementNode extends BaseElementNode {
tagType: ElementTypes.ELEMENT
codegenNode:
| ElementCodegenNode
| undefined
| SimpleExpressionNode // when hoisted
| CacheExpression // when cached by v-once
| SequenceExpression // when turned into a block
| undefined
}

export interface ComponentNode extends BaseElementNode {
tagType: ElementTypes.COMPONENT
codegenNode: ComponentCodegenNode | undefined | CacheExpression // when cached by v-once
codegenNode:
| ComponentCodegenNode
| CacheExpression // when cached by v-once
| undefined
}

export interface SlotOutletNode extends BaseElementNode {
Expand Down
21 changes: 17 additions & 4 deletions packages/compiler-core/src/transforms/transformElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
createObjectProperty,
createSimpleExpression,
createObjectExpression,
Property
Property,
createSequenceExpression
} from '../ast'
import { PatchFlags, PatchFlagNames, isSymbol } from '@vue/shared'
import { createCompilerError, ErrorCodes } from '../errors'
Expand All @@ -26,7 +27,9 @@ import {
MERGE_PROPS,
TO_HANDLERS,
PORTAL,
KEEP_ALIVE
KEEP_ALIVE,
OPEN_BLOCK,
CREATE_BLOCK
} from '../runtimeHelpers'
import {
getInnerRange,
Expand Down Expand Up @@ -67,6 +70,9 @@ export const transformElement: NodeTransform = (node, context) => {
let runtimeDirectives: DirectiveNode[] | undefined
let dynamicPropNames: string[] | undefined
let dynamicComponent: string | CallExpression | undefined
// technically this is web specific but we are keeping it in core to avoid
// extra complexity
let isSVG = false

// handle dynamic component
const isProp = findProp(node, 'is')
Expand Down Expand Up @@ -105,6 +111,7 @@ export const transformElement: NodeTransform = (node, context) => {
} else {
// plain element
nodeType = `"${node.tag}"`
isSVG = node.tag === 'svg'
}

const args: CallExpression['arguments'] = [nodeType]
Expand Down Expand Up @@ -190,8 +197,14 @@ export const transformElement: NodeTransform = (node, context) => {
}

const { loc } = node
const vnode = createCallExpression(context.helper(CREATE_VNODE), args, loc)

const vnode = isSVG
? // <svg> must be forced into blocks so that block updates inside retain
// isSVG flag at runtime. (#639, #643)
createSequenceExpression([
createCallExpression(context.helper(OPEN_BLOCK)),
createCallExpression(context.helper(CREATE_BLOCK), args, loc)
])
: createCallExpression(context.helper(CREATE_VNODE), args, loc)
if (runtimeDirectives && runtimeDirectives.length) {
node.codegenNode = createCallExpression(
context.helper(WITH_DIRECTIVES),
Expand Down

0 comments on commit f2ac28b

Please sign in to comment.