@streetui/dom 1.0.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/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/index.cjs +463 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +215 -0
- package/dist/index.d.ts +215 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
// src/browser-adapter.ts
|
|
2
|
+
var BrowserDOMAdapter = class {
|
|
3
|
+
createElement(tag, ns) {
|
|
4
|
+
if (ns !== void 0) {
|
|
5
|
+
return document.createElementNS(ns, tag);
|
|
6
|
+
}
|
|
7
|
+
return document.createElement(tag);
|
|
8
|
+
}
|
|
9
|
+
createTextNode(data) {
|
|
10
|
+
return document.createTextNode(data);
|
|
11
|
+
}
|
|
12
|
+
createComment(data) {
|
|
13
|
+
return document.createComment(data);
|
|
14
|
+
}
|
|
15
|
+
createFragment() {
|
|
16
|
+
return document.createDocumentFragment();
|
|
17
|
+
}
|
|
18
|
+
appendChild(parent, child) {
|
|
19
|
+
parent.appendChild(child);
|
|
20
|
+
}
|
|
21
|
+
insertBefore(parent, child, reference) {
|
|
22
|
+
parent.insertBefore(child, reference);
|
|
23
|
+
}
|
|
24
|
+
removeChild(parent, child) {
|
|
25
|
+
parent.removeChild(child);
|
|
26
|
+
}
|
|
27
|
+
replaceChild(parent, newChild, oldChild) {
|
|
28
|
+
parent.replaceChild(newChild, oldChild);
|
|
29
|
+
}
|
|
30
|
+
setAttribute(element, name, value) {
|
|
31
|
+
element.setAttribute(name, value);
|
|
32
|
+
}
|
|
33
|
+
removeAttribute(element, name) {
|
|
34
|
+
element.removeAttribute(name);
|
|
35
|
+
}
|
|
36
|
+
getAttribute(element, name) {
|
|
37
|
+
return element.getAttribute(name);
|
|
38
|
+
}
|
|
39
|
+
setProperty(element, name, value) {
|
|
40
|
+
element[name] = value;
|
|
41
|
+
}
|
|
42
|
+
setTextContent(node, text) {
|
|
43
|
+
node.textContent = text;
|
|
44
|
+
}
|
|
45
|
+
getTextContent(node) {
|
|
46
|
+
return node.textContent;
|
|
47
|
+
}
|
|
48
|
+
addEventListener(target, type, handler, options) {
|
|
49
|
+
target.addEventListener(type, handler, options);
|
|
50
|
+
}
|
|
51
|
+
removeEventListener(target, type, handler, options) {
|
|
52
|
+
target.removeEventListener(type, handler, options);
|
|
53
|
+
}
|
|
54
|
+
querySelector(root, selector) {
|
|
55
|
+
return root.querySelector(selector);
|
|
56
|
+
}
|
|
57
|
+
querySelectorAll(root, selector) {
|
|
58
|
+
return root.querySelectorAll(selector);
|
|
59
|
+
}
|
|
60
|
+
getElementById(id) {
|
|
61
|
+
return document.getElementById(id);
|
|
62
|
+
}
|
|
63
|
+
focus(element) {
|
|
64
|
+
element.focus?.();
|
|
65
|
+
}
|
|
66
|
+
isElement(node) {
|
|
67
|
+
return node.nodeType === Node.ELEMENT_NODE;
|
|
68
|
+
}
|
|
69
|
+
isTextNode(node) {
|
|
70
|
+
return node.nodeType === Node.TEXT_NODE;
|
|
71
|
+
}
|
|
72
|
+
tagName(element) {
|
|
73
|
+
return element.tagName.toLowerCase();
|
|
74
|
+
}
|
|
75
|
+
parentNode(node) {
|
|
76
|
+
return node.parentNode;
|
|
77
|
+
}
|
|
78
|
+
nextSibling(node) {
|
|
79
|
+
return node.nextSibling;
|
|
80
|
+
}
|
|
81
|
+
firstChild(node) {
|
|
82
|
+
return node.firstChild;
|
|
83
|
+
}
|
|
84
|
+
childNodes(node) {
|
|
85
|
+
return Array.from(node.childNodes);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var browserDOMAdapter = new BrowserDOMAdapter();
|
|
89
|
+
|
|
90
|
+
// src/server-node.ts
|
|
91
|
+
var ServerStyle = class {
|
|
92
|
+
declarations = /* @__PURE__ */ new Map();
|
|
93
|
+
setProperty(name, value) {
|
|
94
|
+
this.declarations.set(name, value);
|
|
95
|
+
}
|
|
96
|
+
get isEmpty() {
|
|
97
|
+
return this.declarations.size === 0;
|
|
98
|
+
}
|
|
99
|
+
toCss() {
|
|
100
|
+
return [...this.declarations.entries()].map(([k, v]) => `${k}: ${v}`).join("; ");
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var ServerText = class {
|
|
104
|
+
kind = "text";
|
|
105
|
+
parent = null;
|
|
106
|
+
data;
|
|
107
|
+
constructor(data) {
|
|
108
|
+
this.data = data;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var ServerComment = class {
|
|
112
|
+
kind = "comment";
|
|
113
|
+
parent = null;
|
|
114
|
+
data;
|
|
115
|
+
constructor(data) {
|
|
116
|
+
this.data = data;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
var ServerFragment = class {
|
|
120
|
+
kind = "fragment";
|
|
121
|
+
parent = null;
|
|
122
|
+
children = [];
|
|
123
|
+
};
|
|
124
|
+
var ServerElement = class {
|
|
125
|
+
kind = "element";
|
|
126
|
+
parent = null;
|
|
127
|
+
tagName;
|
|
128
|
+
attributes = /* @__PURE__ */ new Map();
|
|
129
|
+
/** JS properties set via `setProperty` (e.g. input `value`, `checked`). */
|
|
130
|
+
properties = /* @__PURE__ */ new Map();
|
|
131
|
+
children = [];
|
|
132
|
+
style = new ServerStyle();
|
|
133
|
+
constructor(tagName) {
|
|
134
|
+
this.tagName = tagName.toLowerCase();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
138
|
+
"area",
|
|
139
|
+
"base",
|
|
140
|
+
"br",
|
|
141
|
+
"col",
|
|
142
|
+
"embed",
|
|
143
|
+
"hr",
|
|
144
|
+
"img",
|
|
145
|
+
"input",
|
|
146
|
+
"link",
|
|
147
|
+
"meta",
|
|
148
|
+
"param",
|
|
149
|
+
"source",
|
|
150
|
+
"track",
|
|
151
|
+
"wbr"
|
|
152
|
+
]);
|
|
153
|
+
var SERIALIZED_PROPERTIES = {
|
|
154
|
+
value: "attr",
|
|
155
|
+
checked: "boolean",
|
|
156
|
+
selected: "boolean"
|
|
157
|
+
};
|
|
158
|
+
function escapeHtmlText(value) {
|
|
159
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
160
|
+
}
|
|
161
|
+
function escapeHtmlAttr(value) {
|
|
162
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
163
|
+
}
|
|
164
|
+
function serializeAttributes(el) {
|
|
165
|
+
const parts = [];
|
|
166
|
+
for (const [name, value] of el.attributes) {
|
|
167
|
+
if (value === "") {
|
|
168
|
+
parts.push(` ${name}`);
|
|
169
|
+
} else {
|
|
170
|
+
parts.push(` ${name}="${escapeHtmlAttr(value)}"`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
for (const [name, kind] of Object.entries(SERIALIZED_PROPERTIES)) {
|
|
174
|
+
if (!el.properties.has(name)) continue;
|
|
175
|
+
if (el.attributes.has(name)) continue;
|
|
176
|
+
const raw = el.properties.get(name);
|
|
177
|
+
if (kind === "boolean") {
|
|
178
|
+
if (raw === true) parts.push(` ${name}`);
|
|
179
|
+
} else {
|
|
180
|
+
if (raw !== void 0 && raw !== null) {
|
|
181
|
+
parts.push(` ${name}="${escapeHtmlAttr(String(raw))}"`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!el.style.isEmpty && !el.attributes.has("style")) {
|
|
186
|
+
parts.push(` style="${escapeHtmlAttr(el.style.toCss())}"`);
|
|
187
|
+
}
|
|
188
|
+
return parts.join("");
|
|
189
|
+
}
|
|
190
|
+
function serializeServerNode(node) {
|
|
191
|
+
switch (node.kind) {
|
|
192
|
+
case "text":
|
|
193
|
+
return escapeHtmlText(node.data);
|
|
194
|
+
case "comment":
|
|
195
|
+
return `<!--${node.data}-->`;
|
|
196
|
+
case "fragment":
|
|
197
|
+
return serializeChildren(node);
|
|
198
|
+
case "element": {
|
|
199
|
+
const el = node;
|
|
200
|
+
const tag = el.tagName;
|
|
201
|
+
const attrs = serializeAttributes(el);
|
|
202
|
+
if (VOID_ELEMENTS.has(tag)) {
|
|
203
|
+
return `<${tag}${attrs}>`;
|
|
204
|
+
}
|
|
205
|
+
return `<${tag}${attrs}>${serializeChildren(el)}</${tag}>`;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function serializeChildren(node) {
|
|
210
|
+
let out = "";
|
|
211
|
+
for (const child of node.children) {
|
|
212
|
+
out += serializeServerNode(child);
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// src/server-adapter.ts
|
|
218
|
+
function asServer(node) {
|
|
219
|
+
return node;
|
|
220
|
+
}
|
|
221
|
+
function asParent(node) {
|
|
222
|
+
return node;
|
|
223
|
+
}
|
|
224
|
+
var ServerDOMAdapter = class {
|
|
225
|
+
createElement(tag, _ns) {
|
|
226
|
+
return new ServerElement(tag);
|
|
227
|
+
}
|
|
228
|
+
createTextNode(data) {
|
|
229
|
+
return new ServerText(data);
|
|
230
|
+
}
|
|
231
|
+
createComment(data) {
|
|
232
|
+
return new ServerComment(data);
|
|
233
|
+
}
|
|
234
|
+
createFragment() {
|
|
235
|
+
return new ServerFragment();
|
|
236
|
+
}
|
|
237
|
+
appendChild(parent, child) {
|
|
238
|
+
const p = asParent(parent);
|
|
239
|
+
const c = asServer(child);
|
|
240
|
+
this._detach(c);
|
|
241
|
+
c.parent = p;
|
|
242
|
+
p.children.push(c);
|
|
243
|
+
}
|
|
244
|
+
insertBefore(parent, child, reference) {
|
|
245
|
+
const p = asParent(parent);
|
|
246
|
+
const c = asServer(child);
|
|
247
|
+
this._detach(c);
|
|
248
|
+
c.parent = p;
|
|
249
|
+
if (reference === null) {
|
|
250
|
+
p.children.push(c);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const ref = asServer(reference);
|
|
254
|
+
const idx = p.children.indexOf(ref);
|
|
255
|
+
if (idx === -1) p.children.push(c);
|
|
256
|
+
else p.children.splice(idx, 0, c);
|
|
257
|
+
}
|
|
258
|
+
removeChild(parent, child) {
|
|
259
|
+
const p = asParent(parent);
|
|
260
|
+
const c = asServer(child);
|
|
261
|
+
const idx = p.children.indexOf(c);
|
|
262
|
+
if (idx !== -1) {
|
|
263
|
+
p.children.splice(idx, 1);
|
|
264
|
+
c.parent = null;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
replaceChild(parent, newChild, oldChild) {
|
|
268
|
+
const p = asParent(parent);
|
|
269
|
+
const nc = asServer(newChild);
|
|
270
|
+
const oc = asServer(oldChild);
|
|
271
|
+
const idx = p.children.indexOf(oc);
|
|
272
|
+
if (idx === -1) return;
|
|
273
|
+
this._detach(nc);
|
|
274
|
+
nc.parent = p;
|
|
275
|
+
p.children.splice(idx, 1, nc);
|
|
276
|
+
oc.parent = null;
|
|
277
|
+
}
|
|
278
|
+
_detach(node) {
|
|
279
|
+
if (node.parent !== null) {
|
|
280
|
+
const siblings = node.parent.children;
|
|
281
|
+
const idx = siblings.indexOf(node);
|
|
282
|
+
if (idx !== -1) siblings.splice(idx, 1);
|
|
283
|
+
node.parent = null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
setAttribute(element, name, value) {
|
|
287
|
+
element.attributes.set(name, value);
|
|
288
|
+
}
|
|
289
|
+
removeAttribute(element, name) {
|
|
290
|
+
element.attributes.delete(name);
|
|
291
|
+
}
|
|
292
|
+
getAttribute(element, name) {
|
|
293
|
+
return element.attributes.get(name) ?? null;
|
|
294
|
+
}
|
|
295
|
+
setProperty(element, name, value) {
|
|
296
|
+
element.properties.set(name, value);
|
|
297
|
+
}
|
|
298
|
+
setTextContent(node, text) {
|
|
299
|
+
const n = asServer(node);
|
|
300
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
301
|
+
const el = n;
|
|
302
|
+
el.children.length = 0;
|
|
303
|
+
const t = new ServerText(text);
|
|
304
|
+
t.parent = el;
|
|
305
|
+
el.children.push(t);
|
|
306
|
+
} else if (n.kind === "text") {
|
|
307
|
+
n.data = text;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
getTextContent(node) {
|
|
311
|
+
const n = asServer(node);
|
|
312
|
+
if (n.kind === "text") return n.data;
|
|
313
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
314
|
+
let out = "";
|
|
315
|
+
for (const c of n.children) {
|
|
316
|
+
out += this.getTextContent(c) ?? "";
|
|
317
|
+
}
|
|
318
|
+
return out;
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
// Server nodes never dispatch events — listeners are a no-op on the server.
|
|
323
|
+
addEventListener() {
|
|
324
|
+
}
|
|
325
|
+
removeEventListener() {
|
|
326
|
+
}
|
|
327
|
+
querySelector() {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
querySelectorAll() {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
getElementById() {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
focus() {
|
|
337
|
+
}
|
|
338
|
+
isElement(node) {
|
|
339
|
+
return asServer(node).kind === "element";
|
|
340
|
+
}
|
|
341
|
+
isTextNode(node) {
|
|
342
|
+
return asServer(node).kind === "text";
|
|
343
|
+
}
|
|
344
|
+
tagName(element) {
|
|
345
|
+
return element.tagName;
|
|
346
|
+
}
|
|
347
|
+
parentNode(node) {
|
|
348
|
+
return asServer(node).parent ?? null;
|
|
349
|
+
}
|
|
350
|
+
nextSibling(node) {
|
|
351
|
+
const n = asServer(node);
|
|
352
|
+
const parent = n.parent;
|
|
353
|
+
if (parent === null) return null;
|
|
354
|
+
const idx = parent.children.indexOf(n);
|
|
355
|
+
if (idx === -1 || idx + 1 >= parent.children.length) return null;
|
|
356
|
+
return parent.children[idx + 1];
|
|
357
|
+
}
|
|
358
|
+
firstChild(node) {
|
|
359
|
+
const n = asServer(node);
|
|
360
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
361
|
+
const el = n;
|
|
362
|
+
return el.children[0] ?? null;
|
|
363
|
+
}
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
childNodes(node) {
|
|
367
|
+
const n = asServer(node);
|
|
368
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
369
|
+
return n.children;
|
|
370
|
+
}
|
|
371
|
+
return [];
|
|
372
|
+
}
|
|
373
|
+
// ── Server-only ────────────────────────────────────────────────────────────
|
|
374
|
+
/** Serialize a node's children ("inner HTML") to an HTML string. */
|
|
375
|
+
serializeInner(node) {
|
|
376
|
+
const n = asServer(node);
|
|
377
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
378
|
+
return serializeChildren(n);
|
|
379
|
+
}
|
|
380
|
+
return "";
|
|
381
|
+
}
|
|
382
|
+
/** Serialize a node (including itself) to an HTML string. */
|
|
383
|
+
serializeOuter(node) {
|
|
384
|
+
return serializeServerNode(asServer(node));
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
var serverDOMAdapter = new ServerDOMAdapter();
|
|
388
|
+
|
|
389
|
+
// src/focus.ts
|
|
390
|
+
var FOCUSABLE_SELECTOR = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
391
|
+
function focusById(dom, root, id) {
|
|
392
|
+
const el = dom.querySelector(root, `[id="${id}"]`);
|
|
393
|
+
if (el === null) return false;
|
|
394
|
+
dom.focus(el);
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
function focusFirst(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
398
|
+
const el = dom.querySelector(container, selector);
|
|
399
|
+
if (el === null) return false;
|
|
400
|
+
dom.focus(el);
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
export {
|
|
404
|
+
BrowserDOMAdapter,
|
|
405
|
+
FOCUSABLE_SELECTOR,
|
|
406
|
+
ServerComment,
|
|
407
|
+
ServerDOMAdapter,
|
|
408
|
+
ServerElement,
|
|
409
|
+
ServerFragment,
|
|
410
|
+
ServerStyle,
|
|
411
|
+
ServerText,
|
|
412
|
+
browserDOMAdapter,
|
|
413
|
+
escapeHtmlAttr,
|
|
414
|
+
escapeHtmlText,
|
|
415
|
+
focusById,
|
|
416
|
+
focusFirst,
|
|
417
|
+
serializeChildren,
|
|
418
|
+
serializeServerNode,
|
|
419
|
+
serverDOMAdapter
|
|
420
|
+
};
|
|
421
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/browser-adapter.ts","../src/server-node.ts","../src/server-adapter.ts","../src/focus.ts"],"sourcesContent":["/**\n * Browser implementation of DOMAdapter — delegates directly to browser APIs.\n */\n\nimport type { DOMAdapter } from './adapter.js';\n\nexport class BrowserDOMAdapter implements DOMAdapter {\n createElement(tag: string, ns?: string): Element {\n if (ns !== undefined) {\n return document.createElementNS(ns, tag);\n }\n return document.createElement(tag);\n }\n\n createTextNode(data: string): Text {\n return document.createTextNode(data);\n }\n\n createComment(data: string): Comment {\n return document.createComment(data);\n }\n\n createFragment(): DocumentFragment {\n return document.createDocumentFragment();\n }\n\n appendChild(parent: Node, child: Node): void {\n parent.appendChild(child);\n }\n\n insertBefore(parent: Node, child: Node, reference: Node | null): void {\n parent.insertBefore(child, reference);\n }\n\n removeChild(parent: Node, child: Node): void {\n parent.removeChild(child);\n }\n\n replaceChild(parent: Node, newChild: Node, oldChild: Node): void {\n parent.replaceChild(newChild, oldChild);\n }\n\n setAttribute(element: Element, name: string, value: string): void {\n element.setAttribute(name, value);\n }\n\n removeAttribute(element: Element, name: string): void {\n element.removeAttribute(name);\n }\n\n getAttribute(element: Element, name: string): string | null {\n return element.getAttribute(name);\n }\n\n setProperty(element: Element, name: string, value: unknown): void {\n (element as unknown as Record<string, unknown>)[name] = value;\n }\n\n setTextContent(node: Node, text: string): void {\n node.textContent = text;\n }\n\n getTextContent(node: Node): string | null {\n return node.textContent;\n }\n\n addEventListener(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: AddEventListenerOptions,\n ): void {\n target.addEventListener(type, handler, options);\n }\n\n removeEventListener(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: EventListenerOptions,\n ): void {\n target.removeEventListener(type, handler, options);\n }\n\n querySelector(root: Element | Document, selector: string): Element | null {\n return root.querySelector(selector);\n }\n\n querySelectorAll(root: Element | Document, selector: string): NodeListOf<Element> {\n return root.querySelectorAll(selector);\n }\n\n getElementById(id: string): Element | null {\n return document.getElementById(id);\n }\n\n focus(element: Element): void {\n (element as unknown as { focus?: () => void }).focus?.();\n }\n\n isElement(node: Node): node is Element {\n return node.nodeType === Node.ELEMENT_NODE;\n }\n\n isTextNode(node: Node): node is Text {\n return node.nodeType === Node.TEXT_NODE;\n }\n\n tagName(element: Element): string {\n return element.tagName.toLowerCase();\n }\n\n parentNode(node: Node): Node | null {\n return node.parentNode;\n }\n\n nextSibling(node: Node): Node | null {\n return node.nextSibling;\n }\n\n firstChild(node: Node): Node | null {\n return node.firstChild;\n }\n\n childNodes(node: Node): Node[] {\n return Array.from(node.childNodes);\n }\n}\n\nexport const browserDOMAdapter = new BrowserDOMAdapter();\n","/**\n * Server-side DOM node model.\n *\n * A tiny, dependency-free tree of plain objects that mirrors just enough of the\n * browser DOM for StreetUI's renderer to build a tree on the server and\n * serialize it to an HTML string. There is NO browser global here — these are\n * ordinary classes usable in any JavaScript environment (Node, workers, tests).\n *\n * The renderer never touches these types directly; it goes through the\n * `DOMAdapter` interface, and `ServerDOMAdapter` translates adapter calls into\n * operations on this model.\n */\n\nexport type ServerNodeKind = 'element' | 'text' | 'comment' | 'fragment';\n\nexport interface ServerNode {\n readonly kind: ServerNodeKind;\n parent: ServerParent | null;\n}\n\nexport type ServerParent = ServerElement | ServerFragment;\n\n/** A minimal inline-style holder mirroring `element.style.setProperty`. */\nexport class ServerStyle {\n readonly declarations = new Map<string, string>();\n setProperty(name: string, value: string): void {\n this.declarations.set(name, value);\n }\n get isEmpty(): boolean {\n return this.declarations.size === 0;\n }\n toCss(): string {\n return [...this.declarations.entries()].map(([k, v]) => `${k}: ${v}`).join('; ');\n }\n}\n\nexport class ServerText implements ServerNode {\n readonly kind = 'text' as const;\n parent: ServerParent | null = null;\n data: string;\n constructor(data: string) {\n this.data = data;\n }\n}\n\nexport class ServerComment implements ServerNode {\n readonly kind = 'comment' as const;\n parent: ServerParent | null = null;\n data: string;\n constructor(data: string) {\n this.data = data;\n }\n}\n\nexport class ServerFragment implements ServerNode {\n readonly kind = 'fragment' as const;\n parent: ServerParent | null = null;\n readonly children: ServerNode[] = [];\n}\n\nexport class ServerElement implements ServerNode {\n readonly kind = 'element' as const;\n parent: ServerParent | null = null;\n readonly tagName: string;\n readonly attributes = new Map<string, string>();\n /** JS properties set via `setProperty` (e.g. input `value`, `checked`). */\n readonly properties = new Map<string, unknown>();\n readonly children: ServerNode[] = [];\n readonly style = new ServerStyle();\n\n constructor(tagName: string) {\n this.tagName = tagName.toLowerCase();\n }\n}\n\n// ── HTML serialization ─────────────────────────────────────────────────────────\n\n/**\n * HTML \"void\" elements — self-closing, never given a closing tag or children.\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\n/**\n * Element properties that should be reflected into the serialized HTML so the\n * hydrated DOM carries the same initial state. `value`/`checked` matter for\n * form controls whose live state is a JS property, not an attribute.\n */\nconst SERIALIZED_PROPERTIES: Record<string, 'attr' | 'boolean'> = {\n value: 'attr',\n checked: 'boolean',\n selected: 'boolean',\n};\n\n/** Escape text node content. */\nexport function escapeHtmlText(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\n/** Escape a double-quoted attribute value. */\nexport function escapeHtmlAttr(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nfunction serializeAttributes(el: ServerElement): string {\n const parts: string[] = [];\n\n for (const [name, value] of el.attributes) {\n if (value === '') {\n parts.push(` ${name}`);\n } else {\n parts.push(` ${name}=\"${escapeHtmlAttr(value)}\"`);\n }\n }\n\n for (const [name, kind] of Object.entries(SERIALIZED_PROPERTIES)) {\n if (!el.properties.has(name)) continue;\n if (el.attributes.has(name)) continue; // an explicit attribute already won\n const raw = el.properties.get(name);\n if (kind === 'boolean') {\n if (raw === true) parts.push(` ${name}`);\n } else {\n if (raw !== undefined && raw !== null) {\n parts.push(` ${name}=\"${escapeHtmlAttr(String(raw))}\"`);\n }\n }\n }\n\n if (!el.style.isEmpty && !el.attributes.has('style')) {\n parts.push(` style=\"${escapeHtmlAttr(el.style.toCss())}\"`);\n }\n\n return parts.join('');\n}\n\n/** Serialize a single server node (element/text/comment/fragment) to HTML. */\nexport function serializeServerNode(node: ServerNode): string {\n switch (node.kind) {\n case 'text':\n return escapeHtmlText((node as ServerText).data);\n case 'comment':\n return `<!--${(node as ServerComment).data}-->`;\n case 'fragment':\n return serializeChildren(node as ServerFragment);\n case 'element': {\n const el = node as ServerElement;\n const tag = el.tagName;\n const attrs = serializeAttributes(el);\n if (VOID_ELEMENTS.has(tag)) {\n return `<${tag}${attrs}>`;\n }\n return `<${tag}${attrs}>${serializeChildren(el)}</${tag}>`;\n }\n }\n}\n\n/** Serialize the children of an element or fragment (its \"inner HTML\"). */\nexport function serializeChildren(node: ServerElement | ServerFragment): string {\n let out = '';\n for (const child of node.children) {\n out += serializeServerNode(child);\n }\n return out;\n}\n","/**\n * Server implementation of `DOMAdapter`.\n *\n * Builds a lightweight in-memory tree (see `server-node.ts`) instead of touching\n * a real browser DOM, then lets the caller serialize it to an HTML string. It is\n * completely free of browser globals, so the exact same renderer that runs in\n * the browser can produce HTML on the server.\n *\n * The `DOMAdapter` interface is typed against the lib DOM types (`Element`,\n * `Node`, `Text`, …). Our server nodes structurally stand in for those at\n * runtime, so the boundary uses `as unknown as` casts in one place. Everything\n * inside operates on the real server-node model.\n */\n\nimport type { DOMAdapter } from './adapter.js';\nimport {\n ServerElement,\n ServerText,\n ServerComment,\n ServerFragment,\n serializeChildren,\n serializeServerNode,\n type ServerNode,\n type ServerParent,\n} from './server-node.js';\n\nfunction asServer(node: unknown): ServerNode {\n return node as unknown as ServerNode;\n}\nfunction asParent(node: unknown): ServerParent {\n return node as unknown as ServerParent;\n}\n\nexport class ServerDOMAdapter implements DOMAdapter {\n createElement(tag: string, _ns?: string): Element {\n return new ServerElement(tag) as unknown as Element;\n }\n\n createTextNode(data: string): Text {\n return new ServerText(data) as unknown as Text;\n }\n\n createComment(data: string): Comment {\n return new ServerComment(data) as unknown as Comment;\n }\n\n createFragment(): DocumentFragment {\n return new ServerFragment() as unknown as DocumentFragment;\n }\n\n appendChild(parent: Node, child: Node): void {\n const p = asParent(parent);\n const c = asServer(child);\n this._detach(c);\n c.parent = p;\n p.children.push(c);\n }\n\n insertBefore(parent: Node, child: Node, reference: Node | null): void {\n const p = asParent(parent);\n const c = asServer(child);\n this._detach(c);\n c.parent = p;\n if (reference === null) {\n p.children.push(c);\n return;\n }\n const ref = asServer(reference);\n const idx = p.children.indexOf(ref);\n if (idx === -1) p.children.push(c);\n else p.children.splice(idx, 0, c);\n }\n\n removeChild(parent: Node, child: Node): void {\n const p = asParent(parent);\n const c = asServer(child);\n const idx = p.children.indexOf(c);\n if (idx !== -1) {\n p.children.splice(idx, 1);\n c.parent = null;\n }\n }\n\n replaceChild(parent: Node, newChild: Node, oldChild: Node): void {\n const p = asParent(parent);\n const nc = asServer(newChild);\n const oc = asServer(oldChild);\n const idx = p.children.indexOf(oc);\n if (idx === -1) return;\n this._detach(nc);\n nc.parent = p;\n p.children.splice(idx, 1, nc);\n oc.parent = null;\n }\n\n private _detach(node: ServerNode): void {\n if (node.parent !== null) {\n const siblings = node.parent.children;\n const idx = siblings.indexOf(node);\n if (idx !== -1) siblings.splice(idx, 1);\n node.parent = null;\n }\n }\n\n setAttribute(element: Element, name: string, value: string): void {\n (element as unknown as ServerElement).attributes.set(name, value);\n }\n\n removeAttribute(element: Element, name: string): void {\n (element as unknown as ServerElement).attributes.delete(name);\n }\n\n getAttribute(element: Element, name: string): string | null {\n return (element as unknown as ServerElement).attributes.get(name) ?? null;\n }\n\n setProperty(element: Element, name: string, value: unknown): void {\n (element as unknown as ServerElement).properties.set(name, value);\n }\n\n setTextContent(node: Node, text: string): void {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n const el = n as ServerElement | ServerFragment;\n el.children.length = 0;\n const t = new ServerText(text);\n t.parent = el;\n el.children.push(t);\n } else if (n.kind === 'text') {\n (n as ServerText).data = text;\n }\n }\n\n getTextContent(node: Node): string | null {\n const n = asServer(node);\n if (n.kind === 'text') return (n as ServerText).data;\n if (n.kind === 'element' || n.kind === 'fragment') {\n let out = '';\n for (const c of (n as ServerElement | ServerFragment).children) {\n out += this.getTextContent(c as unknown as Node) ?? '';\n }\n return out;\n }\n return null;\n }\n\n // Server nodes never dispatch events — listeners are a no-op on the server.\n addEventListener(): void {\n /* no-op on the server */\n }\n removeEventListener(): void {\n /* no-op on the server */\n }\n\n querySelector(): Element | null {\n return null;\n }\n querySelectorAll(): NodeListOf<Element> {\n return [] as unknown as NodeListOf<Element>;\n }\n getElementById(): Element | null {\n return null;\n }\n\n focus(): void {\n // No focus concept on the server — intentional no-op (SSR-safe).\n }\n\n isElement(node: Node): node is Element {\n return asServer(node).kind === 'element';\n }\n\n isTextNode(node: Node): node is Text {\n return asServer(node).kind === 'text';\n }\n\n tagName(element: Element): string {\n return (element as unknown as ServerElement).tagName;\n }\n\n parentNode(node: Node): Node | null {\n return (asServer(node).parent as unknown as Node | null) ?? null;\n }\n\n nextSibling(node: Node): Node | null {\n const n = asServer(node);\n const parent = n.parent;\n if (parent === null) return null;\n const idx = parent.children.indexOf(n);\n if (idx === -1 || idx + 1 >= parent.children.length) return null;\n return parent.children[idx + 1] as unknown as Node;\n }\n\n firstChild(node: Node): Node | null {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n const el = n as ServerElement | ServerFragment;\n return (el.children[0] as unknown as Node) ?? null;\n }\n return null;\n }\n\n childNodes(node: Node): Node[] {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n return (n as ServerElement | ServerFragment).children as unknown as Node[];\n }\n return [];\n }\n\n // ── Server-only ────────────────────────────────────────────────────────────\n\n /** Serialize a node's children (\"inner HTML\") to an HTML string. */\n serializeInner(node: Node): string {\n const n = asServer(node);\n if (n.kind === 'element' || n.kind === 'fragment') {\n return serializeChildren(n as ServerElement | ServerFragment);\n }\n return '';\n }\n\n /** Serialize a node (including itself) to an HTML string. */\n serializeOuter(node: Node): string {\n return serializeServerNode(asServer(node));\n }\n}\n\nexport const serverDOMAdapter = new ServerDOMAdapter();\n","/**\n * Focus helpers built on the {@link DOMAdapter} abstraction.\n *\n * These are the minimal, genuinely-useful focus operations an app needs:\n * focus a specific element (e.g. the first field when a route or modal opens)\n * or focus the first focusable element inside a container (e.g. move focus\n * into a dialog). Both go through the adapter, so they are no-ops on the server\n * (`ServerDOMAdapter.querySelector` returns null / `focus` does nothing) and\n * therefore safe to call from universal code.\n */\n\nimport type { DOMAdapter } from './adapter.js';\n\n/** Default selector for natively focusable / tabbable elements. */\nexport const FOCUSABLE_SELECTOR =\n 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Focus the element with the given id, scoped to `root`.\n * Returns true if an element was found and focused.\n */\nexport function focusById(dom: DOMAdapter, root: Element | Document, id: string): boolean {\n const el = dom.querySelector(root, `[id=\"${id}\"]`);\n if (el === null) return false;\n dom.focus(el);\n return true;\n}\n\n/**\n * Focus the first focusable element inside `container`.\n * Returns true if a focusable element was found and focused.\n */\nexport function focusFirst(\n dom: DOMAdapter,\n container: Element | Document,\n selector: string = FOCUSABLE_SELECTOR,\n): boolean {\n const el = dom.querySelector(container, selector);\n if (el === null) return false;\n dom.focus(el);\n return true;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@streetui/dom",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "StreetUI DOM abstraction layer",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"clean": "rm -rf dist"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"typescript": "*",
|
|
29
|
+
"tsup": "*",
|
|
30
|
+
"vitest": "*",
|
|
31
|
+
"happy-dom": "*"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"sideEffects": false,
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
]
|
|
43
|
+
}
|