expect((first as Element).namespaceURI).toMatch('svg')
expect((last as Element).namespaceURI).toMatch('svg')
})
+
+ test('cached insertion', () => {
+ const content = `<div>one</div><div>two</div>three`
+ const existing = `<div>existing</div>`
+ const parent = document.createElement('div')
+ parent.innerHTML = existing
+ const anchor = parent.firstChild
+
+ const cached = document.createElement('div')
+ cached.innerHTML = content
+
+ const nodes = nodeOps.insertStaticContent!(
+ content,
+ parent,
+ anchor,
+ false,
+ cached.firstChild,
+ cached.lastChild
+ )
+ expect(parent.innerHTML).toBe(content + existing)
+ expect(nodes[0]).toBe(parent.firstChild)
+ expect(nodes[1]).toBe(parent.childNodes[parent.childNodes.length - 2])
+ })
})
})
const doc = (typeof document !== 'undefined' ? document : null) as Document
-const staticTemplateCache = new Map<string, DocumentFragment>()
+const templateContainer = doc && doc.createElement('template')
export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = {
insert: (child, parent, anchor) => {
// Reason: innerHTML.
// 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) {
+ insertStaticContent(content, parent, anchor, isSVG, start, end) {
// <parent> before | first ... last | anchor </parent>
const before = anchor ? anchor.previousSibling : parent.lastChild
- let template = staticTemplateCache.get(content)
- if (!template) {
- const t = doc.createElement('template')
- t.innerHTML = isSVG ? `<svg>${content}</svg>` : content
- template = t.content
+ if (start && end) {
+ // cached
+ while (true) {
+ parent.insertBefore(start!.cloneNode(true), anchor)
+ if (start === end || !(start = start!.nextSibling)) break
+ }
+ } else {
+ // fresh insert
+ templateContainer.innerHTML = isSVG ? `<svg>${content}</svg>` : content
+ const template = templateContainer.content
if (isSVG) {
// remove outer svg wrapper
const wrapper = template.firstChild!
}
template.removeChild(wrapper)
}
- staticTemplateCache.set(content, template)
+ parent.insertBefore(template, anchor)
}
- parent.insertBefore(template.cloneNode(true), anchor)
return [
// first
before ? before.nextSibling! : parent.firstChild!,