@motifx/core 1.2.0-rc.4 → 1.2.0-rc.5

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.
@@ -1,5 +1,65 @@
1
1
  'use strict';
2
2
 
3
+ const state = {
4
+ enabled: false,
5
+ listeners: new Set(),
6
+ warnings: [],
7
+ routes: null,
8
+ exposed: null,
9
+ };
10
+ /** Dev modu: devtools açık ya da `globalThis.__MOTIF_DEV__ === true`. */
11
+ function isDevLike() {
12
+ return state.enabled || globalThis.__MOTIF_DEV__ === true;
13
+ }
14
+ function setDevtoolsEnabled(enabled) {
15
+ state.enabled = enabled;
16
+ try {
17
+ const g = globalThis;
18
+ if (enabled) {
19
+ state.exposed = { version: 1, on, getWarnings, getRoutes, isEnabled };
20
+ g.__MOTIF_DEVTOOLS__ = state.exposed;
21
+ }
22
+ else {
23
+ if (state.exposed !== null && g.__MOTIF_DEVTOOLS__ === state.exposed)
24
+ delete g.__MOTIF_DEVTOOLS__;
25
+ state.exposed = null;
26
+ }
27
+ }
28
+ catch { }
29
+ }
30
+ function isEnabled() { return state.enabled; }
31
+ function devtools() {
32
+ return state.enabled ? emit : undefined;
33
+ }
34
+ function on(listener) {
35
+ state.listeners.add(listener);
36
+ return () => { state.listeners.delete(listener); };
37
+ }
38
+ function emit(type, payload) {
39
+ const ev = { type, payload };
40
+ for (const l of state.listeners) {
41
+ try {
42
+ l(ev);
43
+ }
44
+ catch { }
45
+ }
46
+ }
47
+ function warn(code, message, details) {
48
+ if (!isDevLike())
49
+ return;
50
+ const w = { code, message, details };
51
+ state.warnings.push(w);
52
+ try {
53
+ if (typeof console !== 'undefined')
54
+ details === undefined ? console.warn(`[motifjs] ${code}: ${message}`) : console.warn(`[motifjs] ${code}: ${message}`, details);
55
+ }
56
+ catch { }
57
+ devtools()?.('warning', w);
58
+ }
59
+ function getWarnings() { return state.warnings.slice(); }
60
+ function setRoutes(routes) { state.routes = routes; }
61
+ function getRoutes() { return state.routes; }
62
+
3
63
  function rethrowLater(error) {
4
64
  setTimeout(() => { throw error; }, 0);
5
65
  }
@@ -30,10 +90,7 @@ class ErrorHandler {
30
90
  console.error(error.message);
31
91
  }
32
92
  try {
33
- const bus = globalThis.__MOTIF_DEVTOOLS_BUS__;
34
- if (bus && typeof bus.publish === 'function') {
35
- bus.publish('error:caught', { context: error.code ?? error.name, error: this.serializeError(error) });
36
- }
93
+ devtools()?.('error:caught', { context: error.code ?? error.name, error: this.serializeError(error) });
37
94
  }
38
95
  catch { /* ignore */ }
39
96
  this.emit(error);
@@ -43,10 +100,7 @@ class ErrorHandler {
43
100
  console.error(`[motifjs Error - ${context}]`, error);
44
101
  }
45
102
  try {
46
- const bus = globalThis.__MOTIF_DEVTOOLS_BUS__;
47
- if (bus && typeof bus.publish === 'function') {
48
- bus.publish('error:caught', { context, error: this.serializeError(error) });
49
- }
103
+ devtools()?.('error:caught', { context, error: this.serializeError(error) });
50
104
  }
51
105
  catch { /* ignore */ }
52
106
  }
@@ -176,90 +230,6 @@ function setUnexpectedErrorHandler(handler) {
176
230
  errorHandler.setUnexpectedErrorHandler(handler);
177
231
  }
178
232
 
