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