Files
discord-clone/node_modules/@unhead/vue/dist/index.cjs
2023-01-03 09:29:04 -06:00

1096 lines
32 KiB
JavaScript

'use strict';
const hookable = require('hookable');
const vue = require('vue');
const TagsWithInnerContent = ["script", "style", "noscript"];
const HasElementTags$1 = [
"base",
"meta",
"link",
"style",
"script",
"noscript"
];
const UniqueTags$1 = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
function tagDedupeKey$1(tag, fn) {
const { props, tag: tagName } = tag;
if (UniqueTags$1.includes(tagName))
return tagName;
if (tagName === "link" && props.rel === "canonical")
return "canonical";
if (props.charset)
return "charset";
const name = ["id"];
if (tagName === "meta")
name.push(...["name", "property", "http-equiv"]);
for (const n of name) {
if (typeof props[n] !== "undefined") {
const val = String(props[n]);
if (fn && !fn(val))
return false;
return `${tagName}:${n}:${val}`;
}
}
return false;
}
const setAttrs = (ctx, markSideEffect) => {
const { tag, $el } = ctx;
if (!$el)
return;
Object.entries(tag.props).forEach(([k, value]) => {
value = String(value);
const attrSdeKey = `attr:${k}`;
if (k === "class") {
if (!value)
return;
for (const c of value.split(" ")) {
const classSdeKey = `${attrSdeKey}:${c}`;
if (markSideEffect)
markSideEffect(ctx, classSdeKey, () => $el.classList.remove(c));
if (!$el.classList.contains(c))
$el.classList.add(c);
}
return;
}
if (markSideEffect && !k.startsWith("data-h-"))
markSideEffect(ctx, attrSdeKey, () => $el.removeAttribute(k));
if ($el.getAttribute(k) !== value)
$el.setAttribute(k, value);
});
if (TagsWithInnerContent.includes(tag.tag) && $el.innerHTML !== (tag.children || ""))
$el.innerHTML = tag.children || "";
};
function hashCode(s) {
let h = 9;
for (let i = 0; i < s.length; )
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 8).toLowerCase();
}
async function renderDOMHead(head, options = {}) {
const ctx = { shouldRender: true };
await head.hooks.callHook("dom:beforeRender", ctx);
if (!ctx.shouldRender)
return;
const dom = options.document || window.document;
const staleSideEffects = head._popSideEffectQueue();
head.headEntries().map((entry) => entry._sde).forEach((sde) => {
Object.entries(sde).forEach(([key, fn]) => {
staleSideEffects[key] = fn;
});
});
const preRenderTag = async (tag) => {
const entry = head.headEntries().find((e) => e._i === tag._e);
const renderCtx = {
renderId: tag._d || hashCode(JSON.stringify({ ...tag, _e: void 0, _p: void 0 })),
$el: null,
shouldRender: true,
tag,
entry,
staleSideEffects
};
await head.hooks.callHook("dom:beforeRenderTag", renderCtx);
return renderCtx;
};
const renders = [];
const pendingRenders = {
body: [],
head: []
};
const markSideEffect = (ctx2, key, fn) => {
key = `${ctx2.renderId}:${key}`;
if (ctx2.entry)
ctx2.entry._sde[key] = fn;
delete staleSideEffects[key];
};
const markEl = (ctx2) => {
head._elMap[ctx2.renderId] = ctx2.$el;
renders.push(ctx2);
markSideEffect(ctx2, "el", () => {
ctx2.$el?.remove();
delete head._elMap[ctx2.renderId];
});
};
for (const t of await head.resolveTags()) {
const ctx2 = await preRenderTag(t);
if (!ctx2.shouldRender)
continue;
const { tag } = ctx2;
if (tag.tag === "title") {
dom.title = tag.children || "";
renders.push(ctx2);
continue;
}
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
ctx2.$el = dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"];
setAttrs(ctx2, markSideEffect);
renders.push(ctx2);
continue;
}
ctx2.$el = head._elMap[ctx2.renderId];
if (!ctx2.$el && tag._hash) {
ctx2.$el = dom.querySelector(`${tag.tagPosition?.startsWith("body") ? "body" : "head"} > ${tag.tag}[data-h-${tag._hash}]`);
}
if (ctx2.$el) {
if (ctx2.tag._d)
setAttrs(ctx2);
markEl(ctx2);
continue;
}
ctx2.$el = dom.createElement(tag.tag);
setAttrs(ctx2);
pendingRenders[tag.tagPosition?.startsWith("body") ? "body" : "head"].push(ctx2);
}
Object.entries(pendingRenders).forEach(([pos, queue]) => {
if (!queue.length)
return;
for (const $el of [...dom[pos].children].reverse()) {
const elTag = $el.tagName.toLowerCase();
if (!HasElementTags$1.includes(elTag))
continue;
const dedupeKey = tagDedupeKey$1({
tag: elTag,
props: $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {})
});
const matchIdx = queue.findIndex((ctx2) => ctx2 && (ctx2.tag._d === dedupeKey || $el.isEqualNode(ctx2.$el)));
if (matchIdx !== -1) {
const ctx2 = queue[matchIdx];
ctx2.$el = $el;
setAttrs(ctx2);
markEl(ctx2);
delete queue[matchIdx];
}
}
queue.forEach((ctx2) => {
if (!ctx2.$el)
return;
switch (ctx2.tag.tagPosition) {
case "bodyClose":
dom.body.appendChild(ctx2.$el);
break;
case "bodyOpen":
dom.body.insertBefore(ctx2.$el, dom.body.firstChild);
break;
case "head":
default:
dom.head.appendChild(ctx2.$el);
break;
}
markEl(ctx2);
});
});
for (const ctx2 of renders)
await head.hooks.callHook("dom:renderTag", ctx2);
Object.values(staleSideEffects).forEach((fn) => fn());
}
let domUpdatePromise = null;
async function debouncedRenderDOMHead(head, options = {}) {
function doDomUpdate() {
domUpdatePromise = null;
return renderDOMHead(head, options);
}
const delayFn = options.delayFn || ((fn) => setTimeout(fn, 10));
return domUpdatePromise = domUpdatePromise || new Promise((resolve) => delayFn(() => resolve(doDomUpdate())));
}
const index = {
__proto__: null,
debouncedRenderDOMHead: debouncedRenderDOMHead,
get domUpdatePromise () { return domUpdatePromise; },
hashCode: hashCode,
renderDOMHead: renderDOMHead
};
const ValidHeadTags = [
"title",
"titleTemplate",
"base",
"htmlAttrs",
"bodyAttrs",
"meta",
"link",
"style",
"script",
"noscript"
];
const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
async function normaliseTag(tagName, input) {
const tag = { tag: tagName, props: {} };
if (tagName === "title" || tagName === "titleTemplate") {
tag.children = input instanceof Promise ? await input : input;
return tag;
}
tag.props = await normaliseProps({ ...input });
["children", "innerHtml", "innerHTML"].forEach((key) => {
if (typeof tag.props[key] !== "undefined") {
tag.children = tag.props[key];
if (typeof tag.children === "object")
tag.children = JSON.stringify(tag.children);
delete tag.props[key];
}
});
Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
tag[k] = tag.props[k];
delete tag.props[k];
});
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
}
if (Array.isArray(tag.props.class))
tag.props.class = tag.props.class.join(" ");
if (tag.props.content && Array.isArray(tag.props.content)) {
return tag.props.content.map((v, i) => {
const newTag = { ...tag, props: { ...tag.props } };
newTag.props.content = v;
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
return newTag;
});
}
return tag;
}
async function normaliseProps(props) {
for (const k of Object.keys(props)) {
if (props[k] instanceof Promise) {
props[k] = await props[k];
}
if (String(props[k]) === "true") {
props[k] = "";
} else if (String(props[k]) === "false") {
delete props[k];
}
}
return props;
}
const tagWeight = (tag) => {
if (typeof tag.tagPriority === "number")
return tag.tagPriority;
switch (tag.tagPriority) {
case "critical":
return 2;
case "high":
return 9;
case "low":
return 12;
}
switch (tag.tag) {
case "base":
return -1;
case "title":
return 1;
case "meta":
if (tag.props.charset)
return -2;
if (tag.props["http-equiv"] === "content-security-policy")
return 0;
return 10;
default:
return 10;
}
};
const sortTags = (aTag, bTag) => {
return tagWeight(aTag) - tagWeight(bTag);
};
const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
function tagDedupeKey(tag, fn) {
const { props, tag: tagName } = tag;
if (UniqueTags.includes(tagName))
return tagName;
if (tagName === "link" && props.rel === "canonical")
return "canonical";
if (props.charset)
return "charset";
const name = ["id"];
if (tagName === "meta")
name.push(...["name", "property", "http-equiv"]);
for (const n of name) {
if (typeof props[n] !== "undefined") {
const val = String(props[n]);
if (fn && !fn(val))
return false;
return `${tagName}:${n}:${val}`;
}
}
return false;
}
const renderTitleTemplate = (template, title) => {
if (template == null)
return title || null;
if (typeof template === "function")
return template(title);
return template.replace("%s", title ?? "");
};
function resolveTitleTemplateFromTags(tags) {
let titleTemplateIdx = tags.findIndex((i) => i.tag === "titleTemplate");
const titleIdx = tags.findIndex((i) => i.tag === "title");
if (titleIdx !== -1 && titleTemplateIdx !== -1) {
const newTitle = renderTitleTemplate(
tags[titleTemplateIdx].children,
tags[titleIdx].children
);
if (newTitle !== null) {
tags[titleIdx].children = newTitle || tags[titleIdx].children;
} else {
delete tags[titleIdx];
}
} else if (titleTemplateIdx !== -1) {
const newTitle = renderTitleTemplate(
tags[titleTemplateIdx].children
);
if (newTitle !== null) {
tags[titleTemplateIdx].children = newTitle;
tags[titleTemplateIdx].tag = "title";
titleTemplateIdx = -1;
}
}
if (titleTemplateIdx !== -1) {
delete tags[titleTemplateIdx];
}
return tags.filter(Boolean);
}
const DedupesTagsPlugin = (options) => {
options = options || {};
const dedupeKeys = options.dedupeKeys || ["hid", "vmid", "key"];
return defineHeadPlugin({
hooks: {
"tag:normalise": function({ tag }) {
dedupeKeys.forEach((key) => {
if (tag.props[key]) {
tag.key = tag.props[key];
delete tag.props[key];
}
});
const dedupe = tag.key ? `${tag.tag}:${tag.key}` : tagDedupeKey(tag);
if (dedupe)
tag._d = dedupe;
},
"tags:resolve": function(ctx) {
const deduping = {};
ctx.tags.forEach((tag) => {
let dedupeKey = tag._d || tag._p;
const dupedTag = deduping[dedupeKey];
if (dupedTag) {
let strategy = tag?.tagDuplicateStrategy;
if (!strategy && (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs"))
strategy = "merge";
if (strategy === "merge") {
const oldProps = dupedTag.props;
["class", "style"].forEach((key) => {
if (tag.props[key] && oldProps[key]) {
if (key === "style" && !oldProps[key].endsWith(";"))
oldProps[key] += ";";
tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
}
});
deduping[dedupeKey].props = {
...oldProps,
...tag.props
};
return;
} else if (tag._e === dupedTag._e) {
dedupeKey = tag._d = `${dedupeKey}:${tag._p}`;
}
const propCount = Object.keys(tag.props).length;
if ((propCount === 0 || propCount === 1 && typeof tag.props["data-h-key"] !== "undefined") && !tag.children) {
delete deduping[dedupeKey];
return;
}
}
deduping[dedupeKey] = tag;
});
ctx.tags = Object.values(deduping);
}
}
});
};
const SortTagsPlugin = () => {
return defineHeadPlugin({
hooks: {
"tags:resolve": (ctx) => {
const tagIndexForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
for (const tag of ctx.tags) {
if (!tag.tagPriority || typeof tag.tagPriority === "number")
continue;
const modifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
for (const { prefix, offset } of modifiers) {
if (tag.tagPriority.startsWith(prefix)) {
const key = tag.tagPriority.replace(prefix, "");
const index = tagIndexForKey(key);
if (typeof index !== "undefined")
tag._p = index + offset;
}
}
}
ctx.tags.sort((a, b) => a._p - b._p).sort(sortTags);
}
}
});
};
const TitleTemplatePlugin = () => {
return defineHeadPlugin({
hooks: {
"tags:resolve": (ctx) => {
ctx.tags = resolveTitleTemplateFromTags(ctx.tags);
}
}
});
};
const DeprecatedTagAttrPlugin = () => {
return defineHeadPlugin({
hooks: {
"tag:normalise": function({ tag }) {
if (typeof tag.props.body !== "undefined") {
tag.tagPosition = "bodyClose";
delete tag.props.body;
}
}
}
});
};
const IsBrowser$1 = typeof window !== "undefined";
const ProvideTagHashPlugin = () => {
return defineHeadPlugin({
hooks: {
"tag:normalise": (ctx) => {
const { tag, entry } = ctx;
const isDynamic = typeof tag.props._dynamic !== "undefined";
if (!HasElementTags.includes(tag.tag) || !tag.key)
return;
tag._hash = hashCode(JSON.stringify({ tag: tag.tag, key: tag.key }));
if (IsBrowser$1 || getActiveHead()?.resolvedOptions?.document)
return;
if (entry._m === "server" || isDynamic) {
tag.props[`data-h-${tag._hash}`] = "";
}
},
"tags:resolve": (ctx) => {
ctx.tags = ctx.tags.map((t) => {
delete t.props._dynamic;
return t;
});
}
}
});
};
const PatchDomOnEntryUpdatesPlugin = (options) => {
return defineHeadPlugin({
hooks: {
"entries:updated": function(head) {
if (typeof options?.document === "undefined" && typeof window === "undefined")
return;
let delayFn = options?.delayFn;
if (!delayFn && typeof requestAnimationFrame !== "undefined")
delayFn = requestAnimationFrame;
Promise.resolve().then(function () { return index; }).then(({ debouncedRenderDOMHead }) => {
debouncedRenderDOMHead(head, { document: options?.document || window.document, delayFn });
});
}
}
});
};
const EventHandlersPlugin = () => {
const stripEventHandlers = (mode, tag) => {
const props = {};
const eventHandlers = {};
Object.entries(tag.props).forEach(([key, value]) => {
if (key.startsWith("on") && typeof value === "function")
eventHandlers[key] = value;
else
props[key] = value;
});
let delayedSrc;
if (mode === "dom" && tag.tag === "script" && typeof props.src === "string" && typeof eventHandlers.onload !== "undefined") {
delayedSrc = props.src;
delete props.src;
}
return { props, eventHandlers, delayedSrc };
};
return defineHeadPlugin({
hooks: {
"ssr:render": function(ctx) {
ctx.tags = ctx.tags.map((tag) => {
tag.props = stripEventHandlers("ssr", tag).props;
return tag;
});
},
"dom:beforeRenderTag": function(ctx) {
const { props, eventHandlers, delayedSrc } = stripEventHandlers("dom", ctx.tag);
if (!Object.keys(eventHandlers).length)
return;
ctx.tag.props = props;
ctx.tag._eventHandlers = eventHandlers;
ctx.tag._delayedSrc = delayedSrc;
},
"dom:renderTag": function(ctx) {
const $el = ctx.$el;
if (!ctx.tag._eventHandlers || !$el)
return;
const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" && typeof window !== "undefined" ? window : $el;
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
const eventName = k.slice(2).toLowerCase();
const eventDedupeKey = `data-h-${eventName}`;
delete ctx.staleSideEffects[sdeKey];
if ($el.hasAttribute(eventDedupeKey))
return;
const handler = value;
$el.setAttribute(eventDedupeKey, "");
$eventListenerTarget.addEventListener(eventName, handler);
if (ctx.entry) {
ctx.entry._sde[sdeKey] = () => {
$eventListenerTarget.removeEventListener(eventName, handler);
$el.removeAttribute(eventDedupeKey);
};
}
});
if (ctx.tag._delayedSrc) {
$el.setAttribute("src", ctx.tag._delayedSrc);
}
}
}
});
};
function asArray$1(value) {
return Array.isArray(value) ? value : [value];
}
const HasElementTags = [
"base",
"meta",
"link",
"style",
"script",
"noscript"
];
let activeHead;
const setActiveHead = (head) => activeHead = head;
const getActiveHead = () => activeHead;
const TagEntityBits = 10;
async function normaliseEntryTags(e) {
const tagPromises = [];
Object.entries(e.resolvedInput || e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).forEach(([k, value]) => {
const v = asArray$1(value);
tagPromises.push(...v.map((props) => normaliseTag(k, props)).flat());
});
return (await Promise.all(tagPromises)).flat().map((t, i) => {
t._e = e._i;
t._p = (e._i << TagEntityBits) + i;
return t;
});
}
const CorePlugins = () => [
DedupesTagsPlugin(),
SortTagsPlugin(),
TitleTemplatePlugin(),
ProvideTagHashPlugin(),
EventHandlersPlugin(),
DeprecatedTagAttrPlugin()
];
const DOMPlugins = (options = {}) => [
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn })
];
function createHead$1(options = {}) {
const head = createHeadCore({
...options,
plugins: [...DOMPlugins(options), ...options?.plugins || []]
});
setActiveHead(head);
return head;
}
function createHeadCore(options = {}) {
let entries = [];
let _sde = {};
let _eid = 0;
const hooks = hookable.createHooks();
if (options?.hooks)
hooks.addHooks(options.hooks);
options.plugins = [
...CorePlugins(),
...options?.plugins || []
];
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
const updated = () => hooks.callHook("entries:updated", head);
const head = {
resolvedOptions: options,
headEntries() {
return entries;
},
get hooks() {
return hooks;
},
use(plugin) {
if (plugin.hooks)
hooks.addHooks(plugin.hooks);
},
push(input, options2) {
const activeEntry = {
_i: _eid++,
input,
_sde: {}
};
if (options2?.mode)
activeEntry._m = options2?.mode;
entries.push(activeEntry);
updated();
return {
dispose() {
entries = entries.filter((e) => {
if (e._i !== activeEntry._i)
return true;
_sde = { ..._sde, ...e._sde || {} };
e._sde = {};
updated();
return false;
});
},
patch(input2) {
entries = entries.map((e) => {
if (e._i === activeEntry._i) {
activeEntry.input = e.input = input2;
updated();
}
return e;
});
}
};
},
async resolveTags() {
const resolveCtx = { tags: [], entries: [...entries] };
await hooks.callHook("entries:resolve", resolveCtx);
for (const entry of resolveCtx.entries) {
for (const tag of await normaliseEntryTags(entry)) {
const tagCtx = { tag, entry };
await hooks.callHook("tag:normalise", tagCtx);
resolveCtx.tags.push(tagCtx.tag);
}
}
await hooks.callHook("tags:resolve", resolveCtx);
return resolveCtx.tags;
},
_elMap: {},
_popSideEffectQueue() {
const sde = { ..._sde };
_sde = {};
return sde;
}
};
head.hooks.callHook("init", head);
return head;
}
function defineHeadPlugin(plugin) {
return plugin;
}
const composableNames = [
"useHead",
"useTagTitle",
"useTagBase",
"useTagMeta",
"useTagMetaFlat",
"useSeoMeta",
"useTagLink",
"useTagScript",
"useTagStyle",
"useTagNoscript",
"useHtmlAttrs",
"useBodyAttrs",
"useTitleTemplate",
"useServerHead",
"useServerTagTitle",
"useServerTagBase",
"useServerTagMeta",
"useServerTagMetaFlat",
"useServerTagLink",
"useServerTagScript",
"useServerTagStyle",
"useServerTagNoscript",
"useServerHtmlAttrs",
"useServerBodyAttrs",
"useServerTitleTemplate"
];
function resolveUnref(r) {
return typeof r === "function" ? r() : vue.unref(r);
}
function resolveUnrefHeadInput(ref, lastKey = "") {
if (ref instanceof Promise)
return ref;
const root = resolveUnref(ref);
if (!ref || !root)
return root;
if (Array.isArray(root))
return root.map((r) => resolveUnrefHeadInput(r, lastKey));
if (typeof root === "object") {
let dynamic = false;
const unrefdObj = Object.fromEntries(
Object.entries(root).map(([k, v]) => {
if (k === "titleTemplate" || k.startsWith("on"))
return [k, vue.unref(v)];
if (typeof v === "function" || vue.isRef(v))
dynamic = true;
return [k, resolveUnrefHeadInput(v, k)];
})
);
if (dynamic && HasElementTags.includes(String(lastKey)))
unrefdObj._dynamic = true;
return unrefdObj;
}
return root;
}
function asArray(value) {
return Array.isArray(value) ? value : [value];
}
const Vue3 = vue.version.startsWith("3");
const IsBrowser = typeof window !== "undefined";
const headSymbol = "usehead";
function injectHead() {
return vue.getCurrentInstance() && vue.inject(headSymbol) || getActiveHead();
}
function createHead(options = {}) {
const head = createHead$1({
...options,
domDelayFn: (fn) => setTimeout(() => vue.nextTick(() => fn()), 10),
plugins: [
VueReactiveUseHeadPlugin(),
...options?.plugins || []
]
});
const vuePlugin = {
install(app) {
if (Vue3) {
app.config.globalProperties.$unhead = head;
app.provide(headSymbol, head);
}
}
};
head.install = vuePlugin.install;
return head;
}
const VueHeadMixin = {
created() {
const instance = vue.getCurrentInstance();
if (!instance)
return;
const options = instance.type;
if (!options || !("head" in options))
return;
const source = typeof options.head === "function" ? () => options.head.call(instance.proxy) : options.head;
useHead(source);
}
};
const VueReactiveUseHeadPlugin = () => {
return defineHeadPlugin({
hooks: {
"entries:resolve": function(ctx) {
for (const entry of ctx.entries)
entry.resolvedInput = resolveUnrefHeadInput(entry.input);
}
}
});
};
const Vue2ProvideUnheadPlugin = function(_Vue, head) {
_Vue.mixin({
beforeCreate() {
const options = this.$options;
const origProvide = options.provide;
options.provide = function() {
let origProvideResult;
if (typeof origProvide === "function")
origProvideResult = origProvide.call(this);
else
origProvideResult = origProvide || {};
return {
...origProvideResult,
[headSymbol]: head
};
};
}
});
};
function unpackToArray(input, options) {
const unpacked = [];
const kFn = options.resolveKeyData || ((ctx) => ctx.key);
const vFn = options.resolveValueData || ((ctx) => ctx.value);
for (const [k, v] of Object.entries(input)) {
unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => {
const ctx = { key: k, value: i };
const val = vFn(ctx);
if (typeof val === "object")
return unpackToArray(val, options);
if (Array.isArray(val))
return val;
return {
[typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx),
[typeof options.value === "function" ? options.value(ctx) : options.value]: val
};
}).flat());
}
return unpacked;
}
function unpackToString(value, options) {
return Object.entries(value).map(([key, value2]) => {
if (typeof value2 === "object")
value2 = unpackToString(value2, options);
if (options.resolve) {
const resolved = options.resolve({ key, value: value2 });
if (resolved)
return resolved;
}
if (typeof value2 === "number")
value2 = value2.toString();
if (typeof value2 === "string" && options.wrapValue) {
value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`);
value2 = `${options.wrapValue}${value2}${options.wrapValue}`;
}
return `${key}${options.keyValueSeparator || ""}${value2}`;
}).join(options.entrySeparator || "");
}
const MetaPackingSchema = {
robots: {
unpack: {
keyValueSeparator: ":"
}
},
contentSecurityPolicy: {
unpack: {
keyValueSeparator: " ",
entrySeparator: "; "
},
metaKey: "http-equiv"
},
fbAppId: {
keyValue: "fb:app_id",
metaKey: "property"
},
msapplicationTileImage: {
keyValue: "msapplication-TileImage"
},
msapplicationTileColor: {
keyValue: "msapplication-TileColor"
},
msapplicationConfig: {
keyValue: "msapplication-Config"
},
charset: {
metaKey: "charset"
},
contentType: {
metaKey: "http-equiv"
},
defaultStyle: {
metaKey: "http-equiv"
},
xUaCompatible: {
metaKey: "http-equiv"
},
refresh: {
metaKey: "http-equiv"
}
};
function resolveMetaKeyType(key) {
return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
}
function unpackMeta(input) {
const meta = unpackToArray(input, {
key({ key }) {
return resolveMetaKeyType(key);
},
value({ key }) {
return key === "charset" ? "charset" : "content";
},
resolveKeyData({ key }) {
return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
},
resolveValueData({ value, key }) {
if (value === null)
return "_null";
if (typeof value === "object") {
const definition = MetaPackingSchema[key];
if (key === "refresh")
return `${value.seconds};url=${value.url}`;
return unpackToString(
changeKeyCasingDeep(value),
{
entrySeparator: ", ",
keyValueSeparator: "=",
resolve({ value: value2, key: key2 }) {
if (value2 === null)
return "";
if (typeof value2 === "boolean")
return `${key2}`;
},
...definition?.unpack
}
);
}
return typeof value === "number" ? value.toString() : value;
}
});
return meta.filter((v) => typeof v.content === "undefined" || v.content !== "_null");
}
const PropertyPrefixKeys = /^(og|twitter|fb)/;
function fixKeyCase(key) {
key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
if (PropertyPrefixKeys.test(key)) {
key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
}
return key;
}
function changeKeyCasingDeep(input) {
if (Array.isArray(input)) {
return input.map((entry) => changeKeyCasingDeep(entry));
}
if (typeof input !== "object" || Array.isArray(input))
return input;
const output = {};
for (const [key, value] of Object.entries(input))
output[fixKeyCase(key)] = changeKeyCasingDeep(value);
return output;
}
function clientUseHead(input, options = {}) {
const head = injectHead();
const resolvedInput = vue.ref({});
vue.watchEffect(() => {
resolvedInput.value = resolveUnrefHeadInput(input);
});
const entry = head.push(resolvedInput.value, options);
vue.watch(resolvedInput, (e) => entry.patch(e));
const vm = vue.getCurrentInstance();
if (vm) {
vue.onBeforeUnmount(() => {
entry.dispose();
});
}
return entry;
}
function serverUseHead(input, options = {}) {
const head = injectHead();
return head.push(input, options);
}
function useServerHead(input, options = {}) {
return useHead(input, { ...options, mode: "server" });
}
const useServerTagTitle = (title) => useServerHead({ title });
const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
const useServerTagMeta = (meta) => useServerHead({ meta: asArray(meta) });
const useServerTagMetaFlat = (meta) => {
const input = vue.ref({});
vue.watchEffect(() => {
input.value = unpackMeta(resolveUnrefHeadInput(meta));
});
return useServerHead({ meta: input });
};
const useServerTagLink = (link) => useServerHead({ link: asArray(link) });
const useServerTagScript = (script) => useServerHead({ script: asArray(script) });
const useServerTagStyle = (style) => useServerHead({ style: asArray(style) });
const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray(noscript) });
const useServerTagBase = (base) => useServerHead({ base });
const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
const useServerBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
function useHead(input, options = {}) {
const head = injectHead();
if (head) {
const isBrowser = IsBrowser || !!head.resolvedOptions?.document;
if (options.mode === "server" && isBrowser || options.mode === "client" && !isBrowser)
return;
return isBrowser ? clientUseHead(input, options) : serverUseHead(input, options);
}
}
const useTagTitle = (title) => useHead({ title });
const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
const useTagMeta = (meta) => useHead({ meta: asArray(meta) });
const useTagMetaFlat = (meta) => {
const input = vue.ref({});
vue.watchEffect(() => {
input.value = unpackMeta(resolveUnrefHeadInput(meta));
});
return useHead({ meta: input });
};
const useSeoMeta = useTagMetaFlat;
const useTagLink = (link) => useHead({ link: asArray(link) });
const useTagScript = (script) => useHead({ script: asArray(script) });
const useTagStyle = (style) => useHead({ style: asArray(style) });
const useTagNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
const useTagBase = (base) => useHead({ base });
const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
const coreComposableNames = [
"injectHead"
];
const unheadVueComposablesImports = [
{
from: "@unhead/vue",
imports: [...coreComposableNames, ...composableNames]
}
];
exports.Vue2ProvideUnheadPlugin = Vue2ProvideUnheadPlugin;
exports.VueHeadMixin = VueHeadMixin;
exports.VueReactiveUseHeadPlugin = VueReactiveUseHeadPlugin;
exports.asArray = asArray;
exports.createHead = createHead;
exports.createHeadCore = createHeadCore;
exports.headSymbol = headSymbol;
exports.injectHead = injectHead;
exports.resolveUnrefHeadInput = resolveUnrefHeadInput;
exports.unheadVueComposablesImports = unheadVueComposablesImports;
exports.useBodyAttrs = useBodyAttrs;
exports.useHead = useHead;
exports.useHtmlAttrs = useHtmlAttrs;
exports.useSeoMeta = useSeoMeta;
exports.useServerBodyAttrs = useServerBodyAttrs;
exports.useServerHead = useServerHead;
exports.useServerHtmlAttrs = useServerHtmlAttrs;
exports.useServerTagBase = useServerTagBase;
exports.useServerTagLink = useServerTagLink;
exports.useServerTagMeta = useServerTagMeta;
exports.useServerTagMetaFlat = useServerTagMetaFlat;
exports.useServerTagNoscript = useServerTagNoscript;
exports.useServerTagScript = useServerTagScript;
exports.useServerTagStyle = useServerTagStyle;
exports.useServerTagTitle = useServerTagTitle;
exports.useServerTitleTemplate = useServerTitleTemplate;
exports.useTagBase = useTagBase;
exports.useTagLink = useTagLink;
exports.useTagMeta = useTagMeta;
exports.useTagMetaFlat = useTagMetaFlat;
exports.useTagNoscript = useTagNoscript;
exports.useTagScript = useTagScript;
exports.useTagStyle = useTagStyle;
exports.useTagTitle = useTagTitle;
exports.useTitleTemplate = useTitleTemplate;