unhead 0.4.5 → 0.4.6
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 +30 -24
- package/dist/index.d.ts +2 -3
- package/dist/index.mjs +30 -23
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -229,9 +229,26 @@ const sortTags = (aTag, bTag) => {
|
|
|
229
229
|
return tagWeight(aTag) - tagWeight(bTag);
|
|
230
230
|
};
|
|
231
231
|
|
|
232
|
+
const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
|
|
233
|
+
const ArrayMetaProperties = [
|
|
234
|
+
"og:image",
|
|
235
|
+
"og:video",
|
|
236
|
+
"og:audio",
|
|
237
|
+
"og:locale:alternate",
|
|
238
|
+
"video:actor",
|
|
239
|
+
"video:director",
|
|
240
|
+
"video:writer",
|
|
241
|
+
"video:tag",
|
|
242
|
+
"article:author",
|
|
243
|
+
"article:tag",
|
|
244
|
+
"book:tag",
|
|
245
|
+
"book:author",
|
|
246
|
+
"music:album",
|
|
247
|
+
"music:musician"
|
|
248
|
+
];
|
|
232
249
|
function tagDedupeKey(tag) {
|
|
233
250
|
const { props, tag: tagName } = tag;
|
|
234
|
-
if (
|
|
251
|
+
if (UniqueTags.includes(tagName))
|
|
235
252
|
return tagName;
|
|
236
253
|
if (tagName === "link" && props.rel === "canonical")
|
|
237
254
|
return "canonical";
|
|
@@ -241,7 +258,7 @@ function tagDedupeKey(tag) {
|
|
|
241
258
|
if (tagName === "meta")
|
|
242
259
|
name.push(...["name", "property", "http-equiv"]);
|
|
243
260
|
for (const n of name) {
|
|
244
|
-
if (typeof props[n] !== "undefined") {
|
|
261
|
+
if (typeof props[n] !== "undefined" && !ArrayMetaProperties.findIndex((p) => !props[n].startsWith(p))) {
|
|
245
262
|
return `${tagName}:${n}:${props[n]}`;
|
|
246
263
|
}
|
|
247
264
|
}
|
|
@@ -324,13 +341,9 @@ const DedupesTagsPlugin = (options) => {
|
|
|
324
341
|
return;
|
|
325
342
|
} else if (tag._e === dupedTag._e) {
|
|
326
343
|
dedupeKey = tag._d = `${dedupeKey}:${tag._p}`;
|
|
327
|
-
if (dupedTag._s && typeof dupedTag.props[dupedTag._s] !== "undefined") {
|
|
328
|
-
delete tag.props[dupedTag._s];
|
|
329
|
-
tag._s = `${dupedTag._s}${tag._p}`;
|
|
330
|
-
tag.props[tag._s] = "";
|
|
331
|
-
}
|
|
332
344
|
}
|
|
333
|
-
|
|
345
|
+
const propCount = Object.keys(tag.props).length;
|
|
346
|
+
if ((propCount === 0 || propCount === 1 && typeof tag.props["data-h-key"] !== "undefined") && !tag.children) {
|
|
334
347
|
delete deduping[dedupeKey];
|
|
335
348
|
return;
|
|
336
349
|
}
|
|
@@ -392,23 +405,16 @@ const DeprecatedTagAttrPlugin = () => {
|
|
|
392
405
|
|
|
393
406
|
const IsBrowser = typeof window !== "undefined";
|
|
394
407
|
|
|
395
|
-
|
|
396
|
-
let h = 9;
|
|
397
|
-
for (let i = 0; i < s.length; )
|
|
398
|
-
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
399
|
-
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 7).toLowerCase();
|
|
400
|
-
}
|
|
401
|
-
const HydrateStateFromSSRPlugin = () => {
|
|
408
|
+
const ProvideTagHashPlugin = () => {
|
|
402
409
|
return defineHeadPlugin({
|
|
403
410
|
hooks: {
|
|
404
411
|
"tag:normalise": (ctx) => {
|
|
405
412
|
const { tag, entry } = ctx;
|
|
406
|
-
if (!HasElementTags.includes(tag.tag)
|
|
413
|
+
if (!HasElementTags.includes(tag.tag))
|
|
407
414
|
return;
|
|
408
|
-
tag._s = `data-h-${hashCode(tag._d)}`;
|
|
409
415
|
const isBrowser = IsBrowser || getActiveHead()?.resolvedOptions?.document;
|
|
410
|
-
if (!isBrowser &&
|
|
411
|
-
tag.props[
|
|
416
|
+
if (!isBrowser && entry._m === "server" && tag.key)
|
|
417
|
+
tag.props["data-h-key"] = tag._d;
|
|
412
418
|
}
|
|
413
419
|
}
|
|
414
420
|
});
|
|
@@ -445,7 +451,7 @@ const EventHandlersPlugin = () => {
|
|
|
445
451
|
};
|
|
446
452
|
return defineHeadPlugin({
|
|
447
453
|
hooks: {
|
|
448
|
-
"ssr:
|
|
454
|
+
"ssr:render": function(ctx) {
|
|
449
455
|
ctx.tags = ctx.tags.map((tag) => {
|
|
450
456
|
tag.props = stripEventHandlers(tag).props;
|
|
451
457
|
return tag;
|
|
@@ -463,7 +469,7 @@ const EventHandlersPlugin = () => {
|
|
|
463
469
|
if (!ctx.tag._eventHandlers || !$el)
|
|
464
470
|
return;
|
|
465
471
|
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
466
|
-
const sdeKey = `${ctx.tag.
|
|
472
|
+
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
|
|
467
473
|
const eventName = k.slice(2).toLowerCase();
|
|
468
474
|
const handler = value;
|
|
469
475
|
$el?.addEventListener(eventName, handler);
|
|
@@ -587,8 +593,9 @@ function createHead(options = {}) {
|
|
|
587
593
|
DedupesTagsPlugin(),
|
|
588
594
|
SortTagsPlugin(),
|
|
589
595
|
TitleTemplatePlugin(),
|
|
590
|
-
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
591
596
|
EventHandlersPlugin(),
|
|
597
|
+
ProvideTagHashPlugin(),
|
|
598
|
+
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
592
599
|
...options?.plugins || []
|
|
593
600
|
];
|
|
594
601
|
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
|
|
@@ -668,15 +675,14 @@ function defineHeadPlugin(plugin) {
|
|
|
668
675
|
exports.DedupesTagsPlugin = DedupesTagsPlugin;
|
|
669
676
|
exports.DeprecatedTagAttrPlugin = DeprecatedTagAttrPlugin;
|
|
670
677
|
exports.EventHandlersPlugin = EventHandlersPlugin;
|
|
671
|
-
exports.HydrateStateFromSSRPlugin = HydrateStateFromSSRPlugin;
|
|
672
678
|
exports.PatchDomOnEntryUpdatesPlugin = PatchDomOnEntryUpdatesPlugin;
|
|
679
|
+
exports.ProvideTagHashPlugin = ProvideTagHashPlugin;
|
|
673
680
|
exports.SortTagsPlugin = SortTagsPlugin;
|
|
674
681
|
exports.TitleTemplatePlugin = TitleTemplatePlugin;
|
|
675
682
|
exports.asArray = asArray;
|
|
676
683
|
exports.createHead = createHead;
|
|
677
684
|
exports.defineHeadPlugin = defineHeadPlugin;
|
|
678
685
|
exports.getActiveHead = getActiveHead;
|
|
679
|
-
exports.hashCode = hashCode;
|
|
680
686
|
exports.normaliseEntryTags = normaliseEntryTags;
|
|
681
687
|
exports.setActiveHead = setActiveHead;
|
|
682
688
|
exports.useBodyAttrs = useBodyAttrs;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,8 +13,7 @@ declare const TitleTemplatePlugin: () => _unhead_schema.HeadPlugin;
|
|
|
13
13
|
|
|
14
14
|
declare const DeprecatedTagAttrPlugin: () => _unhead_schema.HeadPlugin;
|
|
15
15
|
|
|
16
|
-
declare
|
|
17
|
-
declare const HydrateStateFromSSRPlugin: () => _unhead_schema.HeadPlugin;
|
|
16
|
+
declare const ProvideTagHashPlugin: () => _unhead_schema.HeadPlugin;
|
|
18
17
|
|
|
19
18
|
interface TriggerDomPatchingOnUpdatesPluginOptions extends RenderDomHeadOptions {
|
|
20
19
|
delayFn?: (fn: () => void) => void;
|
|
@@ -67,4 +66,4 @@ declare function defineHeadPlugin(plugin: HeadPlugin): HeadPlugin;
|
|
|
67
66
|
|
|
68
67
|
declare function normaliseEntryTags<T extends {} = Head>(e: HeadEntry<T>): HeadTag[];
|
|
69
68
|
|
|
70
|
-
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, EventHandlersPlugin,
|
|
69
|
+
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, EventHandlersPlugin, PatchDomOnEntryUpdatesPlugin, ProvideTagHashPlugin, SortTagsPlugin, TitleTemplatePlugin, activeHead, asArray, createHead, defineHeadPlugin, getActiveHead, normaliseEntryTags, setActiveHead, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|
package/dist/index.mjs
CHANGED
|
@@ -227,9 +227,26 @@ const sortTags = (aTag, bTag) => {
|
|
|
227
227
|
return tagWeight(aTag) - tagWeight(bTag);
|
|
228
228
|
};
|
|
229
229
|
|
|
230
|
+
const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
|
|
231
|
+
const ArrayMetaProperties = [
|
|
232
|
+
"og:image",
|
|
233
|
+
"og:video",
|
|
234
|
+
"og:audio",
|
|
235
|
+
"og:locale:alternate",
|
|
236
|
+
"video:actor",
|
|
237
|
+
"video:director",
|
|
238
|
+
"video:writer",
|
|
239
|
+
"video:tag",
|
|
240
|
+
"article:author",
|
|
241
|
+
"article:tag",
|
|
242
|
+
"book:tag",
|
|
243
|
+
"book:author",
|
|
244
|
+
"music:album",
|
|
245
|
+
"music:musician"
|
|
246
|
+
];
|
|
230
247
|
function tagDedupeKey(tag) {
|
|
231
248
|
const { props, tag: tagName } = tag;
|
|
232
|
-
if (
|
|
249
|
+
if (UniqueTags.includes(tagName))
|
|
233
250
|
return tagName;
|
|
234
251
|
if (tagName === "link" && props.rel === "canonical")
|
|
235
252
|
return "canonical";
|
|
@@ -239,7 +256,7 @@ function tagDedupeKey(tag) {
|
|
|
239
256
|
if (tagName === "meta")
|
|
240
257
|
name.push(...["name", "property", "http-equiv"]);
|
|
241
258
|
for (const n of name) {
|
|
242
|
-
if (typeof props[n] !== "undefined") {
|
|
259
|
+
if (typeof props[n] !== "undefined" && !ArrayMetaProperties.findIndex((p) => !props[n].startsWith(p))) {
|
|
243
260
|
return `${tagName}:${n}:${props[n]}`;
|
|
244
261
|
}
|
|
245
262
|
}
|
|
@@ -322,13 +339,9 @@ const DedupesTagsPlugin = (options) => {
|
|
|
322
339
|
return;
|
|
323
340
|
} else if (tag._e === dupedTag._e) {
|
|
324
341
|
dedupeKey = tag._d = `${dedupeKey}:${tag._p}`;
|
|
325
|
-
if (dupedTag._s && typeof dupedTag.props[dupedTag._s] !== "undefined") {
|
|
326
|
-
delete tag.props[dupedTag._s];
|
|
327
|
-
tag._s = `${dupedTag._s}${tag._p}`;
|
|
328
|
-
tag.props[tag._s] = "";
|
|
329
|
-
}
|
|
330
342
|
}
|
|
331
|
-
|
|
343
|
+
const propCount = Object.keys(tag.props).length;
|
|
344
|
+
if ((propCount === 0 || propCount === 1 && typeof tag.props["data-h-key"] !== "undefined") && !tag.children) {
|
|
332
345
|
delete deduping[dedupeKey];
|
|
333
346
|
return;
|
|
334
347
|
}
|
|
@@ -390,23 +403,16 @@ const DeprecatedTagAttrPlugin = () => {
|
|
|
390
403
|
|
|
391
404
|
const IsBrowser = typeof window !== "undefined";
|
|
392
405
|
|
|
393
|
-
|
|
394
|
-
let h = 9;
|
|
395
|
-
for (let i = 0; i < s.length; )
|
|
396
|
-
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
397
|
-
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 7).toLowerCase();
|
|
398
|
-
}
|
|
399
|
-
const HydrateStateFromSSRPlugin = () => {
|
|
406
|
+
const ProvideTagHashPlugin = () => {
|
|
400
407
|
return defineHeadPlugin({
|
|
401
408
|
hooks: {
|
|
402
409
|
"tag:normalise": (ctx) => {
|
|
403
410
|
const { tag, entry } = ctx;
|
|
404
|
-
if (!HasElementTags.includes(tag.tag)
|
|
411
|
+
if (!HasElementTags.includes(tag.tag))
|
|
405
412
|
return;
|
|
406
|
-
tag._s = `data-h-${hashCode(tag._d)}`;
|
|
407
413
|
const isBrowser = IsBrowser || getActiveHead()?.resolvedOptions?.document;
|
|
408
|
-
if (!isBrowser &&
|
|
409
|
-
tag.props[
|
|
414
|
+
if (!isBrowser && entry._m === "server" && tag.key)
|
|
415
|
+
tag.props["data-h-key"] = tag._d;
|
|
410
416
|
}
|
|
411
417
|
}
|
|
412
418
|
});
|
|
@@ -443,7 +449,7 @@ const EventHandlersPlugin = () => {
|
|
|
443
449
|
};
|
|
444
450
|
return defineHeadPlugin({
|
|
445
451
|
hooks: {
|
|
446
|
-
"ssr:
|
|
452
|
+
"ssr:render": function(ctx) {
|
|
447
453
|
ctx.tags = ctx.tags.map((tag) => {
|
|
448
454
|
tag.props = stripEventHandlers(tag).props;
|
|
449
455
|
return tag;
|
|
@@ -461,7 +467,7 @@ const EventHandlersPlugin = () => {
|
|
|
461
467
|
if (!ctx.tag._eventHandlers || !$el)
|
|
462
468
|
return;
|
|
463
469
|
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
464
|
-
const sdeKey = `${ctx.tag.
|
|
470
|
+
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
|
|
465
471
|
const eventName = k.slice(2).toLowerCase();
|
|
466
472
|
const handler = value;
|
|
467
473
|
$el?.addEventListener(eventName, handler);
|
|
@@ -585,8 +591,9 @@ function createHead(options = {}) {
|
|
|
585
591
|
DedupesTagsPlugin(),
|
|
586
592
|
SortTagsPlugin(),
|
|
587
593
|
TitleTemplatePlugin(),
|
|
588
|
-
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
589
594
|
EventHandlersPlugin(),
|
|
595
|
+
ProvideTagHashPlugin(),
|
|
596
|
+
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
590
597
|
...options?.plugins || []
|
|
591
598
|
];
|
|
592
599
|
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
|
|
@@ -663,4 +670,4 @@ function defineHeadPlugin(plugin) {
|
|
|
663
670
|
return plugin;
|
|
664
671
|
}
|
|
665
672
|
|
|
666
|
-
export { DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin,
|
|
673
|
+
export { DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, PatchDomOnEntryUpdatesPlugin, ProvideTagHashPlugin, SortTagsPlugin, TitleTemplatePlugin, activeHead, asArray, createHead, defineHeadPlugin, getActiveHead, normaliseEntryTags, setActiveHead, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unhead",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.6",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@unhead/dom": "0.4.
|
|
34
|
-
"@unhead/schema": "0.4.
|
|
33
|
+
"@unhead/dom": "0.4.6",
|
|
34
|
+
"@unhead/schema": "0.4.6",
|
|
35
35
|
"hookable": "^5.4.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"zhead": "1.0.0-beta.
|
|
38
|
+
"zhead": "1.0.0-beta.12"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "unbuild .",
|