Skip to content

Commit 5b09e74

Browse files
committed
fix(ssr): fix escape and handling for raw Text, Comment and Static vnodes
1 parent 1bddeea commit 5b09e74

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

packages/server-renderer/__tests__/renderToString.spec.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import {
66
resolveComponent,
77
ComponentOptions,
88
ref,
9-
defineComponent
9+
defineComponent,
10+
createTextVNode,
11+
createStaticVNode
1012
} from 'vue'
1113
import { escapeHtml, mockWarn } from '@vue/shared'
1214
import { renderToString, renderComponent } from '../src/renderToString'
@@ -511,6 +513,33 @@ describe('ssr: renderToString', () => {
511513
})
512514
})
513515

516+
describe('raw vnode types', () => {
517+
test('Text', async () => {
518+
expect(await renderToString(createTextVNode('hello <div>'))).toBe(
519+
`hello &lt;div&gt;`
520+
)
521+
})
522+
523+
test('Comment', async () => {
524+
// https://www.w3.org/TR/html52/syntax.html#comments
525+
expect(
526+
await renderToString(
527+
h('div', [
528+
createCommentVNode('>foo'),
529+
createCommentVNode('->foo'),
530+
createCommentVNode('<!--foo-->'),
531+
createCommentVNode('--!>foo<!-')
532+
])
533+
)
534+
).toBe(`<div><!--foo--><!--foo--><!--foo--><!--foo--></div>`)
535+
})
536+
537+
test('Static', async () => {
538+
const content = `<div id="ok">hello<span>world</span></div>`
539+
expect(await renderToString(createStaticVNode(content))).toBe(content)
540+
})
541+
})
542+
514543
describe('scopeId', () => {
515544
// note: here we are only testing scopeId handling for vdom serialization.
516545
// compiled srr render functions will include scopeId directly in strings.

packages/server-renderer/src/renderToString.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
createVNode,
88
Text,
99
Comment,
10+
Static,
1011
Fragment,
1112
ssrUtils,
1213
Slots,
@@ -229,6 +230,9 @@ function ssrCompile(
229230
return (compileCache[template] = Function('require', code)(require))
230231
}
231232

233+
// https://www.w3.org/TR/html52/syntax.html#comments
234+
const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g
235+
232236
function renderVNode(
233237
push: PushFn,
234238
vnode: VNode,
@@ -237,10 +241,17 @@ function renderVNode(
237241
const { type, shapeFlag, children } = vnode
238242
switch (type) {
239243
case Text:
240-
push(children as string)
244+
push(escapeHtml(children as string))
241245
break
242246
case Comment:
243-
push(children ? `<!--${children}-->` : `<!---->`)
247+
push(
248+
children
249+
? `<!--${(children as string).replace(commentStripRE, '')}-->`
250+
: `<!---->`
251+
)
252+
break
253+
case Static:
254+
push(children as string)
244255
break
245256
case Fragment:
246257
push(`<!--[-->`) // open

0 commit comments

Comments
 (0)