unhead 0.3.1 → 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 CHANGED
@@ -431,6 +431,52 @@ const PatchDomOnEntryUpdatesPlugin = (options) => {
431
431
  });
432
432
  };
433
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
+
434
480
  function asArray(value) {
435
481
  return Array.isArray(value) ? value : [value];
436
482
  }
@@ -540,7 +586,8 @@ function createHead(options = {}) {
540
586
  DedupesTagsPlugin(),
541
587
  SortTagsPlugin(),
542
588
  TitleTemplatePlugin(),
543
- PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn })
589
+ PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
590
+ EventHandlersPlugin()
544
591
  ];
545
592
  plugins.push(...options.plugins || []);
546
593
  plugins.forEach((plugin) => hooks.addHooks(plugin.hooks || {}));
@@ -616,6 +663,7 @@ function defineHeadPlugin(plugin) {
616
663
 
617
664
  exports.DedupesTagsPlugin = DedupesTagsPlugin;
618
665
  exports.DeprecatedTagAttrPlugin = DeprecatedTagAttrPlugin;
666
+ exports.EventHandlersPlugin = EventHandlersPlugin;
619
667
  exports.HydratesStatePlugin = HydratesStatePlugin;
620
668
  exports.PatchDomOnEntryUpdatesPlugin = PatchDomOnEntryUpdatesPlugin;
621
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
@@ -429,6 +429,52 @@ const PatchDomOnEntryUpdatesPlugin = (options) => {
429
429
  });
430
430
  };
431
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
+
432
478
  function asArray(value) {
433
479
  return Array.isArray(value) ? value : [value];
434
480
  }
@@ -538,7 +584,8 @@ function createHead(options = {}) {
538
584
  DedupesTagsPlugin(),
539
585
  SortTagsPlugin(),
540
586
  TitleTemplatePlugin(),
541
- PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn })
587
+ PatchDomOnEntryUpdatesPlugin({ document: options?.document, delayFn: options?.domDelayFn }),
588
+ EventHandlersPlugin()
542
589
  ];
543
590
  plugins.push(...options.plugins || []);
544
591
  plugins.forEach((plugin) => hooks.addHooks(plugin.hooks || {}));
@@ -612,4 +659,4 @@ function defineHeadPlugin(plugin) {
612
659
  return plugin;
613
660
  }
614
661
 
615
- export { DedupesTagsPlugin, 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 };
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.3.1",
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,12 +30,12 @@
30
30
  "dist"
31
31
  ],
32
32
  "dependencies": {
33
- "@unhead/dom": "0.3.1",
34
- "@unhead/schema": "0.3.1",
33
+ "@unhead/dom": "0.4.1",
34
+ "@unhead/schema": "0.4.1",
35
35
  "hookable": "^5.4.1"
36
36
  },
37
37
  "devDependencies": {
38
- "zhead": "1.0.0-beta.10"
38
+ "zhead": "1.0.0-beta.11"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "unbuild .",