no message
This commit is contained in:
641
.output/server/node_modules/@unhead/shared/dist/index.mjs
generated
vendored
641
.output/server/node_modules/@unhead/shared/dist/index.mjs
generated
vendored
@@ -1,641 +0,0 @@
|
||||
import { unpackToString, unpackToArray, packArray } from 'packrup';
|
||||
|
||||
function asArray(value) {
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
||||
|
||||
const SelfClosingTags = /* @__PURE__ */ new Set(["meta", "link", "base"]);
|
||||
const TagsWithInnerContent = /* @__PURE__ */ new Set(["title", "titleTemplate", "script", "style", "noscript"]);
|
||||
const HasElementTags = /* @__PURE__ */ new Set([
|
||||
"base",
|
||||
"meta",
|
||||
"link",
|
||||
"style",
|
||||
"script",
|
||||
"noscript"
|
||||
]);
|
||||
const ValidHeadTags = /* @__PURE__ */ new Set([
|
||||
"title",
|
||||
"titleTemplate",
|
||||
"templateParams",
|
||||
"base",
|
||||
"htmlAttrs",
|
||||
"bodyAttrs",
|
||||
"meta",
|
||||
"link",
|
||||
"style",
|
||||
"script",
|
||||
"noscript"
|
||||
]);
|
||||
const UniqueTags = /* @__PURE__ */ new Set(["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs", "templateParams"]);
|
||||
const TagConfigKeys = /* @__PURE__ */ new Set(["tagPosition", "tagPriority", "tagDuplicateStrategy", "children", "innerHTML", "textContent", "processTemplateParams"]);
|
||||
const IsBrowser = typeof window !== "undefined";
|
||||
const composableNames = [
|
||||
"getActiveHead",
|
||||
"useHead",
|
||||
"useSeoMeta",
|
||||
"useHeadSafe",
|
||||
"useServerHead",
|
||||
"useServerSeoMeta",
|
||||
"useServerHeadSafe"
|
||||
];
|
||||
|
||||
function defineHeadPlugin(plugin) {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
function hashTag(tag) {
|
||||
if (tag._h) {
|
||||
return tag._h;
|
||||
}
|
||||
if (tag._d) {
|
||||
return hashCode(tag._d);
|
||||
}
|
||||
let content = `${tag.tag}:${tag.textContent || tag.innerHTML || ""}:`;
|
||||
for (const key in tag.props) {
|
||||
content += `${key}:${String(tag.props[key])},`;
|
||||
}
|
||||
return hashCode(content);
|
||||
}
|
||||
|
||||
const p = (p2) => ({ keyValue: p2, metaKey: "property" });
|
||||
const k = (p2) => ({ keyValue: p2 });
|
||||
const MetaPackingSchema = {
|
||||
appleItunesApp: {
|
||||
unpack: {
|
||||
entrySeparator: ", ",
|
||||
resolve({ key, value }) {
|
||||
return `${fixKeyCase(key)}=${value}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
articleExpirationTime: p("article:expiration_time"),
|
||||
articleModifiedTime: p("article:modified_time"),
|
||||
articlePublishedTime: p("article:published_time"),
|
||||
bookReleaseDate: p("book:release_date"),
|
||||
charset: {
|
||||
metaKey: "charset"
|
||||
},
|
||||
contentSecurityPolicy: {
|
||||
unpack: {
|
||||
entrySeparator: "; ",
|
||||
resolve({ key, value }) {
|
||||
return `${fixKeyCase(key)} ${value}`;
|
||||
}
|
||||
},
|
||||
metaKey: "http-equiv"
|
||||
},
|
||||
contentType: {
|
||||
metaKey: "http-equiv"
|
||||
},
|
||||
defaultStyle: {
|
||||
metaKey: "http-equiv"
|
||||
},
|
||||
fbAppId: p("fb:app_id"),
|
||||
msapplicationConfig: k("msapplication-Config"),
|
||||
msapplicationTileColor: k("msapplication-TileColor"),
|
||||
msapplicationTileImage: k("msapplication-TileImage"),
|
||||
ogAudioSecureUrl: p("og:audio:secure_url"),
|
||||
ogAudioUrl: p("og:audio"),
|
||||
ogImageSecureUrl: p("og:image:secure_url"),
|
||||
ogImageUrl: p("og:image"),
|
||||
ogSiteName: p("og:site_name"),
|
||||
ogVideoSecureUrl: p("og:video:secure_url"),
|
||||
ogVideoUrl: p("og:video"),
|
||||
profileFirstName: p("profile:first_name"),
|
||||
profileLastName: p("profile:last_name"),
|
||||
profileUsername: p("profile:username"),
|
||||
refresh: {
|
||||
metaKey: "http-equiv",
|
||||
unpack: {
|
||||
entrySeparator: ";",
|
||||
resolve({ key, value }) {
|
||||
if (key === "seconds")
|
||||
return `${value}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
robots: {
|
||||
unpack: {
|
||||
entrySeparator: ", ",
|
||||
resolve({ key, value }) {
|
||||
if (typeof value === "boolean")
|
||||
return `${fixKeyCase(key)}`;
|
||||
else
|
||||
return `${fixKeyCase(key)}:${value}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
xUaCompatible: {
|
||||
metaKey: "http-equiv"
|
||||
}
|
||||
};
|
||||
const openGraphNamespaces = /* @__PURE__ */ new Set([
|
||||
"og",
|
||||
"book",
|
||||
"article",
|
||||
"profile"
|
||||
]);
|
||||
function resolveMetaKeyType(key) {
|
||||
const fKey = fixKeyCase(key);
|
||||
const prefixIndex = fKey.indexOf(":");
|
||||
if (openGraphNamespaces.has(fKey.substring(0, prefixIndex)))
|
||||
return "property";
|
||||
return MetaPackingSchema[key]?.metaKey || "name";
|
||||
}
|
||||
function resolveMetaKeyValue(key) {
|
||||
return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
|
||||
}
|
||||
function fixKeyCase(key) {
|
||||
const updated = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
||||
const prefixIndex = updated.indexOf("-");
|
||||
const fKey = updated.substring(0, prefixIndex);
|
||||
if (fKey === "twitter" || openGraphNamespaces.has(fKey))
|
||||
return key.replace(/([A-Z])/g, ":$1").toLowerCase();
|
||||
return updated;
|
||||
}
|
||||
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 in input) {
|
||||
if (!Object.prototype.hasOwnProperty.call(input, key)) {
|
||||
continue;
|
||||
}
|
||||
output[fixKeyCase(key)] = changeKeyCasingDeep(input[key]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function resolvePackedMetaObjectValue(value, key) {
|
||||
const definition = MetaPackingSchema[key];
|
||||
if (key === "refresh")
|
||||
return `${value.seconds};url=${value.url}`;
|
||||
return unpackToString(
|
||||
changeKeyCasingDeep(value),
|
||||
{
|
||||
keyValueSeparator: "=",
|
||||
entrySeparator: ", ",
|
||||
resolve({ value: value2, key: key2 }) {
|
||||
if (value2 === null)
|
||||
return "";
|
||||
if (typeof value2 === "boolean")
|
||||
return `${key2}`;
|
||||
},
|
||||
...definition?.unpack
|
||||
}
|
||||
);
|
||||
}
|
||||
const ObjectArrayEntries = /* @__PURE__ */ new Set(["og:image", "og:video", "og:audio", "twitter:image"]);
|
||||
function sanitize(input) {
|
||||
const out = {};
|
||||
for (const k2 in input) {
|
||||
if (!Object.prototype.hasOwnProperty.call(input, k2)) {
|
||||
continue;
|
||||
}
|
||||
const v = input[k2];
|
||||
if (String(v) !== "false" && k2)
|
||||
out[k2] = v;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function handleObjectEntry(key, v) {
|
||||
const value = sanitize(v);
|
||||
const fKey = fixKeyCase(key);
|
||||
const attr = resolveMetaKeyType(fKey);
|
||||
if (ObjectArrayEntries.has(fKey)) {
|
||||
const input = {};
|
||||
for (const k2 in value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(value, k2)) {
|
||||
continue;
|
||||
}
|
||||
input[`${key}${k2 === "url" ? "" : `${k2[0].toUpperCase()}${k2.slice(1)}`}`] = value[k2];
|
||||
}
|
||||
return unpackMeta(input).sort((a, b) => (a[attr]?.length || 0) - (b[attr]?.length || 0));
|
||||
}
|
||||
return [{ [attr]: fKey, ...value }];
|
||||
}
|
||||
function unpackMeta(input) {
|
||||
const extras = [];
|
||||
const primitives = {};
|
||||
for (const key in input) {
|
||||
if (!Object.prototype.hasOwnProperty.call(input, key)) {
|
||||
continue;
|
||||
}
|
||||
const value = input[key];
|
||||
if (!Array.isArray(value)) {
|
||||
if (typeof value === "object" && value) {
|
||||
if (ObjectArrayEntries.has(fixKeyCase(key))) {
|
||||
extras.push(...handleObjectEntry(key, value));
|
||||
continue;
|
||||
}
|
||||
primitives[key] = sanitize(value);
|
||||
} else {
|
||||
primitives[key] = value;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (const v of value) {
|
||||
extras.push(...typeof v === "string" ? unpackMeta({ [key]: v }) : handleObjectEntry(key, v));
|
||||
}
|
||||
}
|
||||
const meta = unpackToArray(primitives, {
|
||||
key({ key }) {
|
||||
return resolveMetaKeyType(key);
|
||||
},
|
||||
value({ key }) {
|
||||
return key === "charset" ? "charset" : "content";
|
||||
},
|
||||
resolveKeyData({ key }) {
|
||||
return resolveMetaKeyValue(key);
|
||||
},
|
||||
resolveValueData({ value, key }) {
|
||||
if (value === null)
|
||||
return "_null";
|
||||
if (typeof value === "object")
|
||||
return resolvePackedMetaObjectValue(value, key);
|
||||
return typeof value === "number" ? value.toString() : value;
|
||||
}
|
||||
});
|
||||
return [...extras, ...meta].map((m) => {
|
||||
if (m.content === "_null")
|
||||
m.content = null;
|
||||
return m;
|
||||
});
|
||||
}
|
||||
function packMeta(inputs) {
|
||||
const mappedPackingSchema = Object.entries(MetaPackingSchema).map(([key, value]) => [key, value.keyValue]);
|
||||
return packArray(inputs, {
|
||||
key: ["name", "property", "httpEquiv", "http-equiv", "charset"],
|
||||
value: ["content", "charset"],
|
||||
resolveKey(k2) {
|
||||
let key = mappedPackingSchema.filter((sk) => sk[1] === k2)?.[0]?.[0] || k2;
|
||||
const replacer = (_, letter) => letter?.toUpperCase();
|
||||
key = key.replace(/:([a-z])/g, replacer).replace(/-([a-z])/g, replacer);
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function thenable(val, thenFn) {
|
||||
if (val instanceof Promise) {
|
||||
return val.then(thenFn);
|
||||
}
|
||||
return thenFn(val);
|
||||
}
|
||||
|
||||
function normaliseTag(tagName, input, e, normalizedProps) {
|
||||
const props = normalizedProps || normaliseProps(
|
||||
// explicitly check for an object
|
||||
// @ts-expect-error untyped
|
||||
typeof input === "object" && typeof input !== "function" && !(input instanceof Promise) ? { ...input } : { [tagName === "script" || tagName === "noscript" || tagName === "style" ? "innerHTML" : "textContent"]: input },
|
||||
tagName === "templateParams" || tagName === "titleTemplate"
|
||||
);
|
||||
if (props instanceof Promise) {
|
||||
return props.then((val) => normaliseTag(tagName, input, e, val));
|
||||
}
|
||||
const tag = {
|
||||
tag: tagName,
|
||||
props
|
||||
};
|
||||
for (const k of TagConfigKeys) {
|
||||
const val = tag.props[k] !== void 0 ? tag.props[k] : e[k];
|
||||
if (val !== void 0) {
|
||||
if (!(k === "innerHTML" || k === "textContent" || k === "children") || TagsWithInnerContent.has(tag.tag)) {
|
||||
tag[k === "children" ? "innerHTML" : k] = val;
|
||||
}
|
||||
delete tag.props[k];
|
||||
}
|
||||
}
|
||||
if (tag.props.body) {
|
||||
tag.tagPosition = "bodyClose";
|
||||
delete tag.props.body;
|
||||
}
|
||||
if (tag.tag === "script") {
|
||||
if (typeof tag.innerHTML === "object") {
|
||||
tag.innerHTML = JSON.stringify(tag.innerHTML);
|
||||
tag.props.type = tag.props.type || "application/json";
|
||||
}
|
||||
}
|
||||
return Array.isArray(tag.props.content) ? tag.props.content.map((v) => ({ ...tag, props: { ...tag.props, content: v } })) : tag;
|
||||
}
|
||||
function normaliseStyleClassProps(key, v) {
|
||||
const sep = key === "class" ? " " : ";";
|
||||
if (v && typeof v === "object" && !Array.isArray(v)) {
|
||||
v = Object.entries(v).filter(([, v2]) => v2).map(([k, v2]) => key === "style" ? `${k}:${v2}` : k);
|
||||
}
|
||||
return String(Array.isArray(v) ? v.join(sep) : v)?.split(sep).filter((c) => Boolean(c.trim())).join(sep);
|
||||
}
|
||||
function nestedNormaliseProps(props, virtual, keys, startIndex) {
|
||||
for (let i = startIndex; i < keys.length; i += 1) {
|
||||
const k = keys[i];
|
||||
if (k === "class" || k === "style") {
|
||||
props[k] = normaliseStyleClassProps(k, props[k]);
|
||||
continue;
|
||||
}
|
||||
if (props[k] instanceof Promise) {
|
||||
return props[k].then((val) => {
|
||||
props[k] = val;
|
||||
return nestedNormaliseProps(props, virtual, keys, i);
|
||||
});
|
||||
}
|
||||
if (!virtual && !TagConfigKeys.has(k)) {
|
||||
const v = String(props[k]);
|
||||
const isDataKey = k.startsWith("data-");
|
||||
if (v === "true" || v === "") {
|
||||
props[k] = isDataKey ? "true" : true;
|
||||
} else if (!props[k]) {
|
||||
if (isDataKey && v === "false")
|
||||
props[k] = "false";
|
||||
else
|
||||
delete props[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function normaliseProps(props, virtual = false) {
|
||||
const resolvedProps = nestedNormaliseProps(props, virtual, Object.keys(props), 0);
|
||||
if (resolvedProps instanceof Promise) {
|
||||
return resolvedProps.then(() => props);
|
||||
}
|
||||
return props;
|
||||
}
|
||||
const TagEntityBits = 10;
|
||||
function nestedNormaliseEntryTags(headTags, tagPromises, startIndex) {
|
||||
for (let i = startIndex; i < tagPromises.length; i += 1) {
|
||||
const tags = tagPromises[i];
|
||||
if (tags instanceof Promise) {
|
||||
return tags.then((val) => {
|
||||
tagPromises[i] = val;
|
||||
return nestedNormaliseEntryTags(headTags, tagPromises, i);
|
||||
});
|
||||
}
|
||||
if (Array.isArray(tags)) {
|
||||
headTags.push(...tags);
|
||||
} else {
|
||||
headTags.push(tags);
|
||||
}
|
||||
}
|
||||
}
|
||||
function normaliseEntryTags(e) {
|
||||
const tagPromises = [];
|
||||
const input = e.resolvedInput;
|
||||
for (const k in input) {
|
||||
if (!Object.prototype.hasOwnProperty.call(input, k)) {
|
||||
continue;
|
||||
}
|
||||
const v = input[k];
|
||||
if (v === void 0 || !ValidHeadTags.has(k)) {
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(v)) {
|
||||
for (const props of v) {
|
||||
tagPromises.push(normaliseTag(k, props, e));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
tagPromises.push(normaliseTag(k, v, e));
|
||||
}
|
||||
if (tagPromises.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const headTags = [];
|
||||
return thenable(nestedNormaliseEntryTags(headTags, tagPromises, 0), () => headTags.map((t, i) => {
|
||||
t._e = e._i;
|
||||
e.mode && (t._m = e.mode);
|
||||
t._p = (e._i << TagEntityBits) + i;
|
||||
return t;
|
||||
}));
|
||||
}
|
||||
|
||||
const WhitelistAttributes = {
|
||||
htmlAttrs: ["id", "class", "lang", "dir"],
|
||||
bodyAttrs: ["id", "class"],
|
||||
meta: ["id", "name", "property", "charset", "content"],
|
||||
noscript: ["id", "textContent"],
|
||||
script: ["id", "type", "textContent"],
|
||||
link: ["id", "color", "crossorigin", "fetchpriority", "href", "hreflang", "imagesrcset", "imagesizes", "integrity", "media", "referrerpolicy", "rel", "sizes", "type"]
|
||||
};
|
||||
function acceptDataAttrs(value) {
|
||||
const filtered = {};
|
||||
Object.keys(value || {}).filter((a) => a.startsWith("data-")).forEach((a) => {
|
||||
filtered[a] = value[a];
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
function whitelistSafeInput(input) {
|
||||
const filtered = {};
|
||||
Object.keys(input).forEach((key) => {
|
||||
const tagValue = input[key];
|
||||
if (!tagValue)
|
||||
return;
|
||||
switch (key) {
|
||||
// always safe
|
||||
case "title":
|
||||
case "titleTemplate":
|
||||
case "templateParams":
|
||||
filtered[key] = tagValue;
|
||||
break;
|
||||
case "htmlAttrs":
|
||||
case "bodyAttrs":
|
||||
filtered[key] = acceptDataAttrs(tagValue);
|
||||
WhitelistAttributes[key].forEach((a) => {
|
||||
if (tagValue[a])
|
||||
filtered[key][a] = tagValue[a];
|
||||
});
|
||||
break;
|
||||
// meta is safe, except for http-equiv
|
||||
case "meta":
|
||||
if (Array.isArray(tagValue)) {
|
||||
filtered[key] = tagValue.map((meta) => {
|
||||
const safeMeta = acceptDataAttrs(meta);
|
||||
WhitelistAttributes.meta.forEach((key2) => {
|
||||
if (meta[key2])
|
||||
safeMeta[key2] = meta[key2];
|
||||
});
|
||||
return safeMeta;
|
||||
}).filter((meta) => Object.keys(meta).length > 0);
|
||||
}
|
||||
break;
|
||||
// link tags we don't allow stylesheets, scripts, preloading, prerendering, prefetching, etc
|
||||
case "link":
|
||||
if (Array.isArray(tagValue)) {
|
||||
filtered[key] = tagValue.map((meta) => {
|
||||
const link = acceptDataAttrs(meta);
|
||||
WhitelistAttributes.link.forEach((key2) => {
|
||||
const val = meta[key2];
|
||||
if (key2 === "rel" && (val === "stylesheet" || val === "canonical" || val === "modulepreload" || val === "prerender" || val === "preload" || val === "prefetch"))
|
||||
return;
|
||||
if (key2 === "href") {
|
||||
if (val.includes("javascript:") || val.includes("data:"))
|
||||
return;
|
||||
link[key2] = val;
|
||||
} else if (val) {
|
||||
link[key2] = val;
|
||||
}
|
||||
});
|
||||
return link;
|
||||
}).filter((link) => Object.keys(link).length > 1 && !!link.rel);
|
||||
}
|
||||
break;
|
||||
case "noscript":
|
||||
if (Array.isArray(tagValue)) {
|
||||
filtered[key] = tagValue.map((meta) => {
|
||||
const noscript = acceptDataAttrs(meta);
|
||||
WhitelistAttributes.noscript.forEach((key2) => {
|
||||
if (meta[key2])
|
||||
noscript[key2] = meta[key2];
|
||||
});
|
||||
return noscript;
|
||||
}).filter((meta) => Object.keys(meta).length > 0);
|
||||
}
|
||||
break;
|
||||
// we only allow JSON in scripts
|
||||
case "script":
|
||||
if (Array.isArray(tagValue)) {
|
||||
filtered[key] = tagValue.map((script) => {
|
||||
const safeScript = acceptDataAttrs(script);
|
||||
WhitelistAttributes.script.forEach((s) => {
|
||||
if (script[s]) {
|
||||
if (s === "textContent") {
|
||||
try {
|
||||
const jsonVal = typeof script[s] === "string" ? JSON.parse(script[s]) : script[s];
|
||||
safeScript[s] = JSON.stringify(jsonVal, null, 0);
|
||||
} catch (e) {
|
||||
}
|
||||
} else {
|
||||
safeScript[s] = script[s];
|
||||
}
|
||||
}
|
||||
});
|
||||
return safeScript;
|
||||
}).filter((meta) => Object.keys(meta).length > 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
|
||||
const NetworkEvents = /* @__PURE__ */ new Set(["onload", "onerror", "onabort", "onprogress", "onloadstart"]);
|
||||
const ScriptNetworkEvents = /* @__PURE__ */ new Set(["onload", "onerror"]);
|
||||
|
||||
const TAG_WEIGHTS = {
|
||||
// tags
|
||||
base: -10,
|
||||
title: 10
|
||||
};
|
||||
const TAG_ALIASES = {
|
||||
// relative scores to their default values
|
||||
critical: -80,
|
||||
high: -10,
|
||||
low: 20
|
||||
};
|
||||
function tagWeight(tag) {
|
||||
const priority = tag.tagPriority;
|
||||
if (typeof priority === "number")
|
||||
return priority;
|
||||
let weight = 100;
|
||||
if (tag.tag === "meta") {
|
||||
if (tag.props["http-equiv"] === "content-security-policy")
|
||||
weight = -30;
|
||||
else if (tag.props.charset)
|
||||
weight = -20;
|
||||
else if (tag.props.name === "viewport")
|
||||
weight = -15;
|
||||
} else if (tag.tag === "link" && tag.props.rel === "preconnect") {
|
||||
weight = 20;
|
||||
} else if (tag.tag in TAG_WEIGHTS) {
|
||||
weight = TAG_WEIGHTS[tag.tag];
|
||||
}
|
||||
if (priority && priority in TAG_ALIASES) {
|
||||
return weight + TAG_ALIASES[priority];
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
const SortModifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
|
||||
|
||||
const allowedMetaProperties = ["name", "property", "http-equiv"];
|
||||
function tagDedupeKey(tag) {
|
||||
const { props, tag: tagName } = tag;
|
||||
if (UniqueTags.has(tagName))
|
||||
return tagName;
|
||||
if (tagName === "link" && props.rel === "canonical")
|
||||
return "canonical";
|
||||
if (props.charset)
|
||||
return "charset";
|
||||
if (props.id) {
|
||||
return `${tagName}:id:${props.id}`;
|
||||
}
|
||||
for (const n of allowedMetaProperties) {
|
||||
if (props[n] !== void 0) {
|
||||
return `${tagName}:${n}:${props[n]}`;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const sepSub = "%separator";
|
||||
function sub(p, token, isJson = false) {
|
||||
let val;
|
||||
if (token === "s" || token === "pageTitle") {
|
||||
val = p.pageTitle;
|
||||
} else if (token.includes(".")) {
|
||||
const dotIndex = token.indexOf(".");
|
||||
val = p[token.substring(0, dotIndex)]?.[token.substring(dotIndex + 1)];
|
||||
} else {
|
||||
val = p[token];
|
||||
}
|
||||
if (val !== void 0) {
|
||||
return isJson ? (val || "").replace(/"/g, '\\"') : val || "";
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
const sepSubRe = new RegExp(`${sepSub}(?:\\s*${sepSub})*`, "g");
|
||||
function processTemplateParams(s, p, sep, isJson = false) {
|
||||
if (typeof s !== "string" || !s.includes("%"))
|
||||
return s;
|
||||
let decoded = s;
|
||||
try {
|
||||
decoded = decodeURI(s);
|
||||
} catch {
|
||||
}
|
||||
const tokens = decoded.match(/%\w+(?:\.\w+)?/g);
|
||||
if (!tokens) {
|
||||
return s;
|
||||
}
|
||||
const hasSepSub = s.includes(sepSub);
|
||||
s = s.replace(/%\w+(?:\.\w+)?/g, (token) => {
|
||||
if (token === sepSub || !tokens.includes(token)) {
|
||||
return token;
|
||||
}
|
||||
const re = sub(p, token.slice(1), isJson);
|
||||
return re !== void 0 ? re : token;
|
||||
}).trim();
|
||||
if (hasSepSub) {
|
||||
if (s.endsWith(sepSub))
|
||||
s = s.slice(0, -sepSub.length);
|
||||
if (s.startsWith(sepSub))
|
||||
s = s.slice(sepSub.length);
|
||||
s = s.replace(sepSubRe, sep).trim();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function resolveTitleTemplate(template, title) {
|
||||
if (template == null)
|
||||
return title || null;
|
||||
if (typeof template === "function")
|
||||
return template(title);
|
||||
return template;
|
||||
}
|
||||
|
||||
export { HasElementTags, IsBrowser, NetworkEvents, ScriptNetworkEvents, SelfClosingTags, SortModifiers, TAG_ALIASES, TAG_WEIGHTS, TagConfigKeys, TagEntityBits, TagsWithInnerContent, UniqueTags, ValidHeadTags, asArray, composableNames, defineHeadPlugin, hashCode, hashTag, normaliseEntryTags, normaliseProps, normaliseStyleClassProps, normaliseTag, packMeta, processTemplateParams, resolveMetaKeyType, resolveMetaKeyValue, resolvePackedMetaObjectValue, resolveTitleTemplate, tagDedupeKey, tagWeight, thenable, unpackMeta, whitelistSafeInput };
|
||||
Reference in New Issue
Block a user