unhead 1.8.13 → 1.8.15

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
@@ -94,75 +94,41 @@ const PayloadPlugin = shared.defineHeadPlugin({
94
94
  });
95
95
 
96
96
  const ValidEventTags = ["script", "link", "bodyAttrs"];
97
- function stripEventHandlers(tag) {
98
- const props = {};
99
- const eventHandlers = {};
100
- Object.entries(tag.props).forEach(([key, value]) => {
101
- if (key.startsWith("on") && typeof value === "function") {
102
- if (shared.NetworkEvents.includes(key))
103
- props[key] = `this.dataset.${key} = true`;
104
- eventHandlers[key] = value;
105
- } else {
106
- props[key] = value;
107
- }
108
- });
109
- return { props, eventHandlers };
110
- }
111
97
  const EventHandlersPlugin = shared.defineHeadPlugin((head) => ({
112
98
  hooks: {
113
99
  "tags:resolve": function(ctx) {
114
- for (const tag of ctx.tags) {
115
- if (ValidEventTags.includes(tag.tag)) {
116
- const { props, eventHandlers } = stripEventHandlers(tag);
117
- tag.props = props;
118
- if (Object.keys(eventHandlers).length) {
119
- if (tag.props.src || tag.props.href)
120
- tag.key = tag.key || shared.hashCode(tag.props.src || tag.props.href);
121
- tag._eventHandlers = eventHandlers;
100
+ for (const tag of ctx.tags.filter((t) => ValidEventTags.includes(t.tag))) {
101
+ Object.entries(tag.props).forEach(([key, value]) => {
102
+ if (key.startsWith("on") && typeof value === "function") {
103
+ if (head.ssr && shared.NetworkEvents.includes(key)) {
104
+ tag.props[key] = `this.dataset.${key} = true`;
105
+ tag.props["data-unhead-events"] = "";
106
+ } else {
107
+ delete tag.props[key];
108
+ }
109
+ tag._eventHandlers = tag._eventHandlers || {};
110
+ tag._eventHandlers[key] = value;
122
111
  }
112
+ });
113
+ if (head.ssr && tag._eventHandlers && (tag.props.src || tag.props.href)) {
114
+ tag.key = tag.key || shared.hashCode(tag.props.src || tag.props.href);
123
115
  }
124
116
  }
125
117
  },
126
- "dom:renderTag": function(ctx, dom, track) {
127
- if (!ctx.tag._eventHandlers)
118
+ "dom:renderTag": function(ctx) {
119
+ const $el = ctx.$el;
120
+ if (!$el?.dataset || !("unheadEvents" in $el.dataset))
128
121
  return;
129
- const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" ? dom.defaultView : ctx.$el;
130
- Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
131
- const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
132
- const eventName = k.slice(2).toLowerCase();
133
- const eventDedupeKey = `data-h-${eventName}`;
134
- track(ctx.id, sdeKey, () => {
122
+ delete $el.dataset.unheadEvents;
123
+ const handler = (k) => ctx.tag._eventHandlers?.[k]?.call(ctx.$el, new Event(k.replace("on", "")));
124
+ for (const k of Object.keys($el.dataset).filter((k2) => shared.NetworkEvents.includes(k2)))
125
+ handler(k);
126
+ if (typeof MutationObserver !== "undefined") {
127
+ const observer = new MutationObserver((e) => {
128
+ e.filter((m) => m.attributeName && shared.NetworkEvents.includes(m.attributeName.replace("data-", ""))).map((m) => m.attributeName.replace("data-", "")).map(handler);
135
129
  });
136
- if (ctx.$el.hasAttribute(eventDedupeKey))
137
- return;
138
- ctx.$el.setAttribute(eventDedupeKey, "");
139
- let observer;
140
- const handler = (e) => {
141
- value(e);
142
- observer?.disconnect();
143
- };
144
- if (k in ctx.$el.dataset) {
145
- handler(new Event(k.replace("on", "")));
146
- } else if (shared.NetworkEvents.includes(k) && typeof MutationObserver !== "undefined") {
147
- observer = new MutationObserver((e) => {
148
- const hasAttr = e.some((m) => m.attributeName === `data-${k}`);
149
- if (hasAttr) {
150
- handler(new Event(k.replace("on", "")));
151
- observer?.disconnect();
152
- }
153
- });
154
- observer.observe(ctx.$el, {
155
- attributes: true
156
- });
157
- } else {
158
- $eventListenerTarget.addEventListener(eventName, handler);
159
- }
160
- track(ctx.id, sdeKey, () => {
161
- observer?.disconnect();
162
- $eventListenerTarget.removeEventListener(eventName, handler);
163
- ctx.$el.removeAttribute(eventDedupeKey);
164
- });
165
- });
130
+ observer.observe(ctx.$el, { attributes: true });
131
+ }
166
132
  }
167
133
  }
168
134
  }));
@@ -507,7 +473,8 @@ const requestIdleCallback = typeof window === "undefined" ? () => {
507
473
  cb(idleDeadline);
508
474
  }, 1);
509
475
  });
510
- function useScript(input, _options) {
476
+ function useScript(_input, _options) {
477
+ const input = typeof _input === "string" ? { src: _input } : _input;
511
478
  const options = _options || {};
512
479
  const head = options.head || getActiveHead();
513
480
  if (!head)
package/dist/index.d.cts CHANGED
@@ -47,7 +47,7 @@ declare function useServerSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOpt
47
47
  * @experimental
48
48
  * @see https://unhead.unjs.io/usage/composables/use-script
49
49
  */
50
- declare function useScript<T>(input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
50
+ declare function useScript<T>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
51
  $script: ScriptInstance<T>;
52
52
  };
53
53
 
package/dist/index.d.mts CHANGED
@@ -47,7 +47,7 @@ declare function useServerSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOpt
47
47
  * @experimental
48
48
  * @see https://unhead.unjs.io/usage/composables/use-script
49
49
  */
50
- declare function useScript<T>(input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
50
+ declare function useScript<T>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
51
  $script: ScriptInstance<T>;
52
52
  };
53
53
 
package/dist/index.d.ts CHANGED
@@ -47,7 +47,7 @@ declare function useServerSeoMeta(input: UseSeoMetaInput, options?: HeadEntryOpt
47
47
  * @experimental
48
48
  * @see https://unhead.unjs.io/usage/composables/use-script
49
49
  */
50
- declare function useScript<T>(input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
50
+ declare function useScript<T>(_input: UseScriptInput, _options?: UseScriptOptions<T>): T & {
51
51
  $script: ScriptInstance<T>;
52
52
  };
53
53
 
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createHooks } from 'hookable';
2
2
  import { DomPlugin } from '@unhead/dom';
3
- import { defineHeadPlugin, tagDedupeKey, tagWeight, HasElementTags, hashCode, NetworkEvents, SortModifiers, processTemplateParams, resolveTitleTemplate, IsBrowser, normaliseEntryTags, composableNames, whitelistSafeInput, unpackMeta } from '@unhead/shared';
3
+ import { defineHeadPlugin, tagDedupeKey, tagWeight, HasElementTags, NetworkEvents, hashCode, SortModifiers, processTemplateParams, resolveTitleTemplate, IsBrowser, normaliseEntryTags, composableNames, whitelistSafeInput, unpackMeta } from '@unhead/shared';
4
4
  export { composableNames } from '@unhead/shared';
5
5
 
6
6
  const UsesMergeStrategy = ["templateParams", "htmlAttrs", "bodyAttrs"];
@@ -93,75 +93,41 @@ const PayloadPlugin = defineHeadPlugin({
93
93
  });
94
94
 
95
95
  const ValidEventTags = ["script", "link", "bodyAttrs"];
96
- function stripEventHandlers(tag) {
97
- const props = {};
98
- const eventHandlers = {};
99
- Object.entries(tag.props).forEach(([key, value]) => {
100
- if (key.startsWith("on") && typeof value === "function") {
101
- if (NetworkEvents.includes(key))
102
- props[key] = `this.dataset.${key} = true`;
103
- eventHandlers[key] = value;
104
- } else {
105
- props[key] = value;
106
- }
107
- });
108
- return { props, eventHandlers };
109
- }
110
96
  const EventHandlersPlugin = defineHeadPlugin((head) => ({
111
97
  hooks: {
112
98
  "tags:resolve": function(ctx) {
113
- for (const tag of ctx.tags) {
114
- if (ValidEventTags.includes(tag.tag)) {
115
- const { props, eventHandlers } = stripEventHandlers(tag);
116
- tag.props = props;
117
- if (Object.keys(eventHandlers).length) {
118
- if (tag.props.src || tag.props.href)
119
- tag.key = tag.key || hashCode(tag.props.src || tag.props.href);
120
- tag._eventHandlers = eventHandlers;
99
+ for (const tag of ctx.tags.filter((t) => ValidEventTags.includes(t.tag))) {
100
+ Object.entries(tag.props).forEach(([key, value]) => {
101
+ if (key.startsWith("on") && typeof value === "function") {
102
+ if (head.ssr && NetworkEvents.includes(key)) {
103
+ tag.props[key] = `this.dataset.${key} = true`;
104
+ tag.props["data-unhead-events"] = "";
105
+ } else {
106
+ delete tag.props[key];
107
+ }
108
+ tag._eventHandlers = tag._eventHandlers || {};
109
+ tag._eventHandlers[key] = value;
121
110
  }
111
+ });
112
+ if (head.ssr && tag._eventHandlers && (tag.props.src || tag.props.href)) {
113
+ tag.key = tag.key || hashCode(tag.props.src || tag.props.href);
122
114
  }
123
115
  }
124
116
  },
125
- "dom:renderTag": function(ctx, dom, track) {
126
- if (!ctx.tag._eventHandlers)
117
+ "dom:renderTag": function(ctx) {
118
+ const $el = ctx.$el;
119
+ if (!$el?.dataset || !("unheadEvents" in $el.dataset))
127
120
  return;
128
- const $eventListenerTarget = ctx.tag.tag === "bodyAttrs" ? dom.defaultView : ctx.$el;
129
- Object.entries(ctx.tag._eventHandlers).forEach(([k, value]) => {
130
- const sdeKey = `${ctx.tag._d || ctx.tag._p}:${k}`;
131
- const eventName = k.slice(2).toLowerCase();
132
- const eventDedupeKey = `data-h-${eventName}`;
133
- track(ctx.id, sdeKey, () => {
121
+ delete $el.dataset.unheadEvents;
122
+ const handler = (k) => ctx.tag._eventHandlers?.[k]?.call(ctx.$el, new Event(k.replace("on", "")));
123
+ for (const k of Object.keys($el.dataset).filter((k2) => NetworkEvents.includes(k2)))
124
+ handler(k);
125
+ if (typeof MutationObserver !== "undefined") {
126
+ const observer = new MutationObserver((e) => {
127
+ e.filter((m) => m.attributeName && NetworkEvents.includes(m.attributeName.replace("data-", ""))).map((m) => m.attributeName.replace("data-", "")).map(handler);
134
128
  });
135
- if (ctx.$el.hasAttribute(eventDedupeKey))
136
- return;
137
- ctx.$el.setAttribute(eventDedupeKey, "");
138
- let observer;
139
- const handler = (e) => {
140
- value(e);
141
- observer?.disconnect();
142
- };
143
- if (k in ctx.$el.dataset) {
144
- handler(new Event(k.replace("on", "")));
145
- } else if (NetworkEvents.includes(k) && typeof MutationObserver !== "undefined") {
146
- observer = new MutationObserver((e) => {
147
- const hasAttr = e.some((m) => m.attributeName === `data-${k}`);
148
- if (hasAttr) {
149
- handler(new Event(k.replace("on", "")));
150
- observer?.disconnect();
151
- }
152
- });
153
- observer.observe(ctx.$el, {
154
- attributes: true
155
- });
156
- } else {
157
- $eventListenerTarget.addEventListener(eventName, handler);
158
- }
159
- track(ctx.id, sdeKey, () => {
160
- observer?.disconnect();
161
- $eventListenerTarget.removeEventListener(eventName, handler);
162
- ctx.$el.removeAttribute(eventDedupeKey);
163
- });
164
- });
129
+ observer.observe(ctx.$el, { attributes: true });
130
+ }
165
131
  }
166
132
  }
167
133
  }));
@@ -506,7 +472,8 @@ const requestIdleCallback = typeof window === "undefined" ? () => {
506
472
  cb(idleDeadline);
507
473
  }, 1);
508
474
  });
509
- function useScript(input, _options) {
475
+ function useScript(_input, _options) {
476
+ const input = typeof _input === "string" ? { src: _input } : _input;
510
477
  const options = _options || {};
511
478
  const head = options.head || getActiveHead();
512
479
  if (!head)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unhead",
3
3
  "type": "module",
4
- "version": "1.8.13",
4
+ "version": "1.8.15",
5
5
  "author": {
6
6
  "name": "Harlan Wilton",
7
7
  "email": "harlan@harlanzw.com",
@@ -34,9 +34,9 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "hookable": "^5.5.3",
37
- "@unhead/schema": "1.8.13",
38
- "@unhead/dom": "1.8.13",
39
- "@unhead/shared": "1.8.13"
37
+ "@unhead/dom": "1.8.15",
38
+ "@unhead/schema": "1.8.15",
39
+ "@unhead/shared": "1.8.15"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "unbuild .",