fix(ssr): fix escape and handling for raw Text, Comment and Static vnodes

This commit is contained in:
Evan You 2020-05-01 11:52:40 -04:00
parent 1bddeea247
commit 5b09e743a0
2 changed files with 43 additions and 3 deletions

View File

@ -6,7 +6,9 @@ import {
resolveComponent, resolveComponent,
ComponentOptions, ComponentOptions,
ref, ref,
defineComponent defineComponent,
createTextVNode,
createStaticVNode
} from 'vue' } from 'vue'
import { escapeHtml, mockWarn } from '@vue/shared' import { escapeHtml, mockWarn } from '@vue/shared'
import { renderToString, renderComponent } from '../src/renderToString' import { renderToString, renderComponent } from '../src/renderToString'
@ -511,6 +513,33 @@ describe('ssr: renderToString', () => {
}) })
}) })
describe('raw vnode types', () => {
test('Text', async () => {
expect(await renderToString(createTextVNode('hello <div>'))).toBe(
`hello &lt;div&gt;`
)
})
test('Comment', async () => {
// https://www.w3.org/TR/html52/syntax.html#comments
expect(
await renderToString(
h('div', [
createCommentVNode('>foo'),
createCommentVNode('->foo'),
createCommentVNode('<!--foo-->'),
createCommentVNode('--!>foo<!-')
])
)
).toBe(`<div><!--foo--><!--foo--><!--foo--><!--foo--></div>`)
})
test('Static', async () => {
const content = `<div id="ok">hello<span>world</span></div>`
expect(await renderToString(createStaticVNode(content))).toBe(content)
})
})
describe('scopeId', () => { describe('scopeId', () => {
// note: here we are only testing scopeId handling for vdom serialization. // note: here we are only testing scopeId handling for vdom serialization.
// compiled srr render functions will include scopeId directly in strings. // compiled srr render functions will include scopeId directly in strings.

View File

@ -7,6 +7,7 @@ import {
createVNode, createVNode,
Text, Text,
Comment, Comment,
Static,
Fragment, Fragment,
ssrUtils, ssrUtils,
Slots, Slots,
@ -229,6 +230,9 @@ function ssrCompile(
return (compileCache[template] = Function('require', code)(require)) return (compileCache[template] = Function('require', code)(require))
} }
// https://www.w3.org/TR/html52/syntax.html#comments
const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g
function renderVNode( function renderVNode(
push: PushFn, push: PushFn,
vnode: VNode, vnode: VNode,
@ -237,10 +241,17 @@ function renderVNode(
const { type, shapeFlag, children } = vnode const { type, shapeFlag, children } = vnode
switch (type) { switch (type) {
case Text: case Text:
push(children as string) push(escapeHtml(children as string))
break break
case Comment: case Comment:
push(children ? `<!--${children}-->` : `<!---->`) push(
children
? `<!--${(children as string).replace(commentStripRE, '')}-->`
: `<!---->`
)
break
case Static:
push(children as string)
break break
case Fragment: case Fragment:
push(`<!--[-->`) // open push(`<!--[-->`) // open