UNPKG

@tanstack/vue-router

Version:

Modern and scalable routing for Vue applications

146 lines (145 loc) 4.82 kB
import { useRouter } from "./useRouter.js"; import * as Vue from "vue"; import { createVNode, mergeProps } from "vue"; import { isServer } from "@tanstack/router-core/isServer"; //#region src/Asset.tsx var INLINE_CSS_HYDRATION_ATTR = "data-tsr-inline-css"; var Title = Vue.defineComponent({ name: "Title", props: { children: { type: String, default: "" } }, setup(props) { const router = useRouter(); if (!(isServer ?? router.isServer)) { Vue.onMounted(() => { if (props.children) document.title = props.children; }); Vue.watch(() => props.children, (newTitle) => { if (newTitle) document.title = newTitle; }); } return () => Vue.h("title", {}, props.children); } }); var Script = Vue.defineComponent({ name: "Script", props: { attrs: { type: Object, default: () => ({}) }, children: { type: String, default: void 0 } }, setup(props) { const router = useRouter(); const dataScript = typeof props.attrs?.type === "string" && props.attrs.type !== "" && props.attrs.type !== "text/javascript" && props.attrs.type !== "module"; if (!(isServer ?? router.isServer)) Vue.onMounted(() => { if (dataScript) return; const attrs = props.attrs; const children = props.children; if (attrs?.src) { const normSrc = (() => { try { const base = document.baseURI || window.location.href; return new URL(attrs.src, base).href; } catch { return attrs.src; } })(); if (Array.from(document.querySelectorAll("script[src]")).find((el) => el.src === normSrc)) return; const script = document.createElement("script"); for (const [key, value] of Object.entries(attrs)) if (value !== void 0 && value !== false) script.setAttribute(key, typeof value === "boolean" ? "" : String(value)); document.head.appendChild(script); } else if (typeof children === "string") { const typeAttr = typeof attrs?.type === "string" ? attrs.type : "text/javascript"; const nonceAttr = typeof attrs?.nonce === "string" ? attrs.nonce : void 0; if (Array.from(document.querySelectorAll("script:not([src])")).find((el) => { if (!(el instanceof HTMLScriptElement)) return false; const sType = el.getAttribute("type") ?? "text/javascript"; const sNonce = el.getAttribute("nonce") ?? void 0; return el.textContent === children && sType === typeAttr && sNonce === nonceAttr; })) return; const script = document.createElement("script"); script.textContent = children; if (attrs) { for (const [key, value] of Object.entries(attrs)) if (value !== void 0 && value !== false) script.setAttribute(key, typeof value === "boolean" ? "" : String(value)); } document.head.appendChild(script); } }); return () => { if (!(isServer ?? router.isServer)) { if (dataScript && typeof props.children === "string") return Vue.h("script", { ...props.attrs, "data-allow-mismatch": true, innerHTML: props.children }); const { src: _src, ...rest } = props.attrs || {}; return Vue.h("script", { ...rest, "data-allow-mismatch": true, innerHTML: "" }); } if (props.attrs?.src && typeof props.attrs.src === "string") return Vue.h("script", props.attrs); if (typeof props.children === "string") return Vue.h("script", { ...props.attrs, innerHTML: props.children }); return null; }; } }); var InlineCssStyle = Vue.defineComponent({ name: "InlineCssStyle", props: { attrs: { type: Object, default: () => ({}) }, children: { type: String, default: void 0 } }, setup(props) { const isInlineCssPlaceholder = props.children === void 0; const hydratedInlineCss = isInlineCssPlaceholder && typeof document !== "undefined" ? document.querySelector(`style[${INLINE_CSS_HYDRATION_ATTR}]`)?.textContent ?? "" : void 0; return () => Vue.h("style", { ...props.attrs, [INLINE_CSS_HYDRATION_ATTR]: "", "data-allow-mismatch": true, innerHTML: isInlineCssPlaceholder ? hydratedInlineCss ?? "" : props.children ?? "" }); } }); function Asset(asset) { const { tag, attrs, children } = asset; switch (tag) { case "title": return Vue.h(Title, { children }); case "meta": return createVNode("meta", attrs, null); case "link": return createVNode("link", attrs, null); case "style": if (asset.inlineCss && (process.env.TSS_INLINE_CSS_ENABLED === "true" || process.env.TSS_INLINE_CSS_ENABLED === void 0 && isServer)) return Vue.h(InlineCssStyle, { attrs, children }); return createVNode("style", mergeProps(attrs, { "data-allow-mismatch": asset.inlineCss || void 0, "innerHTML": children }), null); case "script": return Vue.h(Script, { attrs, children }); default: return null; } } //#endregion export { Asset }; //# sourceMappingURL=Asset.js.map