2020-02-13 01:12:53 +08:00
|
|
|
import type { RendererOptions } from '@vue/runtime-core'
|
2020-02-13 00:56:42 +08:00
|
|
|
|
2020-04-11 03:23:01 +08:00
|
|
|
export const svgNS = 'http://www.w3.org/2000/svg'
|
2023-12-08 18:25:01 +08:00
|
|
|
export const mathmlNS = 'http://www.w3.org/1998/Math/MathML'
|
2020-04-11 03:23:01 +08:00
|
|
|
|
2020-01-26 11:31:29 +08:00
|
|
|
const doc = (typeof document !== 'undefined' ? document : null) as Document
|
2019-05-26 15:19:44 +08:00
|
|
|
|
2022-04-13 17:39:02 +08:00
|
|
|
const templateContainer = doc && /*#__PURE__*/ doc.createElement('template')
|
2021-07-10 04:18:36 +08:00
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = {
|
|
|
|
|
insert: (child, parent, anchor) => {
|
2020-06-30 01:19:31 +08:00
|
|
|
parent.insertBefore(child, anchor || null)
|
2019-05-26 15:19:44 +08:00
|
|
|
},
|
|
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
remove: child => {
|
2019-05-26 15:19:44 +08:00
|
|
|
const parent = child.parentNode
|
2020-03-19 06:14:51 +08:00
|
|
|
if (parent) {
|
2019-05-26 15:19:44 +08:00
|
|
|
parent.removeChild(child)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2023-12-08 18:25:01 +08:00
|
|
|
createElement: (tag, namespace, is, props): Element => {
|
|
|
|
|
const el =
|
|
|
|
|
namespace === 'svg'
|
|
|
|
|
? doc.createElementNS(svgNS, tag)
|
|
|
|
|
: namespace === 'mathml'
|
|
|
|
|
? doc.createElementNS(mathmlNS, tag)
|
|
|
|
|
: doc.createElement(tag, is ? { is } : undefined)
|
2021-03-26 04:49:34 +08:00
|
|
|
|
|
|
|
|
if (tag === 'select' && props && props.multiple != null) {
|
|
|
|
|
;(el as HTMLSelectElement).setAttribute('multiple', props.multiple)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return el
|
|
|
|
|
},
|
2019-05-26 15:19:44 +08:00
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
createText: text => doc.createTextNode(text),
|
2019-05-26 15:19:44 +08:00
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
createComment: text => doc.createComment(text),
|
2019-05-26 15:19:44 +08:00
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
setText: (node, text) => {
|
2019-05-26 15:19:44 +08:00
|
|
|
node.nodeValue = text
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
setElementText: (el, text) => {
|
2019-05-26 15:19:44 +08:00
|
|
|
el.textContent = text
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
parentNode: node => node.parentNode as Element | null,
|
2019-05-28 13:27:31 +08:00
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
nextSibling: node => node.nextSibling,
|
2019-05-29 16:10:25 +08:00
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
querySelector: selector => doc.querySelector(selector),
|
2019-12-17 02:33:10 +08:00
|
|
|
|
2020-02-13 00:56:42 +08:00
|
|
|
setScopeId(el, id) {
|
2019-12-17 02:33:10 +08:00
|
|
|
el.setAttribute(id, '')
|
2020-02-13 00:56:42 +08:00
|
|
|
},
|
|
|
|
|
|
2020-02-13 04:00:32 +08:00
|
|
|
// __UNSAFE__
|
2021-07-10 04:18:36 +08:00
|
|
|
// Reason: innerHTML.
|
2020-02-13 04:00:32 +08:00
|
|
|
// Static content here can only come from compiled templates.
|
|
|
|
|
// As long as the user only uses trusted templates, this is safe.
|
2023-12-08 18:25:01 +08:00
|
|
|
insertStaticContent(content, parent, anchor, namespace, start, end) {
|
2021-06-22 02:34:08 +08:00
|
|
|
// <parent> before | first ... last | anchor </parent>
|
|
|
|
|
const before = anchor ? anchor.previousSibling : parent.lastChild
|
2022-01-23 21:37:54 +08:00
|
|
|
// #5308 can only take cached path if:
|
|
|
|
|
// - has a single root node
|
|
|
|
|
// - nextSibling info is still available
|
|
|
|
|
if (start && (start === end || start.nextSibling)) {
|
2022-01-16 20:39:55 +08:00
|
|
|
// cached
|
|
|
|
|
while (true) {
|
|
|
|
|
parent.insertBefore(start!.cloneNode(true), anchor)
|
|
|
|
|
if (start === end || !(start = start!.nextSibling)) break
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// fresh insert
|
2023-12-08 18:25:01 +08:00
|
|
|
templateContainer.innerHTML =
|
|
|
|
|
namespace === 'svg'
|
|
|
|
|
? `<svg>${content}</svg>`
|
|
|
|
|
: namespace === 'mathml'
|
|
|
|
|
? `<math>${content}</math>`
|
|
|
|
|
: content
|
|
|
|
|
|
2022-01-16 20:39:55 +08:00
|
|
|
const template = templateContainer.content
|
2023-12-08 18:25:01 +08:00
|
|
|
if (namespace === 'svg' || namespace === 'mathml') {
|
|
|
|
|
// remove outer svg/math wrapper
|
2021-07-10 04:18:36 +08:00
|
|
|
const wrapper = template.firstChild!
|
|
|
|
|
while (wrapper.firstChild) {
|
|
|
|
|
template.appendChild(wrapper.firstChild)
|
|
|
|
|
}
|
|
|
|
|
template.removeChild(wrapper)
|
2021-06-22 02:34:08 +08:00
|
|
|
}
|
2022-01-16 20:39:55 +08:00
|
|
|
parent.insertBefore(template, anchor)
|
2021-07-02 07:17:07 +08:00
|
|
|
}
|
2021-07-10 04:18:36 +08:00
|
|
|
return [
|
|
|
|
|
// first
|
|
|
|
|
before ? before.nextSibling! : parent.firstChild!,
|
|
|
|
|
// last
|
|
|
|
|
anchor ? anchor.previousSibling! : parent.lastChild!,
|
|
|
|
|
]
|
2020-05-01 02:38:13 +08:00
|
|
|
},
|
|
|
|
|
}
|