@unhead/dom 1.11.14 → 2.0.0-alpha.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 CHANGED
@@ -1,201 +1,16 @@
1
1
  'use strict';
2
2
 
3
- const shared = require('@unhead/shared');
3
+ const client = require('unhead/client');
4
4
 
5
- async function renderDOMHead(head, options = {}) {
6
- const dom = options.document || head.resolvedOptions.document;
7
- if (!dom || !head.dirty)
8
- return;
9
- const beforeRenderCtx = { shouldRender: true, tags: [] };
10
- await head.hooks.callHook("dom:beforeRender", beforeRenderCtx);
11
- if (!beforeRenderCtx.shouldRender)
12
- return;
13
- if (head._domUpdatePromise) {
14
- return head._domUpdatePromise;
15
- }
16
- head._domUpdatePromise = new Promise(async (resolve) => {
17
- const tags = (await head.resolveTags()).map((tag) => ({
18
- tag,
19
- id: shared.HasElementTags.has(tag.tag) ? shared.hashTag(tag) : tag.tag,
20
- shouldRender: true
21
- }));
22
- let state = head._dom;
23
- if (!state) {
24
- state = {
25
- elMap: { htmlAttrs: dom.documentElement, bodyAttrs: dom.body }
26
- };
27
- const takenDedupeKeys = /* @__PURE__ */ new Set();
28
- for (const key of ["body", "head"]) {
29
- const children = dom[key]?.children;
30
- for (const c of children) {
31
- const tag = c.tagName.toLowerCase();
32
- if (!shared.HasElementTags.has(tag)) {
33
- continue;
34
- }
35
- const t = {
36
- tag,
37
- props: await shared.normaliseProps(
38
- c.getAttributeNames().reduce((props, name) => ({ ...props, [name]: c.getAttribute(name) }), {})
39
- ),
40
- innerHTML: c.innerHTML
41
- };
42
- const dedupeKey = shared.tagDedupeKey(t);
43
- let d = dedupeKey;
44
- let i = 1;
45
- while (d && takenDedupeKeys.has(d))
46
- d = `${dedupeKey}:${i++}`;
47
- if (d) {
48
- t._d = d;
49
- takenDedupeKeys.add(d);
50
- }
51
- state.elMap[c.getAttribute("data-hid") || shared.hashTag(t)] = c;
52
- }
53
- }
54
- }
55
- state.pendingSideEffects = { ...state.sideEffects };
56
- state.sideEffects = {};
57
- function track(id, scope, fn) {
58
- const k = `${id}:${scope}`;
59
- state.sideEffects[k] = fn;
60
- delete state.pendingSideEffects[k];
61
- }
62
- function trackCtx({ id, $el, tag }) {
63
- const isAttrTag = tag.tag.endsWith("Attrs");
64
- state.elMap[id] = $el;
65
- if (!isAttrTag) {
66
- if (tag.textContent && tag.textContent !== $el.textContent) {
67
- $el.textContent = tag.textContent;
68
- }
69
- if (tag.innerHTML && tag.innerHTML !== $el.innerHTML) {
70
- $el.innerHTML = tag.innerHTML;
71
- }
72
- track(id, "el", () => {
73
- state.elMap[id]?.remove();
74
- delete state.elMap[id];
75
- });
76
- }
77
- if (tag._eventHandlers) {
78
- for (const k in tag._eventHandlers) {
79
- if (!Object.prototype.hasOwnProperty.call(tag._eventHandlers, k)) {
80
- continue;
81
- }
82
- if ($el.getAttribute(`data-${k}`) !== "") {
83
- (tag.tag === "bodyAttrs" ? dom.defaultView : $el).addEventListener(
84
- // onload -> load
85
- k.substring(2),
86
- tag._eventHandlers[k].bind($el)
87
- );
88
- $el.setAttribute(`data-${k}`, "");
89
- }
90
- }
91
- }
92
- for (const k in tag.props) {
93
- if (!Object.prototype.hasOwnProperty.call(tag.props, k)) {
94
- continue;
95
- }
96
- const value = tag.props[k];
97
- const ck = `attr:${k}`;
98
- if (k === "class") {
99
- if (!value) {
100
- continue;
101
- }
102
- for (const c of value.split(" ")) {
103
- isAttrTag && track(id, `${ck}:${c}`, () => $el.classList.remove(c));
104
- !$el.classList.contains(c) && $el.classList.add(c);
105
- }
106
- } else if (k === "style") {
107
- if (!value) {
108
- continue;
109
- }
110
- for (const c of value.split(";")) {
111
- const propIndex = c.indexOf(":");
112
- const k2 = c.substring(0, propIndex).trim();
113
- const v = c.substring(propIndex + 1).trim();
114
- track(id, `${ck}:${k2}`, () => {
115
- $el.style.removeProperty(k2);
116
- });
117
- $el.style.setProperty(k2, v);
118
- }
119
- } else {
120
- $el.getAttribute(k) !== value && $el.setAttribute(k, value === true ? "" : String(value));
121
- isAttrTag && track(id, ck, () => $el.removeAttribute(k));
122
- }
123
- }
124
- }
125
- const pending = [];
126
- const frag = {
127
- bodyClose: void 0,
128
- bodyOpen: void 0,
129
- head: void 0
130
- };
131
- for (const ctx of tags) {
132
- const { tag, shouldRender, id } = ctx;
133
- if (!shouldRender)
134
- continue;
135
- if (tag.tag === "title") {
136
- dom.title = tag.textContent;
137
- continue;
138
- }
139
- ctx.$el = ctx.$el || state.elMap[id];
140
- if (ctx.$el) {
141
- trackCtx(ctx);
142
- } else if (shared.HasElementTags.has(tag.tag)) {
143
- pending.push(ctx);
144
- }
145
- }
146
- for (const ctx of pending) {
147
- const pos = ctx.tag.tagPosition || "head";
148
- ctx.$el = dom.createElement(ctx.tag.tag);
149
- trackCtx(ctx);
150
- frag[pos] = frag[pos] || dom.createDocumentFragment();
151
- frag[pos].appendChild(ctx.$el);
152
- }
153
- for (const ctx of tags)
154
- await head.hooks.callHook("dom:renderTag", ctx, dom, track);
155
- frag.head && dom.head.appendChild(frag.head);
156
- frag.bodyOpen && dom.body.insertBefore(frag.bodyOpen, dom.body.firstChild);
157
- frag.bodyClose && dom.body.appendChild(frag.bodyClose);
158
- for (const k in state.pendingSideEffects) {
159
- state.pendingSideEffects[k]();
160
- }
161
- head._dom = state;
162
- await head.hooks.callHook("dom:rendered", { renders: tags });
163
- resolve();
164
- }).finally(() => {
165
- head._domUpdatePromise = void 0;
166
- head.dirty = false;
167
- });
168
- return head._domUpdatePromise;
169
- }
170
5
 
