UNPKG

vue-jsx-vapor

Version:
113 lines (111 loc) 3.47 kB
import * as Vue from "vue"; import { EffectScope, VaporFragment, insert, isFragment, isVaporComponent, proxyRefs, remove, renderEffect, shallowRef as useRef, toRefs, useAttrs } from "vue"; //#region src/core/runtime.ts function getCurrentInstance() { return Vue.currentInstance || Vue.getCurrentInstance(); } /** * Returns the props of the current component instance. * * @example * ```tsx * import { useProps } from 'vue-jsx-vapor' * * defineComponent(({ foo = '' })=>{ * const props = useProps() // { foo: '' } * }) * ``` */ function useProps() { const i = getCurrentInstance(); return i.props; } /** * Returns the merged props and attrs of the current component.\ * Equivalent to `useProps()` + `useAttrs()`. * * @example * ```tsx * import { useFullProps } from 'vue-jsx-vapor' * * defineComponent((props) => { * const fullProps = useFullProps() // = useAttrs() + useProps() * }) */ function useFullProps() { return proxyRefs({ ...toRefs(useProps()), ...toRefs(useAttrs()) }); } function createFragment(nodes, anchor = document.createTextNode("")) { const frag = new VaporFragment(nodes); frag.anchor = anchor; return frag; } function normalizeNode(node, anchor) { if (node instanceof Node || isFragment(node)) { anchor && (anchor.textContent = ""); return node; } else if (isVaporComponent(node)) { anchor && (anchor.textContent = ""); return createFragment(node, anchor); } else if (Array.isArray(node)) { anchor && (anchor.textContent = ""); return createFragment(node.map((i) => normalizeNode(i)), anchor); } else { const result = node == null || typeof node === "boolean" ? "" : String(node); if (anchor) { anchor.textContent = result; return anchor; } else return document.createTextNode(result); } } function resolveValue(current, value, _anchor) { const node = normalizeNode(value, _anchor); if (current) { if (isFragment(current)) { const { anchor } = current; if (anchor && anchor.parentNode) { remove(current.nodes, anchor.parentNode); insert(node, anchor.parentNode, anchor); !_anchor && anchor.parentNode.removeChild(anchor); } } else if (current instanceof Node) { if (isFragment(node) && current.parentNode) { insert(node, current.parentNode, current); current.parentNode.removeChild(current); } else if (node instanceof Node) { if (current.nodeType === 3 && node.nodeType === 3) { current.textContent = node.textContent; return current; } else if (current.parentNode) current.parentNode.replaceChild(node, current); } } } return node; } function resolveValues(values = [], _anchor) { const nodes = []; const frag = createFragment(nodes, _anchor); const scopes = []; for (const [index, value] of values.entries()) { const anchor = index === values.length - 1 ? _anchor : void 0; if (typeof value === "function") renderEffect(() => { if (scopes[index]) scopes[index].stop(); scopes[index] = new EffectScope(); nodes[index] = scopes[index].run(() => resolveValue(nodes[index], value(), anchor)); }); else nodes[index] = resolveValue(nodes[index], value, anchor); } return frag; } function setNodes(anchor, ...values) { const resolvedValues = resolveValues(values, anchor); anchor.parentNode && insert(resolvedValues, anchor.parentNode, anchor); } function createNodes(...values) { return resolveValues(values); } //#endregion export { createNodes, getCurrentInstance, setNodes, useFullProps, useProps, useRef };