@unhead/vue 0.6.2 → 0.6.4
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/chunks/index.cjs +164 -0
- package/dist/chunks/index.mjs +161 -0
- package/dist/index.cjs +529 -15
- package/dist/index.d.ts +6 -7
- package/dist/index.mjs +524 -7
- package/package.json +4 -5
package/dist/index.cjs
CHANGED
|
@@ -1,24 +1,541 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const shared = require('@vueuse/shared');
|
|
4
3
|
const vue = require('vue');
|
|
5
|
-
const
|
|
6
|
-
const dom = require('@unhead/dom');
|
|
4
|
+
const hookable = require('hookable');
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const ValidHeadTags = [
|
|
7
|
+
"title",
|
|
8
|
+
"titleTemplate",
|
|
9
|
+
"base",
|
|
10
|
+
"htmlAttrs",
|
|
11
|
+
"bodyAttrs",
|
|
12
|
+
"meta",
|
|
13
|
+
"link",
|
|
14
|
+
"style",
|
|
15
|
+
"script",
|
|
16
|
+
"noscript"
|
|
17
|
+
];
|
|
18
|
+
const TagConfigKeys = ["tagPosition", "tagPriority", "tagDuplicateStrategy"];
|
|
19
|
+
|
|
20
|
+
function normaliseTag(tagName, input) {
|
|
21
|
+
const tag = { tag: tagName, props: {} };
|
|
22
|
+
if (tagName === "title" || tagName === "titleTemplate") {
|
|
23
|
+
tag.children = input;
|
|
24
|
+
return tag;
|
|
25
|
+
}
|
|
26
|
+
tag.props = normaliseProps({ ...input });
|
|
27
|
+
["children", "innerHtml", "innerHTML"].forEach((key) => {
|
|
28
|
+
if (typeof tag.props[key] !== "undefined") {
|
|
29
|
+
tag.children = tag.props[key];
|
|
30
|
+
delete tag.props[key];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
Object.keys(tag.props).filter((k) => TagConfigKeys.includes(k)).forEach((k) => {
|
|
34
|
+
tag[k] = tag.props[k];
|
|
35
|
+
delete tag.props[k];
|
|
36
|
+
});
|
|
37
|
+
if (typeof tag.props.class === "object" && !Array.isArray(tag.props.class)) {
|
|
38
|
+
tag.props.class = Object.keys(tag.props.class).filter((k) => tag.props.class[k]);
|
|
39
|
+
}
|
|
40
|
+
if (Array.isArray(tag.props.class))
|
|
41
|
+
tag.props.class = tag.props.class.join(" ");
|
|
42
|
+
if (tag.props.content && Array.isArray(tag.props.content)) {
|
|
43
|
+
return tag.props.content.map((v, i) => {
|
|
44
|
+
const newTag = { ...tag, props: { ...tag.props } };
|
|
45
|
+
newTag.props.content = v;
|
|
46
|
+
newTag.key = `${tag.props.name || tag.props.property}:${i}`;
|
|
47
|
+
return newTag;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return tag;
|
|
51
|
+
}
|
|
52
|
+
function normaliseProps(props) {
|
|
53
|
+
for (const k in props) {
|
|
54
|
+
if (String(props[k]) === "true") {
|
|
55
|
+
props[k] = "";
|
|
56
|
+
} else if (String(props[k]) === "false") {
|
|
57
|
+
delete props[k];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return props;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const tagWeight = (tag) => {
|
|
64
|
+
if (typeof tag.tagPriority === "number")
|
|
65
|
+
return tag.tagPriority;
|
|
66
|
+
switch (tag.tag) {
|
|
67
|
+
case "base":
|
|
68
|
+
return -1;
|
|
69
|
+
case "title":
|
|
70
|
+
return 1;
|
|
71
|
+
case "meta":
|
|
72
|
+
if (tag.props.charset)
|
|
73
|
+
return -2;
|
|
74
|
+
if (tag.props["http-equiv"] === "content-security-policy")
|
|
75
|
+
return 0;
|
|
76
|
+
return 10;
|
|
77
|
+
default:
|
|
78
|
+
return 10;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const sortTags = (aTag, bTag) => {
|
|
82
|
+
return tagWeight(aTag) - tagWeight(bTag);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
|
|
86
|
+
const ArrayMetaProperties = [
|
|
87
|
+
"og:image",
|
|
88
|
+
"og:video",
|
|
89
|
+
"og:audio",
|
|
90
|
+
"og:locale:alternate",
|
|
91
|
+
"video:actor",
|
|
92
|
+
"video:director",
|
|
93
|
+
"video:writer",
|
|
94
|
+
"video:tag",
|
|
95
|
+
"article:author",
|
|
96
|
+
"article:tag",
|
|
97
|
+
"book:tag",
|
|
98
|
+
"book:author",
|
|
99
|
+
"music:album",
|
|
100
|
+
"music:musician"
|
|
101
|
+
];
|
|
102
|
+
function tagDedupeKey(tag) {
|
|
103
|
+
const { props, tag: tagName } = tag;
|
|
104
|
+
if (UniqueTags.includes(tagName))
|
|
105
|
+
return tagName;
|
|
106
|
+
if (tagName === "link" && props.rel === "canonical")
|
|
107
|
+
return "canonical";
|
|
108
|
+
if (props.charset)
|
|
109
|
+
return "charset";
|
|
110
|
+
const name = ["id"];
|
|
111
|
+
if (tagName === "meta")
|
|
112
|
+
name.push(...["name", "property", "http-equiv"]);
|
|
113
|
+
for (const n of name) {
|
|
114
|
+
if (typeof props[n] !== "undefined") {
|
|
115
|
+
const val = String(props[n]);
|
|
116
|
+
if (ArrayMetaProperties.findIndex((p) => val.startsWith(p)) !== -1)
|
|
117
|
+
return false;
|
|
118
|
+
return `${tagName}:${n}:${val}`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const renderTitleTemplate = (template, title) => {
|
|
125
|
+
if (template == null)
|
|
126
|
+
return title || null;
|
|
127
|
+
if (typeof template === "function")
|
|
128
|
+
return template(title);
|
|
129
|
+
return template.replace("%s", title ?? "");
|
|
130
|
+
};
|
|
131
|
+
function resolveTitleTemplateFromTags(tags) {
|
|
132
|
+
const titleTemplateIdx = tags.findIndex((i) => i.tag === "titleTemplate");
|
|
133
|
+
const titleIdx = tags.findIndex((i) => i.tag === "title");
|
|
134
|
+
if (titleIdx !== -1 && titleTemplateIdx !== -1) {
|
|
135
|
+
const newTitle = renderTitleTemplate(
|
|
136
|
+
tags[titleTemplateIdx].children,
|
|
137
|
+
tags[titleIdx].children
|
|
138
|
+
);
|
|
139
|
+
if (newTitle !== null) {
|
|
140
|
+
tags[titleIdx].children = newTitle || tags[titleIdx].children;
|
|
141
|
+
} else {
|
|
142
|
+
delete tags[titleIdx];
|
|
143
|
+
}
|
|
144
|
+
} else if (titleTemplateIdx !== -1) {
|
|
145
|
+
const newTitle = renderTitleTemplate(
|
|
146
|
+
tags[titleTemplateIdx].children
|
|
147
|
+
);
|
|
148
|
+
if (newTitle !== null) {
|
|
149
|
+
tags[titleTemplateIdx].children = newTitle;
|
|
150
|
+
tags[titleTemplateIdx].tag = "title";
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (titleTemplateIdx !== -1) {
|
|
154
|
+
delete tags[titleTemplateIdx];
|
|
155
|
+
}
|
|
156
|
+
return tags.filter(Boolean);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const DedupesTagsPlugin = (options) => {
|
|
160
|
+
options = options || {};
|
|
161
|
+
const dedupeKeys = options.dedupeKeys || ["hid", "vmid", "key"];
|
|
162
|
+
return defineHeadPlugin({
|
|
163
|
+
hooks: {
|
|
164
|
+
"tag:normalise": function({ tag }) {
|
|
165
|
+
dedupeKeys.forEach((key) => {
|
|
166
|
+
if (tag.props[key]) {
|
|
167
|
+
tag.key = tag.props[key];
|
|
168
|
+
delete tag.props[key];
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
const dedupe = tag.key ? `${tag.tag}:${tag.key}` : tagDedupeKey(tag);
|
|
172
|
+
if (dedupe)
|
|
173
|
+
tag._d = dedupe;
|
|
174
|
+
},
|
|
175
|
+
"tags:resolve": function(ctx) {
|
|
176
|
+
const deduping = {};
|
|
177
|
+
ctx.tags.forEach((tag) => {
|
|
178
|
+
let dedupeKey = tag._d || tag._p;
|
|
179
|
+
const dupedTag = deduping[dedupeKey];
|
|
180
|
+
if (dupedTag) {
|
|
181
|
+
let strategy = tag?.tagDuplicateStrategy;
|
|
182
|
+
if (!strategy && (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs"))
|
|
183
|
+
strategy = "merge";
|
|
184
|
+
if (strategy === "merge") {
|
|
185
|
+
const oldProps = dupedTag.props;
|
|
186
|
+
["class", "style"].forEach((key) => {
|
|
187
|
+
if (tag.props[key] && oldProps[key]) {
|
|
188
|
+
if (key === "style" && !oldProps[key].endsWith(";"))
|
|
189
|
+
oldProps[key] += ";";
|
|
190
|
+
tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
deduping[dedupeKey].props = {
|
|
194
|
+
...oldProps,
|
|
195
|
+
...tag.props
|
|
196
|
+
};
|
|
197
|
+
return;
|
|
198
|
+
} else if (tag._e === dupedTag._e) {
|
|
199
|
+
dedupeKey = tag._d = `${dedupeKey}:${tag._p}`;
|
|
200
|
+
}
|
|
201
|
+
const propCount = Object.keys(tag.props).length;
|
|
202
|
+
if ((propCount === 0 || propCount === 1 && typeof tag.props["data-h-key"] !== "undefined") && !tag.children) {
|
|
203
|
+
delete deduping[dedupeKey];
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
deduping[dedupeKey] = tag;
|
|
208
|
+
});
|
|
209
|
+
ctx.tags = Object.values(deduping);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const SortTagsPlugin = () => {
|
|
216
|
+
return defineHeadPlugin({
|
|
217
|
+
hooks: {
|
|
218
|
+
"tags:resolve": (ctx) => {
|
|
219
|
+
const tagIndexForKey = (key) => ctx.tags.find((tag) => tag._d === key)?._p;
|
|
220
|
+
for (const tag of ctx.tags) {
|
|
221
|
+
if (!tag.tagPriority || typeof tag.tagPriority === "number")
|
|
222
|
+
continue;
|
|
223
|
+
const modifiers = [{ prefix: "before:", offset: -1 }, { prefix: "after:", offset: 1 }];
|
|
224
|
+
for (const { prefix, offset } of modifiers) {
|
|
225
|
+
if (tag.tagPriority.startsWith(prefix)) {
|
|
226
|
+
const key = tag.tagPriority.replace(prefix, "");
|
|
227
|
+
const index = tagIndexForKey(key);
|
|
228
|
+
if (typeof index !== "undefined")
|
|
229
|
+
tag._p = index + offset;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
ctx.tags.sort((a, b) => a._p - b._p).sort(sortTags);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const TitleTemplatePlugin = () => {
|
|
240
|
+
return defineHeadPlugin({
|
|
241
|
+
hooks: {
|
|
242
|
+
"tags:resolve": (ctx) => {
|
|
243
|
+
ctx.tags = resolveTitleTemplateFromTags(ctx.tags);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const DeprecatedTagAttrPlugin = () => {
|
|
250
|
+
return defineHeadPlugin({
|
|
251
|
+
hooks: {
|
|
252
|
+
"tag:normalise": function({ tag }) {
|
|
253
|
+
if (typeof tag.props.body !== "undefined") {
|
|
254
|
+
tag.tagPosition = "bodyClose";
|
|
255
|
+
delete tag.props.body;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const IsBrowser$1 = typeof window !== "undefined";
|
|
263
|
+
|
|
264
|
+
const ProvideTagHashPlugin = () => {
|
|
265
|
+
return defineHeadPlugin({
|
|
266
|
+
hooks: {
|
|
267
|
+
"tag:normalise": (ctx) => {
|
|
268
|
+
const { tag, entry } = ctx;
|
|
269
|
+
const isDynamic = typeof tag.props._dynamic !== "undefined";
|
|
270
|
+
if (!HasElementTags.includes(tag.tag) || !tag.key)
|
|
271
|
+
return;
|
|
272
|
+
tag._hash = hashCode(JSON.stringify({ tag: tag.tag, key: tag.key }));
|
|
273
|
+
if (IsBrowser$1 || getActiveHead()?.resolvedOptions?.document)
|
|
274
|
+
return;
|
|
275
|
+
if (entry._m === "server" || isDynamic) {
|
|
276
|
+
tag.props[`data-h-${tag._hash}`] = "";
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
"tags:resolve": (ctx) => {
|
|
280
|
+
ctx.tags = ctx.tags.map((t) => {
|
|
281
|
+
delete t.props._dynamic;
|
|
282
|
+
return t;
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const PatchDomOnEntryUpdatesPlugin = (options) => {
|
|
290
|
+
return defineHeadPlugin({
|
|
291
|
+
hooks: {
|
|
292
|
+
"entries:updated": function(head) {
|
|
293
|
+
if (typeof options?.document === "undefined" && typeof window === "undefined")
|
|
294
|
+
return;
|
|
295
|
+
let delayFn = options?.delayFn;
|
|
296
|
+
if (!delayFn && typeof requestAnimationFrame !== "undefined")
|
|
297
|
+
delayFn = requestAnimationFrame;
|
|
298
|
+
import('./chunks/index.cjs').then(({ debouncedRenderDOMHead }) => {
|
|
299
|
+
debouncedRenderDOMHead(head, { document: options?.document || window.document, delayFn });
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
const EventHandlersPlugin = () => {
|
|
307
|
+
const stripEventHandlers = (mode, tag) => {
|
|
308
|
+
const props = {};
|
|
309
|
+
const eventHandlers = {};
|
|
310
|
+
Object.entries(tag.props).forEach(([key, value]) => {
|
|
311
|
+
if (key.startsWith("on") && typeof value === "function")
|
|
312
|
+
eventHandlers[key] = value;
|
|
313
|
+
else
|
|
314
|
+
props[key] = value;
|
|
315
|
+
});
|
|
316
|
+
let delayedSrc;
|
|
317
|
+
if (mode === "dom" && tag.tag === "script" && typeof props.src === "string" && typeof eventHandlers.onload !== "undefined") {
|
|
318
|
+
delayedSrc = props.src;
|
|
319
|
+
delete props.src;
|
|
320
|
+
}
|
|
321
|
+
return { props, eventHandlers, delayedSrc };
|
|
322
|
+
};
|
|
323
|
+
return defineHeadPlugin({
|
|
324
|
+
hooks: {
|
|
325
|
+
"ssr:render": function(ctx) {
|
|
326
|
+
ctx.tags = ctx.tags.map((tag) => {
|
|
327
|
+
tag.props = stripEventHandlers("ssr", tag).props;
|
|
328
|
+
return tag;
|
|
329
|
+
});
|
|
330
|
+
},
|
|
331
|
+
"dom:beforeRenderTag": function(ctx) {
|
|
332
|
+
const { props, eventHandlers, delayedSrc } = stripEventHandlers("dom", ctx.tag);
|
|
333
|
+
if (!Object.keys(eventHandlers).length)
|
|
334
|
+
return;
|
|
335
|
+
ctx.tag.props = props;
|
|
336
|
+
ctx.tag._eventHandlers = eventHandlers;
|
|
337
|
+
ctx.tag._delayedSrc = delayedSrc;
|
|
338
|
+
},
|
|
339
|
+
"dom:renderTag": function(ctx) {
|
|
340
|
+
const $el = ctx.$el;
|
|
341
|
+
if (!ctx.tag._eventHandlers || !$el)
|
|
342
|
+
return;
|
|
343
|
+
const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" && typeof window !== "undefined" ? window : $el;
|
|
344
|
+
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
345
|
+
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
|
|
346
|
+
const eventName = k.slice(2).toLowerCase();
|
|
347
|
+
const eventDedupeKey = `data-h-${eventName}`;
|
|
348
|
+
delete ctx.queuedSideEffects[sdeKey];
|
|
349
|
+
if ($el.hasAttribute(eventDedupeKey))
|
|
350
|
+
return;
|
|
351
|
+
const handler = value;
|
|
352
|
+
$el.setAttribute(eventDedupeKey, "");
|
|
353
|
+
$eventListenerTarget.addEventListener(eventName, handler);
|
|
354
|
+
ctx.entry._sde[sdeKey] = () => {
|
|
355
|
+
$eventListenerTarget.removeEventListener(eventName, handler);
|
|
356
|
+
$el.removeAttribute(eventDedupeKey);
|
|
357
|
+
};
|
|
358
|
+
});
|
|
359
|
+
if (ctx.tag._delayedSrc) {
|
|
360
|
+
$el.setAttribute("src", ctx.tag._delayedSrc);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
function asArray$1(value) {
|
|
368
|
+
return Array.isArray(value) ? value : [value];
|
|
369
|
+
}
|
|
370
|
+
function hashCode(s) {
|
|
371
|
+
let h = 9;
|
|
372
|
+
for (let i = 0; i < s.length; )
|
|
373
|
+
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
374
|
+
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 8).toLowerCase();
|
|
375
|
+
}
|
|
376
|
+
const HasElementTags = [
|
|
377
|
+
"base",
|
|
378
|
+
"meta",
|
|
379
|
+
"link",
|
|
380
|
+
"style",
|
|
381
|
+
"script",
|
|
382
|
+
"noscript"
|
|
383
|
+
];
|
|
384
|
+
|
|
385
|
+
let activeHead;
|
|
386
|
+
const setActiveHead = (head) => activeHead = head;
|
|
387
|
+
const getActiveHead = () => activeHead;
|
|
388
|
+
|
|
389
|
+
const TagEntityBits = 10;
|
|
390
|
+
|
|
391
|
+
function normaliseEntryTags(e) {
|
|
392
|
+
return Object.entries(e.input).filter(([k, v]) => typeof v !== "undefined" && ValidHeadTags.includes(k)).map(
|
|
393
|
+
([k, value]) => asArray$1(value).map((props) => asArray$1(normaliseTag(k, props)))
|
|
394
|
+
).flat(3).map((t, i) => {
|
|
395
|
+
t._e = e._i;
|
|
396
|
+
t._p = (e._i << TagEntityBits) + i;
|
|
397
|
+
return t;
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function createHead$1(options = {}) {
|
|
402
|
+
let entries = [];
|
|
403
|
+
let _sde = {};
|
|
404
|
+
let _eid = 0;
|
|
405
|
+
const hooks = hookable.createHooks();
|
|
406
|
+
if (options?.hooks)
|
|
407
|
+
hooks.addHooks(options.hooks);
|
|
408
|
+
options.plugins = [
|
|
409
|
+
DeprecatedTagAttrPlugin(),
|
|
410
|
+
DedupesTagsPlugin(),
|
|
411
|
+
SortTagsPlugin(),
|
|
412
|
+
TitleTemplatePlugin(),
|
|
413
|
+
EventHandlersPlugin(),
|
|
414
|
+
ProvideTagHashPlugin(),
|
|
415
|
+
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
416
|
+
...options?.plugins || []
|
|
417
|
+
];
|
|
418
|
+
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
|
|
419
|
+
const triggerUpdateHook = () => hooks.callHook("entries:updated", head);
|
|
420
|
+
const head = {
|
|
421
|
+
resolvedOptions: options,
|
|
422
|
+
headEntries() {
|
|
423
|
+
return entries;
|
|
424
|
+
},
|
|
425
|
+
get hooks() {
|
|
426
|
+
return hooks;
|
|
427
|
+
},
|
|
428
|
+
push(input, options2) {
|
|
429
|
+
const activeEntry = {
|
|
430
|
+
_i: _eid++,
|
|
431
|
+
input,
|
|
432
|
+
_sde: {}
|
|
433
|
+
};
|
|
434
|
+
if (options2?.mode)
|
|
435
|
+
activeEntry._m = options2?.mode;
|
|
436
|
+
entries.push(activeEntry);
|
|
437
|
+
triggerUpdateHook();
|
|
438
|
+
const queueSideEffects = (e) => {
|
|
439
|
+
_sde = { ..._sde, ...e._sde || {} };
|
|
440
|
+
e._sde = {};
|
|
441
|
+
triggerUpdateHook();
|
|
442
|
+
};
|
|
443
|
+
return {
|
|
444
|
+
dispose() {
|
|
445
|
+
entries = entries.filter((e) => {
|
|
446
|
+
if (e._i !== activeEntry._i)
|
|
447
|
+
return true;
|
|
448
|
+
queueSideEffects(e);
|
|
449
|
+
return false;
|
|
450
|
+
});
|
|
451
|
+
},
|
|
452
|
+
patch(input2) {
|
|
453
|
+
entries = entries.map((e) => {
|
|
454
|
+
if (e._i === activeEntry._i) {
|
|
455
|
+
queueSideEffects(e);
|
|
456
|
+
activeEntry.input = e.input = input2;
|
|
457
|
+
activeEntry._i = e._i = _eid++;
|
|
458
|
+
}
|
|
459
|
+
return e;
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
},
|
|
464
|
+
async resolveTags() {
|
|
465
|
+
const resolveCtx = { tags: [], entries: [...entries] };
|
|
466
|
+
await hooks.callHook("entries:resolve", resolveCtx);
|
|
467
|
+
for (const entry of resolveCtx.entries) {
|
|
468
|
+
for (const tag of normaliseEntryTags(entry)) {
|
|
469
|
+
const tagCtx = { tag, entry };
|
|
470
|
+
await hooks.callHook("tag:normalise", tagCtx);
|
|
471
|
+
resolveCtx.tags.push(tagCtx.tag);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
await hooks.callHook("tags:resolve", resolveCtx);
|
|
475
|
+
return resolveCtx.tags;
|
|
476
|
+
},
|
|
477
|
+
_elMap: {},
|
|
478
|
+
_popSideEffectQueue() {
|
|
479
|
+
const sde = { ..._sde };
|
|
480
|
+
_sde = {};
|
|
481
|
+
return sde;
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
head.hooks.callHook("init", head);
|
|
485
|
+
setActiveHead(head);
|
|
486
|
+
return head;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function defineHeadPlugin(plugin) {
|
|
490
|
+
return plugin;
|
|
491
|
+
}
|
|
492
|
+
const composableNames = [
|
|
493
|
+
"useHead",
|
|
494
|
+
"useTagTitle",
|
|
495
|
+
"useTagBase",
|
|
496
|
+
"useTagMeta",
|
|
497
|
+
"useTagMetaFlat",
|
|
498
|
+
"useTagLink",
|
|
499
|
+
"useTagScript",
|
|
500
|
+
"useTagStyle",
|
|
501
|
+
"useTagNoscript",
|
|
502
|
+
"useHtmlAttrs",
|
|
503
|
+
"useBodyAttrs",
|
|
504
|
+
"useTitleTemplate",
|
|
505
|
+
"useServerHead",
|
|
506
|
+
"useServerTagTitle",
|
|
507
|
+
"useServerTagBase",
|
|
508
|
+
"useServerTagMeta",
|
|
509
|
+
"useServerTagMetaFlat",
|
|
510
|
+
"useServerTagLink",
|
|
511
|
+
"useServerTagScript",
|
|
512
|
+
"useServerTagStyle",
|
|
513
|
+
"useServerTagNoscript",
|
|
514
|
+
"useServerHtmlAttrs",
|
|
515
|
+
"useServerBodyAttrs",
|
|
516
|
+
"useServerTitleTemplate"
|
|
517
|
+
];
|
|
518
|
+
|
|
519
|
+
function resolveUnref(r) {
|
|
520
|
+
return typeof r === "function" ? r() : vue.unref(r);
|
|
521
|
+
}
|
|
522
|
+
function resolveUnrefHeadInput(ref, lastKey = "") {
|
|
523
|
+
const root = resolveUnref(ref);
|
|
10
524
|
if (!ref || !root)
|
|
11
525
|
return root;
|
|
12
526
|
if (Array.isArray(root))
|
|
13
|
-
return root.map(resolveUnrefHeadInput);
|
|
527
|
+
return root.map((r) => resolveUnrefHeadInput(r, lastKey));
|
|
14
528
|
if (typeof root === "object") {
|
|
15
|
-
|
|
529
|
+
const unrefdObj = Object.fromEntries(
|
|
16
530
|
Object.entries(root).map(([key, value]) => {
|
|
17
531
|
if (key === "titleTemplate" || key.startsWith("on"))
|
|
18
532
|
return [key, vue.unref(value)];
|
|
19
|
-
return [key, resolveUnrefHeadInput(value)];
|
|
533
|
+
return [key, resolveUnrefHeadInput(value, key)];
|
|
20
534
|
})
|
|
21
535
|
);
|
|
536
|
+
if (HasElementTags.includes(String(lastKey)) && JSON.stringify(unrefdObj) !== JSON.stringify(root))
|
|
537
|
+
unrefdObj._dynamic = true;
|
|
538
|
+
return unrefdObj;
|
|
22
539
|
}
|
|
23
540
|
return root;
|
|
24
541
|
}
|
|
@@ -31,14 +548,14 @@ const IsBrowser = typeof window !== "undefined";
|
|
|
31
548
|
|
|
32
549
|
const headSymbol = "usehead";
|
|
33
550
|
function injectHead() {
|
|
34
|
-
return vue.getCurrentInstance() && vue.inject(headSymbol) ||
|
|
551
|
+
return vue.getCurrentInstance() && vue.inject(headSymbol) || getActiveHead();
|
|
35
552
|
}
|
|
36
553
|
function createHead(options = {}) {
|
|
37
554
|
const plugins = [
|
|
38
555
|
VueReactiveUseHeadPlugin(),
|
|
39
556
|
...options?.plugins || []
|
|
40
557
|
];
|
|
41
|
-
const head =
|
|
558
|
+
const head = createHead$1({
|
|
42
559
|
...options,
|
|
43
560
|
domDelayFn: (fn) => setTimeout(() => vue.nextTick(() => fn()), 10),
|
|
44
561
|
plugins
|
|
@@ -69,7 +586,7 @@ const VueHeadMixin = {
|
|
|
69
586
|
};
|
|
70
587
|
|
|
71
588
|
const VueReactiveUseHeadPlugin = () => {
|
|
72
|
-
return
|
|
589
|
+
return defineHeadPlugin({
|
|
73
590
|
hooks: {
|
|
74
591
|
"entries:resolve": function(ctx) {
|
|
75
592
|
for (const entry of ctx.entries)
|
|
@@ -313,7 +830,7 @@ const coreComposableNames = [
|
|
|
313
830
|
const unheadVueComposablesImports = [
|
|
314
831
|
{
|
|
315
832
|
from: "@unhead/vue",
|
|
316
|
-
imports: [...coreComposableNames, ...
|
|
833
|
+
imports: [...coreComposableNames, ...composableNames]
|
|
317
834
|
}
|
|
318
835
|
];
|
|
319
836
|
|
|
@@ -350,6 +867,3 @@ exports.useTagScript = useTagScript;
|
|
|
350
867
|
exports.useTagStyle = useTagStyle;
|
|
351
868
|
exports.useTagTitle = useTagTitle;
|
|
352
869
|
exports.useTitleTemplate = useTitleTemplate;
|
|
353
|
-
for (const k in dom) {
|
|
354
|
-
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = dom[k];
|
|
355
|
-
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { MaybeComputedRef, MaybeRef } from '@vueuse/shared';
|
|
2
|
-
export { MaybeComputedRef } from '@vueuse/shared';
|
|
3
1
|
import * as _unhead_schema from '@unhead/schema';
|
|
4
2
|
import { Title as Title$1, TitleTemplate as TitleTemplate$1, EntryAugmentation, Base as Base$1, Link as Link$1, Meta as Meta$1, Style as Style$1, Script as Script$1, Noscript as Noscript$1, DataKeys, SchemaAugmentations, DefinedValueOrEmptyObject, MergeHead, BaseHtmlAttr, MaybeArray, BaseBodyAttr, Unhead, CreateHeadOptions, HeadEntryOptions, MetaFlatInput, ActiveHeadEntry } from '@unhead/schema';
|
|
5
3
|
export { ActiveHeadEntry, Head, HeadEntryOptions, HeadTag, MergeHead, Unhead } from '@unhead/schema';
|
|
6
|
-
import { Plugin } from 'vue';
|
|
7
|
-
export * from '@unhead/dom';
|
|
4
|
+
import { ComputedRef, Ref, Plugin } from 'vue';
|
|
8
5
|
|
|
6
|
+
declare type MaybeReadonlyRef<T> = (() => T) | ComputedRef<T>;
|
|
7
|
+
declare type MaybeComputedRef<T> = T | MaybeReadonlyRef<T> | Ref<T>;
|
|
9
8
|
declare type MaybeComputedRefEntries<T> = MaybeComputedRef<T> | {
|
|
10
9
|
[key in keyof T]?: MaybeComputedRef<T[key]>;
|
|
11
10
|
};
|
|
@@ -28,7 +27,7 @@ interface BodyAttr extends Omit<BaseBodyAttr, 'class'> {
|
|
|
28
27
|
class?: MaybeArray<MaybeComputedRef<string>> | Record<string, MaybeComputedRef<boolean>>;
|
|
29
28
|
}
|
|
30
29
|
declare type Title = MaybeComputedRef<Title$1>;
|
|
31
|
-
declare type TitleTemplate =
|
|
30
|
+
declare type TitleTemplate = TitleTemplate$1 | Ref<TitleTemplate$1> | ((title?: string) => TitleTemplate$1);
|
|
32
31
|
declare type Base<E extends EntryAugmentation = {}> = MaybeComputedRef<MaybeComputedRefEntries<Base$1<E>>>;
|
|
33
32
|
declare type Link<E extends EntryAugmentation = {}> = MaybeComputedRefEntries<Link$1<E>>;
|
|
34
33
|
declare type Meta<E extends EntryAugmentation = {}> = MaybeComputedRefEntries<Meta$1<E>>;
|
|
@@ -105,7 +104,7 @@ interface ReactiveHead<E extends MergeHead = MergeHead> {
|
|
|
105
104
|
}
|
|
106
105
|
declare type UseHeadInput<T extends MergeHead = {}> = MaybeComputedRef<ReactiveHead<T>>;
|
|
107
106
|
|
|
108
|
-
declare function resolveUnrefHeadInput(ref: any): any;
|
|
107
|
+
declare function resolveUnrefHeadInput(ref: any, lastKey?: string | number): any;
|
|
109
108
|
declare function asArray<T>(value: Arrayable<T>): T[];
|
|
110
109
|
|
|
111
110
|
declare type VueHeadClient<T extends MergeHead> = Unhead<MaybeComputedRef<ReactiveHead<T>>> & Plugin;
|
|
@@ -152,4 +151,4 @@ declare const unheadVueComposablesImports: {
|
|
|
152
151
|
imports: string[];
|
|
153
152
|
}[];
|
|
154
153
|
|
|
155
|
-
export { Arrayable, Base, BodyAttributes, HtmlAttributes, Link, MaybeComputedRefEntries, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, Vue2ProvideUnheadPlugin, VueHeadClient, VueHeadMixin, VueReactiveUseHeadPlugin, asArray, createHead, headSymbol, injectHead, resolveUnrefHeadInput, unheadVueComposablesImports, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|
|
154
|
+
export { Arrayable, Base, BodyAttributes, HtmlAttributes, Link, MaybeComputedRef, MaybeComputedRefEntries, MaybeReadonlyRef, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, Vue2ProvideUnheadPlugin, VueHeadClient, VueHeadMixin, VueReactiveUseHeadPlugin, asArray, createHead, headSymbol, injectHead, resolveUnrefHeadInput, unheadVueComposablesImports, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|