UNPKG

@skirtle/vue-vnode-utils

Version:
438 lines (437 loc) 13.7 kB
var VueVNodeUtils = (function(exports, vue) { Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); //#region src/base.ts const isComment = (vnode) => { return getType(vnode) === "comment"; }; const isComponent = (vnode) => { return getType(vnode) === "component"; }; const isElement = (vnode) => { return getType(vnode) === "element"; }; const isFragment = (vnode) => { return getType(vnode) === "fragment"; }; const isFunctionalComponent = (vnode) => { return isComponent(vnode) && typeof vnode.type === "function"; }; const isStatefulComponent = (vnode) => { return isComponent(vnode) && typeof vnode.type === "object"; }; const isStatic = (vnode) => { return getType(vnode) === "static"; }; const isText = (vnode) => { return getType(vnode) === "text"; }; const getText = (vnode) => { if (typeof vnode === "string") return vnode; if (typeof vnode === "number") return String(vnode); if ((0, vue.isVNode)(vnode) && vnode.type === vue.Text) return String(vnode.children); }; const getType = (vnode) => { const typeofVNode = typeof vnode; if (vnode == null || typeofVNode === "boolean") return "comment"; else if (typeofVNode === "string" || typeofVNode === "number") return "text"; else if (Array.isArray(vnode)) return "fragment"; if ((0, vue.isVNode)(vnode)) { const { type } = vnode; const typeofType = typeof type; if (typeofType === "symbol") { if (type === vue.Fragment) return "fragment"; else if (type === vue.Text) return "text"; else if (type === vue.Comment) return "comment"; else if (type === vue.Static) return "static"; } else if (typeofType === "string") return "element"; else if (typeofType === "object" || typeofType === "function") return "component"; } }; //#endregion //#region src/iterators.ts const warn = (method, msg) => { console.warn(`[${method}] ${msg}`); }; const checkArguments = (method, passed, expected) => { for (let index = 0; index < passed.length; ++index) { const t = typeOf(passed[index]); const expect = expected[index]; if (expect !== t) warn(method, `Argument ${index + 1} was ${t}, should be ${expect}`); } }; const isEmptyObject = (obj) => { for (const prop in obj) return false; return true; }; const typeOf = (value) => { let t = typeof value; if (t === "object") { if (value === null) t = "null"; else if (Array.isArray(value)) t = "array"; else if ((0, vue.isVNode)(value)) t = "vnode"; else if (value instanceof Date) t = "date"; else if (value instanceof RegExp) t = "regexp"; } return t; }; const getFragmentChildren = (fragmentVNode) => { if (Array.isArray(fragmentVNode)) return fragmentVNode; const { children } = fragmentVNode; if (Array.isArray(children)) return children; warn("getFragmentChildren", `Unknown children for fragment: ${typeOf(children)}`); return []; }; function freeze(obj) { return Object.freeze(obj); } const COMPONENTS_AND_ELEMENTS = /* @__PURE__ */ freeze({ element: true, component: true }); const SKIP_COMMENTS = /* @__PURE__ */ freeze({ element: true, component: true, text: true, static: true }); const ALL_VNODES = /* @__PURE__ */ freeze({ element: true, component: true, text: true, static: true, comment: true }); const promoteToVNode = (node, options) => { const type = getType(node); if (!type || type === "fragment" || !options[type]) return null; if ((0, vue.isVNode)(node)) return node; if (type === "text") return (0, vue.createTextVNode)(getText(node)); return (0, vue.createCommentVNode)(); }; const addProps$1 = (children, callback, options = COMPONENTS_AND_ELEMENTS) => { checkArguments("addProps", [ children, callback, options ], [ "array", "function", "object" ]); return replaceChildrenInternal(children, (vnode) => { const props = callback(vnode); { const typeofProps = typeOf(props); if (![ "object", "null", "undefined" ].includes(typeofProps)) warn("addProps", `Callback returned unexpected ${typeofProps}: ${String(props)}`); } if (props && !isEmptyObject(props)) return (0, vue.cloneVNode)(vnode, props, true); }, options); }; const replaceChildren$1 = (children, callback, options = SKIP_COMMENTS) => { checkArguments("replaceChildren", [ children, callback, options ], [ "array", "function", "object" ]); return replaceChildrenInternal(children, callback, options); }; const replaceChildrenInternal = (children, callback, options) => { var _nc3; let nc = null; for (let index = 0; index < children.length; ++index) { const child = children[index]; if (isFragment(child)) { const oldFragmentChildren = getFragmentChildren(child); const newFragmentChildren = replaceChildrenInternal(oldFragmentChildren, callback, options); let newChild = child; if (oldFragmentChildren !== newFragmentChildren) { var _nc; (_nc = nc) !== null && _nc !== void 0 || (nc = children.slice(0, index)); if (Array.isArray(child)) newChild = newFragmentChildren; else { newChild = (0, vue.cloneVNode)(child); newChild.children = newFragmentChildren; } } nc && nc.push(newChild); } else { const vnode = promoteToVNode(child, options); if (vnode) { var _callback; const newNodes = (_callback = callback(vnode)) !== null && _callback !== void 0 ? _callback : vnode; { const typeOfNewNodes = typeOf(newNodes); if (![ "array", "vnode", "string", "number", "undefined" ].includes(typeOfNewNodes)) warn("replaceChildren", `Callback returned unexpected ${typeOfNewNodes} ${String(newNodes)}`); } if (newNodes !== child) { var _nc2; (_nc2 = nc) !== null && _nc2 !== void 0 || (nc = children.slice(0, index)); } if (Array.isArray(newNodes)) nc && nc.push(...newNodes); else nc && nc.push(newNodes); } else nc && nc.push(child); } } return (_nc3 = nc) !== null && _nc3 !== void 0 ? _nc3 : children; }; const betweenChildren$1 = (children, callback, options = SKIP_COMMENTS) => { checkArguments("betweenChildren", [ children, callback, options ], [ "array", "function", "object" ]); let previousVNode = null; return replaceChildrenInternal(children, (vnode) => { let insertedNodes = void 0; if (previousVNode) { insertedNodes = callback(previousVNode, vnode); { const typeOfInsertedNodes = typeOf(insertedNodes); if (![ "array", "vnode", "string", "number", "undefined" ].includes(typeOfInsertedNodes)) warn("betweenChildren", `Callback returned unexpected ${typeOfInsertedNodes} ${String(insertedNodes)}`); } } previousVNode = vnode; if (insertedNodes == null || Array.isArray(insertedNodes) && insertedNodes.length === 0) return; if (Array.isArray(insertedNodes)) return [...insertedNodes, vnode]; return [insertedNodes, vnode]; }, options); }; const someChild$1 = (children, callback, options = ALL_VNODES) => { checkArguments("someChild", [ children, callback, options ], [ "array", "function", "object" ]); return someChildInternal(children, callback, options); }; const someChildInternal = (children, callback, options) => { for (const child of children) if (isFragment(child)) { if (someChild$1(getFragmentChildren(child), callback, options)) return true; } else { const vnode = promoteToVNode(child, options); if (vnode && callback(vnode)) return true; } return false; }; const everyChild$1 = (children, callback, options = ALL_VNODES) => { checkArguments("everyChild", [ children, callback, options ], [ "array", "function", "object" ]); return !someChildInternal(children, (vnode) => !callback(vnode), options); }; const eachChild$1 = (children, callback, options = ALL_VNODES) => { checkArguments("eachChild", [ children, callback, options ], [ "array", "function", "object" ]); someChildInternal(children, (vnode) => { callback(vnode); }, options); }; const findChild$1 = (children, callback, options = ALL_VNODES) => { checkArguments("findChild", [ children, callback, options ], [ "array", "function", "object" ]); let node = void 0; someChildInternal(children, (vnode) => { if (callback(vnode)) { node = vnode; return true; } }, options); return node; }; const reduceChildren$1 = (children, callback, initialValue, options = ALL_VNODES) => { checkArguments("reduceChildren", [ children, callback, null, options ], [ "array", "function", "null", "object" ]); someChildInternal(children, (vnode) => { initialValue = callback(initialValue, vnode); }, options); return initialValue; }; const COLLAPSIBLE_WHITESPACE_RE = /\S|\u00a0/; const isEmpty = (children) => { checkArguments("isEmpty", [children], ["array"]); return !someChildInternal(children, (vnode) => { if (isText(vnode)) { const text = getText(vnode) || ""; return COLLAPSIBLE_WHITESPACE_RE.test(text); } return true; }, SKIP_COMMENTS); }; const extractSingleChild = (children) => { checkArguments("extractSingleChild", [children], ["array"]); const node = findChild$1(children, () => { return true; }, COMPONENTS_AND_ELEMENTS); someChildInternal(children, (vnode) => { let warning = ""; if (vnode === node) return false; if (isElement(vnode) || isComponent(vnode)) warning = "Multiple root nodes found, only one expected"; else if (isText(vnode)) { const text = getText(vnode) || ""; if (COLLAPSIBLE_WHITESPACE_RE.test(text)) warning = `Non-empty text node:\n'${text}'`; } else warning = `Encountered unexpected ${getType(vnode)} VNode`; if (warning) { warn("extractSingleChild", warning); return true; } }, SKIP_COMMENTS); return node; }; const countChildren = (children, options = ALL_VNODES) => { checkArguments("count", [children, options], ["array", "object"]); let count = 0; someChildInternal(children, () => { ++count; }, options); return count; }; //#endregion //#region src/with-meta/iterators.ts function checkFunction(method, callback) { checkArguments(method, [callback], ["function"]); } function setPropertyValue(obj, key, value) { return Object.defineProperty(obj, key, { value, enumerable: true }); } function createMetaFactory(children, options) { let index = -1; const baseMeta = { get length() { const length = countChildren(children, options); setPropertyValue(baseMeta, "length", length); return length; } }; return () => { return setPropertyValue(Object.create(baseMeta), "index", ++index); }; } function withMeta(iterator, children, callback, options) { const metaFactory = createMetaFactory(children, options); return iterator(children, (vnode) => { return callback(vnode, metaFactory()); }, options); } const addProps = (children, callback, options = COMPONENTS_AND_ELEMENTS) => { checkFunction("addProps", callback); return withMeta(addProps$1, children, callback, options); }; const replaceChildren = (children, callback, options = SKIP_COMMENTS) => { checkFunction("replaceChildren", callback); return withMeta(replaceChildren$1, children, callback, options); }; const betweenChildren = (children, callback, options = SKIP_COMMENTS) => { checkFunction("betweenChildren", callback); const metaFactory = createMetaFactory(children, options); return betweenChildren$1(children, (previousVNode, nextVNode) => { return callback(previousVNode, nextVNode, metaFactory()); }, options); }; const someChild = (children, callback, options = ALL_VNODES) => { checkFunction("someChild", callback); return withMeta(someChild$1, children, callback, options); }; const everyChild = (children, callback, options = ALL_VNODES) => { checkFunction("everyChild", callback); return withMeta(everyChild$1, children, callback, options); }; const eachChild = (children, callback, options = ALL_VNODES) => { checkFunction("eachChild", callback); return withMeta(eachChild$1, children, callback, options); }; const findChild = (children, callback, options = ALL_VNODES) => { checkFunction("findChild", callback); return withMeta(findChild$1, children, callback, options); }; const reduceChildren = (children, callback, initialValue, options = ALL_VNODES) => { checkFunction("reduceChildren", callback); const metaFactory = createMetaFactory(children, options); return reduceChildren$1(children, (previousValue, vnode) => { return callback(previousValue, vnode, metaFactory()); }, initialValue, options); }; //#endregion exports.ALL_VNODES = ALL_VNODES; exports.COMPONENTS_AND_ELEMENTS = COMPONENTS_AND_ELEMENTS; exports.SKIP_COMMENTS = SKIP_COMMENTS; exports.addProps = addProps; exports.betweenChildren = betweenChildren; exports.countChildren = countChildren; exports.eachChild = eachChild; exports.everyChild = everyChild; exports.extractSingleChild = extractSingleChild; exports.findChild = findChild; exports.getText = getText; exports.getType = getType; exports.isComment = isComment; exports.isComponent = isComponent; exports.isElement = isElement; exports.isEmpty = isEmpty; exports.isFragment = isFragment; exports.isFunctionalComponent = isFunctionalComponent; exports.isStatefulComponent = isStatefulComponent; exports.isStatic = isStatic; exports.isText = isText; exports.reduceChildren = reduceChildren; exports.replaceChildren = replaceChildren; exports.someChild = someChild; return exports; })({}, Vue);