179
- const state = {
180
- enabled: false,
181
- listeners: new Set(),
182
- warnings: [],
183
- routes: null,
184
- };
185
- /** Dev modu: devtools açık ya da `globalThis.__MOTIF_DEV__ === true`. */
186
- function isDevLike() {
187
- return state.enabled || globalThis.__MOTIF_DEV__ === true;
188
- }
189
- function isRequestedByFlag() {
190
- try {
191
- if (typeof window === 'undefined')
192
- return false;
193
- const w = window;
194
- if (w.__motif_DEVTOOLS === true)
195
- return true;
196
- if (globalThis.__MOTIF_DEVTOOLS__ === true)
197
- return true;
198
- if (globalThis.__MOTIF_DEVTOOLS_FLAG === true)
199
- return true;
200
- return false;
201
- }
202
- catch {
203
- return false;
204
- }
205
- }
206
- function exposeBus(visible) {
207
- try {
208
- if (visible)
209
- window.__motifDevBus = { on, emit, warn, getWarnings, isEnabled, setRoutes, getRoutes };
210
- else
211
- delete window.__motifDevBus;
212
- }
213
- catch { }
214
- }
215
- function ensureDevtoolsFlagInitialized() {
216
- if (state.enabled)
217
- return;
218
- state.enabled = isRequestedByFlag();
219
- if (state.enabled)
220
- exposeBus(true);
221
- }
222
- function setDevtoolsEnabled(enabled) {
223
- state.enabled = enabled || isRequestedByFlag();
224
- exposeBus(state.enabled);
225
- }
226
- function isEnabled() { return state.enabled; }
227
- function on(listener) {
228
- state.listeners.add(listener);
229
- return () => { state.listeners.delete(listener); };
230
- }
231
- function emit(type, payload) {
232
- const ev = { type, payload };
233
- for (const l of state.listeners) {
234
- try {
235
- l(ev);
236
- }
237
- catch { }
238
- }
239
- try {
240
- const bus = globalThis.__MOTIF_DEVTOOLS_BUS__;
241
- if (bus && typeof bus.publish === 'function') {
242
- bus.publish('devtools:' + type, payload);
243
- }
244
- }
245
- catch { }
246
- }
247
- function warn(code, message, details) {
248
- if (!isDevLike())
249
- return;
250
- const w = { code, message, details };
251
- state.warnings.push(w);
252
- try {
253
- if (typeof console !== 'undefined')
254
- details === undefined ? console.warn(`[motifjs] ${code}: ${message}`) : console.warn(`[motifjs] ${code}: ${message}`, details);
255
- }
256
- catch { }
257
- emit('warning', w);
258
- }
259
- function getWarnings() { return state.warnings.slice(); }
260
- function setRoutes(routes) { state.routes = routes; }
261
- function getRoutes() { return state.routes; }
262
-
263
233
  const motifMessages = {
264
234
  MJX101: (tag) => `dom.createElement('${tag}'): no document is available (no DOM environment).`,
265
235
  MJX102: (description) => `Invalid element selector "${description}".`,
@@ -347,7 +317,6 @@ const motifMessages = {
347
317
  MJX608: () => `Method not implemented.`,
348
318
  MJX609: () => `OperationRunner: the operation threw.`,
349
319
  MJX610: () => `Matching the request path failed.`,
350
- MJX611: () => `The devtools panel failed to load.`,
351
320
  };
352
321
  class MotifError extends Error {
353
322
  constructor(code, message, options) {
@@ -430,11 +399,27 @@ class DisposableStore {
430
399
  if (this._closed) {
431
400
  reportWarning('MJX504', [], new Error().stack);
432
401
  }
433
- else {
434
- (this._items ??= new Set()).add(item);
402
+ else if (this._items !== undefined) {
403
+ this._items.add(item);
404
+ }
405
+ else if (this._one === undefined) {
406
+ this._one = item;
407
+ }
408
+ else if (this._one !== item) {
409
+ this._items = new Set([this._one, item]);
410
+ this._one = undefined;
435
411
  }
436
412
  return item;
437
413
  }
414
+ _take(item) {
415
+ if (this._items !== undefined)
416
+ return this._items.delete(item);
417
+ if (this._one === item) {
418
+ this._one = undefined;
419
+ return true;
420
+ }
421
+ return false;
422
+ }
438
423
  delete(item) {
439
424
  if (!item) {
440
425
  return;
@@ -442,29 +427,48 @@ class DisposableStore {
442
427
  if (item === this) {
443
428
  throw motifError('MJX505');
444
429
  }
445
- this._items?.delete(item);
430
+ this._take(item);
446
431
  item.dispose();
447
432
  }
448
433
  detach(item) {
449
- if (item && this._items?.delete(item)) {
434
+ if (item && this._take(item)) {
450
435
  disposableCore.notifyOwner(item, null);
451
436
  }
452
437
  }
453
438
  clear() {
454
- const items = this._items;
455
- if (!items || items.size === 0) {
439
+ if (this._one === undefined && (this._items === undefined || this._items.size === 0)) {
456
440
  return;
457
441
  }
458
442
  const failures = [];
459
- for (const item of items) {
443
+ let done;
444
+ for (;;) {
445
+ const items = this._items;
446
+ if (items !== undefined) {
447
+ for (const item of items) {
448
+ if (item === done)
449
+ continue;
450
+ try {
451
+ item?.dispose();
452
+ }
453
+ catch (error) {
454
+ failures.push(error);
455
+ }
456
+ }
457
+ items.clear();
458
+ break;
459
+ }
460
+ const one = this._one;
461
+ if (one === undefined || one === done)
462
+ break;
463
+ done = one;
460
464
  try {
461
- item?.dispose();
465
+ one.dispose();
462
466
  }
463
467
  catch (error) {
464
468
  failures.push(error);
465
469
  }
466
470
  }
467
- items.clear();
471
+ this._one = undefined;
468
472
  if (failures.length === 1) {
469
473
  throw failures[0];
470
474
  }
@@ -504,16 +508,19 @@ class Disposable {
504
508
  disposableCore.notifyCreated(this);
505
509
  }
506
510
  dispose() {
507
- disposableCore.notifyDisposed(this);
508
511
  const owned = this._store;
512
+ if (owned === null) {
513
+ reportWarning('MJX501', [], { disposable: this });
514
+ return;
515
+ }
516
+ if (owned !== undefined && owned.isDisposed)
517
+ return;
518
+ disposableCore.notifyDisposed(this);
509
519
  if (owned === undefined) {
510
520
  this._store = sharedClosedStore();
511
521
  }
512
- else if (owned && typeof owned.dispose === 'function') {
513
- owned.dispose();
514
- }
515
522
  else {
516
- reportWarning('MJX501', [], { disposable: this });
523
+ owned.dispose();
517
524
  }
518
525
  }
519
526
  _register(item) {
@@ -703,9 +710,7 @@ class ListBinding {
703
710
  component.motif.options.__fromList = true;
704
711
  }
705
712
  catch { }
706
- if (typeof component.__listAdopted === 'undefined') {
707
- component.__listAdopted = component.parent !== null && component.parent !== undefined;
708
- }
713
+ noteListAdopted(component);
709
714
  return component;
710
715
  }
711
716
  get _indexSensitive() {
@@ -764,7 +769,7 @@ class ListBinding {
764
769
  const seenKeys = new Map();
765
770
  const claimed = new Set();
766
771
  const positionalReuse = new Map();
767
- const isReusable = (c) => !!c && !c.isDisposed && !claimed.has(c) && !c.__listAdopted;
772
+ const isReusable = (c) => !!c && !c.isDisposed && !claimed.has(c) && !isListAdopted(c);
768
773
  const shared = Math.min(items.length, prevItems.length);
769
774
  for (let i = 0; i < shared; i++) {
770
775
  const it = items[i];
@@ -850,7 +855,7 @@ class ListBinding {
850
855
  list.length = count;
851
856
  });
852
857
  this._rendered.forEach(comp => {
853
- if (!usedComponents.has(comp) && !comp.__listAdopted) {
858
+ if (!usedComponents.has(comp) && !isListAdopted(comp)) {
854
859
  try {
855
860
  comp.dispose();
856
861
  }
@@ -1177,6 +1182,15 @@ exports.NodeTypes = void 0;
1177
1182
  NodeTypes[NodeTypes["NOTATION_NODE"] = 12] = "NOTATION_NODE";
1178
1183
  })(exports.NodeTypes || (exports.NodeTypes = {}));
1179
1184
 
1185
+ function pushTight(list, value) {
1186
+ if (list.length === 0) {
1187
+ list.length = 1;
1188
+ list[0] = value;
1189
+ return;
1190
+ }
1191
+ list.push(value);
1192
+ }
1193
+
1180
1194
  class Effect {
1181
1195
  constructor(fn, callback) {
1182
1196
  this.fn = fn;
@@ -1236,7 +1250,7 @@ function track(target, key) {
1236
1250
  deps.set(key, (dep = new Set()));
1237
1251
  if (!dep.has(effect)) {
1238
1252
  dep.add(effect);
1239
- effect.deps.push([rawTarget, key]);
1253
+ pushTight(effect.deps, [rawTarget, key]);
1240
1254
  if (leakEnabled && leakMonitor && leakThreshold > 0) {
1241
1255
  try {
1242
1256
  const cleanup = leakMonitor.check(dep.size);
@@ -1628,6 +1642,43 @@ class Binding {
1628
1642
  }
1629
1643
  }
1630
1644
 
1645
+ class QuietCleanup {
1646
+ constructor(_fn) {
1647
+ this._fn = _fn;
1648
+ }
1649
+ dispose() {
1650
+ const fn = this._fn;
1651
+ if (fn === undefined)
1652
+ return;
1653
+ this._fn = undefined;
1654
+ try {
1655
+ fn();
1656
+ }
1657
+ catch { }
1658
+ }
1659
+ }
1660
+ class TrackedCleanup {
1661
+ constructor(_fn) {
1662
+ this._fn = _fn;
1663
+ disposableCore.notifyCreated(this);
1664
+ }
1665
+ dispose() {
1666
+ const fn = this._fn;
1667
+ if (fn === undefined)
1668
+ return;
1669
+ this._fn = undefined;
1670
+ disposableCore.notifyDisposed(this);
1671
+ fn();
1672
+ }
1673
+ }
1674
+ const coreToDisposable = disposableCore.toDisposable;
1675
+ function quietCleanup(fn) {
1676
+ return new QuietCleanup(fn);
1677
+ }
1678
+ function trackedCleanup(fn) {
1679
+ return disposableCore.toDisposable === coreToDisposable ? new TrackedCleanup(fn) : disposableCore.toDisposable(fn);
1680
+ }
1681
+
1631
1682
  const RAW_KEY = Flags.RAW;
1632
1683
  function isPrototypeObject(o) {
1633
1684
  return Object.prototype.hasOwnProperty.call(o, 'constructor') && typeof o.constructor === 'function' && o.constructor.prototype === o;
@@ -1694,12 +1745,7 @@ class BindingCollection {
1694
1745
  this._branchScope.push(stop);
1695
1746
  return;
1696
1747
  }
1697
- this._component.motif.register(toDisposable(() => {
1698
- try {
1699
- stop();
1700
- }
1701
- catch { }
1702
- }));
1748
+ this._component.motif.register(quietCleanup(stop));
1703
1749
  }
1704
1750
  when(computeFn, renderFn) {
1705
1751
  var frame = new Frame();
@@ -1743,7 +1789,7 @@ class BindingCollection {
1743
1789
  const [propertyName, dataSource, dataMember, formatString, formatInfo] = args;
1744
1790
  binding = new Binding(this._component, propertyName, dataSource, dataMember, formatString, formatInfo);
1745
1791
  }
1746
- this._items.push(binding);
1792
+ pushTight(this._items, binding);
1747
1793
  if (this._component.isBuilt) {
1748
1794
  binding.activate();
1749
1795
  }
@@ -1751,7 +1797,7 @@ class BindingCollection {
1751
1797
  }
1752
1798
  wait(predicate) {
1753
1799
  const binding = new Binding(this._component, 'isWait', predicate);
1754
- this._items.push(binding);
1800
+ pushTight(this._items, binding);
1755
1801
  if (this._component.isBuilt) {
1756
1802
  binding.activate();
1757
1803
  }
@@ -1759,7 +1805,7 @@ class BindingCollection {
1759
1805
  }
1760
1806
  display(predicate) {
1761
1807
  const binding = new Binding(this._component, 'isWait', () => !resolveValue(predicate()));
1762
- this._items.push(binding);
1808
+ pushTight(this._items, binding);
1763
1809
  if (this._component.isBuilt) {
1764
1810
  binding.activate();
1765
1811
  }
@@ -1767,7 +1813,7 @@ class BindingCollection {
1767
1813
  }
1768
1814
  html(predicate) {
1769
1815
  const binding = new Binding(this._component, 'innerHTML', predicate);
1770
- this._items.push(binding);
1816
+ pushTight(this._items, binding);
1771
1817
  if (this._component.isBuilt) {
1772
1818
  binding.activate();
1773
1819
  }
@@ -1775,7 +1821,7 @@ class BindingCollection {
1775
1821
  }
1776
1822
  list(itemsFn, renderFn, options) {
1777
1823
  const binding = new ListBinding(this._component, itemsFn, renderFn, options);
1778
- this._items.push(binding);
1824
+ pushTight(this._items, binding);
1779
1825
  if (this._component.isBuilt) {
1780
1826
  binding.activate();
1781
1827
  }
@@ -1783,7 +1829,7 @@ class BindingCollection {
1783
1829
  }
1784
1830
  loop(itemsFn, renderFn, options) {
1785
1831
  const binding = new ListBinding(this._component, itemsFn, renderFn, options);
1786
- this._items.push(binding);
1832
+ pushTight(this._items, binding);
1787
1833
  if (this._component.isBuilt) {
1788
1834
  binding.activate();
1789
1835
  }
@@ -1822,12 +1868,7 @@ class BindingCollection {
1822
1868
  }
1823
1869
  frame.navigate(result == null ? motifFragment() : result);
1824
1870
  });
1825
- host.motif.register(toDisposable(() => {
1826
- try {
1827
- stop();
1828
- }
1829
- catch { }
1830
- }));
1871
+ host.motif.register(quietCleanup(stop));
1831
1872
  }
1832
1873
  ternary(conditionFn, trueFn, falseFn) {
1833
1874
  const frame = new Frame();
@@ -1894,12 +1935,7 @@ class BindingCollection {
1894
1935
  const ef = effect(() => {
1895
1936
  cb();
1896
1937
  });
1897
- this._component.motif.register(toDisposable(() => {
1898
- try {
1899
- ef();
1900
- }
1901
- catch { }
1902
- }));
1938
+ this._component.motif.register(quietCleanup(ef));
1903
1939
  }
1904
1940
  remove(binding) {
1905
1941
  const index = this._items.indexOf(binding);
@@ -2001,7 +2037,7 @@ class BindingCollection {
2001
2037
  this._component.motif.on('input', writeBack);
2002
2038
  this._component.motif.on('change', writeBack);
2003
2039
  }
2004
- this._items.push(binding);
2040
+ pushTight(this._items, binding);
2005
2041
  if (this._component.isBuilt) {
2006
2042
  binding.activate();
2007
2043
  }
@@ -2067,12 +2103,7 @@ class BindingCollection {
2067
2103
  frame.navigate(motifFragment());
2068
2104
  }
2069
2105
  });
2070
- this._component.motif.register(toDisposable(() => {
2071
- try {
2072
- ef();
2073
- }
2074
- catch { }
2075
- }));
2106
+ this._component.motif.register(quietCleanup(ef));
2076
2107
  return null;
2077
2108
  }
2078
2109
  }
@@ -2265,7 +2296,7 @@ class ComponentEmiter {
2265
2296
  sources.set(lower, set);
2266
2297
  }
2267
2298
  set.add(disp);
2268
- this.component.motif.register(disposableCore.toDisposable(() => {
2299
+ this.component.motif.register(trackedCleanup(() => {
2269
2300
  try {
2270
2301
  disp?.dispose();
2271
2302
  }
@@ -2855,9 +2886,62 @@ class controlClass {
2855
2886
  this._watcherSeq = 0;
2856
2887
  this._parent = parent;
2857
2888
  }
2858
- get _counts() { return this._countsStore ??= new Map(); }
2859
- get _staticSet() { return this._staticSetStore ??= new Set(); }
2860
- get _watchers() { return this._watchersStore ??= new Map(); }
2889
+ get _counts() {
2890
+ if (this._plain !== undefined)
2891
+ this._promote();
2892
+ return this._countsStore ?? this._createCounts();
2893
+ }
2894
+ _createCounts() {
2895
+ const counts = this._countsStore = new Map();
2896
+ if (this._sole !== undefined) {
2897
+ const one = this._watcherOne;
2898
+ this._sole = undefined;
2899
+ if (one !== undefined)
2900
+ for (const cls of one.set)
2901
+ counts.set(cls, (counts.get(cls) || 0) + 1);
2902
+ }
2903
+ return counts;
2904
+ }
2905
+ get _staticSet() {
2906
+ if (this._plain !== undefined)
2907
+ this._promote();
2908
+ return this._staticSetStore ??= new Set();
2909
+ }
2910
+ _promote() {
2911
+ const names = this._plain.split(' ');
2912
+ this._plain = undefined;
2913
+ const set = this._staticSetStore ??= new Set();
2914
+ const counts = this._countsStore ?? this._createCounts();
2915
+ for (const cls of names) {
2916
+ set.add(cls);
2917
+ counts.set(cls, (counts.get(cls) || 0) + 1);
2918
+ }
2919
+ }
2920
+ _watcherEntries() {
2921
+ if (this._watchersStore !== undefined)
2922
+ return Array.from(this._watchersStore.entries());
2923
+ const one = this._watcherOne;
2924
+ return one !== undefined ? [[one.id, one]] : [];
2925
+ }
2926
+ _dropWatcher(id) {
2927
+ if (this._watchersStore !== undefined)
2928
+ this._watchersStore.delete(id);
2929
+ else if (this._watcherOne !== undefined && this._watcherOne.id === id)
2930
+ this._watcherOne = undefined;
2931
+ }
2932
+ _keepWatcher(rec) {
2933
+ if (this._watchersStore !== undefined) {
2934
+ this._watchersStore.set(rec.id, rec);
2935
+ return;
2936
+ }
2937
+ const one = this._watcherOne;
2938
+ if (one === undefined) {
2939
+ this._watcherOne = rec;
2940
+ return;
2941
+ }
2942
+ this._watcherOne = undefined;
2943
+ this._watchersStore = new Map([[one.id, one], [rec.id, rec]]);
2944
+ }
2861
2945
  add(...values) {
2862
2946
  for (const value of values) {
2863
2947
  if (typeof value === 'function') {
@@ -2869,12 +2953,36 @@ class controlClass {
2869
2953
  else if (value && typeof value === 'object') {
2870
2954
  this._addStaticFromObject(value);
2871
2955
  }
2956
+ else if (typeof value === 'string' && value !== '' && !/\s/.test(value)) {
2957
+ this._addStaticName(value);
2958
+ }
2872
2959
  else {
2873
2960
  this._addStaticNames(this._splitClasses(String(value ?? '')));
2874
2961
  }
2875
2962
  }
2876
2963
  return this._parent;
2877
2964
  }
2965
+ _addStaticName(cls) {
2966
+ if (this._countsStore !== undefined || this._staticSetStore !== undefined || this._sole !== undefined) {
2967
+ this._addStaticNames([cls]);
2968
+ return;
2969
+ }
2970
+ const plain = this._plain;
2971
+ if (plain !== undefined && hasName(plain, cls))
2972
+ return;
2973
+ this._plain = plain === undefined ? cls : plain + ' ' + cls;
2974
+ const el = this._getElement();
2975
+ if (!el)
2976
+ return;
2977
+ if (!el.hasAttribute('class'))
2978
+ el.setAttribute('class', cls);
2979
+ else {
2980
+ try {
2981
+ el.classList.add(cls);
2982
+ }
2983
+ catch { }
2984
+ }
2985
+ }
2878
2986
  remove(classNames) {
2879
2987
  const el = this._getElement();
2880
2988
  if (Array.isArray(classNames)) {
@@ -2888,7 +2996,7 @@ class controlClass {
2888
2996
  }
2889
2997
  else {
2890
2998
  if (classNames === '**') {
2891
- for (const [id, w] of Array.from(this._watchers.entries())) {
2999
+ for (const [id, w] of this._watcherEntries()) {
2892
3000
  const prev = new Set(w.set);
2893
3001
  this._applySourceDiff(id, prev, new Set(), el);
2894
3002
  try {
@@ -2899,7 +3007,7 @@ class controlClass {
2899
3007
  w.stop();
2900
3008
  }
2901
3009
  catch { }
2902
- this._watchers.delete(id);
3010
+ this._dropWatcher(id);
2903
3011
  }
2904
3012
  const prev = new Set(this._staticSet);
2905
3013
  this._staticSet.clear();
@@ -2942,7 +3050,7 @@ class controlClass {
2942
3050
  return [input];
2943
3051
  return input.split(/\s+/).filter(s => s.length > 0);
2944
3052
  }
2945
- _normalizeToSet(values, key) {
3053
+ _normalizeToSet(values) {
2946
3054
  const result = new Set();
2947
3055
  if (values == null)
2948
3056
  return result;
@@ -2972,13 +3080,7 @@ class controlClass {
2972
3080
  }
2973
3081
  }
2974
3082
  }
2975
- else if (typeof item === 'boolean') {
2976
- if (key && item) {
2977
- for (const cls of this._splitClasses(String(key)))
2978
- result.add(cls);
2979
- }
2980
- }
2981
- else {
3083
+ else if (typeof item !== 'boolean') {
2982
3084
  for (const cls of this._splitClasses(String(item)))
2983
3085
  result.add(cls);
2984
3086
  }
@@ -2994,19 +3096,32 @@ class controlClass {
2994
3096
  }
2995
3097
  }
2996
3098
  }
2997
- else if (typeof values === 'boolean') {
2998
- if (key && values) {
2999
- for (const cls of this._splitClasses(String(key)))
3000
- result.add(cls);
3001
- }
3002
- }
3003
- else {
3099
+ else if (typeof values !== 'boolean') {
3004
3100
  for (const cls of this._splitClasses(String(values)))
3005
3101
  result.add(cls);
3006
3102
  }
3007
3103
  return result;
3008
3104
  }
3009
3105
  _applySourceDiff(sourceId, prev, next, el) {
3106
+ if (this._countsStore === undefined && this._plain === undefined && this._sole === sourceId) {
3107
+ for (const cls of prev) {
3108
+ if (!next.has(cls) && el) {
3109
+ try {
3110
+ el.classList.remove(cls);
3111
+ }
3112
+ catch { }
3113
+ }
3114
+ }
3115
+ for (const cls of next) {
3116
+ if (!prev.has(cls) && el) {
3117
+ try {
3118
+ el.classList.add(cls);
3119
+ }
3120
+ catch { }
3121
+ }
3122
+ }
3123
+ return;
3124
+ }
3010
3125
  for (const cls of prev) {
3011
3126
  if (!next.has(cls)) {
3012
3127
  const prevCount = this._counts.get(cls) || 0;
@@ -3121,7 +3236,11 @@ class controlClass {
3121
3236
  for (const k of Object.keys(obj)) {
3122
3237
  const v = obj[k];
3123
3238
  const keys = this._splitClasses(String(k));
3124
- if (!!v) {
3239
+ if (typeof v === 'function') {
3240
+ for (const cls of keys)
3241
+ this._addReactive(v, cls);
3242
+ }
3243
+ else if (!!v) {
3125
3244
  for (const cls of keys)
3126
3245
  this._staticSet.add(cls);
3127
3246
  }
@@ -3134,13 +3253,17 @@ class controlClass {
3134
3253
  }
3135
3254
  _addReactive(fn, key) {
3136
3255
  const id = `fx#${++this._watcherSeq}`;
3137
- const rec = { stop: () => { }, binding: undefined, set: new Set() };
3256
+ const rec = { id, stop: () => { }, binding: undefined, set: new Set() };
3138
3257
  const el = this._getElement();
3258
+ if (this._countsStore === undefined && this._staticSetStore === undefined && this._plain === undefined && this._sole === undefined && this._watcherOne === undefined && this._watchersStore === undefined)
3259
+ this._sole = id;
3139
3260
  const run = () => effect(() => {
3140
3261
  let next;
3141
3262
  try {
3142
- const v = fn();
3143
- next = this._normalizeToSet(v, key);
3263
+ let v = fn();
3264
+ if (key !== undefined && typeof v === 'function')
3265
+ v = v();
3266
+ next = key !== undefined ? (v ? new Set([key]) : new Set()) : this._normalizeToSet(v);
3144
3267
  }
3145
3268
  catch {
3146
3269
  next = new Set();
@@ -3176,9 +3299,19 @@ class controlClass {
3176
3299
  catch { }
3177
3300
  rec.stop = stop;
3178
3301
  rec.binding = binding;
3179
- this._watchers.set(id, rec);
3302
+ this._keepWatcher(rec);
3180
3303
  }
3181
3304
  }
3305
+ function hasName(list, name) {
3306
+ let i = list.indexOf(name);
3307
+ while (i !== -1) {
3308
+ const end = i + name.length;
3309
+ if ((i === 0 || list.charCodeAt(i - 1) === 32) && (end === list.length || list.charCodeAt(end) === 32))
3310
+ return true;
3311
+ i = list.indexOf(name, i + 1);
3312
+ }
3313
+ return false;
3314
+ }
3182
3315
 
3183
3316
  const shimAnimation = {
3184
3317
  cancel() { },
@@ -3416,7 +3549,7 @@ class ComponentMotif {
3416
3549
  this._component['_register'](c);
3417
3550
  }
3418
3551
  setDisposable(c) {
3419
- this._component['_register'](disposableCore.toDisposable(c));
3552
+ this._component['_register'](trackedCleanup(c));
3420
3553
  }
3421
3554
  stopAnimations() {
3422
3555
  return this._component['_stopAnimations']();
@@ -4239,6 +4372,9 @@ const F_WAIT = 128;
4239
4372
  const F_POSTCONFIG = 256;
4240
4373
  const F_PREBOUND = 512;
4241
4374
  const F_DISPOSED_FIRED = 1024;
4375
+ const F_BUILDING = 2048;
4376
+ const F_LIST_SEEN = 4096;
4377
+ const F_LIST_ADOPTED = 8192;
4242
4378
  function optionsOf(c) {
4243
4379
  return c?._motif?.options;
4244
4380
  }
@@ -4265,12 +4401,12 @@ function enterModeOf(container) {
4265
4401
  const node = c.element;
4266
4402
  if (!node || node.nodeType !== Node.COMMENT_NODE)
4267
4403
  break;
4268
- c = c.parent ?? c._leaveContainer;
4404
+ c = c.parent ?? c._baseCtx?._leaveContainer;
4269
4405
  }
4270
4406
  return transitionSettings.mode;
4271
4407
  }
4272
4408
  function leaveModeOf(c) {
4273
- return enterModeOf(c.parent ?? c._leaveContainer);
4409
+ return enterModeOf(c.parent ?? c._baseCtx?._leaveContainer);
4274
4410
  }
4275
4411
  function wantsEnterTransition(c) {
4276
4412
  const o = c?._motif?.options;
@@ -4440,12 +4576,14 @@ class ComponentOptionsImpl {
4440
4576
  set enableRouterClassing(value) {
4441
4577
  try {
4442
4578
  const ins = this[OPTIONS_OWNER];
4443
- const callback = ins.context.onRouterChanged(() => {
4579
+ const off = contextApplication(ins).onRouterChanged(() => {
4444
4580
  ComponentHelper.routerClassing.call(ins, value);
4445
4581
  });
4446
- ins.motif.register(disposableCore.toDisposable(() => {
4447
- callback();
4448
- }));
4582
+ if (ins.isDisposed) {
4583
+ off();
4584
+ return;
4585
+ }
4586
+ ins.motif.register(trackedCleanup(off));
4449
4587
  ComponentHelper.routerClassing.call(ins, value);
4450
4588
  }
4451
4589
  catch (error) {
@@ -4496,14 +4634,12 @@ function runHooks(base, listName, sender, ev, label) {
4496
4634
  callReported(() => fn(sender, ev), 'MJX122', label);
4497
4635
  }
4498
4636
  }
4499
- function hasLifecycleHook(component, hook, listName, lowerName, legacyProp) {
4637
+ function hasLifecycleHook(component, hook, listName, lowerName) {
4500
4638
  if (component[hook])
4501
4639
  return true;
4502
4640
  const base = component._baseCtx;
4503
4641
  if (base?.[listName])
4504
4642
  return true;
4505
- if (legacyProp && component[legacyProp])
4506
- return true;
4507
4643
  return !!base?._emiters?.hasListeners(lowerName);
4508
4644
  }
4509
4645
  const RESERVED_METHODS = ['build', 'setState', 'reState', 'setText', 'style', 'dispose', 'disposeAsync', 'using', 'doWork', 'getService', '$', 'useModel', 'context', 'siblings', 'serviceProvider', 'isWait'];
@@ -4561,6 +4697,16 @@ function checkReservedMembers(c) {
4561
4697
  reportWarning('MJX128', [name, member, how]);
4562
4698
  }
4563
4699
  }
4700
+ function releaseInitializers(c) {
4701
+ c._init = undefined;
4702
+ const base = c._baseCtx;
4703
+ if (base === undefined)
4704
+ return;
4705
+ if (base._initializeComponentHandlers !== undefined)
4706
+ base._initializeComponentHandlers = undefined;
4707
+ if (base._onInitializeComponentHandlers !== undefined)
4708
+ base._onInitializeComponentHandlers = undefined;
4709
+ }
4564
4710
  const ComponentHelper = {
4565
4711
  callInitializeComponent(component) {
4566
4712
  const sender = component;
@@ -4584,12 +4730,13 @@ const ComponentHelper = {
4584
4730
  }
4585
4731
  // 4) aggregated extra oninitializeComponent handlers (örn, from props)
4586
4732
  runHooks(component._baseCtx, '_onInitializeComponentHandlers', sender, ev, 'oninitializeComponent');
4733
+ releaseInitializers(component);
4587
4734
  },
4588
4735
  callDisposing(component) {
4589
4736
  if (!component || component.isDisposed) {
4590
4737
  return;
4591
4738
  }
4592
- if (!hasLifecycleHook(component, 'onDisposing', '_onDisposingHandlers', 'ondisposing', 'ondisposing')) {
4739
+ if (!hasLifecycleHook(component, 'onDisposing', '_onDisposingHandlers', 'ondisposing')) {
4593
4740
  return;
4594
4741
  }
4595
4742
  const sender = component, ev = { cancel: false };
@@ -4597,9 +4744,6 @@ const ComponentHelper = {
4597
4744
  callReported(() => component.onDisposing(sender, ev), 'MJX122', 'onDisposing');
4598
4745
  }
4599
4746
  runHooks(component._baseCtx, '_onDisposingHandlers', sender, ev, 'onDisposing');
4600
- if (component.ondisposing) {
4601
- callReported(() => component.ondisposing(sender, ev), 'MJX122', 'ondisposing');
4602
- }
4603
4747
  fireLifecycle(component, 'ondisposing', ev);
4604
4748
  },
4605
4749
  callActivated(component) {
@@ -4662,19 +4806,16 @@ const ComponentHelper = {
4662
4806
  return;
4663
4807
  }
4664
4808
  component._flags |= F_DISPOSED_FIRED;
4665
- if (hasLifecycleHook(component, 'onDisposed', '_onDisposedHandlers', 'ondisposed', 'ondisposed')) {
4809
+ if (hasLifecycleHook(component, 'onDisposed', '_onDisposedHandlers', 'ondisposed')) {
4666
4810
  const sender = component, ev = { cancel: false };
4667
4811
  if (component.onDisposed) {
4668
4812
  callReported(() => component.onDisposed(sender, ev), 'MJX122', 'onDisposed');
4669
4813
  }
4670
4814
  runHooks(component._baseCtx, '_onDisposedHandlers', sender, ev, 'onDisposed');
4671
- if (component.ondisposed) {
4672
- callReported(() => component.ondisposed(sender, ev), 'MJX122', 'ondisposed');
4673
- }
4674
4815
  fireLifecycle(component, 'ondisposed', ev);
4675
4816
  }
4676
4817
  try {
4677
- globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:disposed', { id: component.id, type: component.constructor?.name });
4818
+ devtools()?.('component:disposed', { id: component.id, type: component.constructor?.name });
4678
4819
  }
4679
4820
  catch { }
4680
4821
  },
@@ -4682,19 +4823,16 @@ const ComponentHelper = {
4682
4823
  if (!component || component.isDisposed) {
4683
4824
  return;
4684
4825
  }
4685
- if (hasLifecycleHook(component, 'onBuilt', '_onBuiltHandlers', 'onbuilt', 'onbuilt')) {
4826
+ if (hasLifecycleHook(component, 'onBuilt', '_onBuiltHandlers', 'onbuilt')) {
4686
4827
  const sender = component, ev = { cancel: false };
4687
4828
  if (component.onBuilt) {
4688
4829
  callReported(() => component.onBuilt(sender, ev), 'MJX122', 'onBuilt');
4689
4830
  }
4690
4831
  runHooks(component._baseCtx, '_onBuiltHandlers', sender, ev, 'onBuilt');
4691
- if (component.onbuilt) {
4692
- callReported(() => component.onbuilt(sender, ev), 'MJX122', 'onbuilt');
4693
- }
4694
4832
  fireLifecycle(component, 'onbuilt', ev);
4695
4833
  }
4696
4834
  try {
4697
- globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:mounted', { id: component.id, type: component.constructor?.name });
4835
+ devtools()?.('component:mounted', { id: component.id, type: component.constructor?.name });
4698
4836
  }
4699
4837
  catch { }
4700
4838
  },
@@ -4703,8 +4841,7 @@ const ComponentHelper = {
4703
4841
  return;
4704
4842
  }
4705
4843
  const hasHook = typeof component.onMounted === 'function'
4706
- || !!component._baseCtx?._onMountedHandlers
4707
- || typeof component.onmounted === 'function';
4844
+ || !!component._baseCtx?._onMountedHandlers;
4708
4845
  if (!hasHook) {
4709
4846
  return;
4710
4847
  }
@@ -4720,7 +4857,7 @@ const ComponentHelper = {
4720
4857
  ComponentHelper.callMounted(component);
4721
4858
  });
4722
4859
  if (stop) {
4723
- component._register(disposableCore.toDisposable(stop));
4860
+ component._register(trackedCleanup(stop));
4724
4861
  }
4725
4862
  },
4726
4863
  callMounted(component) {
@@ -4733,9 +4870,6 @@ const ComponentHelper = {
4733
4870
  callReported(() => component.onMounted(sender, ev), 'MJX122', 'onMounted');
4734
4871
  }
4735
4872
  runHooks(component._baseCtx, '_onMountedHandlers', sender, ev, 'onMounted');
4736
- if (component.onmounted) {
4737
- callReported(() => component.onmounted(sender, ev), 'MJX122', 'onmounted');
4738
- }
4739
4873
  fireLifecycle(component, 'onmounted', ev);
4740
4874
  },
4741
4875
  callBuilding(component) {
@@ -4983,7 +5117,7 @@ const ComponentHelper = {
4983
5117
  const path = value.path;
4984
5118
  if (this.isDisposed)
4985
5119
  return;
4986
- const router = this.context?.router;
5120
+ const router = contextApplication(this)?.router;
4987
5121
  if (!router)
4988
5122
  return;
4989
5123
  const requestPath = router.uri.startsWith('/') ? router.uri : '/' + router.uri;
@@ -5204,11 +5338,11 @@ function deepCleanup(c) {
5204
5338
  }
5205
5339
  catch { }
5206
5340
  try {
5207
- c._attr?._attrMapStore?.clear();
5341
+ c._baseCtx?._attr?._attrMapStore?.clear();
5208
5342
  }
5209
5343
  catch { }
5210
5344
  try {
5211
- c._attr?._watchersStore?.clear();
5345
+ c._baseCtx?._attr?._watchersStore?.clear();
5212
5346
  }
5213
5347
  catch { }
5214
5348
  try {
@@ -5294,6 +5428,44 @@ function subtreeDisposesSync(c, root) {
5294
5428
  return true;
5295
5429
  }
5296
5430
  const teardownApplications = new WeakMap();
5431
+ let teardownSeen = false;
5432
+ let contextOverridden = false;
5433
+ let lastCheckedCtor;
5434
+ const checkedCtors = new WeakSet();
5435
+ let baseContextGetter;
5436
+ function noteContextOverride(ctor) {
5437
+ if (contextOverridden || ctor === lastCheckedCtor)
5438
+ return;
5439
+ lastCheckedCtor = ctor;
5440
+ if (checkedCtors.has(ctor))
5441
+ return;
5442
+ checkedCtors.add(ctor);
5443
+ baseContextGetter ??= Object.getOwnPropertyDescriptor(ComponentBase.prototype, 'context').get;
5444
+ if (ctor.prototype.__lookupGetter__('context') !== baseContextGetter)
5445
+ contextOverridden = true;
5446
+ }
5447
+ function applicationOf(c) {
5448
+ const parent = c.parent;
5449
+ let app;
5450
+ if (parent) {
5451
+ baseContextGetter ??= Object.getOwnPropertyDescriptor(ComponentBase.prototype, 'context').get;
5452
+ if (parent.__lookupGetter__('context') === baseContextGetter)
5453
+ app = applicationOf(parent);
5454
+ else {
5455
+ const ctx = parent.context;
5456
+ app = ctx?.[RAW_APPLICATION] ?? ctx;
5457
+ }
5458
+ }
5459
+ return app ?? teardownApplications.get(c) ?? Application.main;
5460
+ }
5461
+ function contextApplication(c) {
5462
+ baseContextGetter ??= Object.getOwnPropertyDescriptor(ComponentBase.prototype, 'context').get;
5463
+ if (c.__lookupGetter__('context') !== baseContextGetter) {
5464
+ const ctx = c.context;
5465
+ return ctx?.[RAW_APPLICATION] ?? ctx;
5466
+ }
5467
+ return contextOverridden || teardownSeen ? applicationOf(c) : Application.main;
5468
+ }
5297
5469
  function owningApplication(c) {
5298
5470
  for (let p = c; p; p = p.parent) {
5299
5471
  if (p.application)
@@ -5308,14 +5480,16 @@ function disposePrefix(c, options, asChild) {
5308
5480
  const ctx = asChild ? 'disposeAsync' : 'dispose';
5309
5481
  if (Application._disposingCount > 0) {
5310
5482
  const app = owningApplication(c);
5311
- if (app && app.state === 'disposing')
5483
+ if (app && app.state === 'disposing') {
5312
5484
  teardownApplications.set(c, app);
5485
+ teardownSeen = true;
5486
+ }
5313
5487
  }
5314
5488
  if (!asChild && options?.skipLeaveTransition) {
5315
5489
  c.motif.options.transition.skipNextLeave = true;
5316
5490
  }
5317
5491
  safeCall(() => { ComponentHelper.callDisposing.call(c, c); }, ctx + '.callDisposing');
5318
- offAll(c);
5492
+ offAll(c, asChild && c._keepElementOnDispose !== true && c.element?.isConnected === false);
5319
5493
  deactivateBindings(c);
5320
5494
  safeCall(() => { c.parent?.controls?.silentDetach?.(c, true); }, ctx + '.silentDetach');
5321
5495
  }
@@ -5497,6 +5671,8 @@ class EventRecord {
5497
5671
  }
5498
5672
  handleEvent(ev) {
5499
5673
  const flags = this.flags;
5674
+ if ((flags & EV_REMOVED) !== 0)
5675
+ return;
5500
5676
  const owner = this.owner;
5501
5677
  if ((flags & EV_SELF) !== 0 && ev.target !== owner.element)
5502
5678
  return;
@@ -5572,7 +5748,7 @@ function hasEventKey(c, key) {
5572
5748
  }
5573
5749
  return false;
5574
5750
  }
5575
- function offAll(c) {
5751
+ function offAll(c, detached = false) {
5576
5752
  const head = c._eventHandlers;
5577
5753
  if (head === undefined)
5578
5754
  return;
@@ -5580,6 +5756,12 @@ function offAll(c) {
5580
5756
  if ((r.flags & (EV_DOM | EV_REMOVED)) !== EV_DOM) {
5581
5757
  continue;
5582
5758
  }
5759
+ if (detached) {
5760
+ r.flags |= EV_REMOVED;
5761
+ r.owner = undefined;
5762
+ r.original = undefined;
5763
+ continue;
5764
+ }
5583
5765
  try {
5584
5766
  c.element.removeEventListener(r.type, r, (r.flags & EV_CAPTURE) !== 0);
5585
5767
  }
@@ -5617,6 +5799,18 @@ function activatePreBindings(c) {
5617
5799
  }
5618
5800
  c._flags |= F_PREBOUND;
5619
5801
  }
5802
+ function setLeaveContainer(c, owner) {
5803
+ (c._baseCtx ?? (c._baseCtx = createBaseCtx(c)))._leaveContainer = owner;
5804
+ }
5805
+ function noteListAdopted(c) {
5806
+ const f = c._flags;
5807
+ if ((f & F_LIST_SEEN) !== 0)
5808
+ return;
5809
+ c._flags = f | F_LIST_SEEN | (c.parent !== null && c.parent !== undefined ? F_LIST_ADOPTED : 0);
5810
+ }
5811
+ function isListAdopted(c) {
5812
+ return (c._flags & F_LIST_ADOPTED) !== 0;
5813
+ }
5620
5814
  function createBaseCtx(owner) {
5621
5815
  const base = Object.create(BASE_PROTO);
5622
5816
  base.owner = owner;
@@ -5751,10 +5945,16 @@ class ComponentBase extends Disposable {
5751
5945
  this._class = value;
5752
5946
  }
5753
5947
  get attr() {
5754
- return this._attr !== undefined || (this.isDisposed && !this.element) ? this._attr : (this._attr = new controlAttribute(this));
5948
+ const base = this._baseCtx;
5949
+ const attr = base !== undefined ? base._attr : undefined;
5950
+ return attr !== undefined || (this.isDisposed && !this.element) ? attr : (this._base._attr = new controlAttribute(this));
5755
5951
  }
5756
5952
  set attr(value) {
5757
- this._attr = value;
5953
+ const base = this._baseCtx;
5954
+ if (base !== undefined)
5955
+ base._attr = value;
5956
+ else if (value !== undefined)
5957
+ this._base._attr = value;
5758
5958
  }
5759
5959
  get bindings() {
5760
5960
  return this._bindings !== undefined || (this.isDisposed && !this.element) ? this._bindings : (this._bindings = new BindingCollection(this));
@@ -5793,7 +5993,7 @@ class ComponentBase extends Disposable {
5793
5993
  }
5794
5994
  return;
5795
5995
  }
5796
- if (value === false && this.parent && this.parent.isBuilt) {
5996
+ if (value === false && this.parent && this.parent.isBuilt && (this._flags & F_BUILDING) === 0) {
5797
5997
  ComponentHelper.internalBuild.call(this.parent, this);
5798
5998
  }
5799
5999
  }
@@ -5806,12 +6006,11 @@ class ComponentBase extends Disposable {
5806
6006
  this._flags = 0;
5807
6007
  this._controls = undefined;
5808
6008
  this._class = undefined;
5809
- this._attr = undefined;
5810
6009
  this._bindings = undefined;
5811
6010
  this._baseCtx = undefined;
5812
6011
  this._init = undefined;
5813
- this._leaveContainer = undefined;
5814
6012
  this.parent = null;
6013
+ noteContextOverride(new.target);
5815
6014
  const asComponentRoot = constructingComponentRoot;
5816
6015
  constructingComponentRoot = false;
5817
6016
  recordServiceOwner(this);
@@ -5870,8 +6069,7 @@ class ComponentBase extends Disposable {
5870
6069
  return this._baseCtx !== undefined || (this.isDisposed && !this.element) ? this._baseCtx : (this._baseCtx = createBaseCtx(this));
5871
6070
  }
5872
6071
  get context() {
5873
- const parentCtx = this.parent?.context;
5874
- const app = parentCtx?.[RAW_APPLICATION] ?? parentCtx ?? teardownApplications.get(this) ?? Application.main;
6072
+ const app = (contextOverridden || teardownSeen ? applicationOf(this) : Application.main);
5875
6073
  if (!app) {
5876
6074
  return app;
5877
6075
  }
@@ -5889,7 +6087,7 @@ class ComponentBase extends Disposable {
5889
6087
  off();
5890
6088
  return off;
5891
6089
  }
5892
- const d = this._register(disposableCore.toDisposable(off));
6090
+ const d = this._register(trackedCleanup(off));
5893
6091
  return () => { this._disposables.detach(d); off(); };
5894
6092
  }
5895
6093
  build(building = true) {
@@ -5902,136 +6100,142 @@ class ComponentBase extends Disposable {
5902
6100
  if (this.isBuilt || this.isWait) {
5903
6101
  return;
5904
6102
  }
5905
- ComponentHelper.callBuilding(this);
5906
- if (this.isDisposed) {
5907
- return;
5908
- }
5909
- var ph = this.element;
5910
- if (building) {
5911
- ph = dom.createDocumentFragment();
5912
- }
5913
- const isFragment = (typeof this.element !== 'string' && this.element.nodeType === Node.COMMENT_NODE);
5914
- if (isFragment) {
5915
- this.motif.options.cache = dom.createDocumentFragment();
5916
- this.element.textContent = "[";
5917
- this.motif.options.cache.appendChild(this.element);
5918
- }
5919
- if (this.isBuilt) {
5920
- return;
5921
- }
5922
- ComponentHelper.callInitializeComponent(this);
5923
- if (this.isDisposed) {
5924
- return;
5925
- }
5926
- if (this.view) {
5927
- const templ = this.view();
5928
- this.controls.add(templ);
6103
+ this._flags |= F_BUILDING;
6104
+ try {
6105
+ ComponentHelper.callBuilding(this);
5929
6106
  if (this.isDisposed) {
5930
6107
  return;
5931
6108
  }
5932
- }
5933
- const deferredSelectValue = this.element?.nodeName === 'SELECT'
5934
- ? this.bindings.items.filter(b => b.propertyName === 'value')
5935
- : NO_BINDINGS;
5936
- if (deferredSelectValue.length) {
5937
- try {
5938
- this.bindings.items.filter(b => !deferredSelectValue.includes(b)).forEach(b => b.activate());
6109
+ var ph = this.element;
6110
+ if (building) {
6111
+ ph = dom.createDocumentFragment();
5939
6112
  }
5940
- catch { }
5941
- }
5942
- else {
5943
- activateBindings(this);
5944
- }
5945
- const kids = childrenOf(this);
5946
- for (const element of kids.length ? kids.slice() : kids) {
5947
- var target = isFragment ? this.motif.options.cache : this.element;
5948
- if (!element.isWait) {
5949
- element.parent = this;
5950
- element.build(false);
6113
+ const isFragment = (typeof this.element !== 'string' && this.element.nodeType === Node.COMMENT_NODE);
6114
+ if (isFragment) {
6115
+ this.motif.options.cache = dom.createDocumentFragment();
6116
+ this.element.textContent = "[";
6117
+ this.motif.options.cache.appendChild(this.element);
5951
6118
  }
5952
- if (element.isWait) {
5953
- if (keepsTrace(element)) {
5954
- const opts = element.motif.options;
5955
- (building ? ph : target).appendChild(opts.placeholder ?? (opts.placeholder = dom.createComment("h")));
5956
- }
5957
- continue;
6119
+ if (this.isBuilt) {
6120
+ return;
5958
6121
  }
5959
- if (building) {
5960
- const cache = optionsOf(element)?.cache;
5961
- if (cache) {
5962
- ph.appendChild(cache);
6122
+ ComponentHelper.callInitializeComponent(this);
6123
+ if (this.isDisposed) {
6124
+ return;
6125
+ }
6126
+ if (this.view) {
6127
+ const templ = this.view();
6128
+ this.controls.add(templ);
6129
+ if (this.isDisposed) {
6130
+ return;
5963
6131
  }
5964
- else {
5965
- ph.appendChild(element.element);
6132
+ }
6133
+ const deferredSelectValue = this.element?.nodeName === 'SELECT'
6134
+ ? this.bindings.items.filter(b => b.propertyName === 'value')
6135
+ : NO_BINDINGS;
6136
+ if (deferredSelectValue.length) {
6137
+ try {
6138
+ this.bindings.items.filter(b => !deferredSelectValue.includes(b)).forEach(b => b.activate());
5966
6139
  }
6140
+ catch { }
5967
6141
  }
5968
6142
  else {
5969
- const cache = optionsOf(element)?.cache;
5970
- if (cache) {
5971
- target.appendChild(cache);
6143
+ activateBindings(this);
6144
+ }
6145
+ const kids = childrenOf(this);
6146
+ for (const element of kids.length ? kids.slice() : kids) {
6147
+ var target = isFragment ? this.motif.options.cache : this.element;
6148
+ if (!element.isWait) {
6149
+ element.parent = this;
6150
+ element.build(false);
6151
+ }
6152
+ if (element.isWait) {
6153
+ if (keepsTrace(element)) {
6154
+ const opts = element.motif.options;
6155
+ (building ? ph : target).appendChild(opts.placeholder ?? (opts.placeholder = dom.createComment("h")));
6156
+ }
6157
+ continue;
6158
+ }
6159
+ if (building) {
6160
+ const cache = optionsOf(element)?.cache;
6161
+ if (cache) {
6162
+ ph.appendChild(cache);
6163
+ }
6164
+ else {
6165
+ ph.appendChild(element.element);
6166
+ }
5972
6167
  }
5973
6168
  else {
5974
- target.appendChild(element.element);
6169
+ const cache = optionsOf(element)?.cache;
6170
+ if (cache) {
6171
+ target.appendChild(cache);
6172
+ }
6173
+ else {
6174
+ target.appendChild(element.element);
6175
+ }
6176
+ }
6177
+ if (element._baseCtx?._inactive && element.isVisible) {
6178
+ ComponentHelper.activateTree(element);
5975
6179
  }
5976
6180
  }
5977
- if (element._baseCtx?._inactive && element.isVisible) {
5978
- ComponentHelper.activateTree(element);
6181
+ if (this.isDisposed) {
6182
+ return;
5979
6183
  }
5980
- }
5981
- if (this.isDisposed) {
5982
- return;
5983
- }
5984
- if (wantsEnterTransition(this)) {
5985
- const node = this.element;
5986
- if (node && node.isConnected) {
5987
- this.motif.options.transition.enterTransition(() => { });
6184
+ if (wantsEnterTransition(this)) {
6185
+ const node = this.element;
6186
+ if (node && node.isConnected) {
6187
+ this.motif.options.transition.enterTransition(() => { });
6188
+ }
6189
+ else {
6190
+ const seq = this._base._enterSeq;
6191
+ queueMicrotask(() => {
6192
+ if (!this.isDisposed && this.isVisible && this.motif.options?.transition && this._base._enterSeq === seq) {
6193
+ this.motif.options.transition.enterTransition(() => { });
6194
+ }
6195
+ });
6196
+ }
5988
6197
  }
5989
6198
  else {
5990
- const seq = this._base._enterSeq;
5991
- queueMicrotask(() => {
5992
- if (!this.isDisposed && this.isVisible && this.motif.options?.transition && this._base._enterSeq === seq) {
5993
- this.motif.options.transition.enterTransition(() => { });
5994
- }
5995
- });
6199
+ clearNavDirection(this);
5996
6200
  }
5997
- }
5998
- else {
5999
- clearNavDirection(this);
6000
- }
6001
- if (building) {
6002
- try {
6003
- var target = isFragment ? this.motif.options.cache : this.element;
6004
- if (target.nodeType === Node.TEXT_NODE) {
6005
- target.appendData(ph.textContent);
6006
- }
6007
- else {
6008
- if (target.appendChild) {
6009
- target.appendChild(ph);
6201
+ if (building) {
6202
+ try {
6203
+ var target = isFragment ? this.motif.options.cache : this.element;
6204
+ if (target.nodeType === Node.TEXT_NODE) {
6205
+ target.appendData(ph.textContent);
6010
6206
  }
6011
6207
  else {
6012
- target.append(ph);
6208
+ if (target.appendChild) {
6209
+ target.appendChild(ph);
6210
+ }
6211
+ else {
6212
+ target.append(ph);
6213
+ }
6013
6214
  }
6014
6215
  }
6216
+ catch (error) {
6217
+ }
6015
6218
  }
6016
- catch (error) {
6219
+ if (deferredSelectValue.length) {
6220
+ try {
6221
+ deferredSelectValue.forEach(b => b.activate());
6222
+ }
6223
+ catch { }
6017
6224
  }
6018
- }
6019
- if (deferredSelectValue.length) {
6020
- try {
6021
- deferredSelectValue.forEach(b => b.activate());
6225
+ if (isFragment) {
6226
+ this.motif.options.closeFragment = dom.createComment("]");
6227
+ this.motif.options.cache.appendChild(this.motif.options.closeFragment);
6228
+ if (this.element.nodeType === Node.COMMENT_NODE && this.motif.options.closeFragment) {
6229
+ fragmentCloseMarkers.set(this.element, this.motif.options.closeFragment);
6230
+ }
6022
6231
  }
6023
- catch { }
6232
+ this.isBuilt = true;
6233
+ ComponentHelper.callBuilt(this);
6234
+ ComponentHelper.scheduleMounted(this);
6024
6235
  }
6025
- if (isFragment) {
6026
- this.motif.options.closeFragment = dom.createComment("]");
6027
- this.motif.options.cache.appendChild(this.motif.options.closeFragment);
6028
- if (this.element.nodeType === Node.COMMENT_NODE && this.motif.options.closeFragment) {
6029
- fragmentCloseMarkers.set(this.element, this.motif.options.closeFragment);
6030
- }
6236
+ finally {
6237
+ this._flags &= ~F_BUILDING;
6031
6238
  }
6032
- this.isBuilt = true;
6033
- ComponentHelper.callBuilt(this);
6034
- ComponentHelper.scheduleMounted(this);
6035
6239
  }
6036
6240
  setState() {
6037
6241
  this.controls.forEach(c => {
@@ -6334,7 +6538,7 @@ class ComponentBase extends Disposable {
6334
6538
  callReported(() => cb.length <= 1 ? cb(ev) : cb(this, ev), 'MJX122', 'x:mounted');
6335
6539
  });
6336
6540
  if (stop) {
6337
- sub = this._register(disposableCore.toDisposable(stop));
6541
+ sub = this._register(trackedCleanup(stop));
6338
6542
  const subs = this._base._mountedSubs ??= new Map();
6339
6543
  let set = subs.get(cb);
6340
6544
  if (!set) {
@@ -6819,17 +7023,6 @@ function ParseProps(props, component) {
6819
7023
  applyTransitionProp(props[key], component);
6820
7024
  delete props[key];
6821
7025
  }
6822
- else if (componentMethods.hasOwnProperty(key.toLowerCase()) || componentMethods.hasOwnProperty("on" + key.toLowerCase())) {
6823
- var eventKey;
6824
- if (!key.toLowerCase().startsWith("on") && key.toLowerCase() !== "initializecomponent") {
6825
- eventKey = "on" + key;
6826
- }
6827
- else {
6828
- eventKey = key;
6829
- }
6830
- component[eventKey] = props[key];
6831
- delete props[key];
6832
- }
6833
7026
  else if (key.startsWith("on")) {
6834
7027
  component.motif.on(key, props[key]);
6835
7028
  }
@@ -7065,22 +7258,6 @@ function applyFallthroughProps(props, component) {
7065
7258
  if (subset)
7066
7259
  applyPlainElementProps(subset, component);
7067
7260
  }
7068
- const componentMethods = {
7069
- "oninitializecomponent": (sender, e) => { },
7070
- "initializecomponent": (sender, e) => { },
7071
- "onconfigured": (sender, e) => { },
7072
- "onconfig": (sender, e) => { },
7073
- "onbuilding": (sender, e) => { },
7074
- "onbuilt": (sender, e) => { },
7075
- "onmounted": (sender, e) => { },
7076
- "oninitializing": (sender, e) => { },
7077
- "oninitialized": (sender, e) => { },
7078
- "ondisposing": (sender, e) => { },
7079
- "ondisposed": (sender, e) => { },
7080
- "onvisibilitychanged": (sender, e) => { },
7081
- "ondeactivated": (sender, e) => { },
7082
- "onactivated": (sender, e) => { },
7083
- };
7084
7261
  function findAppendableComponent(component) {
7085
7262
  return safeCall(() => {
7086
7263
  if (!component || component.isDisposed)
@@ -7689,7 +7866,7 @@ class ControlCollection {
7689
7866
  this.items.splice(index, 0, control);
7690
7867
  }
7691
7868
  else {
7692
- this.items.push(control);
7869
+ pushTight(this.items, control);
7693
7870
  }
7694
7871
  control.parent = this.owner;
7695
7872
  const pendingLeave = control.__pendingLeave;
@@ -7716,7 +7893,7 @@ class ControlCollection {
7716
7893
  remove(control) {
7717
7894
  var index = this.items.indexOf(control);
7718
7895
  if (index > -1) {
7719
- this.items.splice(index, 1);
7896
+ takeAt(this.items, index);
7720
7897
  try {
7721
7898
  control.dispose();
7722
7899
  }
@@ -7727,10 +7904,10 @@ class ControlCollection {
7727
7904
  const index = this.items.indexOf(control);
7728
7905
  if (index === -1)
7729
7906
  return Promise.resolve();
7730
- this.items.splice(index, 1);
7907
+ takeAt(this.items, index);
7731
7908
  if (control.isDisposed)
7732
7909
  return Promise.resolve();
7733
- control._leaveContainer = this.owner;
7910
+ setLeaveContainer(control, this.owner);
7734
7911
  control.parent = null;
7735
7912
  return runLeaveThenDetach(control, () => { if (this.onRemove)
7736
7913
  this.onRemove(control); });
@@ -7743,7 +7920,7 @@ class ControlCollection {
7743
7920
  const index = this.items.indexOf(control);
7744
7921
  if (index === -1)
7745
7922
  return;
7746
- this.items.splice(index, 1);
7923
+ takeAt(this.items, index);
7747
7924
  if (control.isDisposed)
7748
7925
  return;
7749
7926
  control.parent = null;
@@ -7759,8 +7936,8 @@ class ControlCollection {
7759
7936
  const index = this.items.indexOf(control);
7760
7937
  if (index === -1)
7761
7938
  return;
7762
- this.items.splice(index, 1);
7763
- control._leaveContainer = this.owner;
7939
+ takeAt(this.items, index);
7940
+ setLeaveContainer(control, this.owner);
7764
7941
  control.parent = null;
7765
7942
  }
7766
7943
  async clearAsync() {
@@ -7852,6 +8029,12 @@ class ControlCollection {
7852
8029
  }
7853
8030
  }
7854
8031
  /** Owner için DOM'a eklenebilir gerçek element'i bulur. */
8032
+ function takeAt(items, index) {
8033
+ if (index === 0)
8034
+ items.shift();
8035
+ else
8036
+ items.splice(index, 1);
8037
+ }
7855
8038
  function findAppendableElement(owner) {
7856
8039
  let c = owner;
7857
8040
  while (c) {
@@ -8095,7 +8278,7 @@ function Lazy(props) {
8095
8278
  catch { }
8096
8279
  };
8097
8280
  try {
8098
- frame.motif.register(disposableCore.toDisposable(() => clearAllTimers()));
8281
+ frame.motif.register(trackedCleanup(() => clearAllTimers()));
8099
8282
  }
8100
8283
  catch { }
8101
8284
  const initial = opts.Placeholderview ?? opts.Loaderview;
@@ -8147,7 +8330,7 @@ function Lazy(props) {
8147
8330
  const retry = normalizeRetry(opts.retry);
8148
8331
  const cleanups = new Set();
8149
8332
  try {
8150
- frame.motif.register(disposableCore.toDisposable(() => { cleanups.forEach(c => { try {
8333
+ frame.motif.register(trackedCleanup(() => { cleanups.forEach(c => { try {
8151
8334
  c();
8152
8335
  }
8153
8336
  catch { } }); cleanups.clear(); }));
@@ -9302,62 +9485,6 @@ function lintRoutes(routes) {
9302
9485
  visit(r, '', 0);
9303
9486
  }
9304
9487
 
9305
- let overlayHost = null;
9306
- let visible = false;
9307
- function render() {
9308
- return;
9309
- // if (!overlayHost) return;
9310
- // const warnings = getWarnings();
9311
- // const bar = document.createElement('div');
9312
- // bar.style.cssText = 'display:flex; align-items:center; gap:8px; padding:6px 8px; background:#111; color:#fff; border-bottom:1px solid #333;';
9313
- // const title = document.createElement('div');
9314
- // title.style.fontWeight = '600';
9315
- // const closeBtn = document.createElement('button');
9316
- // closeBtn.style.cssText = 'margin-left:auto; background:#333; color:#fff; border:0; padding:2px 6px; cursor:pointer;';
9317
- // const list = document.createElement('div');
9318
- // list.style.cssText = 'max-height:40vh; overflow:auto; padding:8px; background:#181818; color:#ddd; font:12px/1.4 monospace;';
9319
- // for (const w of warnings) {
9320
- // const item = document.createElement('div');
9321
- // item.style.cssText = 'padding:6px 8px; border:1px solid #333; border-radius:4px; margin-bottom:6px; background:#1f1f1f;';
9322
- // const code = document.createElement('div');
9323
- // code.style.cssText = 'color:#ffb86c; font-weight:700;';
9324
- // const msg = document.createElement('div');
9325
- // const det = document.createElement('pre');
9326
- // det.textContent = w.details ? JSON.stringify(w.details, null, 2) : '';
9327
- // det.style.cssText = 'white-space:pre-wrap; color:#aaa; margin:6px 0 0 0;';
9328
- // if (w.details) item.appendChild(det);
9329
- }
9330
- function toggle(force) {
9331
- if (!overlayHost)
9332
- return;
9333
- visible = !visible;
9334
- overlayHost.style.display = visible ? 'block' : 'none';
9335
- }
9336
- function initOverlayIfEnabled() {
9337
- ensureDevtoolsFlagInitialized();
9338
- if (!isRequestedByFlag())
9339
- return;
9340
- try {
9341
- if (!overlayHost) {
9342
- overlayHost = document.createElement('div');
9343
- overlayHost.style.cssText = 'position:fixed; left:12px; bottom:12px; right:12px; z-index:2147483647; background:#111; color:#fff; border:1px solid #333; border-radius:8px; box-shadow:0 4px 14px rgba(0,0,0,0.4); display:none;';
9344
- document.body.appendChild(overlayHost);
9345
- window.addEventListener('keydown', (e) => {
9346
- try {
9347
- if ((e.ctrlKey || e.metaKey) && e.key === '`') {
9348
- e.preventDefault();
9349
- toggle();
9350
- }
9351
- }
9352
- catch { }
9353
- });
9354
- on((ev) => { if (ev.type === 'warning' && visible)
9355
- render(); });
9356
- }
9357
- }
9358
- catch { }
9359
- }
9360
-
9361
9488
  class RouterViewRegistry {
9362
9489
  static { this.outlets = new Map(); }
9363
9490
  static register(name, scopeId, instance) {
@@ -11533,6 +11660,12 @@ class UrlRoutingModule {
11533
11660
  const w = window;
11534
11661
  return this._routerOptions.mode || (w?.location?.protocol === 'file:' ? 'hash' : 'history');
11535
11662
  }
11663
+ addressOf(uri) {
11664
+ const mode = this._addressMode();
11665
+ if (mode === 'hash' || mode === 'file')
11666
+ return uri.startsWith('#') ? uri : '#' + uri;
11667
+ return uri;
11668
+ }
11536
11669
  _readHistoryStamp() {
11537
11670
  try {
11538
11671
  const state = window?.history?.state;
@@ -11667,7 +11800,7 @@ class UrlRoutingModule {
11667
11800
  this._pendingTraversal = null;
11668
11801
  return await safeCallSilentAsync(async () => {
11669
11802
  try {
11670
- globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('route:navigation-start', { uri });
11803
+ devtools()?.('route:navigation-start', { uri });
11671
11804
  }
11672
11805
  catch { }
11673
11806
  const suppressBeforeEachThisCall = this._suppressBeforeEachOnce;
@@ -11851,7 +11984,7 @@ class UrlRoutingModule {
11851
11984
  state: entryState
11852
11985
  });
11853
11986
  try {
11854
- globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('route:navigation-end', { uri: appliedPath, params: target.params });
11987
+ devtools()?.('route:navigation-end', { uri: appliedPath, params: target.params });
11855
11988
  }
11856
11989
  catch { }
11857
11990
  return target;
@@ -12481,6 +12614,7 @@ class Application {
12481
12614
  get state() {
12482
12615
  return this._state;
12483
12616
  }
12617
+ _addressOf(uri) { return this.urlRoutingModule?.addressOf(uri) ?? uri; }
12484
12618
  static CreateBuilder() {
12485
12619
  return new ApplicationBuilder();
12486
12620
  }
@@ -12660,10 +12794,8 @@ class Application {
12660
12794
  this.urlRoutingModule = new UrlRoutingModule(this._routerConfig, this);
12661
12795
  this._routerState.reset();
12662
12796
  safeCallSilent(() => {
12663
- ensureDevtoolsFlagInitialized();
12664
- initOverlayIfEnabled();
12665
12797
  setRoutes(routes);
12666
- if (this._isDevelopment || globalThis.__MOTIF_DEV__ === true || isEnabled()) {
12798
+ if (this._isDevelopment || globalThis.__MOTIF_DEV__ === true) {
12667
12799
  lintRoutes(routes);
12668
12800
  }
12669
12801
  }, 'Application.useRouter.devtools');
@@ -12890,4 +13022,4 @@ exports.untracked = untracked;
12890
13022
  exports.useApplication = useApplication;
12891
13023
  exports.useModel = useModel;
12892
13024
  exports.useNavigation = useNavigation;
12893
- //# sourceMappingURL=core-ZMoM1273.cjs.map
13025
+ //# sourceMappingURL=core-ZhqTS1zK.cjs.map