diff --git a/packages/runtime-dom/__tests__/rendererStaticNode.spec.ts b/packages/runtime-dom/__tests__/rendererStaticNode.spec.ts index c4519d81dfc..889c32fd651 100644 --- a/packages/runtime-dom/__tests__/rendererStaticNode.spec.ts +++ b/packages/runtime-dom/__tests__/rendererStaticNode.spec.ts @@ -47,4 +47,21 @@ describe('static vnode handling', () => { render(h('div', [h('b'), h('b'), s]), root) expect(root.innerHTML).toBe(`
${content}
`) }) + + test('should support tbody tr td...',()=>{ + const content1 = `hello` + const content2 = `hello` + const content3 = `hello` + + const root = document.createElement('div') + const s1 = createStaticVNode(content1,1) + const s2 = createStaticVNode(content2,1) + const s3 = createStaticVNode(content3,1) + render(h('table', [s1]), root) + expect(root.innerHTML).toBe(`${content1}
`) + render(h('table', [s2]), root) + expect(root.innerHTML).toBe(`${content2}
`) + render(h('tr', [s3]), root) + expect(root.innerHTML).toBe(`${content3}`) + }) }) diff --git a/packages/runtime-dom/src/nodeOps.ts b/packages/runtime-dom/src/nodeOps.ts index 6d766385ca3..7ed251d0e44 100644 --- a/packages/runtime-dom/src/nodeOps.ts +++ b/packages/runtime-dom/src/nodeOps.ts @@ -1,5 +1,9 @@ import { RendererOptions } from '@vue/runtime-core' + +interface wrapConfig { + [name: string]: [number,string,string] +} export const svgNS = 'http://www.w3.org/2000/svg' const doc = (typeof document !== 'undefined' ? document : null) as Document @@ -7,6 +11,17 @@ const doc = (typeof document !== 'undefined' ? document : null) as Document let tempContainer: HTMLElement let tempSVGContainer: SVGElement +let wrapMap:wrapConfig = { + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ] +} +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead +wrapMap.th = wrapMap.td +const rtagName = /<([\w:]+)/ + + export const nodeOps: Omit, 'patchProp'> = { insert: (child, parent, anchor) => { if (anchor) { @@ -59,11 +74,22 @@ export const nodeOps: Omit, 'patchProp'> = { // Static content here can only come from compiled templates. // As long as the user only uses trusted templates, this is safe. insertStaticContent(content, parent, anchor, isSVG) { - const temp = isSVG + let temp = isSVG ? tempSVGContainer || (tempSVGContainer = doc.createElementNS(svgNS, 'svg')) : tempContainer || (tempContainer = doc.createElement('div')) - temp.innerHTML = content + const tag = ( rtagName.exec( content ) || ["", ""] )[1].toLowerCase() + if(wrapMap[tag]){ + // wrapping table labels to tr|td elements to return correct dom + let [depth, before, after] = wrapMap[ tag ] || [ 0, "", "" ] + temp.innerHTML = before+content+after + while(depth--){ + temp = temp.firstChild as HTMLElement|SVGElement + } + }else{ + temp.innerHTML = content + } + const first = temp.firstChild as Element let node: Element | null = first let last: Element = node @@ -75,3 +101,5 @@ export const nodeOps: Omit, 'patchProp'> = { return [first, last] } } + +