unhead 1.0.21 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +388 -436
- package/dist/index.d.ts +42 -23
- package/dist/index.mjs +386 -444
- package/package.json +9 -8
package/dist/index.cjs
CHANGED
|
@@ -1,68 +1,313 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const hookable = require('hookable');
|
|
4
|
+
const shared = require('@unhead/shared');
|
|
4
5
|
const dom = require('@unhead/dom');
|
|
5
6
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return tag;
|
|
7
|
+
const TAG_WEIGHTS = {
|
|
8
|
+
// aliases
|
|
9
|
+
critical: 2,
|
|
10
|
+
high: 9,
|
|
11
|
+
low: 12,
|
|
12
|
+
// tags
|
|
13
|
+
base: -1,
|
|
14
|
+
title: 1,
|
|
15
|
+
meta: 10
|
|
16
|
+
};
|
|
17
|
+
function tagWeight(tag) {
|
|
18
|
+
if (typeof tag.tagPriority === "number")
|
|
19
|
+
return tag.tagPriority;
|
|
20
|
+
if (tag.tag === "meta") {
|
|
21
|
+
if (tag.props.charset)
|
|
22
|
+
return -2;
|
|
23
|
+
if (tag.props["http-equiv"] === "content-security-policy")
|
|
24
|
+
return 0;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
const key = tag.tagPriority || tag.tag;
|
|
27
|
+
if (key in TAG_WEIGHTS) {
|
|
28
|
+
return TAG_WEIGHTS[key];
|
|
29
|
+
}
|
|
30
|
+
return 10;
|
|
31
|
+
}
|
|
32
|
+
const SortModifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
|
|
33
|
+
function SortTagsPlugin() {
|
|
34
|
+
return shared.defineHeadPlugin({
|
|
35
|
+
hooks: {
|
|
36
|
+
"tags:resolve": (ctx) => {
|
|
37
|
+
const tagPositionForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
|
|
38
|
+
for (const { prefix, offset } of SortModifiers) {
|
|
39
|
+
for (const tag of ctx.tags.filter((tag2) => typeof tag2.tagPriority === "string" && tag2.tagPriority.startsWith(prefix))) {
|
|
40
|
+
const position = tagPositionForKey(
|
|
41
|
+
tag.tagPriority.replace(prefix, "")
|
|
42
|
+
);
|
|
43
|
+
if (typeof position !== "undefined")
|
|
44
|
+
tag._p = position + offset;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
ctx.tags.sort((a, b) => a._p - b._p).sort((a, b) => tagWeight(a) - tagWeight(b));
|
|
48
|
+
}
|
|
33
49
|
}
|
|
34
50
|
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const renderTitleTemplate = (template, title) => {
|
|
54
|
+
if (template == null)
|
|
55
|
+
return title || null;
|
|
56
|
+
if (typeof template === "function")
|
|
57
|
+
return template(title);
|
|
58
|
+
return template.replace("%s", title ?? "");
|
|
59
|
+
};
|
|
60
|
+
const TitleTemplatePlugin = () => {
|
|
61
|
+
return shared.defineHeadPlugin({
|
|
62
|
+
hooks: {
|
|
63
|
+
"tags:resolve": (ctx) => {
|
|
64
|
+
const { tags } = ctx;
|
|
65
|
+
let titleTemplateIdx = tags.findIndex((i) => i.tag === "titleTemplate");
|
|
66
|
+
const titleIdx = tags.findIndex((i) => i.tag === "title");
|
|
67
|
+
if (titleIdx !== -1 && titleTemplateIdx !== -1) {
|
|
68
|
+
const newTitle = renderTitleTemplate(
|
|
69
|
+
tags[titleTemplateIdx].children,
|
|
70
|
+
tags[titleIdx].children
|
|
71
|
+
);
|
|
72
|
+
if (newTitle !== null) {
|
|
73
|
+
tags[titleIdx].children = newTitle || tags[titleIdx].children;
|
|
74
|
+
} else {
|
|
75
|
+
delete tags[titleIdx];
|
|
76
|
+
}
|
|
77
|
+
} else if (titleTemplateIdx !== -1) {
|
|
78
|
+
const newTitle = renderTitleTemplate(
|
|
79
|
+
tags[titleTemplateIdx].children
|
|
80
|
+
);
|
|
81
|
+
if (newTitle !== null) {
|
|
82
|
+
tags[titleTemplateIdx].children = newTitle;
|
|
83
|
+
tags[titleTemplateIdx].tag = "title";
|
|
84
|
+
titleTemplateIdx = -1;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (titleTemplateIdx !== -1) {
|
|
88
|
+
delete tags[titleTemplateIdx];
|
|
89
|
+
}
|
|
90
|
+
ctx.tags = tags.filter(Boolean);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
38
93
|
});
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const DeprecatedTagAttrPlugin = () => {
|
|
97
|
+
return shared.defineHeadPlugin({
|
|
98
|
+
hooks: {
|
|
99
|
+
"tag:normalise": function({ tag }) {
|
|
100
|
+
if (typeof tag.props.body !== "undefined") {
|
|
101
|
+
tag.tagPosition = "bodyClose";
|
|
102
|
+
delete tag.props.body;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const IsBrowser = typeof window !== "undefined";
|
|
110
|
+
|
|
111
|
+
const ProvideTagHashPlugin = () => {
|
|
112
|
+
return shared.defineHeadPlugin({
|
|
113
|
+
hooks: {
|
|
114
|
+
"tag:normalise": (ctx) => {
|
|
115
|
+
const { tag, entry } = ctx;
|
|
116
|
+
const isDynamic = typeof tag.props._dynamic !== "undefined";
|
|
117
|
+
if (!shared.HasElementTags.includes(tag.tag) || !tag.key)
|
|
118
|
+
return;
|
|
119
|
+
tag._hash = shared.hashCode(JSON.stringify({ tag: tag.tag, key: tag.key }));
|
|
120
|
+
if (IsBrowser || getActiveHead()?.resolvedOptions?.document)
|
|
121
|
+
return;
|
|
122
|
+
if (entry._m === "server" || isDynamic) {
|
|
123
|
+
tag.props[`data-h-${tag._hash}`] = "";
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"tags:resolve": (ctx) => {
|
|
127
|
+
ctx.tags = ctx.tags.map((t) => {
|
|
128
|
+
delete t.props._dynamic;
|
|
129
|
+
return t;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const ValidEventTags = ["script", "link", "bodyAttrs"];
|
|
137
|
+
const EventHandlersPlugin = () => {
|
|
138
|
+
const stripEventHandlers = (mode, tag) => {
|
|
139
|
+
const props = {};
|
|
140
|
+
const eventHandlers = {};
|
|
141
|
+
Object.entries(tag.props).forEach(([key, value]) => {
|
|
142
|
+
if (key.startsWith("on") && typeof value === "function")
|
|
143
|
+
eventHandlers[key] = value;
|
|
144
|
+
else
|
|
145
|
+
props[key] = value;
|
|
50
146
|
});
|
|
147
|
+
let delayedSrc;
|
|
148
|
+
if (mode === "dom" && tag.tag === "script" && typeof props.src === "string" && typeof eventHandlers.onload !== "undefined") {
|
|
149
|
+
delayedSrc = props.src;
|
|
150
|
+
delete props.src;
|
|
151
|
+
}
|
|
152
|
+
return { props, eventHandlers, delayedSrc };
|
|
153
|
+
};
|
|
154
|
+
return shared.defineHeadPlugin({
|
|
155
|
+
hooks: {
|
|
156
|
+
"ssr:render": function(ctx) {
|
|
157
|
+
ctx.tags = ctx.tags.map((tag) => {
|
|
158
|
+
if (!ValidEventTags.includes(tag.tag))
|
|
159
|
+
return tag;
|
|
160
|
+
if (!Object.entries(tag.props).find(([key, value]) => key.startsWith("on") && typeof value === "function"))
|
|
161
|
+
return tag;
|
|
162
|
+
tag.props = stripEventHandlers("ssr", tag).props;
|
|
163
|
+
return tag;
|
|
164
|
+
});
|
|
165
|
+
},
|
|
166
|
+
"dom:beforeRenderTag": function(ctx) {
|
|
167
|
+
if (!ValidEventTags.includes(ctx.tag.tag))
|
|
168
|
+
return;
|
|
169
|
+
if (!Object.entries(ctx.tag.props).find(([key, value]) => key.startsWith("on") && typeof value === "function"))
|
|
170
|
+
return;
|
|
171
|
+
const { props, eventHandlers, delayedSrc } = stripEventHandlers("dom", ctx.tag);
|
|
172
|
+
if (!Object.keys(eventHandlers).length)
|
|
173
|
+
return;
|
|
174
|
+
ctx.tag.props = props;
|
|
175
|
+
ctx.tag._eventHandlers = eventHandlers;
|
|
176
|
+
ctx.tag._delayedSrc = delayedSrc;
|
|
177
|
+
},
|
|
178
|
+
"dom:renderTag": function(ctx) {
|
|
179
|
+
const $el = ctx.$el;
|
|
180
|
+
if (!ctx.tag._eventHandlers || !$el)
|
|
181
|
+
return;
|
|
182
|
+
const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" && typeof window !== "undefined" ? window : $el;
|
|
183
|
+
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
184
|
+
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
|
|
185
|
+
const eventName = k.slice(2).toLowerCase();
|
|
186
|
+
const eventDedupeKey = `data-h-${eventName}`;
|
|
187
|
+
delete ctx.staleSideEffects[sdeKey];
|
|
188
|
+
if ($el.hasAttribute(eventDedupeKey))
|
|
189
|
+
return;
|
|
190
|
+
const handler = value;
|
|
191
|
+
$el.setAttribute(eventDedupeKey, "");
|
|
192
|
+
$eventListenerTarget.addEventListener(eventName, handler);
|
|
193
|
+
if (ctx.entry) {
|
|
194
|
+
ctx.entry._sde[sdeKey] = () => {
|
|
195
|
+
$eventListenerTarget.removeEventListener(eventName, handler);
|
|
196
|
+
$el.removeAttribute(eventDedupeKey);
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
if (ctx.tag._delayedSrc) {
|
|
201
|
+
$el.setAttribute("src", ctx.tag._delayedSrc);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
exports.activeHead = void 0;
|
|
209
|
+
const setActiveHead = (head) => exports.activeHead = head;
|
|
210
|
+
const getActiveHead = () => exports.activeHead;
|
|
211
|
+
|
|
212
|
+
function useHead(input, options = {}) {
|
|
213
|
+
const head = getActiveHead();
|
|
214
|
+
if (head) {
|
|
215
|
+
const isBrowser = IsBrowser || head.resolvedOptions?.document;
|
|
216
|
+
if (options.mode === "server" && isBrowser || options.mode === "client" && !isBrowser)
|
|
217
|
+
return;
|
|
218
|
+
return head.push(input, options);
|
|
51
219
|
}
|
|
52
|
-
return tag;
|
|
53
220
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
221
|
+
const useTagTitle = (title) => useHead({ title });
|
|
222
|
+
const useTagBase = (base) => useHead({ base });
|
|
223
|
+
const useTagMeta = (meta) => useHead({ meta: shared.asArray(meta) });
|
|
224
|
+
const useTagMetaFlat = (meta) => useTagMeta(unpackMeta(meta));
|
|
225
|
+
const useTagLink = (link) => useHead({ link: shared.asArray(link) });
|
|
226
|
+
const useTagScript = (script) => useHead({ script: shared.asArray(script) });
|
|
227
|
+
const useTagStyle = (style) => useHead({ style: shared.asArray(style) });
|
|
228
|
+
const useTagNoscript = (noscript) => useHead({ noscript: shared.asArray(noscript) });
|
|
229
|
+
const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
|
|
230
|
+
const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
|
|
231
|
+
const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
|
|
232
|
+
|
|
233
|
+
function useServerHead(input, options = {}) {
|
|
234
|
+
return useHead(input, { ...options, mode: "server" });
|
|
235
|
+
}
|
|
236
|
+
const useServerTagTitle = (title) => useServerHead({ title });
|
|
237
|
+
const useServerTagBase = (base) => useServerHead({ base });
|
|
238
|
+
const useServerTagMeta = (meta) => useServerHead({ meta: shared.asArray(meta) });
|
|
239
|
+
const useServerTagMetaFlat = (meta) => useServerTagMeta(unpackMeta(meta));
|
|
240
|
+
const useServerTagLink = (link) => useServerHead({ link: shared.asArray(link) });
|
|
241
|
+
const useServerTagScript = (script) => useServerHead({ script: shared.asArray(script) });
|
|
242
|
+
const useServerTagStyle = (style) => useServerHead({ style: shared.asArray(style) });
|
|
243
|
+
const useServerTagNoscript = (noscript) => useServerHead({ noscript: shared.asArray(noscript) });
|
|
244
|
+
const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
|
|
245
|
+
const useServerBodyAttrs = (attrs) => useServerHead({ bodyAttrs: attrs });
|
|
246
|
+
const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
|
|
247
|
+
|
|
248
|
+
const useSeoMeta = (input) => {
|
|
249
|
+
const { title, titleTemplate, ...meta } = input;
|
|
250
|
+
return useHead({
|
|
251
|
+
title,
|
|
252
|
+
titleTemplate,
|
|
253
|
+
meta: unpackMeta(meta)
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
function asArray(input) {
|
|
258
|
+
return Array.isArray(input) ? input : [input];
|
|
259
|
+
}
|
|
260
|
+
const InternalKeySymbol = "_$key";
|
|
261
|
+
function packObject(input, options) {
|
|
262
|
+
const keys = Object.keys(input);
|
|
263
|
+
let [k, v] = keys;
|
|
264
|
+
options = options || {};
|
|
265
|
+
options.key = options.key || k;
|
|
266
|
+
options.value = options.value || v;
|
|
267
|
+
options.resolveKey = options.resolveKey || ((k2) => k2);
|
|
268
|
+
const resolveKey = (index) => {
|
|
269
|
+
const arr = asArray(options?.[index]);
|
|
270
|
+
return arr.find((k2) => {
|
|
271
|
+
if (typeof k2 === "string" && k2.includes(".")) {
|
|
272
|
+
return k2;
|
|
273
|
+
}
|
|
274
|
+
return k2 && keys.includes(k2);
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
const resolveValue = (k2, input2) => {
|
|
278
|
+
if (k2.includes(".")) {
|
|
279
|
+
const paths = k2.split(".");
|
|
280
|
+
let val = input2;
|
|
281
|
+
for (const path of paths)
|
|
282
|
+
val = val[path];
|
|
283
|
+
return val;
|
|
58
284
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
285
|
+
return input2[k2];
|
|
286
|
+
};
|
|
287
|
+
k = resolveKey("key") || k;
|
|
288
|
+
v = resolveKey("value") || v;
|
|
289
|
+
const dedupeKeyPrefix = input.key ? `${InternalKeySymbol}${input.key}-` : "";
|
|
290
|
+
let keyValue = resolveValue(k, input);
|
|
291
|
+
keyValue = options.resolveKey(keyValue);
|
|
292
|
+
return {
|
|
293
|
+
[`${dedupeKeyPrefix}${keyValue}`]: resolveValue(v, input)
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function packArray(input, options) {
|
|
298
|
+
const packed = {};
|
|
299
|
+
for (const i of input) {
|
|
300
|
+
const packedObj = packObject(i, options);
|
|
301
|
+
const pKey = Object.keys(packedObj)[0];
|
|
302
|
+
const isDedupeKey = pKey.startsWith(InternalKeySymbol);
|
|
303
|
+
if (!isDedupeKey && packed[pKey]) {
|
|
304
|
+
packed[pKey] = Array.isArray(packed[pKey]) ? packed[pKey] : [packed[pKey]];
|
|
305
|
+
packed[pKey].push(Object.values(packedObj)[0]);
|
|
306
|
+
} else {
|
|
307
|
+
packed[isDedupeKey ? pKey.split("-").slice(1).join("-") || pKey : pKey] = packedObj[pKey];
|
|
63
308
|
}
|
|
64
309
|
}
|
|
65
|
-
return
|
|
310
|
+
return packed;
|
|
66
311
|
}
|
|
67
312
|
|
|
68
313
|
function unpackToArray(input, options) {
|
|
@@ -158,6 +403,20 @@ function resolveMetaKeyType(key) {
|
|
|
158
403
|
return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
|
|
159
404
|
}
|
|
160
405
|
|
|
406
|
+
function packMeta(inputs) {
|
|
407
|
+
const mappedPackingSchema = Object.entries(MetaPackingSchema).map(([key, value]) => [key, value.keyValue]);
|
|
408
|
+
return packArray(inputs, {
|
|
409
|
+
key: ["name", "property", "httpEquiv", "http-equiv", "charset"],
|
|
410
|
+
value: ["content", "charset"],
|
|
411
|
+
resolveKey(k) {
|
|
412
|
+
let key = mappedPackingSchema.filter((sk) => sk[1] === k)?.[0]?.[0] || k;
|
|
413
|
+
const replacer = (_, letter) => letter?.toUpperCase();
|
|
414
|
+
key = key.replace(/:([a-z])/g, replacer).replace(/-([a-z])/g, replacer);
|
|
415
|
+
return key;
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
161
420
|
const ArrayableInputs = ["Image", "Video", "Audio"];
|
|
162
421
|
function unpackMeta(input) {
|
|
163
422
|
const extras = [];
|
|
@@ -224,393 +483,58 @@ function unpackMeta(input) {
|
|
|
224
483
|
return [...extras, ...meta].filter((v) => typeof v.content === "undefined" || v.content !== "_null");
|
|
225
484
|
}
|
|
226
485
|
|
|
227
|
-
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
|
|
233
|
-
}
|
|
234
|
-
return key;
|
|
235
|
-
}
|
|
236
|
-
function changeKeyCasingDeep(input) {
|
|
237
|
-
if (Array.isArray(input)) {
|
|
238
|
-
return input.map((entry) => changeKeyCasingDeep(entry));
|
|
239
|
-
}
|
|
240
|
-
if (typeof input !== "object" || Array.isArray(input))
|
|
241
|
-
return input;
|
|
242
|
-
const output = {};
|
|
243
|
-
for (const [key, value] of Object.entries(input))
|
|
244
|
-
output[fixKeyCase(key)] = changeKeyCasingDeep(value);
|
|
245
|
-
return output;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const tagWeight = (tag) => {
|
|
249
|
-
if (typeof tag.tagPriority === "number")
|
|
250
|
-
return tag.tagPriority;
|
|
251
|
-
switch (tag.tagPriority) {
|
|
252
|
-
case "critical":
|
|
253
|
-
return 2;
|
|
254
|
-
case "high":
|
|
255
|
-
return 9;
|
|
256
|
-
case "low":
|
|
257
|
-
return 12;
|
|
258
|
-
}
|
|
259
|
-
switch (tag.tag) {
|
|
260
|
-
case "base":
|
|
261
|
-
return -1;
|
|
262
|
-
case "title":
|
|
263
|
-
return 1;
|
|
264
|
-
case "meta":
|
|
265
|
-
if (tag.props.charset)
|
|
266
|
-
return -2;
|
|
267
|
-
if (tag.props["http-equiv"] === "content-security-policy")
|
|
268
|
-
return 0;
|
|
269
|
-
return 10;
|
|
270
|
-
default:
|
|
271
|
-
return 10;
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
const sortTags = (aTag, bTag) => {
|
|
275
|
-
return tagWeight(aTag) - tagWeight(bTag);
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
|
|
279
|
-
function tagDedupeKey(tag, fn) {
|
|
280
|
-
const { props, tag: tagName } = tag;
|
|
281
|
-
if (UniqueTags.includes(tagName))
|
|
282
|
-
return tagName;
|
|
283
|
-
if (tagName === "link" && props.rel === "canonical")
|
|
284
|
-
return "canonical";
|
|
285
|
-
if (props.charset)
|
|
286
|
-
return "charset";
|
|
287
|
-
const name = ["id"];
|
|
288
|
-
if (tagName === "meta")
|
|
289
|
-
name.push(...["name", "property", "http-equiv"]);
|
|
290
|
-
for (const n of name) {
|
|
291
|
-
if (typeof props[n] !== "undefined") {
|
|
292
|
-
const val = String(props[n]);
|
|
293
|
-
if (fn && !fn(val))
|
|
294
|
-
return false;
|
|
295
|
-
return `${tagName}:${n}:${val}`;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const renderTitleTemplate = (template, title) => {
|
|
302
|
-
if (template == null)
|
|
303
|
-
return title || null;
|
|
304
|
-
if (typeof template === "function")
|
|
305
|
-
return template(title);
|
|
306
|
-
return template.replace("%s", title ?? "");
|
|
307
|
-
};
|
|
308
|
-
function resolveTitleTemplateFromTags(tags) {
|
|
309
|
-
let titleTemplateIdx = tags.findIndex((i) => i.tag === "titleTemplate");
|
|
310
|
-
const titleIdx = tags.findIndex((i) => i.tag === "title");
|
|
311
|
-
if (titleIdx !== -1 && titleTemplateIdx !== -1) {
|
|
312
|
-
const newTitle = renderTitleTemplate(
|
|
313
|
-
tags[titleTemplateIdx].children,
|
|
314
|
-
tags[titleIdx].children
|
|
315
|
-
);
|
|
316
|
-
if (newTitle !== null) {
|
|
317
|
-
tags[titleIdx].children = newTitle || tags[titleIdx].children;
|
|
318
|
-
} else {
|
|
319
|
-
delete tags[titleIdx];
|
|
320
|
-
}
|
|
321
|
-
} else if (titleTemplateIdx !== -1) {
|
|
322
|
-
const newTitle = renderTitleTemplate(
|
|
323
|
-
tags[titleTemplateIdx].children
|
|
324
|
-
);
|
|
325
|
-
if (newTitle !== null) {
|
|
326
|
-
tags[titleTemplateIdx].children = newTitle;
|
|
327
|
-
tags[titleTemplateIdx].tag = "title";
|
|
328
|
-
titleTemplateIdx = -1;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
if (titleTemplateIdx !== -1) {
|
|
332
|
-
delete tags[titleTemplateIdx];
|
|
486
|
+
async function normaliseTag(tagName, input) {
|
|
487
|
+
const tag = { tag: tagName, props: {} };
|
|
488
|
+
if (tagName === "title" || tagName === "titleTemplate") {
|
|
489
|
+
tag.children = input instanceof Promise ? await input : input;
|
|
490
|
+
return tag;
|
|
333
491
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
hooks: {
|
|
342
|
-
"tag:normalise": function({ tag }) {
|
|
343
|
-
dedupeKeys.forEach((key) => {
|
|
344
|
-
if (tag.props[key]) {
|
|
345
|
-
tag.key = tag.props[key];
|
|
346
|
-
delete tag.props[key];
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
const dedupe = tag.key ? `${tag.tag}:${tag.key}` : tagDedupeKey(tag);
|
|
350
|
-
if (dedupe)
|
|
351
|
-
tag._d = dedupe;
|
|
352
|
-
},
|
|
353
|
-
"tags:resolve": function(ctx) {
|
|
354
|
-
const deduping = {};
|
|
355
|
-
ctx.tags.forEach((tag) => {
|
|
356
|
-
let dedupeKey = tag._d || tag._p;
|
|
357
|
-
const dupedTag = deduping[dedupeKey];
|
|
358
|
-
if (dupedTag) {
|
|
359
|
-
let strategy = tag?.tagDuplicateStrategy;
|
|
360
|
-
if (!strategy && (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs"))
|
|
361
|
-
strategy = "merge";
|
|
362
|
-
if (strategy === "merge") {
|
|
363
|
-
const oldProps = dupedTag.props;
|
|
364
|
-
["class", "style"].forEach((key) => {
|
|
365
|
-
if (tag.props[key] && oldProps[key]) {
|
|
366
|
-
if (key === "style" && !oldProps[key].endsWith(";"))
|
|
367
|
-
oldProps[key] += ";";
|
|
368
|
-
tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
deduping[dedupeKey].props = {
|
|
372
|
-
...oldProps,
|
|
373
|
-
...tag.props
|
|
374
|
-
};
|
|
375
|
-
return;
|
|
376
|
-
} else if (tag._e === dupedTag._e) {
|
|
377
|
-
dedupeKey = tag._d = `${dedupeKey}:${tag._p}`;
|
|
378
|
-
}
|
|
379
|
-
const propCount = Object.keys(tag.props).length;
|
|
380
|
-
if ((propCount === 0 || propCount === 1 && typeof tag.props["data-h-key"] !== "undefined") && !tag.children) {
|
|
381
|
-
delete deduping[dedupeKey];
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
deduping[dedupeKey] = tag;
|
|
386
|
-
});
|
|
387
|
-
ctx.tags = Object.values(deduping);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
};
|
|
392
|
-
|
|
393
|
-
const SortTagsPlugin = () => {
|
|
394
|
-
return defineHeadPlugin({
|
|
395
|
-
hooks: {
|
|
396
|
-
"tags:resolve": (ctx) => {
|
|
397
|
-
const tagIndexForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
|
|
398
|
-
for (const tag of ctx.tags) {
|
|
399
|
-
if (!tag.tagPriority || typeof tag.tagPriority === "number")
|
|
400
|
-
continue;
|
|
401
|
-
const modifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
|
|
402
|
-
for (const { prefix, offset } of modifiers) {
|
|
403
|
-
if (tag.tagPriority.startsWith(prefix)) {
|
|
404
|
-
const key = tag.tagPriority.replace(prefix, "");
|
|
405
|
-
const index = tagIndexForKey(key);
|
|
406
|
-
if (typeof index !== "undefined")
|
|
407
|
-
tag._p = index + offset;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
ctx.tags.sort((a, b) => a._p - b._p).sort(sortTags);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
const TitleTemplatePlugin = () => {
|
|
418
|
-
return defineHeadPlugin({
|
|
419
|
-
hooks: {
|
|
420
|
-
"tags:resolve": (ctx) => {
|
|
421
|
-
ctx.tags = resolveTitleTemplateFromTags(ctx.tags);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
const DeprecatedTagAttrPlugin = () => {
|
|
428
|
-
return defineHeadPlugin({
|
|
429
|
-
hooks: {
|
|
430
|
-
"tag:normalise": function({ tag }) {
|
|
431
|
-
if (typeof tag.props.body !== "undefined") {
|
|
432
|
-
tag.tagPosition = "bodyClose";
|
|
433
|
-
delete tag.props.body;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
const IsBrowser = typeof window !== "undefined";
|
|
441
|
-
|
|
442
|
-
const ProvideTagHashPlugin = () => {
|
|
443
|
-
return defineHeadPlugin({
|
|
444
|
-
hooks: {
|
|
445
|
-
"tag:normalise": (ctx) => {
|
|
446
|
-
const { tag, entry } = ctx;
|
|
447
|
-
const isDynamic = typeof tag.props._dynamic !== "undefined";
|
|
448
|
-
if (!HasElementTags.includes(tag.tag) || !tag.key)
|
|
449
|
-
return;
|
|
450
|
-
tag._hash = dom.hashCode(JSON.stringify({ tag: tag.tag, key: tag.key }));
|
|
451
|
-
if (IsBrowser || getActiveHead()?.resolvedOptions?.document)
|
|
452
|
-
return;
|
|
453
|
-
if (entry._m === "server" || isDynamic) {
|
|
454
|
-
tag.props[`data-h-${tag._hash}`] = "";
|
|
455
|
-
}
|
|
456
|
-
},
|
|
457
|
-
"tags:resolve": (ctx) => {
|
|
458
|
-
ctx.tags = ctx.tags.map((t) => {
|
|
459
|
-
delete t.props._dynamic;
|
|
460
|
-
return t;
|
|
461
|
-
});
|
|
462
|
-
}
|
|
492
|
+
tag.props = await normaliseProps({ ...input });
|
|
493
|
+
["children", "innerHtml", "innerHTML"].forEach((key) => {
|
|
494
|
+
if (typeof tag.props[key] !== "undefined") {
|
|
495
|
+
tag.children = tag.props[key];
|
|
496
|
+
if (typeof tag.children === "object")
|
|
497
|
+
tag.children = JSON.stringify(tag.children);
|
|
498
|
+
delete tag.props[key];
|
|
463
499
|
}
|
|
464
500
|
});
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
return defineHeadPlugin({
|
|
469
|
-
hooks: {
|
|
470
|
-
"entries:updated": function(head) {
|
|
471
|
-
if (typeof options?.document === "undefined" && typeof window === "undefined")
|
|
472
|
-
return;
|
|
473
|
-
let delayFn = options?.delayFn;
|
|
474
|
-
if (!delayFn && typeof requestAnimationFrame !== "undefined")
|
|
475
|
-
delayFn = requestAnimationFrame;
|
|
476
|
-
import('@unhead/dom').then(({ debouncedRenderDOMHead }) => {
|
|
477
|
-
debouncedRenderDOMHead(head, { document: options?.document || window.document, delayFn });
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
}
|
|
501
|
+
Object.keys(tag.props).filter((k) => shared.TagConfigKeys.includes(k)).forEach((k) => {
|
|
502
|
+
tag[k] = tag.props[k];
|
|
503
|
+
delete tag.props[k];
|
|
481
504
|
});
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
505
|
+
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
|
|
506
|
+
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
|
|
507
|
+
}
|
|
508
|
+
if (Array.isArray(tag.props.class))
|
|
509
|
+
tag.props.class = tag.props.class.join(" ");
|
|
510
|
+
if (tag.props.content && Array.isArray(tag.props.content)) {
|
|
511
|
+
return tag.props.content.map((v, i) => {
|
|
512
|
+
const newTag = { ...tag, props: { ...tag.props } };
|
|
513
|
+
newTag.props.content = v;
|
|
514
|
+
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
|
|
515
|
+
return newTag;
|
|
493
516
|
});
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
517
|
+
}
|
|
518
|
+
return tag;
|
|
519
|
+
}
|
|
520
|
+
async function normaliseProps(props) {
|
|
521
|
+
for (const k of Object.keys(props)) {
|
|
522
|
+
if (props[k] instanceof Promise) {
|
|
523
|
+
props[k] = await props[k];
|
|
498
524
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
"ssr:render": function(ctx) {
|
|
504
|
-
ctx.tags = ctx.tags.map((tag) => {
|
|
505
|
-
tag.props = stripEventHandlers("ssr", tag).props;
|
|
506
|
-
return tag;
|
|
507
|
-
});
|
|
508
|
-
},
|
|
509
|
-
"dom:beforeRenderTag": function(ctx) {
|
|
510
|
-
const { props, eventHandlers, delayedSrc } = stripEventHandlers("dom", ctx.tag);
|
|
511
|
-
if (!Object.keys(eventHandlers).length)
|
|
512
|
-
return;
|
|
513
|
-
ctx.tag.props = props;
|
|
514
|
-
ctx.tag._eventHandlers = eventHandlers;
|
|
515
|
-
ctx.tag._delayedSrc = delayedSrc;
|
|
516
|
-
},
|
|
517
|
-
"dom:renderTag": function(ctx) {
|
|
518
|
-
const $el = ctx.$el;
|
|
519
|
-
if (!ctx.tag._eventHandlers || !$el)
|
|
520
|
-
return;
|
|
521
|
-
const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" && typeof window !== "undefined" ? window : $el;
|
|
522
|
-
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
523
|
-
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
|
|
524
|
-
const eventName = k.slice(2).toLowerCase();
|
|
525
|
-
const eventDedupeKey = `data-h-${eventName}`;
|
|
526
|
-
delete ctx.staleSideEffects[sdeKey];
|
|
527
|
-
if ($el.hasAttribute(eventDedupeKey))
|
|
528
|
-
return;
|
|
529
|
-
const handler = value;
|
|
530
|
-
$el.setAttribute(eventDedupeKey, "");
|
|
531
|
-
$eventListenerTarget.addEventListener(eventName, handler);
|
|
532
|
-
if (ctx.entry) {
|
|
533
|
-
ctx.entry._sde[sdeKey] = () => {
|
|
534
|
-
$eventListenerTarget.removeEventListener(eventName, handler);
|
|
535
|
-
$el.removeAttribute(eventDedupeKey);
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
if (ctx.tag._delayedSrc) {
|
|
540
|
-
$el.setAttribute("src", ctx.tag._delayedSrc);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
525
|
+
if (String(props[k]) === "true") {
|
|
526
|
+
props[k] = "";
|
|
527
|
+
} else if (String(props[k]) === "false") {
|
|
528
|
+
delete props[k];
|
|
543
529
|
}
|
|
544
|
-
});
|
|
545
|
-
};
|
|
546
|
-
|
|
547
|
-
function asArray(value) {
|
|
548
|
-
return Array.isArray(value) ? value : [value];
|
|
549
|
-
}
|
|
550
|
-
const HasElementTags = [
|
|
551
|
-
"base",
|
|
552
|
-
"meta",
|
|
553
|
-
"link",
|
|
554
|
-
"style",
|
|
555
|
-
"script",
|
|
556
|
-
"noscript"
|
|
557
|
-
];
|
|
558
|
-
|
|
559
|
-
exports.activeHead = void 0;
|
|
560
|
-
const setActiveHead = (head) => exports.activeHead = head;
|
|
561
|
-
const getActiveHead = () => exports.activeHead;
|
|
562
|
-
|
|
563
|
-
function useHead(input, options = {}) {
|
|
564
|
-
const head = getActiveHead();
|
|
565
|
-
if (head) {
|
|
566
|
-
const isBrowser = IsBrowser || head.resolvedOptions?.document;
|
|
567
|
-
if (options.mode === "server" && isBrowser || options.mode === "client" && !isBrowser)
|
|
568
|
-
return;
|
|
569
|
-
return head.push(input, options);
|
|
570
530
|
}
|
|
531
|
+
return props;
|
|
571
532
|
}
|
|
572
|
-
const useTagTitle = (title) => useHead({ title });
|
|
573
|
-
const useTagBase = (base) => useHead({ base });
|
|
574
|
-
const useTagMeta = (meta) => useHead({ meta: asArray(meta) });
|
|
575
|
-
const useTagMetaFlat = (meta) => useTagMeta(unpackMeta(meta));
|
|
576
|
-
const useTagLink = (link) => useHead({ link: asArray(link) });
|
|
577
|
-
const useTagScript = (script) => useHead({ script: asArray(script) });
|
|
578
|
-
const useTagStyle = (style) => useHead({ style: asArray(style) });
|
|
579
|
-
const useTagNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
|
|
580
|
-
const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
|
|
581
|
-
const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
|
|
582
|
-
const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
|
|
583
|
-
|
|
584
|
-
function useServerHead(input, options = {}) {
|
|
585
|
-
return useHead(input, { ...options, mode: "server" });
|
|
586
|
-
}
|
|
587
|
-
const useServerTagTitle = (title) => useServerHead({ title });
|
|
588
|
-
const useServerTagBase = (base) => useServerHead({ base });
|
|
589
|
-
const useServerTagMeta = (meta) => useServerHead({ meta: asArray(meta) });
|
|
590
|
-
const useServerTagMetaFlat = (meta) => useServerTagMeta(unpackMeta(meta));
|
|
591
|
-
const useServerTagLink = (link) => useServerHead({ link: asArray(link) });
|
|
592
|
-
const useServerTagScript = (script) => useServerHead({ script: asArray(script) });
|
|
593
|
-
const useServerTagStyle = (style) => useServerHead({ style: asArray(style) });
|
|
594
|
-
const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray(noscript) });
|
|
595
|
-
const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
|
|
596
|
-
const useServerBodyAttrs = (attrs) => useServerHead({ bodyAttrs: attrs });
|
|
597
|
-
const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
|
|
598
|
-
|
|
599
|
-
const useSeoMeta = (input) => {
|
|
600
|
-
const { title, titleTemplate, ...meta } = input;
|
|
601
|
-
return useHead({
|
|
602
|
-
title,
|
|
603
|
-
titleTemplate,
|
|
604
|
-
meta: unpackMeta(meta)
|
|
605
|
-
});
|
|
606
|
-
};
|
|
607
|
-
|
|
608
533
|
const TagEntityBits = 10;
|
|
609
|
-
|
|
610
534
|
async function normaliseEntryTags(e) {
|
|
611
535
|
const tagPromises = [];
|
|
612
|
-
Object.entries(e.resolvedInput || e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).forEach(([k, value]) => {
|
|
613
|
-
const v = asArray(value);
|
|
536
|
+
Object.entries(e.resolvedInput || e.input).filter(([k, v]) => typeof v !== "undefined" && shared.ValidHeadTags.includes(k)).forEach(([k, value]) => {
|
|
537
|
+
const v = shared.asArray(value);
|
|
614
538
|
tagPromises.push(...v.map((props) => normaliseTag(k, props)).flat());
|
|
615
539
|
});
|
|
616
540
|
return (await Promise.all(tagPromises)).flat().map((t, i) => {
|
|
@@ -620,9 +544,30 @@ async function normaliseEntryTags(e) {
|
|
|
620
544
|
});
|
|
621
545
|
}
|
|
622
546
|
|
|
547
|
+
const PropertyPrefixKeys = /^(og|fb)/;
|
|
548
|
+
const ColonPrefixKeys = /^(og|twitter|fb)/;
|
|
549
|
+
function fixKeyCase(key) {
|
|
550
|
+
key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
551
|
+
if (ColonPrefixKeys.test(key)) {
|
|
552
|
+
key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
|
|
553
|
+
}
|
|
554
|
+
return key;
|
|
555
|
+
}
|
|
556
|
+
function changeKeyCasingDeep(input) {
|
|
557
|
+
if (Array.isArray(input)) {
|
|
558
|
+
return input.map((entry) => changeKeyCasingDeep(entry));
|
|
559
|
+
}
|
|
560
|
+
if (typeof input !== "object" || Array.isArray(input))
|
|
561
|
+
return input;
|
|
562
|
+
const output = {};
|
|
563
|
+
for (const [key, value] of Object.entries(input))
|
|
564
|
+
output[fixKeyCase(key)] = changeKeyCasingDeep(value);
|
|
565
|
+
return output;
|
|
566
|
+
}
|
|
567
|
+
|
|
623
568
|
const CorePlugins = () => [
|
|
624
569
|
// dedupe needs to come first
|
|
625
|
-
DedupesTagsPlugin(),
|
|
570
|
+
shared.DedupesTagsPlugin(),
|
|
626
571
|
SortTagsPlugin(),
|
|
627
572
|
TitleTemplatePlugin(),
|
|
628
573
|
ProvideTagHashPlugin(),
|
|
@@ -630,7 +575,7 @@ const CorePlugins = () => [
|
|
|
630
575
|
DeprecatedTagAttrPlugin()
|
|
631
576
|
];
|
|
632
577
|
const DOMPlugins = (options = {}) => [
|
|
633
|
-
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn })
|
|
578
|
+
dom.PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn })
|
|
634
579
|
];
|
|
635
580
|
function createHead(options = {}) {
|
|
636
581
|
const head = createHeadCore({
|
|
@@ -722,10 +667,6 @@ function createHeadCore(options = {}) {
|
|
|
722
667
|
return head;
|
|
723
668
|
}
|
|
724
669
|
|
|
725
|
-
function defineHeadPlugin(plugin) {
|
|
726
|
-
return plugin;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
670
|
const coreComposableNames = [
|
|
730
671
|
"getActiveHead"
|
|
731
672
|
];
|
|
@@ -765,25 +706,33 @@ const unheadComposablesImports = [
|
|
|
765
706
|
}
|
|
766
707
|
];
|
|
767
708
|
|
|
709
|
+
exports.ColonPrefixKeys = ColonPrefixKeys;
|
|
768
710
|
exports.CorePlugins = CorePlugins;
|
|
769
711
|
exports.DOMPlugins = DOMPlugins;
|
|
770
|
-
exports.DedupesTagsPlugin = DedupesTagsPlugin;
|
|
771
712
|
exports.DeprecatedTagAttrPlugin = DeprecatedTagAttrPlugin;
|
|
772
713
|
exports.EventHandlersPlugin = EventHandlersPlugin;
|
|
773
|
-
exports.
|
|
774
|
-
exports.PatchDomOnEntryUpdatesPlugin = PatchDomOnEntryUpdatesPlugin;
|
|
714
|
+
exports.PropertyPrefixKeys = PropertyPrefixKeys;
|
|
775
715
|
exports.ProvideTagHashPlugin = ProvideTagHashPlugin;
|
|
716
|
+
exports.SortModifiers = SortModifiers;
|
|
776
717
|
exports.SortTagsPlugin = SortTagsPlugin;
|
|
718
|
+
exports.TAG_WEIGHTS = TAG_WEIGHTS;
|
|
719
|
+
exports.TagEntityBits = TagEntityBits;
|
|
777
720
|
exports.TitleTemplatePlugin = TitleTemplatePlugin;
|
|
778
|
-
exports.
|
|
721
|
+
exports.changeKeyCasingDeep = changeKeyCasingDeep;
|
|
779
722
|
exports.composableNames = composableNames;
|
|
780
723
|
exports.createHead = createHead;
|
|
781
724
|
exports.createHeadCore = createHeadCore;
|
|
782
|
-
exports.
|
|
725
|
+
exports.fixKeyCase = fixKeyCase;
|
|
783
726
|
exports.getActiveHead = getActiveHead;
|
|
784
727
|
exports.normaliseEntryTags = normaliseEntryTags;
|
|
728
|
+
exports.normaliseProps = normaliseProps;
|
|
729
|
+
exports.normaliseTag = normaliseTag;
|
|
730
|
+
exports.packMeta = packMeta;
|
|
731
|
+
exports.renderTitleTemplate = renderTitleTemplate;
|
|
785
732
|
exports.setActiveHead = setActiveHead;
|
|
733
|
+
exports.tagWeight = tagWeight;
|
|
786
734
|
exports.unheadComposablesImports = unheadComposablesImports;
|
|
735
|
+
exports.unpackMeta = unpackMeta;
|
|
787
736
|
exports.useBodyAttrs = useBodyAttrs;
|
|
788
737
|
exports.useHead = useHead;
|
|
789
738
|
exports.useHtmlAttrs = useHtmlAttrs;
|
|
@@ -809,3 +758,6 @@ exports.useTagScript = useTagScript;
|
|
|
809
758
|
exports.useTagStyle = useTagStyle;
|
|
810
759
|
exports.useTagTitle = useTagTitle;
|
|
811
760
|
exports.useTitleTemplate = useTitleTemplate;
|
|
761
|
+
Object.keys(shared).forEach(function (k) {
|
|
762
|
+
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = shared[k];
|
|
763
|
+
});
|