@unhead/dom 0.6.6 → 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 -89
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +137 -90
- 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,102 +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
|
-
entry._sde[key] = fn;
|
|
66
|
-
delete staleSideEffects[key];
|
|
67
|
-
};
|
|
68
|
-
const setAttrs = ($el, sideEffects = true) => {
|
|
69
|
-
Object.entries(tag.props).forEach(([k, value]) => {
|
|
70
|
-
value = String(value);
|
|
71
|
-
const attrSdeKey = `attr:${k}`;
|
|
72
|
-
if (k === "class") {
|
|
73
|
-
for (const c of value.split(" ")) {
|
|
74
|
-
const classSdeKey = `${attrSdeKey}:${c}`;
|
|
75
|
-
sideEffects && markSideEffect(classSdeKey, () => $el.classList.remove(c));
|
|
76
|
-
if (!$el.classList.contains(c))
|
|
77
|
-
$el.classList.add(c);
|
|
78
|
-
}
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (sideEffects && !k.startsWith("data-h-"))
|
|
82
|
-
markSideEffect(attrSdeKey, () => $el.removeAttribute(k));
|
|
83
|
-
if ($el.getAttribute(k) !== value)
|
|
84
|
-
$el.setAttribute(k, value);
|
|
85
|
-
});
|
|
86
|
-
if (TagsWithInnerContent.includes(tag.tag) && $el.innerHTML !== (tag.children || ""))
|
|
87
|
-
$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
|
|
88
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
|
+
}
|
|
89
139
|
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
|
|
90
|
-
|
|
91
|
-
setAttrs(
|
|
92
|
-
|
|
140
|
+
ctx2.$el = dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"];
|
|
141
|
+
setAttrs(ctx2, markSideEffect);
|
|
142
|
+
renders.push(ctx2);
|
|
143
|
+
continue;
|
|
93
144
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const $target = dom[tag.tagPosition?.startsWith("body") ? "body" : "head"];
|
|
98
|
-
if (!$previousEl && tag._hash) {
|
|
99
|
-
$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}]`);
|
|
100
148
|
}
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const key = tagDedupeKey({
|
|
107
|
-
tag: elTag,
|
|
108
|
-
props: $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {})
|
|
109
|
-
});
|
|
110
|
-
if (key === tag._d || $el.isEqualNode($newEl)) {
|
|
111
|
-
$previousEl = $el;
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
149
|
+
if (ctx2.$el) {
|
|
150
|
+
if (ctx2.tag._d)
|
|
151
|
+
setAttrs(ctx2);
|
|
152
|
+
markEl(ctx2);
|
|
153
|
+
continue;
|
|
115
154
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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) }), {})
|
|
121
169
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
$newEl = dom.body.appendChild($newEl);
|
|
131
|
-
break;
|
|
132
|
-
case "bodyOpen":
|
|
133
|
-
$newEl = dom.body.insertBefore($newEl, dom.body.firstChild);
|
|
134
|
-
break;
|
|
135
|
-
case "head":
|
|
136
|
-
default:
|
|
137
|
-
$newEl = dom.head.appendChild($newEl);
|
|
138
|
-
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
|
+
}
|
|
139
178
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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);
|
|
152
199
|
Object.values(staleSideEffects).forEach((fn) => fn());
|
|
153
200
|
}
|
|
154
201
|
exports.domUpdatePromise = null;
|
|
@@ -162,4 +209,5 @@ async function debouncedRenderDOMHead(head, options = {}) {
|
|
|
162
209
|
}
|
|
163
210
|
|
|
164
211
|
exports.debouncedRenderDOMHead = debouncedRenderDOMHead;
|
|
212
|
+
exports.hashCode = hashCode;
|
|
165
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,102 +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
|
-
entry._sde[key] = fn;
|
|
64
|
-
delete staleSideEffects[key];
|
|
65
|
-
};
|
|
66
|
-
const setAttrs = ($el, sideEffects = true) => {
|
|
67
|
-
Object.entries(tag.props).forEach(([k, value]) => {
|
|
68
|
-
value = String(value);
|
|
69
|
-
const attrSdeKey = `attr:${k}`;
|
|
70
|
-
if (k === "class") {
|
|
71
|
-
for (const c of value.split(" ")) {
|
|
72
|
-
const classSdeKey = `${attrSdeKey}:${c}`;
|
|
73
|
-
sideEffects && markSideEffect(classSdeKey, () => $el.classList.remove(c));
|
|
74
|
-
if (!$el.classList.contains(c))
|
|
75
|
-
$el.classList.add(c);
|
|
76
|
-
}
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (sideEffects && !k.startsWith("data-h-"))
|
|
80
|
-
markSideEffect(attrSdeKey, () => $el.removeAttribute(k));
|
|
81
|
-
if ($el.getAttribute(k) !== value)
|
|
82
|
-
$el.setAttribute(k, value);
|
|
83
|
-
});
|
|
84
|
-
if (TagsWithInnerContent.includes(tag.tag) && $el.innerHTML !== (tag.children || ""))
|
|
85
|
-
$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
|
|
86
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
|
+
}
|
|
87
137
|
if (tag.tag === "htmlAttrs" || tag.tag === "bodyAttrs") {
|
|
88
|
-
|
|
89
|
-
setAttrs(
|
|
90
|
-
|
|
138
|
+
ctx2.$el = dom[tag.tag === "htmlAttrs" ? "documentElement" : "body"];
|
|
139
|
+
setAttrs(ctx2, markSideEffect);
|
|
140
|
+
renders.push(ctx2);
|
|
141
|
+
continue;
|
|
91
142
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const $target = dom[tag.tagPosition?.startsWith("body") ? "body" : "head"];
|
|
96
|
-
if (!$previousEl && tag._hash) {
|
|
97
|
-
$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}]`);
|
|
98
146
|
}
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const key = tagDedupeKey({
|
|
105
|
-
tag: elTag,
|
|
106
|
-
props: $el.getAttributeNames().reduce((props, name) => ({ ...props, [name]: $el.getAttribute(name) }), {})
|
|
107
|
-
});
|
|
108
|
-
if (key === tag._d || $el.isEqualNode($newEl)) {
|
|
109
|
-
$previousEl = $el;
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
147
|
+
if (ctx2.$el) {
|
|
148
|
+
if (ctx2.tag._d)
|
|
149
|
+
setAttrs(ctx2);
|
|
150
|
+
markEl(ctx2);
|
|
151
|
+
continue;
|
|
113
152
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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) }), {})
|
|
119
167
|
});
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
$newEl = dom.body.appendChild($newEl);
|
|
129
|
-
break;
|
|
130
|
-
case "bodyOpen":
|
|
131
|
-
$newEl = dom.body.insertBefore($newEl, dom.body.firstChild);
|
|
132
|
-
break;
|
|
133
|
-
case "head":
|
|
134
|
-
default:
|
|
135
|
-
$newEl = dom.head.appendChild($newEl);
|
|
136
|
-
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
|
+
}
|
|
137
176
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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);
|
|
150
197
|
Object.values(staleSideEffects).forEach((fn) => fn());
|
|
151
198
|
}
|
|
152
199
|
let domUpdatePromise = null;
|
|
@@ -159,4 +206,4 @@ async function debouncedRenderDOMHead(head, options = {}) {
|
|
|
159
206
|
return domUpdatePromise = domUpdatePromise || new Promise((resolve) => delayFn(() => resolve(doDomUpdate())));
|
|
160
207
|
}
|
|
161
208
|
|
|
162
|
-
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"
|