@madojs/mado 0.5.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.
Files changed (162) hide show
  1. package/AGENTS.md +291 -0
  2. package/CHANGELOG.md +23 -0
  3. package/LICENSE +21 -0
  4. package/README.md +371 -0
  5. package/ROADMAP.md +52 -0
  6. package/dist/src/component.d.ts +48 -0
  7. package/dist/src/component.js +140 -0
  8. package/dist/src/component.js.map +1 -0
  9. package/dist/src/context.d.ts +40 -0
  10. package/dist/src/context.js +67 -0
  11. package/dist/src/context.js.map +1 -0
  12. package/dist/src/css.d.ts +54 -0
  13. package/dist/src/css.js +137 -0
  14. package/dist/src/css.js.map +1 -0
  15. package/dist/src/devtools.d.ts +22 -0
  16. package/dist/src/devtools.js +63 -0
  17. package/dist/src/devtools.js.map +1 -0
  18. package/dist/src/diagnostics.d.ts +11 -0
  19. package/dist/src/diagnostics.js +28 -0
  20. package/dist/src/diagnostics.js.map +1 -0
  21. package/dist/src/each.d.ts +39 -0
  22. package/dist/src/each.js +35 -0
  23. package/dist/src/each.js.map +1 -0
  24. package/dist/src/forms.d.ts +71 -0
  25. package/dist/src/forms.js +161 -0
  26. package/dist/src/forms.js.map +1 -0
  27. package/dist/src/head.d.ts +19 -0
  28. package/dist/src/head.js +97 -0
  29. package/dist/src/head.js.map +1 -0
  30. package/dist/src/html/bindings.d.ts +78 -0
  31. package/dist/src/html/bindings.js +304 -0
  32. package/dist/src/html/bindings.js.map +1 -0
  33. package/dist/src/html/parser.d.ts +64 -0
  34. package/dist/src/html/parser.js +521 -0
  35. package/dist/src/html/parser.js.map +1 -0
  36. package/dist/src/html/template-types.d.ts +27 -0
  37. package/dist/src/html/template-types.js +8 -0
  38. package/dist/src/html/template-types.js.map +1 -0
  39. package/dist/src/html/template.d.ts +45 -0
  40. package/dist/src/html/template.js +119 -0
  41. package/dist/src/html/template.js.map +1 -0
  42. package/dist/src/html.d.ts +16 -0
  43. package/dist/src/html.js +16 -0
  44. package/dist/src/html.js.map +1 -0
  45. package/dist/src/index.d.ts +35 -0
  46. package/dist/src/index.js +39 -0
  47. package/dist/src/index.js.map +1 -0
  48. package/dist/src/lazy.d.ts +38 -0
  49. package/dist/src/lazy.js +73 -0
  50. package/dist/src/lazy.js.map +1 -0
  51. package/dist/src/lifecycle.d.ts +45 -0
  52. package/dist/src/lifecycle.js +66 -0
  53. package/dist/src/lifecycle.js.map +1 -0
  54. package/dist/src/page.d.ts +161 -0
  55. package/dist/src/page.js +38 -0
  56. package/dist/src/page.js.map +1 -0
  57. package/dist/src/persisted.d.ts +47 -0
  58. package/dist/src/persisted.js +119 -0
  59. package/dist/src/persisted.js.map +1 -0
  60. package/dist/src/resource.d.ts +120 -0
  61. package/dist/src/resource.js +275 -0
  62. package/dist/src/resource.js.map +1 -0
  63. package/dist/src/router/manifest.d.ts +56 -0
  64. package/dist/src/router/manifest.js +302 -0
  65. package/dist/src/router/manifest.js.map +1 -0
  66. package/dist/src/router/match.d.ts +62 -0
  67. package/dist/src/router/match.js +117 -0
  68. package/dist/src/router/match.js.map +1 -0
  69. package/dist/src/router/navigation.d.ts +89 -0
  70. package/dist/src/router/navigation.js +263 -0
  71. package/dist/src/router/navigation.js.map +1 -0
  72. package/dist/src/router.d.ts +13 -0
  73. package/dist/src/router.js +13 -0
  74. package/dist/src/router.js.map +1 -0
  75. package/dist/src/signal.d.ts +67 -0
  76. package/dist/src/signal.js +238 -0
  77. package/dist/src/signal.js.map +1 -0
  78. package/docs/README.md +12 -0
  79. package/docs/en/00-the-mado-way.md +106 -0
  80. package/docs/en/01-routing.md +204 -0
  81. package/docs/en/02-project-layout.md +58 -0
  82. package/docs/en/03-static-bake.md +251 -0
  83. package/docs/en/04-ide-setup.md +162 -0
  84. package/docs/en/05-why-mado.md +193 -0
  85. package/docs/en/06-for-backenders.md +422 -0
  86. package/docs/en/07-llm-pitfalls.md +486 -0
  87. package/docs/en/08-llm-zero-history-test.md +56 -0
  88. package/docs/en/09-shadow-vs-light-dom.md +122 -0
  89. package/docs/en/README.md +16 -0
  90. package/docs/fr/00-the-mado-way.md +108 -0
  91. package/docs/fr/01-routing.md +202 -0
  92. package/docs/fr/02-project-layout.md +58 -0
  93. package/docs/fr/03-static-bake.md +290 -0
  94. package/docs/fr/04-ide-setup.md +162 -0
  95. package/docs/fr/05-why-mado.md +193 -0
  96. package/docs/fr/06-for-backenders.md +432 -0
  97. package/docs/fr/07-llm-pitfalls.md +487 -0
  98. package/docs/fr/08-llm-zero-history-test.md +60 -0
  99. package/docs/fr/09-shadow-vs-light-dom.md +121 -0
  100. package/docs/fr/README.md +16 -0
  101. package/docs/ru/00-the-mado-way.md +93 -0
  102. package/docs/ru/01-routing.md +194 -0
  103. package/docs/ru/02-project-layout.md +57 -0
  104. package/docs/ru/03-static-bake.md +251 -0
  105. package/docs/ru/04-ide-setup.md +144 -0
  106. package/docs/ru/05-why-mado.md +193 -0
  107. package/docs/ru/06-for-backenders.md +422 -0
  108. package/docs/ru/07-llm-pitfalls.md +485 -0
  109. package/docs/ru/08-llm-zero-history-test.md +56 -0
  110. package/docs/ru/09-shadow-vs-light-dom.md +122 -0
  111. package/docs/ru/README.md +14 -0
  112. package/docs/uk/00-the-mado-way.md +54 -0
  113. package/docs/uk/01-routing.md +82 -0
  114. package/docs/uk/02-project-layout.md +46 -0
  115. package/docs/uk/03-static-bake.md +49 -0
  116. package/docs/uk/04-ide-setup.md +26 -0
  117. package/docs/uk/05-why-mado.md +34 -0
  118. package/docs/uk/06-for-backenders.md +50 -0
  119. package/docs/uk/07-llm-pitfalls.md +82 -0
  120. package/docs/uk/08-llm-zero-history-test.md +31 -0
  121. package/docs/uk/09-shadow-vs-light-dom.md +40 -0
  122. package/docs/uk/README.md +16 -0
  123. package/llms.txt +155 -0
  124. package/package.json +81 -0
  125. package/scripts/bake.mjs +406 -0
  126. package/scripts/bundle.mjs +146 -0
  127. package/scripts/cli.mjs +382 -0
  128. package/scripts/new.mjs +80 -0
  129. package/scripts/preview.mjs +176 -0
  130. package/scripts/release-notes.mjs +66 -0
  131. package/scripts/showcase-regression.mjs +392 -0
  132. package/server/serve.mjs +292 -0
  133. package/starters/crud/README.md +21 -0
  134. package/starters/crud/index.html +20 -0
  135. package/starters/crud/package.json +17 -0
  136. package/starters/crud/src/components/app-shell.ts +51 -0
  137. package/starters/crud/src/components/ticket-detail.ts +33 -0
  138. package/starters/crud/src/components/ticket-form.ts +69 -0
  139. package/starters/crud/src/components/ticket-list.ts +66 -0
  140. package/starters/crud/src/lib/api.ts +76 -0
  141. package/starters/crud/src/main.ts +12 -0
  142. package/starters/crud/src/pages/home.ts +18 -0
  143. package/starters/crud/src/pages/not-found.ts +12 -0
  144. package/starters/crud/src/pages/ticket-detail.ts +6 -0
  145. package/starters/crud/src/pages/ticket-new.ts +6 -0
  146. package/starters/crud/src/pages/tickets.ts +6 -0
  147. package/starters/crud/src/routes.ts +9 -0
  148. package/starters/crud/src/styles/global.ts +155 -0
  149. package/starters/crud/tsconfig.json +15 -0
  150. package/starters/minimal/README.md +19 -0
  151. package/starters/minimal/index.html +20 -0
  152. package/starters/minimal/package.json +17 -0
  153. package/starters/minimal/src/components/app-counter.ts +31 -0
  154. package/starters/minimal/src/main.ts +9 -0
  155. package/starters/minimal/src/pages/home.ts +18 -0
  156. package/starters/minimal/src/pages/not-found.ts +14 -0
  157. package/starters/minimal/src/routes.ts +6 -0
  158. package/starters/minimal/src/styles/global.ts +60 -0
  159. package/starters/minimal/tsconfig.json +15 -0
  160. package/templates/page-detail.ts +63 -0
  161. package/templates/page-form.ts +94 -0
  162. package/templates/page-list.ts +79 -0
