const template = '<div id="foo" class="bar"></div>'
expect(code).toMatchSnapshot()
expect(code).contains(JSON.stringify(template))
- expect(ir.template).toMatchObject([template])
+ expect([...ir.template.keys()]).toMatchObject([template])
expect(ir.block.effect).lengthOf(0)
})
const template = '<div id="foo"><span></span></div>'
expect(code).toMatchSnapshot()
expect(code).contains(JSON.stringify(template))
- expect(ir.template).toMatchObject([template])
+ expect([...ir.template.keys()]).toMatchObject([template])
expect(ir.block.effect).lengthOf(0)
})
<form><form/></form>`,
)
expect(code).toMatchSnapshot()
- expect(ir.template).toEqual(['<div>123</div>', '<p></p>', '<form></form>'])
+ expect([...ir.template.keys()]).toEqual([
+ '<div>123</div>',
+ '<p></p>',
+ '<form></form>',
+ ])
expect(ir.block.dynamic).toMatchObject({
children: [
{ id: 1, template: 1, children: [{ id: 0, template: 0 }] },
expect(code).contains(
'_template("<svg><circle r=\\"40\\"></circle></svg>", true, 1)',
)
- expect(ir.template).toMatchObject([t])
- expect(ir.templateNS.get(t)).toBe(1)
+ expect([...ir.template.keys()]).toMatchObject([t])
+ expect(ir.template.get(t)).toBe(1)
})
test('MathML', () => {
expect(code).contains(
'_template("<math><mrow><mi>x</mi></mrow></math>", true, 2)',
)
- expect(ir.template).toMatchObject([t])
- expect(ir.templateNS.get(t)).toBe(2)
+ expect([...ir.template.keys()]).toMatchObject([t])
+ expect(ir.template.get(t)).toBe(2)
})
})
test('default slot outlet with fallback', () => {
const { ir, code } = compileWithSlotsOutlet(`<slot><div/></slot>`)
expect(code).toMatchSnapshot()
- expect(ir.template[0]).toBe('<div></div>')
+ expect([...ir.template.keys()][0]).toBe('<div></div>')
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.SLOT_OUTLET_NODE,
id: 0,
`<slot name="foo"><div/></slot>`,
)
expect(code).toMatchSnapshot()
- expect(ir.template[0]).toBe('<div></div>')
+ expect([...ir.template.keys()][0]).toBe('<div></div>')
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.SLOT_OUTLET_NODE,
id: 0,
`<slot :foo="bar"><div/></slot>`,
)
expect(code).toMatchSnapshot()
- expect(ir.template[0]).toBe('<div></div>')
+ expect([...ir.template.keys()][0]).toBe('<div></div>')
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.SLOT_OUTLET_NODE,
id: 0,
`<slot name="foo" :foo="bar"><div/></slot>`,
)
expect(code).toMatchSnapshot()
- expect(ir.template[0]).toBe('<div></div>')
+ expect([...ir.template.keys()][0]).toBe('<div></div>')
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.SLOT_OUTLET_NODE,
id: 0,
id: 0,
flags: DynamicFlag.REFERENCED,
})
- expect(ir.template).toEqual(['<div></div>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>'])
expect(ir.block.operation).lengthOf(1)
expect(ir.block.operation[0]).toMatchObject({
type: IRNodeTypes.SET_TEMPLATE_REF,
id: 0,
flags: DynamicFlag.REFERENCED,
})
- expect(ir.template).toEqual(['<div></div>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>'])
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.DECLARE_OLD_REF,
id: 0,
flags: DynamicFlag.REFERENCED,
})
- expect(ir.template).toEqual(['<div></div>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>'])
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.DECLARE_OLD_REF,
id: 0,
flags: DynamicFlag.REFERENCED,
})
- expect(ir.template).toEqual(['<div></div>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>'])
expect(ir.block.effect).lengthOf(1)
expect(ir.block.effect[0].expressions).lengthOf(1)
expect(ir.block.effect[0].operations).lengthOf(1)
end: { line: 1, column: 19 },
},
})
- expect(ir.template).toEqual(['<div arg></div>'])
+ expect([...ir.template.keys()]).toEqual(['<div arg></div>'])
expect(code).matchSnapshot()
expect(code).contains(JSON.stringify('<div arg></div>'))
expect(code).matchSnapshot()
expect(helpers).contains('createFor')
- expect(ir.template).toEqual(['<div> </div>'])
+ expect([...ir.template.keys()]).toEqual(['<div> </div>'])
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.FOR,
id: 0,
`_createFor(() => (_for_item0.value), (_for_item1) => {`,
)
expect(code).contains(`_for_item1.value+_for_item0.value`)
- expect(ir.template).toEqual(['<span> </span>', '<div></div>'])
+ expect([...ir.template.keys()]).toEqual(['<span> </span>', '<div></div>'])
const parentOp = ir.block.dynamic.children[0].operation
expect(parentOp).toMatchObject({
type: IRNodeTypes.FOR,
expect(helpers).contains('setHtml')
// children should have been removed
- expect(ir.template).toEqual(['<div></div>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>'])
expect(ir.block.operation).toMatchObject([])
expect(ir.block.effect).toMatchObject([
expect(helpers).contains('createIf')
- expect(ir.template).toEqual(['<div> </div>'])
+ expect([...ir.template.keys()]).toEqual(['<div> </div>'])
const op = ir.block.dynamic.children[0].operation
expect(op).toMatchObject({
)
expect(code).matchSnapshot()
- expect(ir.template).toEqual(['<div></div>', 'hello', '<p> </p>'])
+ expect([...ir.template.keys()]).toEqual([
+ '<div></div>',
+ 'hello',
+ '<p> </p>',
+ ])
expect(ir.block.effect).toEqual([])
const op = ir.block.dynamic.children[0].operation as IfIRNode
expect(op.positive.effect).toMatchObject([
`<div v-if="ok">hello</div><div v-if="ok">hello</div>`,
)
expect(code).matchSnapshot()
- expect(ir.template).toEqual(['<div>hello</div>'])
+ expect([...ir.template.keys()]).toEqual(['<div>hello</div>'])
expect(ir.block.returns).toEqual([0, 3])
})
test('v-if + v-else', () => {
const { code, ir, helpers } = compileWithVIf(`<div v-if="ok"/><p v-else/>`)
expect(code).matchSnapshot()
- expect(ir.template).toEqual(['<div></div>', '<p></p>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>', '<p></p>'])
expect(helpers).contains('createIf')
expect(ir.block.effect).lengthOf(0)
`<div v-if="ok"/><p v-else-if="orNot"/>`,
)
expect(code).matchSnapshot()
- expect(ir.template).toEqual(['<div></div>', '<p></p>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>', '<p></p>'])
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.IF,
`<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`,
)
expect(code).matchSnapshot()
- expect(ir.template).toEqual(['<div></div>', '<p></p>', 'fine'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>', '<p></p>', 'fine'])
expect(ir.block.returns).toEqual([0])
expect(ir.block.dynamic.children[0].operation).toMatchObject({
<div v-text="text" />
`)
expect(code).matchSnapshot()
- expect(ir.template).toEqual([
+ expect([...ir.template.keys()]).toEqual([
'<div></div>',
'<!--foo-->',
'<p></p>',
const { ir, code } = compileWithSlots(`<Comp><div/></Comp>`)
expect(code).toMatchSnapshot()
- expect(ir.template).toEqual(['<div></div>'])
+ expect([...ir.template.keys()]).toEqual(['<div></div>'])
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.CREATE_COMPONENT_NODE,
id: 1,
)
expect(code).toMatchSnapshot()
- expect(ir.template).toEqual(['foo', 'bar', '<span></span>'])
+ expect([...ir.template.keys()]).toEqual(['foo', 'bar', '<span></span>'])
expect(ir.block.dynamic.children[0].operation).toMatchObject({
type: IRNodeTypes.CREATE_COMPONENT_NODE,
id: 4,
])
// children should have been removed
- expect(ir.template).toEqual(['<div> </div>'])
+ expect([...ir.template.keys()]).toEqual(['<div> </div>'])
expect(ir.block.effect).toMatchObject([
{
import { type CodeFragment, NEWLINE, buildCodeFragment, genCall } from './utils'
export function genTemplates(
- templates: string[],
+ templates: Map<string, number>,
rootIndex: number | undefined,
- { helper, ir: { templateNS } }: CodegenContext,
+ { helper }: CodegenContext,
): string {
- return templates
- .map((template, i) => {
- const ns = templateNS.get(template)
- return `const t${i} = ${helper('template')}(${JSON.stringify(
+ const result: string[] = []
+ let i = 0
+ templates.forEach((ns, template) => {
+ result.push(
+ `const t${i} = ${helper('template')}(${JSON.stringify(
template,
- )}${i === rootIndex ? ', true' : ns ? ', false' : ''}${ns ? `, ${ns}` : ''})\n`
- })
- .join('')
+ )}${i === rootIndex ? ', true' : ns ? ', false' : ''}${ns ? `, ${ns}` : ''})\n`,
+ )
+ i++
+ })
+ return result.join('')
}
export function genSelf(
type: IRNodeTypes.ROOT
node: RootNode
source: string
- template: string[]
- templateNS: Map<string, number>
+ template: Map<string, number>
+ templateIndexMap: Map<string, number>
rootTemplateIndex?: number
component: Set<string>
directive: Set<string>
>
template: string = ''
- templateNS: Map<string, number> = new Map<string, number>()
childrenTemplate: (string | null)[] = []
dynamic: IRDynamicInfo = this.ir.block.dynamic
}
enterBlock(ir: BlockIRNode, isVFor: boolean = false): () => void {
- const { block, template, templateNS, dynamic, childrenTemplate, slots } =
- this
+ const { block, template, dynamic, childrenTemplate, slots } = this
this.block = ir
this.dynamic = ir.dynamic
this.template = ''
- this.templateNS = new Map<string, number>()
this.childrenTemplate = []
this.slots = []
isVFor && this.inVFor++
this.registerTemplate()
this.block = block
this.template = template
- this.templateNS = templateNS
this.dynamic = dynamic
this.childrenTemplate = childrenTemplate
this.slots = slots
}
pushTemplate(content: string): number {
- const existing = this.ir.template.findIndex(
- template => template === content,
- )
- if (existing !== -1) return existing
- this.ir.template.push(content)
- this.ir.templateNS.set(content, (this.node as PlainElementNode).ns)
- return this.ir.template.length - 1
+ const existingIndex = this.ir.templateIndexMap.get(content)
+ if (existingIndex !== undefined) {
+ return existingIndex
+ }
+
+ const newIndex = this.ir.template.size
+ this.ir.template.set(content, (this.node as PlainElementNode).ns)
+ this.ir.templateIndexMap.set(content, newIndex)
+ return newIndex
}
registerTemplate(): number {
if (!this.template) return -1
type: IRNodeTypes.ROOT,
node,
source: node.source,
- template: [],
- templateNS: new Map<string, number>(),
+ template: new Map<string, number>(),
+ templateIndexMap: new Map<string, number>(),
component: new Set(),
directive: new Set(),
block: newBlock(node),
}
if (singleRoot) {
- context.ir.rootTemplateIndex = context.ir.template.length
+ context.ir.rootTemplateIndex = context.ir.template.size
}
if (