@tanstack/vue-router
Version:
Modern and scalable routing for Vue applications
146 lines (145 loc) • 4.82 kB
JavaScript
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