@unhead/dom 1.0.22 → 1.1.0
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 +85 -61
- package/dist/index.d.ts +11 -5
- package/dist/index.mjs +86 -63
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const shared = require('@unhead/shared');
|
|
4
4
|
|
|
5
|
-
const setAttrs = (ctx, markSideEffect) => {
|
|
5
|
+
const setAttrs = (ctx, newEntry = false, markSideEffect) => {
|
|
6
6
|
const { tag, $el } = ctx;
|
|
7
7
|
if (!$el)
|
|
8
8
|
return;
|
|
@@ -23,86 +23,97 @@ const setAttrs = (ctx, markSideEffect) => {
|
|
|
23
23
|
}
|
|
24
24
|
if (markSideEffect && !k.startsWith("data-h-"))
|
|
25
25
|
markSideEffect(ctx, attrSdeKey, () => $el.removeAttribute(k));
|
|
26
|
-
if ($el.getAttribute(k) !== value)
|
|
26
|
+
if (newEntry || $el.getAttribute(k) !== value)
|
|
27
27
|
$el.setAttribute(k, value);
|
|
28
28
|
});
|
|
29
|
-
if (shared.TagsWithInnerContent.includes(tag.tag)
|
|
30
|
-
|
|
29
|
+
if (shared.TagsWithInnerContent.includes(tag.tag)) {
|
|
30
|
+
if (tag.textContent && tag.textContent !== $el.textContent)
|
|
31
|
+
$el.textContent = tag.textContent;
|
|
32
|
+
else if (tag.innerHTML && tag.innerHTML !== $el.innerHTML)
|
|
33
|
+
$el.innerHTML = tag.innerHTML;
|
|
34
|
+
}
|
|
31
35
|
};
|
|
32
36
|
|
|
37
|
+
let prevHash = false;
|
|
33
38
|
async function renderDOMHead(head, options = {}) {
|
|
34
|
-
const
|
|
35
|
-
await head.hooks.callHook("dom:beforeRender",
|
|
36
|
-
if (!
|
|
39
|
+
const beforeRenderCtx = { shouldRender: true };
|
|
40
|
+
await head.hooks.callHook("dom:beforeRender", beforeRenderCtx);
|
|
41
|
+
if (!beforeRenderCtx.shouldRender)
|
|
37
42
|
return;
|
|
38
|
-
const dom = options.document || window.document;
|
|
43
|
+
const dom = options.document || head.resolvedOptions.document || window.document;
|
|
44
|
+
const tagContexts = (await head.resolveTags()).map(setupTagRenderCtx);
|
|
45
|
+
if (head.resolvedOptions.experimentalHashHydration) {
|
|
46
|
+
prevHash = prevHash || head._hash || false;
|
|
47
|
+
if (prevHash) {
|
|
48
|
+
const hash = shared.computeHashes(tagContexts.map((ctx) => ctx.tag._h));
|
|
49
|
+
if (prevHash === hash)
|
|
50
|
+
return;
|
|
51
|
+
prevHash = hash;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
39
54
|
const staleSideEffects = head._popSideEffectQueue();
|
|
40
55
|
head.headEntries().map((entry) => entry._sde).forEach((sde) => {
|
|
41
56
|
Object.entries(sde).forEach(([key, fn]) => {
|
|
42
57
|
staleSideEffects[key] = fn;
|
|
43
58
|
});
|
|
44
59
|
});
|
|
45
|
-
const
|
|
60
|
+
const markSideEffect = (ctx, key, fn) => {
|
|
61
|
+
key = `${ctx.renderId}:${key}`;
|
|
62
|
+
if (ctx.entry)
|
|
63
|
+
ctx.entry._sde[key] = fn;
|
|
64
|
+
delete staleSideEffects[key];
|
|
65
|
+
};
|
|
66
|
+
function setupTagRenderCtx(tag) {
|
|
46
67
|
const entry = head.headEntries().find((e) => e._i === tag._e);
|
|
47
68
|
const renderCtx = {
|
|
48
|
-
renderId: tag._d || shared.
|
|
69
|
+
renderId: tag._d || shared.hashTag(tag),
|
|
49
70
|
$el: null,
|
|
50
71
|
shouldRender: true,
|
|
51
72
|
tag,
|
|
52
73
|
entry,
|
|
53
|
-
|
|
74
|
+
markSideEffect: (key, fn) => markSideEffect(renderCtx, key, fn)
|
|
54
75
|
};
|
|
55
|
-
await head.hooks.callHook("dom:beforeRenderTag", renderCtx);
|
|
56
76
|
return renderCtx;
|
|
57
|
-
}
|
|
77
|
+
}
|
|
58
78
|
const renders = [];
|
|
59
79
|
const pendingRenders = {
|
|
60
80
|
body: [],
|
|
61
81
|
head: []
|
|
62
82
|
};
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const markEl = (ctx2) => {
|
|
70
|
-
head._elMap[ctx2.renderId] = ctx2.$el;
|
|
71
|
-
renders.push(ctx2);
|
|
72
|
-
markSideEffect(ctx2, "el", () => {
|
|
73
|
-
ctx2.$el?.remove();
|
|
74
|
-
delete head._elMap[ctx2.renderId];
|
|
83
|
+
const markEl = (ctx) => {
|
|
84
|
+
head._elMap[ctx.renderId] = ctx.$el;
|
|
85
|
+
renders.push(ctx);
|
|
86
|
+
markSideEffect(ctx, "el", () => {
|
|
87
|
+
ctx.$el?.remove();
|
|
88
|
+
delete head._elMap[ctx.renderId];
|
|
75
89
|
});
|
|
76
90
|
};
|
|
77
|
-
for (const
|
|
78
|
-
|
|
79
|
-
if (!
|
|
91
|
+
for (const ctx of tagContexts) {
|
|
92
|
+
await head.hooks.callHook("dom:beforeRenderTag", ctx);
|
|
93
|
+
if (!ctx.shouldRender)
|
|
80
94
|
continue;
|
|
81
|
-
const { tag } =
|
|
95
|
+
const { tag } = ctx;
|
|
82
96
|
if (tag.tag === "title") {
|
|
83
|
-
dom.title = tag.
|
|
84
|
-
renders.push(
|
|
97
|
+
dom.title = tag.textContent || "";
|
|
98
|
+
renders.push(ctx);
|
|
85
99
|
continue;
|
|
86
100
|
}
|
|
87
101
|
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
|
|
88
|
-
|
|
89
|
-
setAttrs(
|
|
90
|
-
renders.push(
|
|
102
|
+
ctx.$el = dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"];
|
|
103
|
+
setAttrs(ctx, false, markSideEffect);
|
|
104
|
+
renders.push(ctx);
|
|
91
105
|
continue;
|
|
92
106
|
}
|
|
93
|
-
|
|
94
|
-
if (!
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
markEl(ctx2);
|
|
107
|
+
ctx.$el = head._elMap[ctx.renderId];
|
|
108
|
+
if (!ctx.$el && tag.key)
|
|
109
|
+
ctx.$el = dom.querySelector(`${tag.tagPosition?.startsWith("body") ? "body" : "head"} > ${tag.tag}[data-h-${tag._h}]`);
|
|
110
|
+
if (ctx.$el) {
|
|
111
|
+
if (ctx.tag._d)
|
|
112
|
+
setAttrs(ctx);
|
|
113
|
+
markEl(ctx);
|
|
101
114
|
continue;
|
|
102
115
|
}
|
|
103
|
-
|
|
104
|
-
setAttrs(ctx2);
|
|
105
|
-
pendingRenders[tag.tagPosition?.startsWith("body") ? "body" : "head"].push(ctx2);
|
|
116
|
+
pendingRenders[tag.tagPosition?.startsWith("body") ? "body" : "head"].push(ctx);
|
|
106
117
|
}
|
|
107
118
|
const fragments = {
|
|
108
119
|
bodyClose: void 0,
|
|
@@ -119,25 +130,33 @@ async function renderDOMHead(head, options = {}) {
|
|
|
119
130
|
const elTag = $el.tagName.toLowerCase();
|
|
120
131
|
if (!shared.HasElementTags.includes(elTag))
|
|
121
132
|
continue;
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
const props = $el.getAttributeNames().reduce((props2, name) => ({ ...props2, [name]: $el.getAttribute(name) }), {});
|
|
134
|
+
const tmpTag = { tag: elTag, props };
|
|
135
|
+
if ($el.innerHTML)
|
|
136
|
+
tmpTag.innerHTML = $el.innerHTML;
|
|
137
|
+
const tmpRenderId = shared.hashTag(tmpTag);
|
|
138
|
+
let matchIdx = queue.findIndex((ctx) => ctx?.renderId === tmpRenderId);
|
|
139
|
+
if (matchIdx === -1) {
|
|
140
|
+
const tmpDedupeKey = shared.tagDedupeKey(tmpTag);
|
|
141
|
+
matchIdx = queue.findIndex((ctx) => ctx?.tag._d && ctx.tag._d === tmpDedupeKey);
|
|
142
|
+
}
|
|
128
143
|
if (matchIdx !== -1) {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
setAttrs(
|
|
132
|
-
markEl(
|
|
144
|
+
const ctx = queue[matchIdx];
|
|
145
|
+
ctx.$el = $el;
|
|
146
|
+
setAttrs(ctx);
|
|
147
|
+
markEl(ctx);
|
|
133
148
|
delete queue[matchIdx];
|
|
134
149
|
}
|
|
135
150
|
}
|
|
136
|
-
queue.forEach((
|
|
137
|
-
const pos2 =
|
|
151
|
+
queue.forEach((ctx) => {
|
|
152
|
+
const pos2 = ctx.tag.tagPosition || "head";
|
|
138
153
|
fragments[pos2] = fragments[pos2] || dom.createDocumentFragment();
|
|
139
|
-
|
|
140
|
-
|
|
154
|
+
if (!ctx.$el) {
|
|
155
|
+
ctx.$el = dom.createElement(ctx.tag.tag);
|
|
156
|
+
setAttrs(ctx, true);
|
|
157
|
+
}
|
|
158
|
+
fragments[pos2].appendChild(ctx.$el);
|
|
159
|
+
markEl(ctx);
|
|
141
160
|
});
|
|
142
161
|
});
|
|
143
162
|
if (fragments.head)
|
|
@@ -146,8 +165,8 @@ async function renderDOMHead(head, options = {}) {
|
|
|
146
165
|
dom.body.insertBefore(fragments.bodyOpen, dom.body.firstChild);
|
|
147
166
|
if (fragments.bodyClose)
|
|
148
167
|
dom.body.appendChild(fragments.bodyClose);
|
|
149
|
-
for (const
|
|
150
|
-
await head.hooks.callHook("dom:renderTag",
|
|
168
|
+
for (const ctx of renders)
|
|
169
|
+
await head.hooks.callHook("dom:renderTag", ctx);
|
|
151
170
|
Object.values(staleSideEffects).forEach((fn) => fn());
|
|
152
171
|
}
|
|
153
172
|
exports.domUpdatePromise = null;
|
|
@@ -175,7 +194,12 @@ const PatchDomOnEntryUpdatesPlugin = (options) => {
|
|
|
175
194
|
});
|
|
176
195
|
};
|
|
177
196
|
|
|
197
|
+
function maybeGetSSRHash(document) {
|
|
198
|
+
return document?.head.querySelector('meta[name="unhead:ssr"]')?.getAttribute("content") || false;
|
|
199
|
+
}
|
|
200
|
+
|
|
178
201
|
exports.PatchDomOnEntryUpdatesPlugin = PatchDomOnEntryUpdatesPlugin;
|
|
179
202
|
exports.debouncedRenderDOMHead = debouncedRenderDOMHead;
|
|
203
|
+
exports.maybeGetSSRHash = maybeGetSSRHash;
|
|
180
204
|
exports.renderDOMHead = renderDOMHead;
|
|
181
205
|
exports.setAttrs = setAttrs;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ interface RenderDomHeadOptions {
|
|
|
7
7
|
*/
|
|
8
8
|
document?: Document;
|
|
9
9
|
}
|
|
10
|
+
interface DebouncedRenderDomHeadOptions extends RenderDomHeadOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Specify a custom delay function for delaying the render.
|
|
13
|
+
*/
|
|
14
|
+
delayFn?: (fn: () => void) => void;
|
|
15
|
+
}
|
|
10
16
|
/**
|
|
11
17
|
* Render the head tags to the DOM.
|
|
12
18
|
*/
|
|
@@ -18,9 +24,7 @@ declare let domUpdatePromise: Promise<void> | null;
|
|
|
18
24
|
/**
|
|
19
25
|
* Queue a debounced update of the DOM head.
|
|
20
26
|
*/
|
|
21
|
-
declare function debouncedRenderDOMHead<T extends Unhead<any>>(head: T, options?:
|
|
22
|
-
delayFn?: (fn: () => void) => void;
|
|
23
|
-
}): Promise<void>;
|
|
27
|
+
declare function debouncedRenderDOMHead<T extends Unhead<any>>(head: T, options?: DebouncedRenderDomHeadOptions): Promise<void>;
|
|
24
28
|
|
|
25
29
|
interface TriggerDomPatchingOnUpdatesPluginOptions extends RenderDomHeadOptions {
|
|
26
30
|
delayFn?: (fn: () => void) => void;
|
|
@@ -30,6 +34,8 @@ declare const PatchDomOnEntryUpdatesPlugin: (options?: TriggerDomPatchingOnUpdat
|
|
|
30
34
|
/**
|
|
31
35
|
* Set attributes on a DOM element, while adding entry side effects.
|
|
32
36
|
*/
|
|
33
|
-
declare const setAttrs: (ctx: DomRenderTagContext, markSideEffect?: ((ctx: DomRenderTagContext, k: string, fn: () => void) => void) | undefined) => void;
|
|
37
|
+
declare const setAttrs: (ctx: DomRenderTagContext, newEntry?: boolean, markSideEffect?: ((ctx: DomRenderTagContext, k: string, fn: () => void) => void) | undefined) => void;
|
|
38
|
+
|
|
39
|
+
declare function maybeGetSSRHash(document: Document): string | false;
|
|
34
40
|
|
|
35
|
-
export { PatchDomOnEntryUpdatesPlugin, RenderDomHeadOptions, TriggerDomPatchingOnUpdatesPluginOptions, debouncedRenderDOMHead, domUpdatePromise, renderDOMHead, setAttrs };
|
|
41
|
+
export { DebouncedRenderDomHeadOptions, PatchDomOnEntryUpdatesPlugin, RenderDomHeadOptions, TriggerDomPatchingOnUpdatesPluginOptions, debouncedRenderDOMHead, domUpdatePromise, maybeGetSSRHash, renderDOMHead, setAttrs };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { TagsWithInnerContent, HasElementTags, tagDedupeKey,
|
|
1
|
+
import { TagsWithInnerContent, computeHashes, hashTag, HasElementTags, tagDedupeKey, defineHeadPlugin } from '@unhead/shared';
|
|
2
2
|
|
|
3
|
-
const setAttrs = (ctx, markSideEffect) => {
|
|
3
|
+
const setAttrs = (ctx, newEntry = false, markSideEffect) => {
|
|
4
4
|
const { tag, $el } = ctx;
|
|
5
5
|
if (!$el)
|
|
6
6
|
return;
|
|
@@ -21,86 +21,97 @@ const setAttrs = (ctx, markSideEffect) => {
|
|
|
21
21
|
}
|
|
22
22
|
if (markSideEffect && !k.startsWith("data-h-"))
|
|
23
23
|
markSideEffect(ctx, attrSdeKey, () => $el.removeAttribute(k));
|
|
24
|
-
if ($el.getAttribute(k) !== value)
|
|
24
|
+
if (newEntry || $el.getAttribute(k) !== value)
|
|
25
25
|
$el.setAttribute(k, value);
|
|
26
26
|
});
|
|
27
|
-
if (TagsWithInnerContent.includes(tag.tag)
|
|
28
|
-
|
|
27
|
+
if (TagsWithInnerContent.includes(tag.tag)) {
|
|
28
|
+
if (tag.textContent && tag.textContent !== $el.textContent)
|
|
29
|
+
$el.textContent = tag.textContent;
|
|
30
|
+
else if (tag.innerHTML && tag.innerHTML !== $el.innerHTML)
|
|
31
|
+
$el.innerHTML = tag.innerHTML;
|
|
32
|
+
}
|
|
29
33
|
};
|
|
30
34
|
|
|
35
|
+
let prevHash = false;
|
|
31
36
|
async function renderDOMHead(head, options = {}) {
|
|
32
|
-
const
|
|
33
|
-
await head.hooks.callHook("dom:beforeRender",
|
|
34
|
-
if (!
|
|
37
|
+
const beforeRenderCtx = { shouldRender: true };
|
|
38
|
+
await head.hooks.callHook("dom:beforeRender", beforeRenderCtx);
|
|
39
|
+
if (!beforeRenderCtx.shouldRender)
|
|
35
40
|
return;
|
|
36
|
-
const dom = options.document || window.document;
|
|
41
|
+
const dom = options.document || head.resolvedOptions.document || window.document;
|
|
42
|
+
const tagContexts = (await head.resolveTags()).map(setupTagRenderCtx);
|
|
43
|
+
if (head.resolvedOptions.experimentalHashHydration) {
|
|
44
|
+
prevHash = prevHash || head._hash || false;
|
|
45
|
+
if (prevHash) {
|
|
46
|
+
const hash = computeHashes(tagContexts.map((ctx) => ctx.tag._h));
|
|
47
|
+
if (prevHash === hash)
|
|
48
|
+
return;
|
|
49
|
+
prevHash = hash;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
37
52
|
const staleSideEffects = head._popSideEffectQueue();
|
|
38
53
|
head.headEntries().map((entry) => entry._sde).forEach((sde) => {
|
|
39
54
|
Object.entries(sde).forEach(([key, fn]) => {
|
|
40
55
|
staleSideEffects[key] = fn;
|
|
41
56
|
});
|
|
42
57
|
});
|
|
43
|
-
const
|
|
58
|
+
const markSideEffect = (ctx, key, fn) => {
|
|
59
|
+
key = `${ctx.renderId}:${key}`;
|
|
60
|
+
if (ctx.entry)
|
|
61
|
+
ctx.entry._sde[key] = fn;
|
|
62
|
+
delete staleSideEffects[key];
|
|
63
|
+
};
|
|
64
|
+
function setupTagRenderCtx(tag) {
|
|
44
65
|
const entry = head.headEntries().find((e) => e._i === tag._e);
|
|
45
66
|
const renderCtx = {
|
|
46
|
-
renderId: tag._d ||
|
|
67
|
+
renderId: tag._d || hashTag(tag),
|
|
47
68
|
$el: null,
|
|
48
69
|
shouldRender: true,
|
|
49
70
|
tag,
|
|
50
71
|
entry,
|
|
51
|
-
|
|
72
|
+
markSideEffect: (key, fn) => markSideEffect(renderCtx, key, fn)
|
|
52
73
|
};
|
|
53
|
-
await head.hooks.callHook("dom:beforeRenderTag", renderCtx);
|
|
54
74
|
return renderCtx;
|
|
55
|
-
}
|
|
75
|
+
}
|
|
56
76
|
const renders = [];
|
|
57
77
|
const pendingRenders = {
|
|
58
78
|
body: [],
|
|
59
79
|
head: []
|
|
60
80
|
};
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const markEl = (ctx2) => {
|
|
68
|
-
head._elMap[ctx2.renderId] = ctx2.$el;
|
|
69
|
-
renders.push(ctx2);
|
|
70
|
-
markSideEffect(ctx2, "el", () => {
|
|
71
|
-
ctx2.$el?.remove();
|
|
72
|
-
delete head._elMap[ctx2.renderId];
|
|
81
|
+
const markEl = (ctx) => {
|
|
82
|
+
head._elMap[ctx.renderId] = ctx.$el;
|
|
83
|
+
renders.push(ctx);
|
|
84
|
+
markSideEffect(ctx, "el", () => {
|
|
85
|
+
ctx.$el?.remove();
|
|
86
|
+
delete head._elMap[ctx.renderId];
|
|
73
87
|
});
|
|
74
88
|
};
|
|
75
|
-
for (const
|
|
76
|
-
|
|
77
|
-
if (!
|
|
89
|
+
for (const ctx of tagContexts) {
|
|
90
|
+
await head.hooks.callHook("dom:beforeRenderTag", ctx);
|
|
91
|
+
if (!ctx.shouldRender)
|
|
78
92
|
continue;
|
|
79
|
-
const { tag } =
|
|
93
|
+
const { tag } = ctx;
|
|
80
94
|
if (tag.tag === "title") {
|
|
81
|
-
dom.title = tag.
|
|
82
|
-
renders.push(
|
|
95
|
+
dom.title = tag.textContent || "";
|
|
96
|
+
renders.push(ctx);
|
|
83
97
|
continue;
|
|
84
98
|
}
|
|
85
99
|
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
|
|
86
|
-
|
|
87
|
-
setAttrs(
|
|
88
|
-
renders.push(
|
|
100
|
+
ctx.$el = dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"];
|
|
101
|
+
setAttrs(ctx, false, markSideEffect);
|
|
102
|
+
renders.push(ctx);
|
|
89
103
|
continue;
|
|
90
104
|
}
|
|
91
|
-
|
|
92
|
-
if (!
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
markEl(ctx2);
|
|
105
|
+
ctx.$el = head._elMap[ctx.renderId];
|
|
106
|
+
if (!ctx.$el && tag.key)
|
|
107
|
+
ctx.$el = dom.querySelector(`${tag.tagPosition?.startsWith("body") ? "body" : "head"} > ${tag.tag}[data-h-${tag._h}]`);
|
|
108
|
+
if (ctx.$el) {
|
|
109
|
+
if (ctx.tag._d)
|
|
110
|
+
setAttrs(ctx);
|
|
111
|
+
markEl(ctx);
|
|
99
112
|
continue;
|
|
100
113
|
}
|
|
101
|
-
|
|
102
|
-
setAttrs(ctx2);
|
|
103
|
-
pendingRenders[tag.tagPosition?.startsWith("body") ? "body" : "head"].push(ctx2);
|
|
114
|
+
pendingRenders[tag.tagPosition?.startsWith("body") ? "body" : "head"].push(ctx);
|
|
104
115
|
}
|
|
105
116
|
const fragments = {
|
|
106
117
|
bodyClose: void 0,
|
|
@@ -117,25 +128,33 @@ async function renderDOMHead(head, options = {}) {
|
|
|
117
128
|
const elTag = $el.tagName.toLowerCase();
|
|
118
129
|
if (!HasElementTags.includes(elTag))
|
|
119
130
|
continue;
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
const props = $el.getAttributeNames().reduce((props2, name) => ({ ...props2, [name]: $el.getAttribute(name) }), {});
|
|
132
|
+
const tmpTag = { tag: elTag, props };
|
|
133
|
+
if ($el.innerHTML)
|
|
134
|
+
tmpTag.innerHTML = $el.innerHTML;
|
|
135
|
+
const tmpRenderId = hashTag(tmpTag);
|
|
136
|
+
let matchIdx = queue.findIndex((ctx) => ctx?.renderId === tmpRenderId);
|
|
137
|
+
if (matchIdx === -1) {
|
|
138
|
+
const tmpDedupeKey = tagDedupeKey(tmpTag);
|
|
139
|
+
matchIdx = queue.findIndex((ctx) => ctx?.tag._d && ctx.tag._d === tmpDedupeKey);
|
|
140
|
+
}
|
|
126
141
|
if (matchIdx !== -1) {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
setAttrs(
|
|
130
|
-
markEl(
|
|
142
|
+
const ctx = queue[matchIdx];
|
|
143
|
+
ctx.$el = $el;
|
|
144
|
+
setAttrs(ctx);
|
|
145
|
+
markEl(ctx);
|
|
131
146
|
delete queue[matchIdx];
|
|
132
147
|
}
|
|
133
148
|
}
|
|
134
|
-
queue.forEach((
|
|
135
|
-
const pos2 =
|
|
149
|
+
queue.forEach((ctx) => {
|
|
150
|
+
const pos2 = ctx.tag.tagPosition || "head";
|
|
136
151
|
fragments[pos2] = fragments[pos2] || dom.createDocumentFragment();
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
if (!ctx.$el) {
|
|
153
|
+
ctx.$el = dom.createElement(ctx.tag.tag);
|
|
154
|
+
setAttrs(ctx, true);
|
|
155
|
+
}
|
|
156
|
+
fragments[pos2].appendChild(ctx.$el);
|
|
157
|
+
markEl(ctx);
|
|
139
158
|
});
|
|
140
159
|
});
|
|
141
160
|
if (fragments.head)
|
|
@@ -144,8 +163,8 @@ async function renderDOMHead(head, options = {}) {
|
|
|
144
163
|
dom.body.insertBefore(fragments.bodyOpen, dom.body.firstChild);
|
|
145
164
|
if (fragments.bodyClose)
|
|
146
165
|
dom.body.appendChild(fragments.bodyClose);
|
|
147
|
-
for (const
|
|
148
|
-
await head.hooks.callHook("dom:renderTag",
|
|
166
|
+
for (const ctx of renders)
|
|
167
|
+
await head.hooks.callHook("dom:renderTag", ctx);
|
|
149
168
|
Object.values(staleSideEffects).forEach((fn) => fn());
|
|
150
169
|
}
|
|
151
170
|
let domUpdatePromise = null;
|
|
@@ -173,4 +192,8 @@ const PatchDomOnEntryUpdatesPlugin = (options) => {
|
|
|
173
192
|
});
|
|
174
193
|
};
|
|
175
194
|
|
|
176
|
-
|
|
195
|
+
function maybeGetSSRHash(document) {
|
|
196
|
+
return document?.head.querySelector('meta[name="unhead:ssr"]')?.getAttribute("content") || false;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export { PatchDomOnEntryUpdatesPlugin, debouncedRenderDOMHead, domUpdatePromise, maybeGetSSRHash, renderDOMHead, setAttrs };
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unhead/dom",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0
|
|
5
|
-
"packageManager": "pnpm@7.
|
|
4
|
+
"version": "1.1.0",
|
|
5
|
+
"packageManager": "pnpm@7.27.1",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"funding": "https://github.com/sponsors/harlan-zw",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@unhead/schema": "1.0
|
|
34
|
-
"@unhead/shared": "1.0
|
|
33
|
+
"@unhead/schema": "1.1.0",
|
|
34
|
+
"@unhead/shared": "1.1.0"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "unbuild .",
|