@@ -0,0 +1,521 @@
1
+ /**
2
+ * Tagged-template parser: a state machine that turns strings[] into
3
+ * { template: HTMLTemplateElement, bindings: BindingSpec[] }
4
+ *
5
+ * It does not depend on the reactive runtime (signal/each/effect), only on DOM
6
+ * APIs (document.createElement and walking Node trees). That makes it possible
7
+ * to test the parser in isolation and reuse it for bake / SSR through linkedom.
8
+ *
9
+ * Algorithm:
10
+ * 1. Walk strings[] char-by-char through an explicit finite state machine.
11
+ * For every `${}` slot we know the current context: text, attribute,
12
+ * attribute value, comment, or raw text.
13
+ * 2. Build the final HTML string with markers:
14
+ * - `<!--mado$N-->` for child slots
15
+ * - `data-mado-bind-N="…"` for attributes
16
+ * and keep a parallel BindingSpec list that describes each slot.
17
+ * 3. Parse HTML through `<template>.innerHTML`, then walk() finds markers in
18
+ * the DOM and fills BindingSpec.path and childIndex. Marker attributes are
19
+ * removed from elements; marker comments remain as child binding anchors.
20
+ * 4. Cache by strings identity. TemplateStringsArray is stable for the same
21
+ * tagged literal between calls.
22
+ */
23
+ // ---------- Markers ----------
24
+ export const CHILD_MARKER_PREFIX = "mado$";
25
+ export const ATTR_MARKER_PREFIX = "data-mado-bind-";
26
+ // ---------- Cache ----------
27
+ const templateCache = new WeakMap();
28
+ // Tags inside which HTML is not parsed.
29
+ const RAW_TEXT_TAGS = new Set(["script", "style", "textarea", "title"]);
30
+ /**
31
+ * Main export: parse a tagged-template literal into a ready-to-instantiate
32
+ * ParsedTemplate. Idempotent (cached by strings).
33
+ */
34
+ export function parseTemplate(strings) {
35
+ const cached = templateCache.get(strings);
36
+ if (cached)
37
+ return cached;
38
+ const bindings = [];
39
+ let html = "";
40
+ let state = "TEXT";
41
+ let tagName = "";
42
+ let attr = null;
43
+ let rawTagName = "";
44
+ let nextId = 0;
45
+ /** Creates a child binding and adds a marker to html. */
46
+ const emitChildMarker = (slot) => {
47
+ const id = nextId++;
48
+ html += `<!--${CHILD_MARKER_PREFIX}${id}-->`;
49
+ bindings.push({
50
+ type: "child",
51
+ id,
52
+ path: [], // filled during walk
53
+ childIndex: 0,
54
+ slot,
55
+ });
56
+ };
57
+ /** Closes the current attribute and flushes it into html. */
58
+ const flushAttr = () => {
59
+ if (!attr)
60
+ return;
61
+ // Finalize the last fragment.
62
+ if (attr.hasValue) {
63
+ attr.valueParts.push(attr.current);
64
+ }
65
+ if (attr.slots.length === 0) {
66
+ // Static attribute: emit as-is.
67
+ if (!attr.hasValue) {
68
+ html += " " + attr.rawName;
69
+ }
70
+ else if (attr.quote) {
71
+ html +=
72
+ " " + attr.rawName + "=" + attr.quote + attr.current + attr.quote;
73
+ }
74
+ else {
75
+ html += " " + attr.rawName + "=" + attr.current;
76
+ }
77
+ }
78
+ else {
79
+ // dynamic attribute — place marker, write binding
80
+ const id = nextId++;
81
+ // escape name for safe writing into a data attribute value
82
+ const escapedName = attr.rawName
83
+ .replace(/&/g, "&amp;")
84
+ .replace(/"/g, "&quot;");
85
+ html += ` ${ATTR_MARKER_PREFIX}${id}="${escapedName}"`;
86
+ const parts = attr.valueParts.length > 0 ? attr.valueParts : ["", ""];
87
+ // single-part: the attribute is entirely defined by one slot
88
+ // (all static fragments are empty ⇒ value = just values[slot])
89
+ const isMulti = attr.slots.length > 1 || parts.some((p) => p !== "");
90
+ bindings.push({
91
+ type: "attr",
92
+ id,
93
+ path: [], // filled during walk
94
+ name: attr.rawName,
95
+ strings: parts,
96
+ slots: attr.slots,
97
+ isMulti,
98
+ });
99
+ }
100
+ attr = null;
101
+ };
102
+ /** Processes one character of a template string. */
103
+ const processChar = (c, i, s) => {
104
+ switch (state) {
105
+ // ---------- TEXT ----------
106
+ case "TEXT": {
107
+ if (c === "<") {
108
+ // Potential tag start.
109
+ const next = s[i + 1] ?? "";
110
+ if (/[a-zA-Z]/.test(next)) {
111
+ html += "<";
112
+ tagName = "";
113
+ state = "TAG_NAME";
114
+ }
115
+ else if (next === "/") {
116
+ html += "<";
117
+ state = "CLOSE_TAG";
118
+ }
119
+ else if (next === "!") {
120
+ // Check for <!--.
121
+ if (s[i + 2] === "-" && s[i + 3] === "-") {
122
+ html += "<";
123
+ state = "COMMENT";
124
+ // Every following char is copied into html as-is.
125
+ }
126
+ else {
127
+ // <!doctype or <![CDATA[: treat as a normal tag-like block.
128
+ html += "<";
129
+ state = "CLOSE_TAG"; // Reuse CLOSE_TAG as "wait until >".
130
+ }
131
+ }
132
+ else {
133
+ // '<' does not open a tag here, e.g. "a < b".
134
+ html += "&lt;";
135
+ }
136
+ }
137
+ else {
138
+ html += c;
139
+ }
140
+ break;
141
+ }
142
+ // ---------- TAG_NAME ----------
143
+ case "TAG_NAME": {
144
+ if (/\s/.test(c)) {
145
+ html += c;
146
+ state = "BEFORE_ATTR";
147
+ }
148
+ else if (c === "/") {
149
+ state = "SELF_CLOSE";
150
+ }
151
+ else if (c === ">") {
152
+ html += c;
153
+ if (RAW_TEXT_TAGS.has(tagName.toLowerCase())) {
154
+ rawTagName = tagName.toLowerCase();
155
+ state = "RAW_TEXT";
156
+ }
157
+ else {
158
+ state = "TEXT";
159
+ }
160
+ }
161
+ else {
162
+ tagName += c;
163
+ html += c;
164
+ }
165
+ break;
166
+ }
167
+ // ---------- BEFORE_ATTR ----------
168
+ case "BEFORE_ATTR": {
169
+ if (/\s/.test(c)) {
170
+ html += c;
171
+ }
172
+ else if (c === "/") {
173
+ state = "SELF_CLOSE";
174
+ }
175
+ else if (c === ">") {
176
+ html += c;
177
+ if (RAW_TEXT_TAGS.has(tagName.toLowerCase())) {
178
+ rawTagName = tagName.toLowerCase();
179
+ state = "RAW_TEXT";
180
+ }
181
+ else {
182
+ state = "TEXT";
183
+ }
184
+ }
185
+ else {
186
+ // Start a new attribute accumulator.
187
+ attr = {
188
+ rawName: c,
189
+ valueParts: [],
190
+ current: "",
191
+ slots: [],
192
+ quote: "",
193
+ hasValue: false,
194
+ };
195
+ state = "ATTR_NAME";
196
+ }
197
+ break;
198
+ }
199
+ // ---------- ATTR_NAME ----------
200
+ case "ATTR_NAME": {
201
+ if (c === "=") {
202
+ attr.hasValue = true;
203
+ state = "BEFORE_ATTR_VALUE";
204
+ }
205
+ else if (/\s/.test(c)) {
206
+ state = "AFTER_ATTR_NAME";
207
+ }
208
+ else if (c === "/") {
209
+ flushAttr();
210
+ state = "SELF_CLOSE";
211
+ }
212
+ else if (c === ">") {
213
+ flushAttr();
214
+ html += c;
215
+ if (RAW_TEXT_TAGS.has(tagName.toLowerCase())) {
216
+ rawTagName = tagName.toLowerCase();
217
+ state = "RAW_TEXT";
218
+ }
219
+ else {
220
+ state = "TEXT";
221
+ }
222
+ }
223
+ else {
224
+ attr.rawName += c;
225
+ }
226
+ break;
227
+ }
228
+ // ---------- AFTER_ATTR_NAME ----------
229
+ case "AFTER_ATTR_NAME": {
230
+ if (/\s/.test(c)) {
231
+ // Keep skipping whitespace.
232
+ }
233
+ else if (c === "=") {
234
+ attr.hasValue = true;
235
+ state = "BEFORE_ATTR_VALUE";
236
+ }
237
+ else if (c === "/") {
238
+ flushAttr();
239
+ html += " ";
240
+ state = "SELF_CLOSE";
241
+ }
242
+ else if (c === ">") {
243
+ flushAttr();
244
+ html += c;
245
+ if (RAW_TEXT_TAGS.has(tagName.toLowerCase())) {
246
+ rawTagName = tagName.toLowerCase();
247
+ state = "RAW_TEXT";
248
+ }
249
+ else {
250
+ state = "TEXT";
251
+ }
252
+ }
253
+ else {
254
+ // This starts a new attribute; the previous one was boolean.
255
+ flushAttr();
256
+ html += " ";
257
+ attr = {
258
+ rawName: c,
259
+ valueParts: [],
260
+ current: "",
261
+ slots: [],
262
+ quote: "",
263
+ hasValue: false,
264
+ };
265
+ state = "ATTR_NAME";
266
+ }
267
+ break;
268
+ }
269
+ // ---------- BEFORE_ATTR_VALUE ----------
270
+ case "BEFORE_ATTR_VALUE": {
271
+ if (/\s/.test(c)) {
272
+ // skip
273
+ }
274
+ else if (c === '"') {
275
+ attr.quote = '"';
276
+ state = "ATTR_VALUE_DQ";
277
+ }
278
+ else if (c === "'") {
279
+ attr.quote = "'";
280
+ state = "ATTR_VALUE_SQ";
281
+ }
282
+ else if (c === ">") {
283
+ // Empty value through =
284
+ flushAttr();
285
+ html += c;
286
+ state = "TEXT";
287
+ }
288
+ else {
289
+ attr.quote = "";
290
+ attr.current = c;
291
+ state = "ATTR_VALUE_UNQ";
292
+ }
293
+ break;
294
+ }
295
+ // ---------- ATTR_VALUE_DQ ----------
296
+ case "ATTR_VALUE_DQ": {
297
+ if (c === '"') {
298
+ flushAttr();
299
+ state = "BEFORE_ATTR";
300
+ }
301
+ else {
302
+ attr.current += c;
303
+ }
304
+ break;
305
+ }
306
+ // ---------- ATTR_VALUE_SQ ----------
307
+ case "ATTR_VALUE_SQ": {
308
+ if (c === "'") {
309
+ flushAttr();
310
+ state = "BEFORE_ATTR";
311
+ }
312
+ else {
313
+ attr.current += c;
314
+ }
315
+ break;
316
+ }
317
+ // ---------- ATTR_VALUE_UNQ ----------
318
+ case "ATTR_VALUE_UNQ": {
319
+ if (/\s/.test(c)) {
320
+ flushAttr();
321
+ html += c;
322
+ state = "BEFORE_ATTR";
323
+ }
324
+ else if (c === ">") {
325
+ flushAttr();
326
+ html += c;
327
+ if (RAW_TEXT_TAGS.has(tagName.toLowerCase())) {
328
+ rawTagName = tagName.toLowerCase();
329
+ state = "RAW_TEXT";
330
+ }
331
+ else {
332
+ state = "TEXT";
333
+ }
334
+ }
335
+ else if (c === "/" && s[i + 1] === ">") {
336
+ // Self-closing after an unquoted value: <x-icon name=${v}/>
337
+ flushAttr();
338
+ state = "SELF_CLOSE";
339
+ }
340
+ else {
341
+ attr.current += c;
342
+ }
343
+ break;
344
+ }
345
+ // ---------- SELF_CLOSE ----------
346
+ case "SELF_CLOSE": {
347
+ if (c === ">") {
348
+ html += "/>";
349
+ state = "TEXT";
350
+ }
351
+ else if (/\s/.test(c)) {
352
+ // ignore
353
+ }
354
+ else {
355
+ // Not self-closing: roll back into a normal attribute.
356
+ html += "/";
357
+ attr = {
358
+ rawName: c,
359
+ valueParts: [],
360
+ current: "",
361
+ slots: [],
362
+ quote: "",
363
+ hasValue: false,
364
+ };
365
+ state = "ATTR_NAME";
366
+ }
367
+ break;
368
+ }
369
+ // ---------- COMMENT ----------
370
+ case "COMMENT": {
371
+ html += c;
372
+ // Look for '-->' by checking the last three html chars.
373
+ if (html.endsWith("-->") &&
374
+ // Guard: it must be at least the length of "<!---->".
375
+ html.length >= 7) {
376
+ state = "TEXT";
377
+ }
378
+ break;
379
+ }
380
+ // ---------- RAW_TEXT ----------
381
+ case "RAW_TEXT": {
382
+ html += c;
383
+ // Look for the closing </tagName>.
384
+ const closing = "</" + rawTagName;
385
+ if (c === ">" && html.toLowerCase().endsWith(closing + ">")) {
386
+ rawTagName = "";
387
+ state = "TEXT";
388
+ }
389
+ break;
390
+ }
391
+ // ---------- CLOSE_TAG ----------
392
+ case "CLOSE_TAG": {
393
+ html += c;
394
+ if (c === ">") {
395
+ state = "TEXT";
396
+ }
397
+ break;
398
+ }
399
+ }
400
+ };
401
+ /** Processes the slot ${...} between strings[i] and strings[i+1]. */
402
+ const processSlot = (slot) => {
403
+ switch (state) {
404
+ case "TEXT": {
405
+ emitChildMarker(slot);
406
+ break;
407
+ }
408
+ case "TAG_NAME":
409
+ case "BEFORE_ATTR":
410
+ case "ATTR_NAME":
411
+ case "AFTER_ATTR_NAME": {
412
+ throw new Error(`[mado] Dynamic slot in tag/attribute name position is not supported (state=${state}).`);
413
+ }
414
+ case "BEFORE_ATTR_VALUE": {
415
+ // <attr=${v}> without quotes: the slot is the whole value.
416
+ attr.quote = "";
417
+ attr.slots.push(slot);
418
+ attr.valueParts.push(attr.current);
419
+ attr.current = "";
420
+ state = "ATTR_VALUE_UNQ";
421
+ break;
422
+ }
423
+ case "ATTR_VALUE_DQ":
424
+ case "ATTR_VALUE_SQ":
425
+ case "ATTR_VALUE_UNQ": {
426
+ attr.slots.push(slot);
427
+ attr.valueParts.push(attr.current);
428
+ attr.current = "";
429
+ break;
430
+ }
431
+ case "COMMENT": {
432
+ // binding inside a static comment — ignore
433
+ break;
434
+ }
435
+ case "RAW_TEXT": {
436
+ // binding inside <script>/<style>: ignore for security
437
+ // (can be extended later if a real use-case arises)
438
+ break;
439
+ }
440
+ case "SELF_CLOSE":
441
+ case "CLOSE_TAG":
442
+ case "TAG_OPEN": {
443
+ throw new Error(`[mado] Dynamic slot in position ${state} is not supported.`);
444
+ }
445
+ }
446
+ };
447
+ for (let i = 0; i < strings.length; i++) {
448
+ const s = strings[i];
449
+ for (let j = 0; j < s.length; j++) {
450
+ processChar(s[j], j, s);
451
+ }
452
+ if (i < strings.length - 1) {
453
+ processSlot(i);
454
+ }
455
+ }
456
+ // 2) Parse the final HTML string through <template>.
457
+ const tpl = document.createElement("template");
458
+ tpl.innerHTML = html;
459
+ // 3) Walk content, find markers, fill path/childIndex for bindings.
460
+ const byId = new Map();
461
+ for (const b of bindings)
462
+ byId.set(b.id, b);
463
+ walk(tpl.content, [], byId);
464
+ const parsed = { template: tpl, bindings };
465
+ templateCache.set(strings, parsed);
466
+ return parsed;
467
+ }
468
+ /**
469
+ * Walk the template DOM: for each marker (attribute or comment)
470
+ * find the corresponding BindingSpec and fill its `path` (how to
471
+ * reach it from root) and `childIndex` (for child bindings — position
472
+ * of the placeholder comment among the parent's children).
473
+ *
474
+ * Marker attributes `data-mado-bind-N` are removed from elements;
475
+ * marker comments remain — they serve as an "anchor" for child binding.
476
+ */
477
+ function walk(node, path, byId) {
478
+ if (node.nodeType === Node.ELEMENT_NODE) {
479
+ const el = node;
480
+ const toRemove = [];
481
+ for (const attr of [...el.attributes]) {
482
+ if (attr.name.startsWith(ATTR_MARKER_PREFIX)) {
483
+ const id = Number(attr.name.slice(ATTR_MARKER_PREFIX.length));
484
+ const b = byId.get(id);
485
+ if (b && b.type === "attr") {
486
+ b.path = [...path];
487
+ }
488
+ toRemove.push(attr.name);
489
+ }
490
+ }
491
+ for (const n of toRemove)
492
+ el.removeAttribute(n);
493
+ }
494
+ if (node.nodeType === Node.COMMENT_NODE) {
495
+ const c = node;
496
+ if (c.data.startsWith(CHILD_MARKER_PREFIX)) {
497
+ const id = Number(c.data.slice(CHILD_MARKER_PREFIX.length));
498
+ const b = byId.get(id);
499
+ if (b && b.type === "child") {
500
+ // Path points to the parent; index is the node position among children.
501
+ b.path = path.slice(0, -1);
502
+ b.childIndex = path[path.length - 1];
503
+ }
504
+ }
505
+ }
506
+ const children = node.childNodes;
507
+ for (let i = 0; i < children.length; i++) {
508
+ walk(children[i], [...path, i], byId);
509
+ }
510
+ }
511
+ /**
512
+ * Retrieve a node by path from root. Used when instantiating
513
+ * a template to resolve BindingSpec.path → concrete Node in the clone.
514
+ */
515
+ export function resolvePath(root, path) {
516
+ let n = root;
517
+ for (const i of path)
518
+ n = n.childNodes[i];
519
+ return n;
520
+ }
521
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/html/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Small shared type module extracted from html.ts to avoid a cycle:
3
+ * bindings.ts knows about TemplateResult / InstantiatedTemplate, template.ts
4
+ * instantiates through them, and neither module depends on the other directly
5
+ * (instantiate is passed into bindings as a parameter).
6
+ */
7
+ export interface TemplateResult {
8
+ readonly _mado: true;
9
+ readonly strings: TemplateStringsArray;
10
+ readonly values: readonly unknown[];
11
+ }
12
+ export declare const isTemplateResult: (v: unknown) => v is TemplateResult;
13
+ /**
14
+ * Ready-to-use template instance: already cloned, bindings attached, nodes
15
+ * extracted. Insert the fragment into the DOM, then call update() when values
16
+ * change and dispose() when removing it.
17
+ *
18
+ * `_strings` lets keyed each decide whether an instance can be reused
19
+ * (same tagged literal) or must be recreated.
20
+ */
21
+ export interface InstantiatedTemplate {
22
+ fragment: DocumentFragment;
23
+ nodes: Node[];
24
+ update(values: readonly unknown[]): void;
25
+ dispose(): void;
26
+ _strings: TemplateStringsArray;
27
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Small shared type module extracted from html.ts to avoid a cycle:
3
+ * bindings.ts knows about TemplateResult / InstantiatedTemplate, template.ts
4
+ * instantiates through them, and neither module depends on the other directly
5
+ * (instantiate is passed into bindings as a parameter).
6
+ */
7
+ export const isTemplateResult = (v) => typeof v === "object" && v !== null && v._mado === true;
8
+ //# sourceMappingURL=template-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-types.js","sourceRoot":"","sources":["../../../src/html/template-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAU,EAAuB,EAAE,CAClE,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAK,CAAoB,CAAC,KAAK,KAAK,IAAI,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Template instantiation + public `html\`\`` tag + `render()`.
3
+ *
4
+ * Data flow:
5
+ * html`...` → TemplateResult { strings, values }
6
+ * parseTemplate(strings) → ParsedTemplate { template, bindings } (cached by strings)
7
+ * instantiate(result) → InstantiatedTemplate { fragment, nodes, update, dispose }
8
+ * render(result, host) → clones or reuses instance in host
9
+ *
10
+ * Only the glue lives here: parser and bindings are in neighbour files.
11
+ */
12
+ import type { InstantiatedTemplate, TemplateResult } from "./template-types.js";
13
+ /**
14
+ * `html\`<div>${value}</div>\`` → template descriptor.
15
+ *
16
+ * By itself renders and parses NOTHING — this simply captures
17
+ * { strings, values } from the tagged-template literal. The heavy work
18
+ * (parsing + cloning) happens on the first `render()` /
19
+ * `instantiate()` call and is cached by `strings` identity.
20
+ */
21
+ export declare function html(strings: TemplateStringsArray, ...values: unknown[]): TemplateResult;
22
+ /**
23
+ * Create a ready template instance: clones the pre-parsed template,
24
+ * resolves all BindingSpec → concrete DOM nodes of the clone, binds
25
+ * initial values. The returned object is self-contained: update(values)
26
+ * patches only what actually changed, dispose() cleans up effects
27
+ * and removes nodes from the DOM.
28
+ *
29
+ * Exported (not only used from render()) so that
30
+ * keyed `each` reconciliation can manage instance lifetimes directly.
31
+ */
32
+ export declare function instantiate(result: TemplateResult): InstantiatedTemplate;
33
+ /**
34
+ * Render a TemplateResult into a container.
35
+ *
36
+ * Semantics:
37
+ * - first call → instantiate + appendChild;
38
+ * - repeated call with the same tagged literal (same strings identity) →
39
+ * update(values), DOM is not recreated;
40
+ * - repeated call with a different literal → dispose old + new instantiate.
41
+ *
42
+ * Container can be either an Element or a ShadowRoot (used
43
+ * in component() for rendering into a shadow tree).
44
+ */
45
+ export declare function render(result: TemplateResult, container: Element | ShadowRoot): void;