@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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 StreetUI contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @streetui/dom
|
|
2
|
+
|
|
3
|
+
StreetUI DOM abstraction layer
|
|
4
|
+
|
|
5
|
+
Part of [StreetUI](https://github.com/streetui/streetui) — a semantic,
|
|
6
|
+
signal-based UI framework with its own reactivity and keyed DOM reconciler
|
|
7
|
+
(no virtual DOM).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @streetui/dom
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import * as pkg from '@streetui/dom';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Both ESM (`import`) and CommonJS (`require`) entry points are shipped, with
|
|
22
|
+
matching TypeScript declarations.
|
|
23
|
+
|
|
24
|
+
## License
|
|
25
|
+
|
|
26
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
BrowserDOMAdapter: () => BrowserDOMAdapter,
|
|
24
|
+
FOCUSABLE_SELECTOR: () => FOCUSABLE_SELECTOR,
|
|
25
|
+
ServerComment: () => ServerComment,
|
|
26
|
+
ServerDOMAdapter: () => ServerDOMAdapter,
|
|
27
|
+
ServerElement: () => ServerElement,
|
|
28
|
+
ServerFragment: () => ServerFragment,
|
|
29
|
+
ServerStyle: () => ServerStyle,
|
|
30
|
+
ServerText: () => ServerText,
|
|
31
|
+
browserDOMAdapter: () => browserDOMAdapter,
|
|
32
|
+
escapeHtmlAttr: () => escapeHtmlAttr,
|
|
33
|
+
escapeHtmlText: () => escapeHtmlText,
|
|
34
|
+
focusById: () => focusById,
|
|
35
|
+
focusFirst: () => focusFirst,
|
|
36
|
+
serializeChildren: () => serializeChildren,
|
|
37
|
+
serializeServerNode: () => serializeServerNode,
|
|
38
|
+
serverDOMAdapter: () => serverDOMAdapter
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
|
+
|
|
42
|
+
// src/browser-adapter.ts
|
|
43
|
+
var BrowserDOMAdapter = class {
|
|
44
|
+
createElement(tag, ns) {
|
|
45
|
+
if (ns !== void 0) {
|
|
46
|
+
return document.createElementNS(ns, tag);
|
|
47
|
+
}
|
|
48
|
+
return document.createElement(tag);
|
|
49
|
+
}
|
|
50
|
+
createTextNode(data) {
|
|
51
|
+
return document.createTextNode(data);
|
|
52
|
+
}
|
|
53
|
+
createComment(data) {
|
|
54
|
+
return document.createComment(data);
|
|
55
|
+
}
|
|
56
|
+
createFragment() {
|
|
57
|
+
return document.createDocumentFragment();
|
|
58
|
+
}
|
|
59
|
+
appendChild(parent, child) {
|
|
60
|
+
parent.appendChild(child);
|
|
61
|
+
}
|
|
62
|
+
insertBefore(parent, child, reference) {
|
|
63
|
+
parent.insertBefore(child, reference);
|
|
64
|
+
}
|
|
65
|
+
removeChild(parent, child) {
|
|
66
|
+
parent.removeChild(child);
|
|
67
|
+
}
|
|
68
|
+
replaceChild(parent, newChild, oldChild) {
|
|
69
|
+
parent.replaceChild(newChild, oldChild);
|
|
70
|
+
}
|
|
71
|
+
setAttribute(element, name, value) {
|
|
72
|
+
element.setAttribute(name, value);
|
|
73
|
+
}
|
|
74
|
+
removeAttribute(element, name) {
|
|
75
|
+
element.removeAttribute(name);
|
|
76
|
+
}
|
|
77
|
+
getAttribute(element, name) {
|
|
78
|
+
return element.getAttribute(name);
|
|
79
|
+
}
|
|
80
|
+
setProperty(element, name, value) {
|
|
81
|
+
element[name] = value;
|
|
82
|
+
}
|
|
83
|
+
setTextContent(node, text) {
|
|
84
|
+
node.textContent = text;
|
|
85
|
+
}
|
|
86
|
+
getTextContent(node) {
|
|
87
|
+
return node.textContent;
|
|
88
|
+
}
|
|
89
|
+
addEventListener(target, type, handler, options) {
|
|
90
|
+
target.addEventListener(type, handler, options);
|
|
91
|
+
}
|
|
92
|
+
removeEventListener(target, type, handler, options) {
|
|
93
|
+
target.removeEventListener(type, handler, options);
|
|
94
|
+
}
|
|
95
|
+
querySelector(root, selector) {
|
|
96
|
+
return root.querySelector(selector);
|
|
97
|
+
}
|
|
98
|
+
querySelectorAll(root, selector) {
|
|
99
|
+
return root.querySelectorAll(selector);
|
|
100
|
+
}
|
|
101
|
+
getElementById(id) {
|
|
102
|
+
return document.getElementById(id);
|
|
103
|
+
}
|
|
104
|
+
focus(element) {
|
|
105
|
+
element.focus?.();
|
|
106
|
+
}
|
|
107
|
+
isElement(node) {
|
|
108
|
+
return node.nodeType === Node.ELEMENT_NODE;
|
|
109
|
+
}
|
|
110
|
+
isTextNode(node) {
|
|
111
|
+
return node.nodeType === Node.TEXT_NODE;
|
|
112
|
+
}
|
|
113
|
+
tagName(element) {
|
|
114
|
+
return element.tagName.toLowerCase();
|
|
115
|
+
}
|
|
116
|
+
parentNode(node) {
|
|
117
|
+
return node.parentNode;
|
|
118
|
+
}
|
|
119
|
+
nextSibling(node) {
|
|
120
|
+
return node.nextSibling;
|
|
121
|
+
}
|
|
122
|
+
firstChild(node) {
|
|
123
|
+
return node.firstChild;
|
|
124
|
+
}
|
|
125
|
+
childNodes(node) {
|
|
126
|
+
return Array.from(node.childNodes);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var browserDOMAdapter = new BrowserDOMAdapter();
|
|
130
|
+
|
|
131
|
+
// src/server-node.ts
|
|
132
|
+
var ServerStyle = class {
|
|
133
|
+
declarations = /* @__PURE__ */ new Map();
|
|
134
|
+
setProperty(name, value) {
|
|
135
|
+
this.declarations.set(name, value);
|
|
136
|
+
}
|
|
137
|
+
get isEmpty() {
|
|
138
|
+
return this.declarations.size === 0;
|
|
139
|
+
}
|
|
140
|
+
toCss() {
|
|
141
|
+
return [...this.declarations.entries()].map(([k, v]) => `${k}: ${v}`).join("; ");
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var ServerText = class {
|
|
145
|
+
kind = "text";
|
|
146
|
+
parent = null;
|
|
147
|
+
data;
|
|
148
|
+
constructor(data) {
|
|
149
|
+
this.data = data;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
var ServerComment = class {
|
|
153
|
+
kind = "comment";
|
|
154
|
+
parent = null;
|
|
155
|
+
data;
|
|
156
|
+
constructor(data) {
|
|
157
|
+
this.data = data;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var ServerFragment = class {
|
|
161
|
+
kind = "fragment";
|
|
162
|
+
parent = null;
|
|
163
|
+
children = [];
|
|
164
|
+
};
|
|
165
|
+
var ServerElement = class {
|
|
166
|
+
kind = "element";
|
|
167
|
+
parent = null;
|
|
168
|
+
tagName;
|
|
169
|
+
attributes = /* @__PURE__ */ new Map();
|
|
170
|
+
/** JS properties set via `setProperty` (e.g. input `value`, `checked`). */
|
|
171
|
+
properties = /* @__PURE__ */ new Map();
|
|
172
|
+
children = [];
|
|
173
|
+
style = new ServerStyle();
|
|
174
|
+
constructor(tagName) {
|
|
175
|
+
this.tagName = tagName.toLowerCase();
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
179
|
+
"area",
|
|
180
|
+
"base",
|
|
181
|
+
"br",
|
|
182
|
+
"col",
|
|
183
|
+
"embed",
|
|
184
|
+
"hr",
|
|
185
|
+
"img",
|
|
186
|
+
"input",
|
|
187
|
+
"link",
|
|
188
|
+
"meta",
|
|
189
|
+
"param",
|
|
190
|
+
"source",
|
|
191
|
+
"track",
|
|
192
|
+
"wbr"
|
|
193
|
+
]);
|
|
194
|
+
var SERIALIZED_PROPERTIES = {
|
|
195
|
+
value: "attr",
|
|
196
|
+
checked: "boolean",
|
|
197
|
+
selected: "boolean"
|
|
198
|
+
};
|
|
199
|
+
function escapeHtmlText(value) {
|
|
200
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
201
|
+
}
|
|
202
|
+
function escapeHtmlAttr(value) {
|
|
203
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
204
|
+
}
|
|
205
|
+
function serializeAttributes(el) {
|
|
206
|
+
const parts = [];
|
|
207
|
+
for (const [name, value] of el.attributes) {
|
|
208
|
+
if (value === "") {
|
|
209
|
+
parts.push(` ${name}`);
|
|
210
|
+
} else {
|
|
211
|
+
parts.push(` ${name}="${escapeHtmlAttr(value)}"`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
for (const [name, kind] of Object.entries(SERIALIZED_PROPERTIES)) {
|
|
215
|
+
if (!el.properties.has(name)) continue;
|
|
216
|
+
if (el.attributes.has(name)) continue;
|
|
217
|
+
const raw = el.properties.get(name);
|
|
218
|
+
if (kind === "boolean") {
|
|
219
|
+
if (raw === true) parts.push(` ${name}`);
|
|
220
|
+
} else {
|
|
221
|
+
if (raw !== void 0 && raw !== null) {
|
|
222
|
+
parts.push(` ${name}="${escapeHtmlAttr(String(raw))}"`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (!el.style.isEmpty && !el.attributes.has("style")) {
|
|
227
|
+
parts.push(` style="${escapeHtmlAttr(el.style.toCss())}"`);
|
|
228
|
+
}
|
|
229
|
+
return parts.join("");
|
|
230
|
+
}
|
|
231
|
+
function serializeServerNode(node) {
|
|
232
|
+
switch (node.kind) {
|
|
233
|
+
case "text":
|
|
234
|
+
return escapeHtmlText(node.data);
|
|
235
|
+
case "comment":
|
|
236
|
+
return `<!--${node.data}-->`;
|
|
237
|
+
case "fragment":
|
|
238
|
+
return serializeChildren(node);
|
|
239
|
+
case "element": {
|
|
240
|
+
const el = node;
|
|
241
|
+
const tag = el.tagName;
|
|
242
|
+
const attrs = serializeAttributes(el);
|
|
243
|
+
if (VOID_ELEMENTS.has(tag)) {
|
|
244
|
+
return `<${tag}${attrs}>`;
|
|
245
|
+
}
|
|
246
|
+
return `<${tag}${attrs}>${serializeChildren(el)}</${tag}>`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function serializeChildren(node) {
|
|
251
|
+
let out = "";
|
|
252
|
+
for (const child of node.children) {
|
|
253
|
+
out += serializeServerNode(child);
|
|
254
|
+
}
|
|
255
|
+
return out;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/server-adapter.ts
|
|
259
|
+
function asServer(node) {
|
|
260
|
+
return node;
|
|
261
|
+
}
|
|
262
|
+
function asParent(node) {
|
|
263
|
+
return node;
|
|
264
|
+
}
|
|
265
|
+
var ServerDOMAdapter = class {
|
|
266
|
+
createElement(tag, _ns) {
|
|
267
|
+
return new ServerElement(tag);
|
|
268
|
+
}
|
|
269
|
+
createTextNode(data) {
|
|
270
|
+
return new ServerText(data);
|
|
271
|
+
}
|
|
272
|
+
createComment(data) {
|
|
273
|
+
return new ServerComment(data);
|
|
274
|
+
}
|
|
275
|
+
createFragment() {
|
|
276
|
+
return new ServerFragment();
|
|
277
|
+
}
|
|
278
|
+
appendChild(parent, child) {
|
|
279
|
+
const p = asParent(parent);
|
|
280
|
+
const c = asServer(child);
|
|
281
|
+
this._detach(c);
|
|
282
|
+
c.parent = p;
|
|
283
|
+
p.children.push(c);
|
|
284
|
+
}
|
|
285
|
+
insertBefore(parent, child, reference) {
|
|
286
|
+
const p = asParent(parent);
|
|
287
|
+
const c = asServer(child);
|
|
288
|
+
this._detach(c);
|
|
289
|
+
c.parent = p;
|
|
290
|
+
if (reference === null) {
|
|
291
|
+
p.children.push(c);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const ref = asServer(reference);
|
|
295
|
+
const idx = p.children.indexOf(ref);
|
|
296
|
+
if (idx === -1) p.children.push(c);
|
|
297
|
+
else p.children.splice(idx, 0, c);
|
|
298
|
+
}
|
|
299
|
+
removeChild(parent, child) {
|
|
300
|
+
const p = asParent(parent);
|
|
301
|
+
const c = asServer(child);
|
|
302
|
+
const idx = p.children.indexOf(c);
|
|
303
|
+
if (idx !== -1) {
|
|
304
|
+
p.children.splice(idx, 1);
|
|
305
|
+
c.parent = null;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
replaceChild(parent, newChild, oldChild) {
|
|
309
|
+
const p = asParent(parent);
|
|
310
|
+
const nc = asServer(newChild);
|
|
311
|
+
const oc = asServer(oldChild);
|
|
312
|
+
const idx = p.children.indexOf(oc);
|
|
313
|
+
if (idx === -1) return;
|
|
314
|
+
this._detach(nc);
|
|
315
|
+
nc.parent = p;
|
|
316
|
+
p.children.splice(idx, 1, nc);
|
|
317
|
+
oc.parent = null;
|
|
318
|
+
}
|
|
319
|
+
_detach(node) {
|
|
320
|
+
if (node.parent !== null) {
|
|
321
|
+
const siblings = node.parent.children;
|
|
322
|
+
const idx = siblings.indexOf(node);
|
|
323
|
+
if (idx !== -1) siblings.splice(idx, 1);
|
|
324
|
+
node.parent = null;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
setAttribute(element, name, value) {
|
|
328
|
+
element.attributes.set(name, value);
|
|
329
|
+
}
|
|
330
|
+
removeAttribute(element, name) {
|
|
331
|
+
element.attributes.delete(name);
|
|
332
|
+
}
|
|
333
|
+
getAttribute(element, name) {
|
|
334
|
+
return element.attributes.get(name) ?? null;
|
|
335
|
+
}
|
|
336
|
+
setProperty(element, name, value) {
|
|
337
|
+
element.properties.set(name, value);
|
|
338
|
+
}
|
|
339
|
+
setTextContent(node, text) {
|
|
340
|
+
const n = asServer(node);
|
|
341
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
342
|
+
const el = n;
|
|
343
|
+
el.children.length = 0;
|
|
344
|
+
const t = new ServerText(text);
|
|
345
|
+
t.parent = el;
|
|
346
|
+
el.children.push(t);
|
|
347
|
+
} else if (n.kind === "text") {
|
|
348
|
+
n.data = text;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
getTextContent(node) {
|
|
352
|
+
const n = asServer(node);
|
|
353
|
+
if (n.kind === "text") return n.data;
|
|
354
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
355
|
+
let out = "";
|
|
356
|
+
for (const c of n.children) {
|
|
357
|
+
out += this.getTextContent(c) ?? "";
|
|
358
|
+
}
|
|
359
|
+
return out;
|
|
360
|
+
}
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
// Server nodes never dispatch events — listeners are a no-op on the server.
|
|
364
|
+
addEventListener() {
|
|
365
|
+
}
|
|
366
|
+
removeEventListener() {
|
|
367
|
+
}
|
|
368
|
+
querySelector() {
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
querySelectorAll() {
|
|
372
|
+
return [];
|
|
373
|
+
}
|
|
374
|
+
getElementById() {
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
focus() {
|
|
378
|
+
}
|
|
379
|
+
isElement(node) {
|
|
380
|
+
return asServer(node).kind === "element";
|
|
381
|
+
}
|
|
382
|
+
isTextNode(node) {
|
|
383
|
+
return asServer(node).kind === "text";
|
|
384
|
+
}
|
|
385
|
+
tagName(element) {
|
|
386
|
+
return element.tagName;
|
|
387
|
+
}
|
|
388
|
+
parentNode(node) {
|
|
389
|
+
return asServer(node).parent ?? null;
|
|
390
|
+
}
|
|
391
|
+
nextSibling(node) {
|
|
392
|
+
const n = asServer(node);
|
|
393
|
+
const parent = n.parent;
|
|
394
|
+
if (parent === null) return null;
|
|
395
|
+
const idx = parent.children.indexOf(n);
|
|
396
|
+
if (idx === -1 || idx + 1 >= parent.children.length) return null;
|
|
397
|
+
return parent.children[idx + 1];
|
|
398
|
+
}
|
|
399
|
+
firstChild(node) {
|
|
400
|
+
const n = asServer(node);
|
|
401
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
402
|
+
const el = n;
|
|
403
|
+
return el.children[0] ?? null;
|
|
404
|
+
}
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
childNodes(node) {
|
|
408
|
+
const n = asServer(node);
|
|
409
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
410
|
+
return n.children;
|
|
411
|
+
}
|
|
412
|
+
return [];
|
|
413
|
+
}
|
|
414
|
+
// ── Server-only ────────────────────────────────────────────────────────────
|
|
415
|
+
/** Serialize a node's children ("inner HTML") to an HTML string. */
|
|
416
|
+
serializeInner(node) {
|
|
417
|
+
const n = asServer(node);
|
|
418
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
419
|
+
return serializeChildren(n);
|
|
420
|
+
}
|
|
421
|
+
return "";
|
|
422
|
+
}
|
|
423
|
+
/** Serialize a node (including itself) to an HTML string. */
|
|
424
|
+
serializeOuter(node) {
|
|
425
|
+
return serializeServerNode(asServer(node));
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
var serverDOMAdapter = new ServerDOMAdapter();
|
|
429
|
+
|
|
430
|
+
// src/focus.ts
|
|
431
|
+
var FOCUSABLE_SELECTOR = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
432
|
+
function focusById(dom, root, id) {
|
|
433
|
+
const el = dom.querySelector(root, `[id="${id}"]`);
|
|
434
|
+
if (el === null) return false;
|
|
435
|
+
dom.focus(el);
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
function focusFirst(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
439
|
+
const el = dom.querySelector(container, selector);
|
|
440
|
+
if (el === null) return false;
|
|
441
|
+
dom.focus(el);
|
|
442
|
+
return true;
|
|
443
|
+
}
|
|
444
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
445
|
+
0 && (module.exports = {
|
|
446
|
+
BrowserDOMAdapter,
|
|
447
|
+
FOCUSABLE_SELECTOR,
|
|
448
|
+
ServerComment,
|
|
449
|
+
ServerDOMAdapter,
|
|
450
|
+
ServerElement,
|
|
451
|
+
ServerFragment,
|
|
452
|
+
ServerStyle,
|
|
453
|
+
ServerText,
|
|
454
|
+
browserDOMAdapter,
|
|
455
|
+
escapeHtmlAttr,
|
|
456
|
+
escapeHtmlText,
|
|
457
|
+
focusById,
|
|
458
|
+
focusFirst,
|
|
459
|
+
serializeChildren,
|
|
460
|
+
serializeServerNode,
|
|
461
|
+
serverDOMAdapter
|
|
462
|
+
});
|
|
463
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/browser-adapter.ts","../src/server-node.ts","../src/server-adapter.ts","../src/focus.ts"],"sourcesContent":["export * from './adapter.js';\nexport * from './browser-adapter.js';\nexport * from './server-node.js';\nexport * from './server-adapter.js';\nexport * from './focus.js';\n","/**\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":[]}
|