171
- function debouncedRenderDOMHead(head, options = {}) {
172
- const fn = options.delayFn || ((fn2) => setTimeout(fn2, 10));
173
- return head._domDebouncedUpdatePromise = head._domDebouncedUpdatePromise || new Promise((resolve) => fn(() => {
174
- return renderDOMHead(head, options).then(() => {
175
- delete head._domDebouncedUpdatePromise;
176
- resolve();
177
- });
178
- }));
179
- }
180
6
 
181
- // @__NO_SIDE_EFFECTS__
182
- function DomPlugin(options) {
183
- return shared.defineHeadPlugin((head) => {
184
- const initialPayload = head.resolvedOptions.document?.head.querySelector('script[id="unhead:payload"]')?.innerHTML || false;
185
- if (initialPayload) {
186
- head.push(JSON.parse(initialPayload));
187
- }
188
- return {
189
- mode: "client",
190
- hooks: {
191
- "entries:updated": (head2) => {
192
- debouncedRenderDOMHead(head2, options);
193
- }
194
- }
195
- };
196
- });
197
- }
7
+ Object.prototype.hasOwnProperty.call(client, '__proto__') &&
8
+ !Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
9
+ Object.defineProperty(exports, '__proto__', {
10
+ enumerable: true,
11
+ value: client['__proto__']
12
+ });
198
13
 
