@unhead/dom 0.6.5 → 0.6.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 +137 -88
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +137 -89
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const TagsWithInnerContent = ["script", "style", "noscript"];
|
|
4
|
+
const HasElementTags = [
|
|
5
|
+
"base",
|
|
6
|
+
"meta",
|
|
7
|
+
"link",
|
|
8
|
+
"style",
|
|
9
|
+
"script",
|
|
10
|
+
"noscript"
|
|
11
|
+
];
|
|
4
12
|
|
|
5
13
|
const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
|
|
6
14
|
const ArrayMetaProperties = [
|
|
@@ -41,6 +49,39 @@ function tagDedupeKey(tag) {
|
|
|
41
49
|
return false;
|
|
42
50
|
}
|
|
43
51
|
|
|
52
|
+
const setAttrs = (ctx, markSideEffect) => {
|
|
53
|
+
const { tag, $el } = ctx;
|
|
54
|
+
if (!$el)
|
|
55
|
+
return;
|
|
56
|
+
Object.entries(tag.props).forEach(([k, value]) => {
|
|
57
|
+
value = String(value);
|
|
58
|
+
const attrSdeKey = `attr:${k}`;
|
|
59
|
+
if (k === "class") {
|
|
60
|
+
for (const c of value.split(" ")) {
|
|
61
|
+
const classSdeKey = `${attrSdeKey}:${c}`;
|
|
62
|
+
if (markSideEffect)
|
|
63
|
+
markSideEffect(ctx, classSdeKey, () => $el.classList.remove(c));
|
|
64
|
+
if (!$el.classList.contains(c))
|
|
65
|
+
$el.classList.add(c);
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (markSideEffect && !k.startsWith("data-h-"))
|
|
70
|
+
markSideEffect(ctx, attrSdeKey, () => $el.removeAttribute(k));
|
|
71
|
+
if ($el.getAttribute(k) !== value)
|
|
72
|
+
$el.setAttribute(k, value);
|
|
73
|
+
});
|
|
74
|
+
if (TagsWithInnerContent.includes(tag.tag) && $el.innerHTML !== (tag.children || ""))
|
|
75
|
+
$el.innerHTML = tag.children || "";
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
function hashCode(s) {
|
|
79
|
+
let h = 9;
|
|
80
|
+
for (let i = 0; i < s.length; )
|
|
81
|
+
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
82
|
+
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 8).toLowerCase();
|
|
83
|
+
}
|
|
84
|
+
|
|
44
85
|
async function renderDOMHead(head, options = {}) {
|
|
45
86
|
const ctx = { shouldRender: true };
|
|
46
87
|
await head.hooks.callHook("dom:beforeRender", ctx);
|
|
@@ -53,101 +94,108 @@ async function renderDOMHead(head, options = {}) {
|
|
|
53
94
|
staleSideEffects[key] = fn;
|
|
54
95
|
});
|
|
55
96
|
});
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
delete staleSideEffects[key];
|
|
66
|
-
};
|
|
67
|
-
const setAttrs = ($el, sideEffects = true) => {
|
|
68
|
-
Object.entries(tag.props).forEach(([k, value]) => {
|
|
69
|
-
value = String(value);
|
|
70
|
-
const attrSdeKey = `attr:${k}`;
|
|
71
|
-
if (k === "class") {
|
|
72
|
-
for (const c of value.split(" ")) {
|
|
73
|
-
const classSdeKey = `${attrSdeKey}:${c}`;
|
|
74
|
-
sideEffects && markSideEffect(classSdeKey, () => $el.classList.remove(c));
|
|
75
|
-
if (!$el.classList.contains(c))
|
|
76
|
-
$el.classList.add(c);
|
|
77
|
-
}
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
if (sideEffects && !k.startsWith("data-h-"))
|
|
81
|
-
markSideEffect(attrSdeKey, () => $el.removeAttribute(k));
|
|
82
|
-
if ($el.getAttribute(k) !== value)
|
|
83
|
-
$el.setAttribute(k, value);
|
|
84
|
-
});
|
|
85
|
-
if (TagsWithInnerContent.includes(tag.tag) && $el.innerHTML !== (tag.children || ""))
|
|
86
|
-
$el.innerHTML = tag.children || "";
|
|
97
|
+
const preRenderTag = async (tag) => {
|
|
98
|
+
const entry = head.headEntries().find((e) => e._i === tag._e);
|
|
99
|
+
const renderCtx = {
|
|
100
|
+
renderId: tag._d || hashCode(JSON.stringify({ ...tag, _e: void 0, _p: void 0 })),
|
|
101
|
+
$el: null,
|
|
102
|
+
shouldRender: true,
|
|
103
|
+
tag,
|
|
104
|
+
entry,
|
|
105
|
+
staleSideEffects
|
|
87
106
|
};
|
|
107
|
+
await head.hooks.callHook("dom:beforeRenderTag", renderCtx);
|
|
108
|
+
return renderCtx;
|
|
109
|
+
};
|
|
110
|
+
const renders = [];
|
|
111
|
+
const pendingRenders = {
|
|
112
|
+
body: [],
|
|
113
|
+
head: []
|
|
114
|
+
};
|
|
115
|
+
const markSideEffect = (ctx2, key, fn) => {
|
|
116
|
+
key = `${ctx2.renderId}:${key}`;
|
|
117
|
+
if (ctx2.entry)
|
|
118
|
+
ctx2.entry._sde[key] = fn;
|
|
119
|
+
delete staleSideEffects[key];
|
|
120
|
+
};
|
|
121
|
+
const markEl = (ctx2) => {
|
|
122
|
+
head._elMap[ctx2.renderId] = ctx2.$el;
|
|
123
|
+
renders.push(ctx2);
|
|
124
|
+
markSideEffect(ctx2, "el", () => {
|
|
125
|
+
ctx2.$el?.remove();
|
|
126
|
+
delete head._elMap[ctx2.renderId];
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
for (const t of await head.resolveTags()) {
|
|
130
|
+
const ctx2 = await preRenderTag(t);
|
|
131
|
+
if (!ctx2.shouldRender)
|
|
132
|
+
continue;
|
|
133
|
+
const { tag } = ctx2;
|
|
134
|
+
if (tag.tag === "title") {
|
|
135
|
+
dom.title = tag.children || "";
|
|
136
|
+
renders.push(ctx2);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
88
139
|
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
|
|
89
|
-
|
|
90
|
-
setAttrs(
|
|
91
|
-
|
|
140
|
+
ctx2.$el = dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"];
|
|
141
|
+
setAttrs(ctx2, markSideEffect);
|
|
142
|
+
renders.push(ctx2);
|
|
143
|
+
continue;
|
|
92
144
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const $target = dom[tag.tagPosition?.startsWith("body") ? "body" : "head"];
|
|
97
|
-
if (!$previousEl && tag._hash) {
|
|
98
|
-
$previousEl = $target.querySelector(`${tag.tag}[data-h-${tag._hash}]`);
|
|
145
|
+
ctx2.$el = head._elMap[ctx2.renderId];
|
|
146
|
+
if (!ctx2.$el && tag._hash) {
|
|
147
|
+
ctx2.$el = dom.querySelector(`${tag.tagPosition?.startsWith("body") ? "body" : "head"} > ${tag.tag}[data-h-${tag._hash}]`);
|
|
99
148
|
}
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const key = tagDedupeKey({
|
|
106
|
-
tag: elTag,
|
|
107
|
-
props: $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {})
|
|
108
|
-
});
|
|
109
|
-
if (key === tag._d || $el.isEqualNode($newEl)) {
|
|
110
|
-
$previousEl = $el;
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
149
|
+
if (ctx2.$el) {
|
|
150
|
+
if (ctx2.tag._d)
|
|
151
|
+
setAttrs(ctx2);
|
|
152
|
+
markEl(ctx2);
|
|
153
|
+
continue;
|
|
114
154
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
155
|
+
ctx2.$el = dom.createElement(tag.tag);
|
|
156
|
+
setAttrs(ctx2);
|
|
157
|
+
pendingRenders[tag.tagPosition?.startsWith("body") ? "body" : "head"].push(ctx2);
|
|
158
|
+
}
|
|
159
|
+
Object.entries(pendingRenders).forEach(([pos, queue]) => {
|
|
160
|
+
if (!queue.length)
|
|
161
|
+
return;
|
|
162
|
+
for (const $el of [...dom[pos].children].reverse()) {
|
|
163
|
+
const elTag = $el.tagName.toLowerCase();
|
|
164
|
+
if (!HasElementTags.includes(elTag))
|
|
165
|
+
continue;
|
|
166
|
+
const dedupeKey = tagDedupeKey({
|
|
167
|
+
tag: elTag,
|
|
168
|
+
props: $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {})
|
|
120
169
|
});
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
$newEl = dom.body.appendChild($newEl);
|
|
130
|
-
break;
|
|
131
|
-
case "bodyOpen":
|
|
132
|
-
$newEl = dom.body.insertBefore($newEl, dom.body.firstChild);
|
|
133
|
-
break;
|
|
134
|
-
case "head":
|
|
135
|
-
default:
|
|
136
|
-
$newEl = dom.head.appendChild($newEl);
|
|
137
|
-
break;
|
|
170
|
+
const matchIdx = queue.findIndex((ctx2) => ctx2 && (ctx2.tag._d === dedupeKey || $el.isEqualNode(ctx2.$el)));
|
|
171
|
+
if (matchIdx !== -1) {
|
|
172
|
+
const ctx2 = queue[matchIdx];
|
|
173
|
+
ctx2.$el = $el;
|
|
174
|
+
setAttrs(ctx2);
|
|
175
|
+
markEl(ctx2);
|
|
176
|
+
delete queue[matchIdx];
|
|
177
|
+
}
|
|
138
178
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
179
|
+
queue.forEach((ctx2) => {
|
|
180
|
+
if (!ctx2.$el)
|
|
181
|
+
return;
|
|
182
|
+
switch (ctx2.tag.tagPosition) {
|
|
183
|
+
case "bodyClose":
|
|
184
|
+
dom.body.appendChild(ctx2.$el);
|
|
185
|
+
break;
|
|
186
|
+
case "bodyOpen":
|
|
187
|
+
dom.body.insertBefore(ctx2.$el, dom.body.firstChild);
|
|
188
|
+
break;
|
|
189
|
+
case "head":
|
|
190
|
+
default:
|
|
191
|
+
dom.head.appendChild(ctx2.$el);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
markEl(ctx2);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
for (const ctx2 of renders)
|
|
198
|
+
await head.hooks.callHook("dom:renderTag", ctx2);
|
|
151
199
|
Object.values(staleSideEffects).forEach((fn) => fn());
|
|
152
200
|
}
|
|
153
201
|
exports.domUpdatePromise = null;
|
|
@@ -161,4 +209,5 @@ async function debouncedRenderDOMHead(head, options = {}) {
|
|
|
161
209
|
}
|
|
162
210
|
|
|
163
211
|
exports.debouncedRenderDOMHead = debouncedRenderDOMHead;
|
|
212
|
+
exports.hashCode = hashCode;
|
|
164
213
|
exports.renderDOMHead = renderDOMHead;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,4 +21,6 @@ declare function debouncedRenderDOMHead<T extends Unhead<any>>(head: T, options?
|
|
|
21
21
|
delayFn?: (fn: () => void) => void;
|
|
22
22
|
}): Promise<void>;
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
declare function hashCode(s: string): string;
|
|
25
|
+
|
|
26
|
+
export { RenderDomHeadOptions, debouncedRenderDOMHead, domUpdatePromise, hashCode, renderDOMHead };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
const TagsWithInnerContent = ["script", "style", "noscript"];
|
|
2
|
+
const HasElementTags = [
|
|
3
|
+
"base",
|
|
4
|
+
"meta",
|
|
5
|
+
"link",
|
|
6
|
+
"style",
|
|
7
|
+
"script",
|
|
8
|
+
"noscript"
|
|
9
|
+
];
|
|
2
10
|
|
|
3
11
|
const UniqueTags = ["base", "title", "titleTemplate", "bodyAttrs", "htmlAttrs"];
|
|
4
12
|
const ArrayMetaProperties = [
|
|
@@ -39,6 +47,39 @@ function tagDedupeKey(tag) {
|
|
|
39
47
|
return false;
|
|
40
48
|
}
|
|
41
49
|
|
|
50
|
+
const setAttrs = (ctx, markSideEffect) => {
|
|
51
|
+
const { tag, $el } = ctx;
|
|
52
|
+
if (!$el)
|
|
53
|
+
return;
|
|
54
|
+
Object.entries(tag.props).forEach(([k, value]) => {
|
|
55
|
+
value = String(value);
|
|
56
|
+
const attrSdeKey = `attr:${k}`;
|
|
57
|
+
if (k === "class") {
|
|
58
|
+
for (const c of value.split(" ")) {
|
|
59
|
+
const classSdeKey = `${attrSdeKey}:${c}`;
|
|
60
|
+
if (markSideEffect)
|
|
61
|
+
markSideEffect(ctx, classSdeKey, () => $el.classList.remove(c));
|
|
62
|
+
if (!$el.classList.contains(c))
|
|
63
|
+
$el.classList.add(c);
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (markSideEffect && !k.startsWith("data-h-"))
|
|
68
|
+
markSideEffect(ctx, attrSdeKey, () => $el.removeAttribute(k));
|
|
69
|
+
if ($el.getAttribute(k) !== value)
|
|
70
|
+
$el.setAttribute(k, value);
|
|
71
|
+
});
|
|
72
|
+
if (TagsWithInnerContent.includes(tag.tag) && $el.innerHTML !== (tag.children || ""))
|
|
73
|
+
$el.innerHTML = tag.children || "";
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function hashCode(s) {
|
|
77
|
+
let h = 9;
|
|
78
|
+
for (let i = 0; i < s.length; )
|
|
79
|
+
h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
|
|
80
|
+
return ((h ^ h >>> 9) + 65536).toString(16).substring(1, 8).toLowerCase();
|
|
81
|
+
}
|
|
82
|
+
|
|
42
83
|
async function renderDOMHead(head, options = {}) {
|
|
43
84
|
const ctx = { shouldRender: true };
|
|
44
85
|
await head.hooks.callHook("dom:beforeRender", ctx);
|
|
@@ -51,101 +92,108 @@ async function renderDOMHead(head, options = {}) {
|
|
|
51
92
|
staleSideEffects[key] = fn;
|
|
52
93
|
});
|
|
53
94
|
});
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
delete staleSideEffects[key];
|
|
64
|
-
};
|
|
65
|
-
const setAttrs = ($el, sideEffects = true) => {
|
|
66
|
-
Object.entries(tag.props).forEach(([k, value]) => {
|
|
67
|
-
value = String(value);
|
|
68
|
-
const attrSdeKey = `attr:${k}`;
|
|
69
|
-
if (k === "class") {
|
|
70
|
-
for (const c of value.split(" ")) {
|
|
71
|
-
const classSdeKey = `${attrSdeKey}:${c}`;
|
|
72
|
-
sideEffects && markSideEffect(classSdeKey, () => $el.classList.remove(c));
|
|
73
|
-
if (!$el.classList.contains(c))
|
|
74
|
-
$el.classList.add(c);
|
|
75
|
-
}
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (sideEffects && !k.startsWith("data-h-"))
|
|
79
|
-
markSideEffect(attrSdeKey, () => $el.removeAttribute(k));
|
|
80
|
-
if ($el.getAttribute(k) !== value)
|
|
81
|
-
$el.setAttribute(k, value);
|
|
82
|
-
});
|
|
83
|
-
if (TagsWithInnerContent.includes(tag.tag) && $el.innerHTML !== (tag.children || ""))
|
|
84
|
-
$el.innerHTML = tag.children || "";
|
|
95
|
+
const preRenderTag = async (tag) => {
|
|
96
|
+
const entry = head.headEntries().find((e) => e._i === tag._e);
|
|
97
|
+
const renderCtx = {
|
|
98
|
+
renderId: tag._d || hashCode(JSON.stringify({ ...tag, _e: void 0, _p: void 0 })),
|
|
99
|
+
$el: null,
|
|
100
|
+
shouldRender: true,
|
|
101
|
+
tag,
|
|
102
|
+
entry,
|
|
103
|
+
staleSideEffects
|
|
85
104
|
};
|
|
105
|
+
await head.hooks.callHook("dom:beforeRenderTag", renderCtx);
|
|
106
|
+
return renderCtx;
|
|
107
|
+
};
|
|
108
|
+
const renders = [];
|
|
109
|
+
const pendingRenders = {
|
|
110
|
+
body: [],
|
|
111
|
+
head: []
|
|
112
|
+
};
|
|
113
|
+
const markSideEffect = (ctx2, key, fn) => {
|
|
114
|
+
key = `${ctx2.renderId}:${key}`;
|
|
115
|
+
if (ctx2.entry)
|
|
116
|
+
ctx2.entry._sde[key] = fn;
|
|
117
|
+
delete staleSideEffects[key];
|
|
118
|
+
};
|
|
119
|
+
const markEl = (ctx2) => {
|
|
120
|
+
head._elMap[ctx2.renderId] = ctx2.$el;
|
|
121
|
+
renders.push(ctx2);
|
|
122
|
+
markSideEffect(ctx2, "el", () => {
|
|
123
|
+
ctx2.$el?.remove();
|
|
124
|
+
delete head._elMap[ctx2.renderId];
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
for (const t of await head.resolveTags()) {
|
|
128
|
+
const ctx2 = await preRenderTag(t);
|
|
129
|
+
if (!ctx2.shouldRender)
|
|
130
|
+
continue;
|
|
131
|
+
const { tag } = ctx2;
|
|
132
|
+
if (tag.tag === "title") {
|
|
133
|
+
dom.title = tag.children || "";
|
|
134
|
+
renders.push(ctx2);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
86
137
|
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
|
|
87
|
-
|
|
88
|
-
setAttrs(
|
|
89
|
-
|
|
138
|
+
ctx2.$el = dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"];
|
|
139
|
+
setAttrs(ctx2, markSideEffect);
|
|
140
|
+
renders.push(ctx2);
|
|
141
|
+
continue;
|
|
90
142
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const $target = dom[tag.tagPosition?.startsWith("body") ? "body" : "head"];
|
|
95
|
-
if (!$previousEl && tag._hash) {
|
|
96
|
-
$previousEl = $target.querySelector(`${tag.tag}[data-h-${tag._hash}]`);
|
|
143
|
+
ctx2.$el = head._elMap[ctx2.renderId];
|
|
144
|
+
if (!ctx2.$el && tag._hash) {
|
|
145
|
+
ctx2.$el = dom.querySelector(`${tag.tagPosition?.startsWith("body") ? "body" : "head"} > ${tag.tag}[data-h-${tag._hash}]`);
|
|
97
146
|
}
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const key = tagDedupeKey({
|
|
104
|
-
tag: elTag,
|
|
105
|
-
props: $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {})
|
|
106
|
-
});
|
|
107
|
-
if (key === tag._d || $el.isEqualNode($newEl)) {
|
|
108
|
-
$previousEl = $el;
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
147
|
+
if (ctx2.$el) {
|
|
148
|
+
if (ctx2.tag._d)
|
|
149
|
+
setAttrs(ctx2);
|
|
150
|
+
markEl(ctx2);
|
|
151
|
+
continue;
|
|
112
152
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
153
|
+
ctx2.$el = dom.createElement(tag.tag);
|
|
154
|
+
setAttrs(ctx2);
|
|
155
|
+
pendingRenders[tag.tagPosition?.startsWith("body") ? "body" : "head"].push(ctx2);
|
|
156
|
+
}
|
|
157
|
+
Object.entries(pendingRenders).forEach(([pos, queue]) => {
|
|
158
|
+
if (!queue.length)
|
|
159
|
+
return;
|
|
160
|
+
for (const $el of [...dom[pos].children].reverse()) {
|
|
161
|
+
const elTag = $el.tagName.toLowerCase();
|
|
162
|
+
if (!HasElementTags.includes(elTag))
|
|
163
|
+
continue;
|
|
164
|
+
const dedupeKey = tagDedupeKey({
|
|
165
|
+
tag: elTag,
|
|
166
|
+
props: $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {})
|
|
118
167
|
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
$newEl = dom.body.appendChild($newEl);
|
|
128
|
-
break;
|
|
129
|
-
case "bodyOpen":
|
|
130
|
-
$newEl = dom.body.insertBefore($newEl, dom.body.firstChild);
|
|
131
|
-
break;
|
|
132
|
-
case "head":
|
|
133
|
-
default:
|
|
134
|
-
$newEl = dom.head.appendChild($newEl);
|
|
135
|
-
break;
|
|
168
|
+
const matchIdx = queue.findIndex((ctx2) => ctx2 && (ctx2.tag._d === dedupeKey || $el.isEqualNode(ctx2.$el)));
|
|
169
|
+
if (matchIdx !== -1) {
|
|
170
|
+
const ctx2 = queue[matchIdx];
|
|
171
|
+
ctx2.$el = $el;
|
|
172
|
+
setAttrs(ctx2);
|
|
173
|
+
markEl(ctx2);
|
|
174
|
+
delete queue[matchIdx];
|
|
175
|
+
}
|
|
136
176
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
177
|
+
queue.forEach((ctx2) => {
|
|
178
|
+
if (!ctx2.$el)
|
|
179
|
+
return;
|
|
180
|
+
switch (ctx2.tag.tagPosition) {
|
|
181
|
+
case "bodyClose":
|
|
182
|
+
dom.body.appendChild(ctx2.$el);
|
|
183
|
+
break;
|
|
184
|
+
case "bodyOpen":
|
|
185
|
+
dom.body.insertBefore(ctx2.$el, dom.body.firstChild);
|
|
186
|
+
break;
|
|
187
|
+
case "head":
|
|
188
|
+
default:
|
|
189
|
+
dom.head.appendChild(ctx2.$el);
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
markEl(ctx2);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
for (const ctx2 of renders)
|
|
196
|
+
await head.hooks.callHook("dom:renderTag", ctx2);
|
|
149
197
|
Object.values(staleSideEffects).forEach((fn) => fn());
|
|
150
198
|
}
|
|
151
199
|
let domUpdatePromise = null;
|
|
@@ -158,4 +206,4 @@ async function debouncedRenderDOMHead(head, options = {}) {
|
|
|
158
206
|
return domUpdatePromise = domUpdatePromise || new Promise((resolve) => delayFn(() => resolve(doDomUpdate())));
|
|
159
207
|
}
|
|
160
208
|
|
|
161
|
-
export { debouncedRenderDOMHead, domUpdatePromise, renderDOMHead };
|
|
209
|
+
export { debouncedRenderDOMHead, domUpdatePromise, hashCode, renderDOMHead };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unhead/dom",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.7",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@unhead/schema": "0.6.
|
|
33
|
+
"@unhead/schema": "0.6.7"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"zhead": "1.0.0-beta.13"
|