unhead 0.2.7 → 0.4.1
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 +61 -15
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +61 -16
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -311,8 +311,11 @@ const DedupesTagsPlugin = (options) => {
|
|
|
311
311
|
if (strategy === "merge") {
|
|
312
312
|
const oldProps = dupedTag.props;
|
|
313
313
|
["class", "style"].forEach((key) => {
|
|
314
|
-
if (tag.props[key] && oldProps[key])
|
|
314
|
+
if (tag.props[key] && oldProps[key]) {
|
|
315
|
+
if (key === "style" && !oldProps[key].endsWith(";"))
|
|
316
|
+
oldProps[key] += ";";
|
|
315
317
|
tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
|
|
318
|
+
}
|
|
316
319
|
});
|
|
317
320
|
deduping[dedupeKey].props = {
|
|
318
321
|
...oldProps,
|
|
@@ -327,8 +330,6 @@ const DedupesTagsPlugin = (options) => {
|
|
|
327
330
|
tag.props[tag._s] = "";
|
|
328
331
|
}
|
|
329
332
|
tag._d = dedupeKey;
|
|
330
|
-
} else {
|
|
331
|
-
tag._p = dupedTag._p;
|
|
332
333
|
}
|
|
333
334
|
if (Object.keys(tag.props).length === 0 && !tag.children) {
|
|
334
335
|
delete deduping[dedupeKey];
|
|
@@ -406,18 +407,13 @@ const HydratesStatePlugin = () => {
|
|
|
406
407
|
return;
|
|
407
408
|
if (typeof tag._d === "undefined" && entry._m === "server")
|
|
408
409
|
return;
|
|
409
|
-
|
|
410
|
-
tag._s = `data-h-${hashCode(tag._d || tag.tag + (hasChildren ? tag.children : JSON.stringify(tag.props)))}`;
|
|
410
|
+
tag._s = `data-h-${hashCode(tag._d || JSON.stringify({ tag: tag.tag, props: tag.props, children: tag.children }))}`;
|
|
411
411
|
tag.props[tag._s] = "";
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
414
|
});
|
|
415
415
|
};
|
|
416
416
|
|
|
417
|
-
function defineHeadPlugin(plugin) {
|
|
418
|
-
return plugin;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
417
|
const PatchDomOnEntryUpdatesPlugin = (options) => {
|
|
422
418
|
return defineHeadPlugin({
|
|
423
419
|
hooks: {
|
|
@@ -435,6 +431,52 @@ const PatchDomOnEntryUpdatesPlugin = (options) => {
|
|
|
435
431
|
});
|
|
436
432
|
};
|
|
437
433
|
|
|
434
|
+
const EventHandlersPlugin = () => {
|
|
435
|
+
const stripEventHandlers = (tag) => {
|
|
436
|
+
const props = {};
|
|
437
|
+
const eventHandlers = {};
|
|
438
|
+
Object.entries(tag.props).forEach(([key, value]) => {
|
|
439
|
+
if (key.startsWith("on") && typeof value === "function")
|
|
440
|
+
eventHandlers[key] = value;
|
|
441
|
+
else
|
|
442
|
+
props[key] = value;
|
|
443
|
+
});
|
|
444
|
+
return { props, eventHandlers };
|
|
445
|
+
};
|
|
446
|
+
return defineHeadPlugin({
|
|
447
|
+
hooks: {
|
|
448
|
+
"ssr:beforeRender": function(ctx) {
|
|
449
|
+
ctx.tags = ctx.tags.map((tag) => {
|
|
450
|
+
tag.props = stripEventHandlers(tag).props;
|
|
451
|
+
return tag;
|
|
452
|
+
});
|
|
453
|
+
},
|
|
454
|
+
"dom:beforeRenderTag": function(ctx) {
|
|
455
|
+
const { props, eventHandlers } = stripEventHandlers(ctx.tag);
|
|
456
|
+
if (!Object.keys(eventHandlers).length)
|
|
457
|
+
return;
|
|
458
|
+
ctx.tag.props = props;
|
|
459
|
+
ctx.tag._eventHandlers = eventHandlers;
|
|
460
|
+
},
|
|
461
|
+
"dom:renderTag": function(ctx) {
|
|
462
|
+
const $el = ctx.$el;
|
|
463
|
+
if (!ctx.tag._eventHandlers || !$el)
|
|
464
|
+
return;
|
|
465
|
+
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
466
|
+
const sdeKey = `${ctx.tag._s || ctx.tag._p}:${k}`;
|
|
467
|
+
const eventName = k.slice(2).toLowerCase();
|
|
468
|
+
const handler = value;
|
|
469
|
+
$el?.addEventListener(eventName, handler);
|
|
470
|
+
ctx.entry._sde[sdeKey] = () => {
|
|
471
|
+
$el.removeEventListener(eventName, handler);
|
|
472
|
+
};
|
|
473
|
+
delete ctx.queuedSideEffects[sdeKey];
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
};
|
|
479
|
+
|
|
438
480
|
function asArray(value) {
|
|
439
481
|
return Array.isArray(value) ? value : [value];
|
|
440
482
|
}
|
|
@@ -544,18 +586,17 @@ function createHead(options = {}) {
|
|
|
544
586
|
DedupesTagsPlugin(),
|
|
545
587
|
SortTagsPlugin(),
|
|
546
588
|
TitleTemplatePlugin(),
|
|
547
|
-
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn })
|
|
589
|
+
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
590
|
+
EventHandlersPlugin()
|
|
548
591
|
];
|
|
549
592
|
plugins.push(...options.plugins || []);
|
|
550
593
|
plugins.forEach((plugin) => hooks.addHooks(plugin.hooks || {}));
|
|
551
594
|
const triggerUpdate = () => hooks.callHook("entries:updated", head);
|
|
552
595
|
const head = {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
},
|
|
556
|
-
_flushQueuedSideEffects() {
|
|
557
|
-
Object.values(_sde).forEach((fn) => fn());
|
|
596
|
+
_popSideEffectQueue() {
|
|
597
|
+
const sde = { ..._sde };
|
|
558
598
|
_sde = {};
|
|
599
|
+
return sde;
|
|
559
600
|
},
|
|
560
601
|
headEntries() {
|
|
561
602
|
return entries;
|
|
@@ -616,8 +657,13 @@ function createHead(options = {}) {
|
|
|
616
657
|
return head;
|
|
617
658
|
}
|
|
618
659
|
|
|
660
|
+
function defineHeadPlugin(plugin) {
|
|
661
|
+
return plugin;
|
|
662
|
+
}
|
|
663
|
+
|
|
619
664
|
exports.DedupesTagsPlugin = DedupesTagsPlugin;
|
|
620
665
|
exports.DeprecatedTagAttrPlugin = DeprecatedTagAttrPlugin;
|
|
666
|
+
exports.EventHandlersPlugin = EventHandlersPlugin;
|
|
621
667
|
exports.HydratesStatePlugin = HydratesStatePlugin;
|
|
622
668
|
exports.PatchDomOnEntryUpdatesPlugin = PatchDomOnEntryUpdatesPlugin;
|
|
623
669
|
exports.SortTagsPlugin = SortTagsPlugin;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,13 @@ interface TriggerDomPatchingOnUpdatesPluginOptions extends RenderDomHeadOptions
|
|
|
20
20
|
}
|
|
21
21
|
declare const PatchDomOnEntryUpdatesPlugin: (options?: TriggerDomPatchingOnUpdatesPluginOptions) => _unhead_schema.HeadPlugin;
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Supports DOM event handlers (i.e `onload`) as functions.
|
|
25
|
+
*
|
|
26
|
+
* When SSR we need to strip out these values. On CSR we
|
|
27
|
+
*/
|
|
28
|
+
declare const EventHandlersPlugin: () => _unhead_schema.HeadPlugin;
|
|
29
|
+
|
|
23
30
|
declare type Arrayable<T> = T | Array<T>;
|
|
24
31
|
declare function asArray<T>(value: Arrayable<T>): T[];
|
|
25
32
|
|
|
@@ -59,4 +66,4 @@ declare function defineHeadPlugin(plugin: HeadPlugin): HeadPlugin;
|
|
|
59
66
|
|
|
60
67
|
declare function normaliseEntryTags<T extends {} = Head>(e: HeadEntry<T>): HeadTag[];
|
|
61
68
|
|
|
62
|
-
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, HydratesStatePlugin, PatchDomOnEntryUpdatesPlugin, 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 };
|
|
69
|
+
export { Arrayable, DedupesTagsPlugin, DedupesTagsPluginOptions, DeprecatedTagAttrPlugin, EventHandlersPlugin, HydratesStatePlugin, PatchDomOnEntryUpdatesPlugin, 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
|
@@ -309,8 +309,11 @@ const DedupesTagsPlugin = (options) => {
|
|
|
309
309
|
if (strategy === "merge") {
|
|
310
310
|
const oldProps = dupedTag.props;
|
|
311
311
|
["class", "style"].forEach((key) => {
|
|
312
|
-
if (tag.props[key] && oldProps[key])
|
|
312
|
+
if (tag.props[key] && oldProps[key]) {
|
|
313
|
+
if (key === "style" && !oldProps[key].endsWith(";"))
|
|
314
|
+
oldProps[key] += ";";
|
|
313
315
|
tag.props[key] = `${oldProps[key]} ${tag.props[key]}`;
|
|
316
|
+
}
|
|
314
317
|
});
|
|
315
318
|
deduping[dedupeKey].props = {
|
|
316
319
|
...oldProps,
|
|
@@ -325,8 +328,6 @@ const DedupesTagsPlugin = (options) => {
|
|
|
325
328
|
tag.props[tag._s] = "";
|
|
326
329
|
}
|
|
327
330
|
tag._d = dedupeKey;
|
|
328
|
-
} else {
|
|
329
|
-
tag._p = dupedTag._p;
|
|
330
331
|
}
|
|
331
332
|
if (Object.keys(tag.props).length === 0 && !tag.children) {
|
|
332
333
|
delete deduping[dedupeKey];
|
|
@@ -404,18 +405,13 @@ const HydratesStatePlugin = () => {
|
|
|
404
405
|
return;
|
|
405
406
|
if (typeof tag._d === "undefined" && entry._m === "server")
|
|
406
407
|
return;
|
|
407
|
-
|
|
408
|
-
tag._s = `data-h-${hashCode(tag._d || tag.tag + (hasChildren ? tag.children : JSON.stringify(tag.props)))}`;
|
|
408
|
+
tag._s = `data-h-${hashCode(tag._d || JSON.stringify({ tag: tag.tag, props: tag.props, children: tag.children }))}`;
|
|
409
409
|
tag.props[tag._s] = "";
|
|
410
410
|
}
|
|
411
411
|
}
|
|
412
412
|
});
|
|
413
413
|
};
|
|
414
414
|
|
|
415
|
-
function defineHeadPlugin(plugin) {
|
|
416
|
-
return plugin;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
415
|
const PatchDomOnEntryUpdatesPlugin = (options) => {
|
|
420
416
|
return defineHeadPlugin({
|
|
421
417
|
hooks: {
|
|
@@ -433,6 +429,52 @@ const PatchDomOnEntryUpdatesPlugin = (options) => {
|
|
|
433
429
|
});
|
|
434
430
|
};
|
|
435
431
|
|
|
432
|
+
const EventHandlersPlugin = () => {
|
|
433
|
+
const stripEventHandlers = (tag) => {
|
|
434
|
+
const props = {};
|
|
435
|
+
const eventHandlers = {};
|
|
436
|
+
Object.entries(tag.props).forEach(([key, value]) => {
|
|
437
|
+
if (key.startsWith("on") && typeof value === "function")
|
|
438
|
+
eventHandlers[key] = value;
|
|
439
|
+
else
|
|
440
|
+
props[key] = value;
|
|
441
|
+
});
|
|
442
|
+
return { props, eventHandlers };
|
|
443
|
+
};
|
|
444
|
+
return defineHeadPlugin({
|
|
445
|
+
hooks: {
|
|
446
|
+
"ssr:beforeRender": function(ctx) {
|
|
447
|
+
ctx.tags = ctx.tags.map((tag) => {
|
|
448
|
+
tag.props = stripEventHandlers(tag).props;
|
|
449
|
+
return tag;
|
|
450
|
+
});
|
|
451
|
+
},
|
|
452
|
+
"dom:beforeRenderTag": function(ctx) {
|
|
453
|
+
const { props, eventHandlers } = stripEventHandlers(ctx.tag);
|
|
454
|
+
if (!Object.keys(eventHandlers).length)
|
|
455
|
+
return;
|
|
456
|
+
ctx.tag.props = props;
|
|
457
|
+
ctx.tag._eventHandlers = eventHandlers;
|
|
458
|
+
},
|
|
459
|
+
"dom:renderTag": function(ctx) {
|
|
460
|
+
const $el = ctx.$el;
|
|
461
|
+
if (!ctx.tag._eventHandlers || !$el)
|
|
462
|
+
return;
|
|
463
|
+
Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
|
|
464
|
+
const sdeKey = `${ctx.tag._s || ctx.tag._p}:${k}`;
|
|
465
|
+
const eventName = k.slice(2).toLowerCase();
|
|
466
|
+
const handler = value;
|
|
467
|
+
$el?.addEventListener(eventName, handler);
|
|
468
|
+
ctx.entry._sde[sdeKey] = () => {
|
|
469
|
+
$el.removeEventListener(eventName, handler);
|
|
470
|
+
};
|
|
471
|
+
delete ctx.queuedSideEffects[sdeKey];
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
};
|
|
477
|
+
|
|
436
478
|
function asArray(value) {
|
|
437
479
|
return Array.isArray(value) ? value : [value];
|
|
438
480
|
}
|
|
@@ -542,18 +584,17 @@ function createHead(options = {}) {
|
|
|
542
584
|
DedupesTagsPlugin(),
|
|
543
585
|
SortTagsPlugin(),
|
|
544
586
|
TitleTemplatePlugin(),
|
|
545
|
-
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn })
|
|
587
|
+
PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
|
|
588
|
+
EventHandlersPlugin()
|
|
546
589
|
];
|
|
547
590
|
plugins.push(...options.plugins || []);
|
|
548
591
|
plugins.forEach((plugin) => hooks.addHooks(plugin.hooks || {}));
|
|
549
592
|
const triggerUpdate = () => hooks.callHook("entries:updated", head);
|
|
550
593
|
const head = {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
},
|
|
554
|
-
_flushQueuedSideEffects() {
|
|
555
|
-
Object.values(_sde).forEach((fn) => fn());
|
|
594
|
+
_popSideEffectQueue() {
|
|
595
|
+
const sde = { ..._sde };
|
|
556
596
|
_sde = {};
|
|
597
|
+
return sde;
|
|
557
598
|
},
|
|
558
599
|
headEntries() {
|
|
559
600
|
return entries;
|
|
@@ -614,4 +655,8 @@ function createHead(options = {}) {
|
|
|
614
655
|
return head;
|
|
615
656
|
}
|
|
616
657
|
|
|
617
|
-
|
|
658
|
+
function defineHeadPlugin(plugin) {
|
|
659
|
+
return plugin;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
export { DedupesTagsPlugin, DeprecatedTagAttrPlugin, EventHandlersPlugin, HydratesStatePlugin, PatchDomOnEntryUpdatesPlugin, 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
|
+
"version": "0.4.1",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,11 +30,12 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@unhead/
|
|
33
|
+
"@unhead/dom": "0.4.1",
|
|
34
|
+
"@unhead/schema": "0.4.1",
|
|
34
35
|
"hookable": "^5.4.1"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"zhead": "1.0.0-beta.
|
|
38
|
+
"zhead": "1.0.0-beta.11"
|
|
38
39
|
},
|
|
39
40
|
"scripts": {
|
|
40
41
|
"build": "unbuild .",
|