micra.js 2.1.0 → 2.2.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/CHANGELOG.md +231 -0
- package/README.md +39 -14
- package/dist/core/mount.d.ts +8 -2
- package/dist/core/registry.d.ts +13 -4
- package/dist/dom/directives.d.ts +11 -15
- package/dist/dom/each.d.ts +6 -4
- package/dist/dom/events.d.ts +15 -5
- package/dist/dom/refs.d.ts +5 -5
- package/dist/dom/scan.d.ts +34 -0
- package/dist/index.d.ts +1 -1
- package/dist/micra.cjs.js +196 -143
- package/dist/micra.cjs.js.map +4 -4
- package/dist/micra.esm.js +196 -143
- package/dist/micra.esm.js.map +4 -4
- package/dist/micra.js +196 -143
- package/dist/micra.js.map +4 -4
- package/dist/micra.min.js +2 -2
- package/dist/types.d.ts +63 -21
- package/llms-full.txt +600 -0
- package/llms.txt +148 -0
- package/package.json +11 -3
- package/src/core/mount.ts +126 -98
- package/src/core/registry.ts +19 -9
- package/src/dom/directives.ts +34 -120
- package/src/dom/each.ts +36 -19
- package/src/dom/events.ts +23 -31
- package/src/dom/refs.ts +6 -7
- package/src/dom/scan.ts +189 -0
- package/src/index.ts +2 -0
- package/src/types.ts +76 -21
package/dist/micra.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Micra.js v2.
|
|
1
|
+
/* Micra.js v2.2.0 — https://github.com/micra-js/micra — MIT */
|
|
2
2
|
|
|
3
3
|
// src/utils/fetch.ts
|
|
4
4
|
function getCSRF() {
|
|
@@ -221,27 +221,6 @@ function createScheduler(render) {
|
|
|
221
221
|
};
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
// src/dom/query.ts
|
|
225
|
-
function queryAll(root, sel) {
|
|
226
|
-
return Array.from(root.querySelectorAll(sel));
|
|
227
|
-
}
|
|
228
|
-
function queryOwn(root, attr) {
|
|
229
|
-
return filterOwn(root, queryAll(root, `[${attr}]`));
|
|
230
|
-
}
|
|
231
|
-
function queryOwnAll(root, sel) {
|
|
232
|
-
return filterOwn(root, queryAll(root, sel));
|
|
233
|
-
}
|
|
234
|
-
function filterOwn(root, els) {
|
|
235
|
-
return els.filter((el) => {
|
|
236
|
-
let node = el.parentElement;
|
|
237
|
-
while (node && node !== root) {
|
|
238
|
-
if (node.hasAttribute("data-component")) return false;
|
|
239
|
-
node = node.parentElement;
|
|
240
|
-
}
|
|
241
|
-
return true;
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
|
|
245
224
|
// src/dom/directives.ts
|
|
246
225
|
function applyText(el, expr, state) {
|
|
247
226
|
var _a;
|
|
@@ -295,92 +274,37 @@ function applyClass(el, pairs, state) {
|
|
|
295
274
|
el.classList.toggle(cls, Boolean(evalExpr(valExpr, state)));
|
|
296
275
|
}
|
|
297
276
|
}
|
|
298
|
-
function parsePairs(expr) {
|
|
299
|
-
const out = [];
|
|
300
|
-
for (const part of expr.split(",")) {
|
|
301
|
-
const colonIdx = part.indexOf(":");
|
|
302
|
-
if (colonIdx === -1) continue;
|
|
303
|
-
const left = part.slice(0, colonIdx).trim();
|
|
304
|
-
const right = part.slice(colonIdx + 1).trim();
|
|
305
|
-
if (!left) continue;
|
|
306
|
-
out.push([left, right]);
|
|
307
|
-
}
|
|
308
|
-
return out;
|
|
309
|
-
}
|
|
310
277
|
function applyModel(el, key, rawState) {
|
|
311
278
|
const html = el;
|
|
312
279
|
const stateVal = rawState[key];
|
|
313
280
|
const desired = stateVal == null ? "" : String(stateVal);
|
|
314
281
|
if (html.value !== desired) html.value = desired;
|
|
315
282
|
}
|
|
316
|
-
function
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if: pick("data-if"),
|
|
328
|
-
show: pick("data-show"),
|
|
329
|
-
bind: pickPairs("data-bind"),
|
|
330
|
-
model: pick("data-model"),
|
|
331
|
-
class: pickPairs("data-class")
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
function applyDirectives(root, state, rawState, _instance) {
|
|
335
|
-
if (root.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
336
|
-
applyFromList(buildFragmentList(root), state, rawState);
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
const el = root;
|
|
340
|
-
if (!el.__micraCache) el.__micraCache = buildCache(el);
|
|
341
|
-
applyFromList(el.__micraCache, state, rawState);
|
|
342
|
-
}
|
|
343
|
-
function applyFromList(cache, state, rawState) {
|
|
344
|
-
cache.if.forEach((b) => applyIf(b, state));
|
|
345
|
-
cache.text.forEach((b) => applyText(b.el, b.expr, state));
|
|
346
|
-
cache.html.forEach((b) => applyHtml(b.el, b.expr, state));
|
|
347
|
-
cache.show.forEach((b) => applyShow(b.el, b.expr, state));
|
|
348
|
-
cache.bind.forEach((b) => applyBind(b.el, b.pairs, state));
|
|
349
|
-
cache.model.forEach((b) => applyModel(b.el, b.expr.trim(), rawState));
|
|
350
|
-
cache.class.forEach((b) => applyClass(b.el, b.pairs, state));
|
|
351
|
-
}
|
|
352
|
-
function buildFragmentList(frag) {
|
|
353
|
-
const pick = (attr) => queryAll(frag, `[${attr}]`).filter((el) => !el.closest("template")).map((el) => ({ el, expr: el.getAttribute(attr) }));
|
|
354
|
-
const pickPairs = (attr) => pick(attr).map((b) => ({ ...b, pairs: parsePairs(b.expr) }));
|
|
355
|
-
return {
|
|
356
|
-
text: pick("data-text"),
|
|
357
|
-
html: pick("data-html"),
|
|
358
|
-
if: pick("data-if"),
|
|
359
|
-
show: pick("data-show"),
|
|
360
|
-
bind: pickPairs("data-bind"),
|
|
361
|
-
model: pick("data-model"),
|
|
362
|
-
class: pickPairs("data-class")
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
function validateDirectives(root) {
|
|
366
|
-
var _a, _b;
|
|
367
|
-
queryOwn(root, "data-each").forEach((el) => {
|
|
283
|
+
function applyDirectives(scan, state, rawState, _instance) {
|
|
284
|
+
for (const b of scan.if) applyIf(b, state);
|
|
285
|
+
for (const b of scan.text) applyText(b.el, b.expr, state);
|
|
286
|
+
for (const b of scan.html) applyHtml(b.el, b.expr, state);
|
|
287
|
+
for (const b of scan.show) applyShow(b.el, b.expr, state);
|
|
288
|
+
for (const b of scan.bind) applyBind(b.el, b.pairs, state);
|
|
289
|
+
for (const b of scan.model) applyModel(b.el, b.expr.trim(), rawState);
|
|
290
|
+
for (const b of scan.class) applyClass(b.el, b.pairs, state);
|
|
291
|
+
}
|
|
292
|
+
function validateDirectives(scan) {
|
|
293
|
+
for (const el of scan.each) {
|
|
368
294
|
const tmpl = el;
|
|
369
295
|
if (!el.hasAttribute("data-key") && !tmpl.__micraNoKeyWarned) {
|
|
370
296
|
tmpl.__micraNoKeyWarned = true;
|
|
371
|
-
warn(
|
|
297
|
+
warn(
|
|
298
|
+
`data-each="${el.getAttribute("data-each")}" has no data-key \u2014 keyed diff disabled. Add data-key="id" for better performance.`
|
|
299
|
+
);
|
|
372
300
|
}
|
|
373
|
-
}
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
return ((_a2 = p.trim().split(":")[0]) == null ? void 0 : _a2.trim()) === "class";
|
|
381
|
-
});
|
|
382
|
-
if (hasClassBind && el.hasAttribute("data-class")) {
|
|
383
|
-
warn(`element has both data-bind="class:..." and data-class \u2014 they fight on every render. Use one.`);
|
|
301
|
+
}
|
|
302
|
+
for (const b of scan.bind) {
|
|
303
|
+
const hasClassBind = b.pairs.some((p) => p[0] === "class");
|
|
304
|
+
if (hasClassBind && b.el.hasAttribute("data-class")) {
|
|
305
|
+
warn(
|
|
306
|
+
`element has both data-bind="class:..." and data-class \u2014 they fight on every render. Use one.`
|
|
307
|
+
);
|
|
384
308
|
}
|
|
385
309
|
}
|
|
386
310
|
}
|
|
@@ -391,17 +315,13 @@ function track(instance, el, type, fn) {
|
|
|
391
315
|
el.addEventListener(type, fn);
|
|
392
316
|
((_a = instance.__micraListeners) != null ? _a : instance.__micraListeners = []).push({ el, type, fn });
|
|
393
317
|
}
|
|
394
|
-
function bindDataOn(
|
|
395
|
-
var _a
|
|
396
|
-
const isFragment = root.nodeType === 11;
|
|
397
|
-
const els = isFragment ? queryAll(root, "[data-on]") : queryOwn(root, "data-on");
|
|
398
|
-
if (!isFragment && ((_a = root.hasAttribute) == null ? void 0 : _a.call(root, "data-on")) && !els.includes(root))
|
|
399
|
-
els.unshift(root);
|
|
318
|
+
function bindDataOn(els, instance) {
|
|
319
|
+
var _a;
|
|
400
320
|
for (const el of els) {
|
|
401
321
|
const mEl = el;
|
|
402
322
|
if (mEl.__micraEvents) continue;
|
|
403
323
|
mEl.__micraEvents = true;
|
|
404
|
-
const spec = (
|
|
324
|
+
const spec = (_a = mEl.dataset["on"]) != null ? _a : "";
|
|
405
325
|
for (const part of spec.split(",")) {
|
|
406
326
|
const [evSpec, method] = part.trim().split(":");
|
|
407
327
|
if (!evSpec || !method) continue;
|
|
@@ -417,11 +337,8 @@ function bindDataOn(root, instance) {
|
|
|
417
337
|
}
|
|
418
338
|
}
|
|
419
339
|
}
|
|
420
|
-
function bindAtEvents(
|
|
421
|
-
const
|
|
422
|
-
const all = isFragment ? queryAll(root, "*") : queryOwnAll(root, "*");
|
|
423
|
-
if (!isFragment && !all.includes(root)) all.unshift(root);
|
|
424
|
-
for (const el of all) {
|
|
340
|
+
function bindAtEvents(els, instance) {
|
|
341
|
+
for (const el of els) {
|
|
425
342
|
const mEl = el;
|
|
426
343
|
if (mEl.__micraAtBound) continue;
|
|
427
344
|
let bound = false;
|
|
@@ -442,15 +359,12 @@ function bindAtEvents(root, instance) {
|
|
|
442
359
|
if (bound) mEl.__micraAtBound = true;
|
|
443
360
|
}
|
|
444
361
|
}
|
|
445
|
-
function bindModels(
|
|
446
|
-
|
|
447
|
-
const isFragment = root.nodeType === 11;
|
|
448
|
-
const els = isFragment ? queryAll(root, "[data-model]") : queryOwn(root, "data-model");
|
|
449
|
-
for (const el of els) {
|
|
362
|
+
function bindModels(bindings, instance) {
|
|
363
|
+
for (const { el, expr } of bindings) {
|
|
450
364
|
const mEl = el;
|
|
451
365
|
if (mEl.__micraModel) continue;
|
|
452
366
|
mEl.__micraModel = true;
|
|
453
|
-
const key = (
|
|
367
|
+
const key = expr.trim();
|
|
454
368
|
const tag = el.tagName;
|
|
455
369
|
const inputEl = el;
|
|
456
370
|
const inputType = inputEl.type;
|
|
@@ -471,11 +385,132 @@ function bindModels(root, instance) {
|
|
|
471
385
|
}
|
|
472
386
|
}
|
|
473
387
|
|
|
388
|
+
// src/dom/scan.ts
|
|
389
|
+
function emptyScan() {
|
|
390
|
+
return {
|
|
391
|
+
text: [],
|
|
392
|
+
html: [],
|
|
393
|
+
if: [],
|
|
394
|
+
show: [],
|
|
395
|
+
bind: [],
|
|
396
|
+
model: [],
|
|
397
|
+
class: [],
|
|
398
|
+
each: [],
|
|
399
|
+
on: [],
|
|
400
|
+
atEvents: [],
|
|
401
|
+
refs: []
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function parsePairs(expr) {
|
|
405
|
+
const out = [];
|
|
406
|
+
for (const part of expr.split(",")) {
|
|
407
|
+
const colon = part.indexOf(":");
|
|
408
|
+
if (colon === -1) continue;
|
|
409
|
+
const left = part.slice(0, colon).trim();
|
|
410
|
+
const right = part.slice(colon + 1).trim();
|
|
411
|
+
if (!left) continue;
|
|
412
|
+
out.push([left, right]);
|
|
413
|
+
}
|
|
414
|
+
return out;
|
|
415
|
+
}
|
|
416
|
+
function classify(el, scan) {
|
|
417
|
+
if (el.tagName === "TEMPLATE") {
|
|
418
|
+
if (el.hasAttribute("data-each")) scan.each.push(el);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const attrs = el.attributes;
|
|
422
|
+
let atEventSeen = false;
|
|
423
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
424
|
+
const a = attrs[i];
|
|
425
|
+
const name = a.name;
|
|
426
|
+
const first = name.charCodeAt(0);
|
|
427
|
+
if (first === 64) {
|
|
428
|
+
if (!atEventSeen) {
|
|
429
|
+
scan.atEvents.push(el);
|
|
430
|
+
atEventSeen = true;
|
|
431
|
+
}
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (first === 100 && name.length >= 6 && name.charCodeAt(4) === 45) {
|
|
435
|
+
const rest = name.slice(5);
|
|
436
|
+
switch (rest) {
|
|
437
|
+
case "text":
|
|
438
|
+
scan.text.push({ el, expr: a.value });
|
|
439
|
+
break;
|
|
440
|
+
case "html":
|
|
441
|
+
scan.html.push({ el, expr: a.value });
|
|
442
|
+
break;
|
|
443
|
+
case "if":
|
|
444
|
+
scan.if.push({ el, expr: a.value });
|
|
445
|
+
break;
|
|
446
|
+
case "show":
|
|
447
|
+
scan.show.push({ el, expr: a.value });
|
|
448
|
+
break;
|
|
449
|
+
case "bind": {
|
|
450
|
+
const pairs = parsePairs(a.value);
|
|
451
|
+
scan.bind.push({ el, expr: a.value, pairs });
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
case "model":
|
|
455
|
+
scan.model.push({ el, expr: a.value });
|
|
456
|
+
break;
|
|
457
|
+
case "class": {
|
|
458
|
+
const pairs = parsePairs(a.value);
|
|
459
|
+
scan.class.push({ el, expr: a.value, pairs });
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
case "on":
|
|
463
|
+
scan.on.push(el);
|
|
464
|
+
break;
|
|
465
|
+
case "ref":
|
|
466
|
+
scan.refs.push(el);
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
var NESTED_COMPONENT_FILTER = {
|
|
473
|
+
acceptNode(node) {
|
|
474
|
+
if (node.hasAttribute("data-component"))
|
|
475
|
+
return NodeFilter.FILTER_REJECT;
|
|
476
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
function scanComponent(root) {
|
|
480
|
+
const scan = emptyScan();
|
|
481
|
+
classify(root, scan);
|
|
482
|
+
const walker = document.createTreeWalker(
|
|
483
|
+
root,
|
|
484
|
+
NodeFilter.SHOW_ELEMENT,
|
|
485
|
+
NESTED_COMPONENT_FILTER
|
|
486
|
+
);
|
|
487
|
+
let node = walker.nextNode();
|
|
488
|
+
while (node) {
|
|
489
|
+
classify(node, scan);
|
|
490
|
+
node = walker.nextNode();
|
|
491
|
+
}
|
|
492
|
+
return scan;
|
|
493
|
+
}
|
|
494
|
+
function scanFragment(frag) {
|
|
495
|
+
const scan = emptyScan();
|
|
496
|
+
const walker = document.createTreeWalker(
|
|
497
|
+
frag,
|
|
498
|
+
NodeFilter.SHOW_ELEMENT,
|
|
499
|
+
NESTED_COMPONENT_FILTER
|
|
500
|
+
);
|
|
501
|
+
let node = walker.nextNode();
|
|
502
|
+
while (node) {
|
|
503
|
+
classify(node, scan);
|
|
504
|
+
node = walker.nextNode();
|
|
505
|
+
}
|
|
506
|
+
return scan;
|
|
507
|
+
}
|
|
508
|
+
|
|
474
509
|
// src/dom/each.ts
|
|
475
|
-
function renderList(
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if (tmplEl.tagName !== "TEMPLATE")
|
|
510
|
+
function renderList(templates, state, rawState, instance) {
|
|
511
|
+
var _a;
|
|
512
|
+
for (const tmplEl of templates) {
|
|
513
|
+
if (tmplEl.tagName !== "TEMPLATE") continue;
|
|
479
514
|
const tmpl = tmplEl;
|
|
480
515
|
const itemsExpr = tmpl.getAttribute("data-each");
|
|
481
516
|
const keyAttr = (_a = tmpl.getAttribute("data-key")) != null ? _a : null;
|
|
@@ -490,21 +525,22 @@ function renderList(root, state, rawState, instance) {
|
|
|
490
525
|
const marker = tmpl.__micraMarker;
|
|
491
526
|
const keyMap = tmpl.__micraNodes;
|
|
492
527
|
const parent = marker.parentNode;
|
|
493
|
-
if (!parent)
|
|
528
|
+
if (!parent) continue;
|
|
494
529
|
if (!Array.isArray(items)) {
|
|
495
530
|
tmpl.__micraList.forEach((n) => n.remove());
|
|
496
531
|
tmpl.__micraList = [];
|
|
497
532
|
keyMap.clear();
|
|
498
|
-
|
|
533
|
+
continue;
|
|
499
534
|
}
|
|
500
535
|
if (keyAttr) {
|
|
501
536
|
renderKeyed(tmpl, items, keyAttr, marker, keyMap, parent, state, rawState, instance);
|
|
502
537
|
} else {
|
|
503
538
|
renderNoKey(tmpl, items, marker, parent, state, rawState, instance);
|
|
504
539
|
}
|
|
505
|
-
}
|
|
540
|
+
}
|
|
506
541
|
}
|
|
507
542
|
function renderKeyed(tmpl, items, keyAttr, marker, keyMap, parent, state, rawState, instance) {
|
|
543
|
+
var _a;
|
|
508
544
|
const nextKeys = /* @__PURE__ */ new Set();
|
|
509
545
|
const nextNodes = [];
|
|
510
546
|
let warnedNullKey = false;
|
|
@@ -532,14 +568,18 @@ function renderKeyed(tmpl, items, keyAttr, marker, keyMap, parent, state, rawSta
|
|
|
532
568
|
}
|
|
533
569
|
node.__micraKey = key;
|
|
534
570
|
keyMap.set(key, node);
|
|
535
|
-
|
|
536
|
-
|
|
571
|
+
const rowScan2 = scanComponent(node);
|
|
572
|
+
node.__micraScan = rowScan2;
|
|
573
|
+
bindDataOn(rowScan2.on, instance);
|
|
574
|
+
bindAtEvents(rowScan2.atEvents, instance);
|
|
575
|
+
bindModels(rowScan2.model, instance);
|
|
537
576
|
}
|
|
538
577
|
const itemState = Object.assign(
|
|
539
578
|
Object.create(state),
|
|
540
579
|
{ item, index, $index: index }
|
|
541
580
|
);
|
|
542
|
-
|
|
581
|
+
const rowScan = (_a = node.__micraScan) != null ? _a : node.__micraScan = scanComponent(node);
|
|
582
|
+
applyDirectives(rowScan, itemState, rawState, instance);
|
|
543
583
|
nextNodes.push(node);
|
|
544
584
|
}
|
|
545
585
|
for (const [key, node] of keyMap) {
|
|
@@ -565,9 +605,11 @@ function renderNoKey(tmpl, items, marker, parent, state, rawState, instance) {
|
|
|
565
605
|
Object.create(state),
|
|
566
606
|
{ item, index, $index: index }
|
|
567
607
|
);
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
608
|
+
const fragScan = scanFragment(clone);
|
|
609
|
+
applyDirectives(fragScan, itemState, rawState, instance);
|
|
610
|
+
bindDataOn(fragScan.on, instance);
|
|
611
|
+
bindAtEvents(fragScan.atEvents, instance);
|
|
612
|
+
bindModels(fragScan.model, instance);
|
|
571
613
|
const nodes = Array.from(clone.childNodes);
|
|
572
614
|
nodes.forEach((n) => {
|
|
573
615
|
n.__micraEach = true;
|
|
@@ -579,9 +621,9 @@ function renderNoKey(tmpl, items, marker, parent, state, rawState, instance) {
|
|
|
579
621
|
}
|
|
580
622
|
|
|
581
623
|
// src/dom/refs.ts
|
|
582
|
-
function collectRefs(
|
|
624
|
+
function collectRefs(els, instance) {
|
|
583
625
|
instance.refs = {};
|
|
584
|
-
for (const el of
|
|
626
|
+
for (const el of els) {
|
|
585
627
|
const name = el.dataset["ref"];
|
|
586
628
|
if (name) instance.refs[name] = el;
|
|
587
629
|
}
|
|
@@ -595,10 +637,13 @@ function mount(selector, definition) {
|
|
|
595
637
|
warn(`"${selector}" not found`);
|
|
596
638
|
return null;
|
|
597
639
|
}
|
|
598
|
-
if (_instances.has(root))
|
|
640
|
+
if (_instances.has(root))
|
|
641
|
+
return _instances.get(root);
|
|
599
642
|
const rawState = { ...(_a = definition.state) != null ? _a : {} };
|
|
600
643
|
const instance = { $el: root, refs: {} };
|
|
601
|
-
for (const [key, val] of Object.entries(
|
|
644
|
+
for (const [key, val] of Object.entries(
|
|
645
|
+
definition
|
|
646
|
+
)) {
|
|
602
647
|
if (key === "state" || key === "onCreate" || key === "onDestroy") continue;
|
|
603
648
|
if (typeof val === "function") instance[key] = val;
|
|
604
649
|
}
|
|
@@ -642,22 +687,27 @@ function mount(selector, definition) {
|
|
|
642
687
|
});
|
|
643
688
|
let warnedReentry = false;
|
|
644
689
|
instance.render = function() {
|
|
690
|
+
var _a2;
|
|
645
691
|
if (instance.__micraDestroyed) return;
|
|
646
692
|
if (isRendering) {
|
|
647
693
|
if (!warnedReentry) {
|
|
648
|
-
warn(
|
|
694
|
+
warn(
|
|
695
|
+
"render() re-entry detected \u2014 mutation inside a directive expression is ignored. Move state writes to a method."
|
|
696
|
+
);
|
|
649
697
|
warnedReentry = true;
|
|
650
698
|
}
|
|
651
699
|
return;
|
|
652
700
|
}
|
|
653
701
|
isRendering = true;
|
|
654
702
|
try {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
703
|
+
const mRoot2 = root;
|
|
704
|
+
const scan = (_a2 = mRoot2.__micraScan) != null ? _a2 : mRoot2.__micraScan = scanComponent(root);
|
|
705
|
+
applyDirectives(scan, exprState, rawState, instance);
|
|
706
|
+
renderList(scan.each, exprState, rawState, instance);
|
|
707
|
+
bindDataOn(scan.on, instance);
|
|
708
|
+
bindAtEvents(scan.atEvents, instance);
|
|
709
|
+
bindModels(scan.model, instance);
|
|
710
|
+
collectRefs(scan.refs, instance);
|
|
661
711
|
} finally {
|
|
662
712
|
isRendering = false;
|
|
663
713
|
}
|
|
@@ -666,14 +716,16 @@ function mount(selector, definition) {
|
|
|
666
716
|
var _a2, _b;
|
|
667
717
|
if (instance.__micraDestroyed) return;
|
|
668
718
|
instance.__micraDestroyed = true;
|
|
669
|
-
(_a2 = instance.__micraListeners) == null ? void 0 : _a2.forEach(
|
|
719
|
+
(_a2 = instance.__micraListeners) == null ? void 0 : _a2.forEach(
|
|
720
|
+
({ el, type, fn }) => el.removeEventListener(type, fn)
|
|
721
|
+
);
|
|
670
722
|
instance.__micraListeners = [];
|
|
671
723
|
const clearFlags = (el) => {
|
|
672
724
|
const m = el;
|
|
673
725
|
delete m.__micraEvents;
|
|
674
726
|
delete m.__micraAtBound;
|
|
675
727
|
delete m.__micraModel;
|
|
676
|
-
delete m.
|
|
728
|
+
delete m.__micraScan;
|
|
677
729
|
};
|
|
678
730
|
clearFlags(root);
|
|
679
731
|
root.querySelectorAll("*").forEach(clearFlags);
|
|
@@ -685,7 +737,8 @@ function mount(selector, definition) {
|
|
|
685
737
|
};
|
|
686
738
|
_instances.set(root, instance);
|
|
687
739
|
instance.render();
|
|
688
|
-
|
|
740
|
+
const mRoot = root;
|
|
741
|
+
if (mRoot.__micraScan) validateDirectives(mRoot.__micraScan);
|
|
689
742
|
if (typeof definition.onCreate === "function")
|
|
690
743
|
Promise.resolve().then(
|
|
691
744
|
() => definition.onCreate.call(instance)
|