unhead 0.4.5 → 0.4.7
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 +33 -24
- package/dist/index.d.ts +2 -3
- package/dist/index.mjs +33 -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";
|
|
@@ -242,7 +259,10 @@ function tagDedupeKey(tag) {
|
|
|
242
259
|
name.push(...["name", "property", "http-equiv"]);
|
|
243
260
|
for (const n of name) {
|
|
244
261
|
if (typeof props[n] !== "undefined") {
|
|
245
|
-
|
|
262
|
+
const val = String(props[n]);
|
|
263
|
+
if (ArrayMetaProperties.findIndex((p) => val.startsWith(p)) !== -1)
|
|
264
|
+
return false;
|
|
265
|
+
return `${tagName}:${n}:${val}`;
|
|
246
266
|
}
|
|
247
267
|
}
|
|
248
268
|
return false;
|
|
@@ -324,13 +344,9 @@ const DedupesTagsPlugin = (options) => {
|
|
|
324
344
|
return;
|
|
325
345
|
} else if (tag._e === dupedTag._e) {
|
|
326
346
|
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
347
|
}
|
|
333
|
-
|
|
348
|
+
const propCount = Object.keys(tag.props).length;
|
|
349
|
+
if ((propCount === 0 || propCount === 1 && typeof tag.props["data-h-key"] !== "undefined") && !tag.children) {
|
|
334
350
|
delete deduping[dedupeKey];
|
|
335
351
|
return;
|
|
336
352
|
}
|
|
@@ -392,23 +408,16 @@ const DeprecatedTagAttrPlugin = () => {
|
|
|
392
408
|
|
|
393
409
|
const IsBrowser = typeof window !== "undefined";
|
|
394
410
|
|
|
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 = () => {
|
|
411
|
+
const ProvideTagHashPlugin = () => {
|
|
402
412
|
return defineHeadPlugin({
|
|
403
413
|
hooks: {
|
|
404
414
|
"tag:normalise": (ctx) => {
|
|
405
415
|
const { tag, entry } = ctx;
|
|
406
|
-
if (!HasElementTags.includes(tag.tag)
|
|
416
|
+
if (!HasElementTags.includes(tag.tag))
|
|
407
417
|
return;
|
|
408
|
-
tag._s = `data-h-${hashCode(tag._d)}`;
|
|
409
418
|
const isBrowser = IsBrowser || getActiveHead()?.resolvedOptions?.document;
|
|
410
|
-
if (!isBrowser &&
|
|
411
|
-
tag.props[
|
|
419
|
+
if (!isBrowser && entry._m === "server" && tag.key)
|
|
420
|
+
tag.props["data-h-key"] = tag._d;
|
|
412
421
|
}
|
|
413
422
|
}
|
|
414
423
|
});
|
|
@@ -445,7 +454,7 @@ const EventHandlersPlugin = () => {
|
|
|
445
454
|
};
|
|
446
455
|
return defineHeadPlugin({
|
|
447
456
|
hooks: {
|
|
448
|
-
"ssr:
|
|
457
|
+
"ssr:render": function(ctx) {
|
|
449
458
|
ctx.tags = ctx.tags.map((tag) => {
|
|
450
459
|
tag.props = stripEventHandlers(tag).props;
|
|
451
460
|
return tag;
|
|
@@ -463,7 +472,7 @@ const EventHandlersPlugin = () => {
|
|
|
463
472
|
if (!ctx.tag._eventHandlers || !$el)
|
|
464
473
|
return;
|
|
465
474
|
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
466
|
-
const sdeKey = `${ctx.tag.
|
|
475
|
+
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
|
|
467
476
|
const eventName = k.slice(2).toLowerCase();
|
|
468
477
|
const handler = value;
|
|
469
478
|
$el?.addEventListener(eventName, handler);
|
|
@@ -587,8 +596,9 @@ function createHead(options = {}) {
|
|
|
587
596
|
DedupesTagsPlugin(),
|
|
588
597
|
SortTagsPlugin(),
|
|
589
598
|
TitleTemplatePlugin(),
|
|
590
|
-
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
591
599
|
EventHandlersPlugin(),
|
|
600
|
+
ProvideTagHashPlugin(),
|
|
601
|
+
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
592
602
|
...options?.plugins || []
|
|
593
603
|
];
|
|
594
604
|
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
|
|
@@ -668,15 +678,14 @@ function defineHeadPlugin(plugin) {
|
|
|
668
678
|
exports.DedupesTagsPlugin = DedupesTagsPlugin;
|
|
669
679
|
exports.DeprecatedTagAttrPlugin = DeprecatedTagAttrPlugin;
|
|
670
680
|
exports.EventHandlersPlugin = EventHandlersPlugin;
|
|
671
|
-
exports.HydrateStateFromSSRPlugin = HydrateStateFromSSRPlugin;
|
|
672
681
|
exports.PatchDomOnEntryUpdatesPlugin = PatchDomOnEntryUpdatesPlugin;
|
|
682
|
+
exports.ProvideTagHashPlugin = ProvideTagHashPlugin;
|
|
673
683
|
exports.SortTagsPlugin = SortTagsPlugin;
|
|
674
684
|
exports.TitleTemplatePlugin = TitleTemplatePlugin;
|
|
675
685
|
exports.asArray = asArray;
|
|
676
686
|
exports.createHead = createHead;
|
|
677
687
|
exports.defineHeadPlugin = defineHeadPlugin;
|
|
678
688
|
exports.getActiveHead = getActiveHead;
|
|
679
|
-
exports.hashCode = hashCode;
|
|
680
689
|
exports.normaliseEntryTags = normaliseEntryTags;
|
|
681
690
|
exports.setActiveHead = setActiveHead;
|
|
682
691
|
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";
|
|
@@ -240,7 +257,10 @@ function tagDedupeKey(tag) {
|
|
|
240
257
|
name.push(...["name", "property", "http-equiv"]);
|
|
241
258
|
for (const n of name) {
|
|
242
259
|
if (typeof props[n] !== "undefined") {
|
|
243
|
-
|
|
260
|
+
const val = String(props[n]);
|
|
261
|
+
if (ArrayMetaProperties.findIndex((p) => val.startsWith(p)) !== -1)
|
|
262
|
+
return false;
|
|
263
|
+
return `${tagName}:${n}:${val}`;
|
|
244
264
|
}
|
|
245
265
|
}
|
|
246
266
|
return false;
|
|
@@ -322,13 +342,9 @@ const DedupesTagsPlugin = (options) => {
|
|
|
322
342
|
return;
|
|
323
343
|
} else if (tag._e === dupedTag._e) {
|
|
324
344
|
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
345
|
}
|
|
331
|
-
|
|
346
|
+
const propCount = Object.keys(tag.props).length;
|
|
347
|
+
if ((propCount === 0 || propCount === 1 && typeof tag.props["data-h-key"] !== "undefined") && !tag.children) {
|
|
332
348
|
delete deduping[dedupeKey];
|
|
333
349
|
return;
|
|
334
350
|
}
|
|
@@ -390,23 +406,16 @@ const DeprecatedTagAttrPlugin = () => {
|
|
|
390
406
|
|
|
391
407
|
const IsBrowser = typeof window !== "undefined";
|
|
392
408
|
|
|
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 = () => {
|
|
409
|
+
const ProvideTagHashPlugin = () => {
|
|
400
410
|
return defineHeadPlugin({
|
|
401
411
|
hooks: {
|
|
402
412
|
"tag:normalise": (ctx) => {
|
|
403
413
|
const { tag, entry } = ctx;
|
|
404
|
-
if (!HasElementTags.includes(tag.tag)
|
|
414
|
+
if (!HasElementTags.includes(tag.tag))
|
|
405
415
|
return;
|
|
406
|
-
tag._s = `data-h-${hashCode(tag._d)}`;
|
|
407
416
|
const isBrowser = IsBrowser || getActiveHead()?.resolvedOptions?.document;
|
|
408
|
-
if (!isBrowser &&
|
|
409
|
-
tag.props[
|
|
417
|
+
if (!isBrowser && entry._m === "server" && tag.key)
|
|
418
|
+
tag.props["data-h-key"] = tag._d;
|
|
410
419
|
}
|
|
411
420
|
}
|
|
412
421
|
});
|
|
@@ -443,7 +452,7 @@ const EventHandlersPlugin = () => {
|
|
|
443
452
|
};
|
|
444
453
|
return defineHeadPlugin({
|
|
445
454
|
hooks: {
|
|
446
|
-
"ssr:
|
|
455
|
+
"ssr:render": function(ctx) {
|
|
447
456
|
ctx.tags = ctx.tags.map((tag) => {
|
|
448
457
|
tag.props = stripEventHandlers(tag).props;
|
|
449
458
|
return tag;
|
|
@@ -461,7 +470,7 @@ const EventHandlersPlugin = () => {
|
|
|
461
470
|
if (!ctx.tag._eventHandlers || !$el)
|
|
462
471
|
return;
|
|
463
472
|
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
464
|
-
const sdeKey = `${ctx.tag.
|
|
473
|
+
const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
|
|
465
474
|
const eventName = k.slice(2).toLowerCase();
|
|
466
475
|
const handler = value;
|
|
467
476
|
$el?.addEventListener(eventName, handler);
|
|
@@ -585,8 +594,9 @@ function createHead(options = {}) {
|
|
|
585
594
|
DedupesTagsPlugin(),
|
|
586
595
|
SortTagsPlugin(),
|
|
587
596
|
TitleTemplatePlugin(),
|
|
588
|
-
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
589
597
|
EventHandlersPlugin(),
|
|
598
|
+
ProvideTagHashPlugin(),
|
|
599
|
+
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
590
600
|
...options?.plugins || []
|
|
591
601
|
];
|
|
592
602
|
options.plugins.forEach((p) => p.hooks && hooks.addHooks(p.hooks));
|
|
@@ -663,4 +673,4 @@ function defineHeadPlugin(plugin) {
|
|
|
663
673
|
return plugin;
|
|
664
674
|
}
|
|
665
675
|
|
|
666
|
-
export { DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin,
|
|
676
|
+
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.7",
|
|
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.7",
|
|
34
|
+
"@unhead/schema": "0.4.7",
|
|
35
35
|
"hookable": "^5.4.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"zhead": "1.0.0-beta.
|
|
38
|
+
"zhead": "1.0.0-beta.13"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "unbuild .",
|