199
- exports.DomPlugin = DomPlugin;
200
- exports.debouncedRenderDOMHead = debouncedRenderDOMHead;
201
- exports.renderDOMHead = renderDOMHead;
14
+ Object.keys(client).forEach(function (k) {
15
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = client[k];
16
+ });
package/dist/index.d.cts CHANGED
@@ -1,31 +1 @@
1
- import * as _unhead_schema from '@unhead/schema';
2
- import { Unhead } from '@unhead/schema';
3
-
4
- interface RenderDomHeadOptions {
5
- /**
6
- * Document to use for rendering. Allows stubbing for testing.
7
- */
8
- document?: Document;
9
- }
10
- /**
11
- * Render the head tags to the DOM.
12
- */
13
- declare function renderDOMHead<T extends Unhead<any>>(head: T, options?: RenderDomHeadOptions): Promise<void>;
14
-
15
- interface DebouncedRenderDomHeadOptions extends RenderDomHeadOptions {
16
- /**
17
- * Specify a custom delay function for delaying the render.
18
- */
19
- delayFn?: (fn: () => void) => void;
20
- }
21
- /**
22
- * Queue a debounced update of the DOM head.
23
- */
24
- declare function debouncedRenderDOMHead<T extends Unhead<any>>(head: T, options?: DebouncedRenderDomHeadOptions): Promise<void>;
25
-
26
- interface DomPluginOptions extends RenderDomHeadOptions {
27
- delayFn?: (fn: () => void) => void;
28
- }
29
- declare function DomPlugin(options?: DomPluginOptions): _unhead_schema.HeadPluginInput;
30
-
31
- export { type DebouncedRenderDomHeadOptions, DomPlugin, type DomPluginOptions, type RenderDomHeadOptions, debouncedRenderDOMHead, renderDOMHead };
1
+ export * from 'unhead/client';
package/dist/index.d.mts CHANGED
@@ -1,31 +1 @@
1
- import * as _unhead_schema from '@unhead/schema';
2
- import { Unhead } from '@unhead/schema';
3
-
4
- interface RenderDomHeadOptions {
5
- /**
6
- * Document to use for rendering. Allows stubbing for testing.
7
- */
8
- document?: Document;
9
- }
10
- /**
11
- * Render the head tags to the DOM.
12
- */
13
- declare function renderDOMHead<T extends Unhead<any>>(head: T, options?: RenderDomHeadOptions): Promise<void>;
14
-
15
- interface DebouncedRenderDomHeadOptions extends RenderDomHeadOptions {
16
- /**
17
- * Specify a custom delay function for delaying the render.
18
- */
19
- delayFn?: (fn: () => void) => void;
20
- }
21
- /**
22
- * Queue a debounced update of the DOM head.
23
- */
24
- declare function debouncedRenderDOMHead<T extends Unhead<any>>(head: T, options?: DebouncedRenderDomHeadOptions): Promise<void>;
25
-
26
- interface DomPluginOptions extends RenderDomHeadOptions {
27
- delayFn?: (fn: () => void) => void;
28
- }
29
- declare function DomPlugin(options?: DomPluginOptions): _unhead_schema.HeadPluginInput;
30
-
31
- export { type DebouncedRenderDomHeadOptions, DomPlugin, type DomPluginOptions, type RenderDomHeadOptions, debouncedRenderDOMHead, renderDOMHead };
1
+ export * from 'unhead/client';
package/dist/index.d.ts CHANGED
@@ -1,31 +1 @@
1
- import * as _unhead_schema from '@unhead/schema';
2
- import { Unhead } from '@unhead/schema';
3
-
4
- interface RenderDomHeadOptions {
5
- /**
6
- * Document to use for rendering. Allows stubbing for testing.
7
- */
8
- document?: Document;
9
- }
10
- /**
11
- * Render the head tags to the DOM.
12
- */
13
- declare function renderDOMHead<T extends Unhead<any>>(head: T, options?: RenderDomHeadOptions): Promise<void>;
14
-
15
- interface DebouncedRenderDomHeadOptions extends RenderDomHeadOptions {
16
- /**
17
- * Specify a custom delay function for delaying the render.
18
- */
19
- delayFn?: (fn: () => void) => void;
20
- }
21
- /**
22
- * Queue a debounced update of the DOM head.
23
- */
24
- declare function debouncedRenderDOMHead<T extends Unhead<any>>(head: T, options?: DebouncedRenderDomHeadOptions): Promise<void>;
25
-
26
- interface DomPluginOptions extends RenderDomHeadOptions {
27
- delayFn?: (fn: () => void) => void;
28
- }
29
- declare function DomPlugin(options?: DomPluginOptions): _unhead_schema.HeadPluginInput;
30
-
31
- export { type DebouncedRenderDomHeadOptions, DomPlugin, type DomPluginOptions, type RenderDomHeadOptions, debouncedRenderDOMHead, renderDOMHead };
1
+ export * from 'unhead/client';
package/dist/index.mjs CHANGED
@@ -1,197 +1 @@
1
- import { HasElementTags, hashTag, normaliseProps, tagDedupeKey, defineHeadPlugin } from '@unhead/shared';
2
-
3
- async function renderDOMHead(head, options = {}) {
4
- const dom = options.document || head.resolvedOptions.document;
5
- if (!dom || !head.dirty)
6
- return;
7
- const beforeRenderCtx = { shouldRender: true, tags: [] };
8
- await head.hooks.callHook("dom:beforeRender", beforeRenderCtx);
9
- if (!beforeRenderCtx.shouldRender)
10
- return;
11
- if (head._domUpdatePromise) {
12
- return head._domUpdatePromise;
13
- }
14
- head._domUpdatePromise = new Promise(async (resolve) => {
15
- const tags = (await head.resolveTags()).map((tag) => ({
16
- tag,
17
- id: HasElementTags.has(tag.tag) ? hashTag(tag) : tag.tag,
18
- shouldRender: true
19
- }));
20
- let state = head._dom;
21
- if (!state) {
22
- state = {
23
- elMap: { htmlAttrs: dom.documentElement, bodyAttrs: dom.body }
24
- };
25
- const takenDedupeKeys = /* @__PURE__ */ new Set();
26
- for (const key of ["body", "head"]) {
27
- const children = dom[key]?.children;
28
- for (const c of children) {
29
- const tag = c.tagName.toLowerCase();
30
- if (!HasElementTags.has(tag)) {
31
- continue;
32
- }
33
- const t = {
34
- tag,
35
- props: await normaliseProps(
36
- c.getAttributeNames().reduce((props, name) => ({ ...props, [name]: c.getAttribute(name) }), {})
37
- ),
38
- innerHTML: c.innerHTML
39
- };
40
- const dedupeKey = tagDedupeKey(t);
41
- let d = dedupeKey;
42
- let i = 1;
43
- while (d && takenDedupeKeys.has(d))
44
- d = `${dedupeKey}:${i++}`;
45
- if (d) {
46
- t._d = d;
47
- takenDedupeKeys.add(d);
48
- }
49
- state.elMap[c.getAttribute("data-hid") || hashTag(t)] = c;
50
- }
51
- }
52
- }
53
- state.pendingSideEffects = { ...state.sideEffects };
54
- state.sideEffects = {};
55
- function track(id, scope, fn) {
56
- const k = `${id}:${scope}`;
57
- state.sideEffects[k] = fn;
58
- delete state.pendingSideEffects[k];
59
- }
60
- function trackCtx({ id, $el, tag }) {
61
- const isAttrTag = tag.tag.endsWith("Attrs");
62
- state.elMap[id] = $el;
63
- if (!isAttrTag) {
64
- if (tag.textContent && tag.textContent !== $el.textContent) {
65
- $el.textContent = tag.textContent;
66
- }
67
- if (tag.innerHTML && tag.innerHTML !== $el.innerHTML) {
68
- $el.innerHTML = tag.innerHTML;
69
- }
70
- track(id, "el", () => {
71
- state.elMap[id]?.remove();
72
- delete state.elMap[id];
73
- });
74
- }
75
- if (tag._eventHandlers) {
76
- for (const k in tag._eventHandlers) {
77
- if (!Object.prototype.hasOwnProperty.call(tag._eventHandlers, k)) {
78
- continue;
79
- }
80
- if ($el.getAttribute(`data-${k}`) !== "") {
81
- (tag.tag === "bodyAttrs" ? dom.defaultView : $el).addEventListener(
82
- // onload -> load
83
- k.substring(2),
84
- tag._eventHandlers[k].bind($el)
85
- );
86
- $el.setAttribute(`data-${k}`, "");
87
- }
88
- }
89
- }
90
- for (const k in tag.props) {
91
- if (!Object.prototype.hasOwnProperty.call(tag.props, k)) {
92
- continue;
93
- }
94
- const value = tag.props[k];
95
- const ck = `attr:${k}`;
96
- if (k === "class") {
97
- if (!value) {
98
- continue;
99
- }
100
- for (const c of value.split(" ")) {
101
- isAttrTag && track(id, `${ck}:${c}`, () => $el.classList.remove(c));
102
- !$el.classList.contains(c) && $el.classList.add(c);
103
- }
104
- } else if (k === "style") {
105
- if (!value) {
106
- continue;
107
- }
108
- for (const c of value.split(";")) {
109
- const propIndex = c.indexOf(":");
110
- const k2 = c.substring(0, propIndex).trim();
111
- const v = c.substring(propIndex + 1).trim();
112
- track(id, `${ck}:${k2}`, () => {
113
- $el.style.removeProperty(k2);
114
- });
115
- $el.style.setProperty(k2, v);
116
- }
117
- } else {
118
- $el.getAttribute(k) !== value && $el.setAttribute(k, value === true ? "" : String(value));
119
- isAttrTag && track(id, ck, () => $el.removeAttribute(k));
120
- }
121
- }
122
- }
123
- const pending = [];
124
- const frag = {
125
- bodyClose: void 0,
126
- bodyOpen: void 0,
127
- head: void 0
128
- };
129
- for (const ctx of tags) {
130
- const { tag, shouldRender, id } = ctx;
131
- if (!shouldRender)
132
- continue;
133
- if (tag.tag === "title") {
134
- dom.title = tag.textContent;
135
- continue;
136
- }
137
- ctx.$el = ctx.$el || state.elMap[id];
138
- if (ctx.$el) {
139
- trackCtx(ctx);
140
- } else if (HasElementTags.has(tag.tag)) {
141
- pending.push(ctx);
142
- }
143
- }
144
- for (const ctx of pending) {
145
- const pos = ctx.tag.tagPosition || "head";
146
- ctx.$el = dom.createElement(ctx.tag.tag);
147
- trackCtx(ctx);
148
- frag[pos] = frag[pos] || dom.createDocumentFragment();
149
- frag[pos].appendChild(ctx.$el);
150
- }
151
- for (const ctx of tags)
152
- await head.hooks.callHook("dom:renderTag", ctx, dom, track);
153
- frag.head && dom.head.appendChild(frag.head);
154
- frag.bodyOpen && dom.body.insertBefore(frag.bodyOpen, dom.body.firstChild);
155
- frag.bodyClose && dom.body.appendChild(frag.bodyClose);
156
- for (const k in state.pendingSideEffects) {
157
- state.pendingSideEffects[k]();
158
- }
159
- head._dom = state;
160
- await head.hooks.callHook("dom:rendered", { renders: tags });
161
- resolve();
162
- }).finally(() => {
163
- head._domUpdatePromise = void 0;
164
- head.dirty = false;
165
- });
166
- return head._domUpdatePromise;
167
- }
168
-
169
- function debouncedRenderDOMHead(head, options = {}) {
170
- const fn = options.delayFn || ((fn2) => setTimeout(fn2, 10));
171
- return head._domDebouncedUpdatePromise = head._domDebouncedUpdatePromise || new Promise((resolve) => fn(() => {
172
- return renderDOMHead(head, options).then(() => {
173
- delete head._domDebouncedUpdatePromise;
174
- resolve();
175
- });
176
- }));
177
- }
178
-
179
- // @__NO_SIDE_EFFECTS__
180
- function DomPlugin(options) {
181
- return defineHeadPlugin((head) => {
182
- const initialPayload = head.resolvedOptions.document?.head.querySelector('script[id="unhead:payload"]')?.innerHTML || false;
183
- if (initialPayload) {
184
- head.push(JSON.parse(initialPayload));
185
- }
186
- return {
187
- mode: "client",
188
- hooks: {
189
- "entries:updated": (head2) => {
190
- debouncedRenderDOMHead(head2, options);
191
- }
192
- }
193
- };
194
- });
195
- }
196
-
197
- export { DomPlugin, debouncedRenderDOMHead, renderDOMHead };
1
+ export * from 'unhead/client';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unhead/dom",
3
3
  "type": "module",
4
- "version": "1.11.14",
4
+ "version": "2.0.0-alpha.0",
5
5
  "author": "Harlan Wilton <harlan@harlanzw.com>",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/harlan-zw",
@@ -28,13 +28,11 @@
28
28
  "files": [
29
29
  "dist"
30
30
  ],
31
- "dependencies": {
32
- "@unhead/shared": "1.11.14",
33
- "@unhead/schema": "1.11.14"
31
+ "peerDependencies": {
32
+ "unhead": "2.0.0-alpha.0"
34
33
  },
35
34
  "scripts": {
36
- "build": "unbuild .",
37
- "stub": "unbuild . --stub",
38
- "export:sizes": "npx export-size . -r"
35
+ "build": "unbuild ",
36
+ "stub": "unbuild --stub"
39
37
  }
40
38
  }
package/README.md DELETED
@@ -1,12 +0,0 @@
1
- # @unhead/dom
2
-
3
- ## Install
4
-
5
- ```bash
6
- # yarn add @unhead/dom
7
- npm install @unhead/dom
8
- ```
9
-
10
- ## Documentation
11
-
12
- See the [@unhead/dom](https://unhead.unjs.io/guide/getting-started/how-it-works#unheaddom) for how this works.