@motifx/core 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -188,7 +188,7 @@
188
188
  function isDevLike() {
189
189
  return state.enabled || globalThis.__MOTIF_DEV__ === true;
190
190
  }
191
- function detectEnabled() {
191
+ function isRequestedByFlag() {
192
192
  try {
193
193
  if (typeof window === 'undefined')
194
194
  return false;
@@ -199,25 +199,31 @@
199
199
  return true;
200
200
  if (globalThis.__MOTIF_DEVTOOLS_FLAG === true)
201
201
  return true;
202
- const qs = (w.location && w.location.search) || '';
203
- if (qs && /(?:[?&])devtools=1(?:&|$)/i.test(qs))
204
- return true;
205
202
  return false;
206
203
  }
207
204
  catch {
208
205
  return false;
209
206
  }
210
207
  }
208
+ function exposeBus(visible) {
209
+ try {
210
+ if (visible)
211
+ window.__motifDevBus = { on, emit, warn, getWarnings, isEnabled, setRoutes, getRoutes };
212
+ else
213
+ delete window.__motifDevBus;
214
+ }
215
+ catch { }
216
+ }
211
217
  function ensureDevtoolsFlagInitialized() {
212
218
  if (state.enabled)
213
219
  return;
214
- state.enabled = detectEnabled();
215
- if (state.enabled) {
216
- try {
217
- window.__motifDevBus = { on, emit, warn, getWarnings, isEnabled, setRoutes, getRoutes };
218
- }
219
- catch { }
220
- }
220
+ state.enabled = isRequestedByFlag();
221
+ if (state.enabled)
222
+ exposeBus(true);
223
+ }
224
+ function setDevtoolsEnabled(enabled) {
225
+ state.enabled = enabled || isRequestedByFlag();
226
+ exposeBus(state.enabled);
221
227
  }
222
228
  function isEnabled() { return state.enabled; }
223
229
  function on(listener) {
@@ -280,6 +286,9 @@
280
286
  MJX121: (compiled, runtime) => `This code was compiled for compiler contract ${compiled}, but the @motifx/core runtime implements contract ${runtime}. Install matching versions of @motifx/compiler and @motifx/core, and rebuild packages that ship compiled JSX.`,
281
287
  MJX122: (hook) => `The component ${hook} hook threw.`,
282
288
  MJX123: (event) => `The '${event}' event handler threw.`,
289
+ MJX124: () => `A spread object on a DOM tag cannot set innerHTML; the key was ignored. Use x-html for trusted HTML.`,
290
+ MJX125: (key) => `A spread object on a DOM tag cannot set a javascript: URL on '${key}'; the value was ignored. Write the attribute on the tag if it is intended.`,
291
+ MJX126: () => `Lazy: loading the component failed and no Fallbackview is set; the host was cleared.`,
283
292
  MJX201: () => `ListBinding: renderFn must return a component instance, a component class, or a factory function.`,
284
293
  MJX202: (key, index) => `ListBinding: duplicate key "${String(key)}" at index ${index}. Rows are matched by the item object, not by key, so rendering is not affected; keep keys unique so they identify items.`,
285
294
  MJX203: (max) => `An effect ran ${max} times in one flush and keeps triggering itself; it is skipped for the rest of this flush. It probably writes a value it reads (for example state.n++). Wrap the write in untracked(...).`,
@@ -490,20 +499,27 @@
490
499
  }
491
500
  }
492
501
 
502
+ const Flags = {
503
+ IS_REACTIVE: Symbol.for('motif.isReactive'),
504
+ IS_READONLY: Symbol.for('motif.isReadonly'),
505
+ IS_SUPERFICIAL: Symbol.for('motif.isSuperficial'),
506
+ RAW: Symbol.for('motif.raw'),
507
+ GET_SETUP: Symbol.for('motif.getSetup'),
508
+ };
493
509
  const ITERATE_KEY = Symbol('');
494
510
  let followTracking = true;
495
511
  let arrayScope = { enabled: false, key: '' };
496
512
  function getRaw(value) {
497
513
  let current = value;
498
- while (current && current["[__raw__]" /* Flags.RAW */]) {
499
- current = current["[__raw__]" /* Flags.RAW */];
514
+ while (current && current[Flags.RAW]) {
515
+ current = current[Flags.RAW];
500
516
  }
501
517
  return current;
502
518
  }
503
519
  function isReadonly(candidate) {
504
520
  if (candidate == null)
505
521
  return false;
506
- return Boolean(candidate["[__isReadonly__]" /* Flags.IS_READONLY */]);
522
+ return Boolean(candidate[Flags.IS_READONLY]);
507
523
  }
508
524
  function hasOwn(target, key) {
509
525
  return Object.prototype.hasOwnProperty.call(target, key);
@@ -691,13 +707,28 @@
691
707
  }
692
708
  _setupBinding() {
693
709
  const update = () => {
694
- const items = this._toArray(this.itemsFn());
710
+ const source = this._toArray(this.itemsFn());
711
+ const rawSource = getRaw(source);
712
+ const count = source.length;
713
+ let items;
714
+ if (rawSource === source) {
715
+ items = source;
716
+ }
717
+ else {
718
+ items = new Array(count);
719
+ for (let i = 0; i < count; i++) {
720
+ if (i in rawSource)
721
+ items[i] = source[i];
722
+ else
723
+ void source[i];
724
+ }
725
+ }
695
726
  const prevItems = this.olditems;
696
727
  const prevComponents = this._rendered;
697
728
  if (this.olditems.length > 0) {
698
729
  const currentRaws = new Set();
699
- for (const it of items)
700
- currentRaws.add(getRaw(it));
730
+ for (let i = 0; i < count; i++)
731
+ currentRaws.add(getRaw(items[i]));
701
732
  for (const old of this.olditems) {
702
733
  const raw = getRaw(old);
703
734
  if (!currentRaws.has(raw)) {
@@ -814,8 +845,8 @@
814
845
  });
815
846
  this._syncContainer(newComponents);
816
847
  this._rendered = newComponents;
817
- this.olditems = items.slice();
818
- return items.length;
848
+ this.olditems = items === source ? source.slice() : items;
849
+ return count;
819
850
  };
820
851
  this._effectCleanup = effect(() => update());
821
852
  }
@@ -831,6 +862,34 @@
831
862
  }
832
863
  return;
833
864
  }
865
+ if (newComponents.length >= items.length) {
866
+ let appendOnly = true;
867
+ for (let i = 0; i < items.length; i++) {
868
+ if (newComponents[i] !== items[i]) {
869
+ appendOnly = false;
870
+ break;
871
+ }
872
+ }
873
+ if (appendOnly && newComponents.length > items.length) {
874
+ const existing = new Set(items);
875
+ for (let i = items.length; i < newComponents.length; i++) {
876
+ if (existing.has(newComponents[i])) {
877
+ appendOnly = false;
878
+ break;
879
+ }
880
+ existing.add(newComponents[i]);
881
+ }
882
+ }
883
+ if (appendOnly) {
884
+ for (let i = items.length; i < newComponents.length; i++) {
885
+ try {
886
+ controls.add(newComponents[i]);
887
+ }
888
+ catch { }
889
+ }
890
+ return;
891
+ }
892
+ }
834
893
  const oldIndex = new Map();
835
894
  items.forEach((c, i) => oldIndex.set(c, i));
836
895
  const sources = newComponents.map(c => {
@@ -947,10 +1006,11 @@
947
1006
  }
948
1007
  ;
949
1008
  remove(item) {
1009
+ const index = this.__list.indexOf(item);
1010
+ if (index === -1)
1011
+ return [];
950
1012
  this._map.delete(item);
951
- this.__list.splice(this.__list.indexOf(item), 1);
952
- item = null;
953
- return [];
1013
+ return this.__list.splice(index, 1);
954
1014
  }
955
1015
  ;
956
1016
  indexOf(item) {
@@ -977,7 +1037,7 @@
977
1037
  this.__list?.forEach(callbackfn);
978
1038
  }
979
1039
  ReverseClone() {
980
- return this.__list.reverse();
1040
+ return this.__list.slice().reverse();
981
1041
  }
982
1042
  filter(callbackfn) {
983
1043
  return this.__list.filter(callbackfn);
@@ -1092,8 +1152,7 @@
1092
1152
  }
1093
1153
  OnItemAdded;
1094
1154
  removeIndex(index) {
1095
- var i = this.__values.removeIndex(index - 1);
1096
- return i;
1155
+ return this.__values.removeIndex(index);
1097
1156
  }
1098
1157
  ;
1099
1158
  remove(Key) {
@@ -1763,27 +1822,64 @@
1763
1822
  }
1764
1823
  }
1765
1824
 
1825
+ const RAW_KEY = Flags.RAW;
1826
+ function isPrototypeObject(o) {
1827
+ return Object.prototype.hasOwnProperty.call(o, 'constructor') && typeof o.constructor === 'function' && o.constructor.prototype === o;
1828
+ }
1829
+ function overridesBelow(instance, proto, name) {
1830
+ let p = Object.getPrototypeOf(instance);
1831
+ while (p && p !== proto) {
1832
+ if (Object.prototype.hasOwnProperty.call(p, name))
1833
+ return true;
1834
+ p = Object.getPrototypeOf(p);
1835
+ }
1836
+ return false;
1837
+ }
1838
+ function lazyBindMethods(proto, names) {
1839
+ for (const name of names) {
1840
+ let fn = proto[name];
1841
+ if (typeof fn !== 'function')
1842
+ continue;
1843
+ Object.defineProperty(proto, name, {
1844
+ configurable: true,
1845
+ enumerable: false,
1846
+ get() {
1847
+ if (this === proto || isPrototypeObject(this))
1848
+ return fn;
1849
+ const target = this[RAW_KEY] ?? this;
1850
+ const bound = fn.bind(target);
1851
+ if (!overridesBelow(target, proto, name)) {
1852
+ try {
1853
+ Object.defineProperty(target, name, { value: bound, writable: true, configurable: true, enumerable: true });
1854
+ }
1855
+ catch { }
1856
+ }
1857
+ return bound;
1858
+ },
1859
+ set(value) {
1860
+ if (this === proto && typeof value === 'function') {
1861
+ fn = value;
1862
+ return;
1863
+ }
1864
+ Object.defineProperty(this, name, { value, writable: true, configurable: true, enumerable: true });
1865
+ },
1866
+ });
1867
+ }
1868
+ }
1869
+
1870
+ function isWritablePathKey(target, key) {
1871
+ if (key === '__proto__')
1872
+ return false;
1873
+ if (key === 'constructor' || key === 'prototype')
1874
+ return Object.prototype.hasOwnProperty.call(target, key);
1875
+ return true;
1876
+ }
1766
1877
  class BindingCollection {
1767
1878
  _items = [];
1768
1879
  _component;
1769
1880
  _branchScope = null;
1770
1881
  constructor(component) {
1771
1882
  this._component = component;
1772
- this.add = this.add.bind(this);
1773
- this.remove = this.remove.bind(this);
1774
- this.clear = this.clear.bind(this);
1775
- this.activateAll = this.activateAll.bind(this);
1776
- this.deactivateAll = this.deactivateAll.bind(this);
1777
- this.reActivateAll = this.reActivateAll.bind(this);
1778
- this.when = this.when.bind(this);
1779
- this.text = this.text.bind(this);
1780
- this.value = this.value.bind(this);
1781
- this.list = this.list.bind(this);
1782
- this.loop = this.loop.bind(this);
1783
- this.method = this.method.bind(this);
1784
- this.watch = this.watch.bind(this);
1785
- this.display = this.display.bind(this);
1786
- this.wait = this.wait.bind(this);
1787
1883
  }
1788
1884
  _own(stop) {
1789
1885
  if (this._branchScope) {
@@ -1980,12 +2076,12 @@
1980
2076
  stopInner();
1981
2077
  });
1982
2078
  }
1983
- ternaryCall = (condFn, onTrue, onFalse) => {
2079
+ ternaryCall(condFn, onTrue, onFalse) {
1984
2080
  this._ternarySchedule(condFn, onTrue, onFalse, (run) => queueMicrotask(run));
1985
- };
1986
- _ternaryCallTop = (condFn, onTrue, onFalse) => {
2081
+ }
2082
+ _ternaryCallTop(condFn, onTrue, onFalse) {
1987
2083
  this._ternarySchedule(condFn, onTrue, onFalse, (run) => setTimeout(run, 0));
1988
- };
2084
+ }
1989
2085
  watch(cb) {
1990
2086
  const ef = effect(() => {
1991
2087
  cb();
@@ -2072,11 +2168,17 @@
2072
2168
  if (member && source != null) {
2073
2169
  const path = member.split('.');
2074
2170
  let target = source;
2075
- for (let i = 0; i < path.length - 1 && target != null; i++) {
2076
- target = target[path[i]];
2171
+ for (let i = 0; i < path.length && target != null; i++) {
2172
+ const key = path[i];
2173
+ if (!isWritablePathKey(target, key))
2174
+ return;
2175
+ if (i === path.length - 1) {
2176
+ target[key] = value;
2177
+ }
2178
+ else {
2179
+ target = target[key];
2180
+ }
2077
2181
  }
2078
- if (target != null)
2079
- target[path[path.length - 1]] = value;
2080
2182
  }
2081
2183
  else if (source != null && typeof source === 'object' && 'value' in source) {
2082
2184
  source.value = value;
@@ -2145,6 +2247,11 @@
2145
2247
  return null;
2146
2248
  }
2147
2249
  }
2250
+ lazyBindMethods(BindingCollection.prototype, [
2251
+ 'add', 'remove', 'clear', 'activateAll', 'deactivateAll', 'reActivateAll',
2252
+ 'when', 'text', 'value', 'list', 'loop', 'method', 'watch', 'display', 'wait',
2253
+ 'ternaryCall', '_ternaryCallTop'
2254
+ ]);
2148
2255
 
2149
2256
  class Emitter {
2150
2257
  _subscriptions = [];
@@ -2235,18 +2342,14 @@
2235
2342
 
2236
2343
  class ComponentEmiter {
2237
2344
  component;
2238
- _emitters = new Map();
2239
- _sourceDisposables = new Map();
2240
- _listenerDisposables = new Map();
2345
+ _emitters;
2346
+ _sourceDisposables;
2347
+ _listenerDisposables;
2241
2348
  constructor(component) {
2242
2349
  this.component = component;
2243
- this.fire = this.fire.bind(this);
2244
- this.on = this.on.bind(this);
2245
- this.off = this.off.bind(this);
2246
- this.createEvent = this.createEvent.bind(this);
2247
- this.getOrCreateEmitter = this.getOrCreateEmitter.bind(this);
2248
- this.addSource = this.addSource.bind(this);
2249
- this.clear = this.clear.bind(this);
2350
+ }
2351
+ hasListeners(eventName) {
2352
+ return this._emitters !== undefined && this._emitters.has(eventName);
2250
2353
  }
2251
2354
  fire(eventName, args) {
2252
2355
  try {
@@ -2266,7 +2369,7 @@
2266
2369
  }
2267
2370
  off(event, cb) {
2268
2371
  const lower = String(event).toLowerCase();
2269
- const map = this._listenerDisposables.get(lower);
2372
+ const map = this._listenerDisposables?.get(lower);
2270
2373
  if (!map)
2271
2374
  return this;
2272
2375
  const list = map.get(cb);
@@ -2278,10 +2381,11 @@
2278
2381
  return this;
2279
2382
  }
2280
2383
  getOrCreateEmitter(name) {
2281
- let e = this._emitters.get(name);
2384
+ const emitters = this._emitters ??= new Map();
2385
+ let e = emitters.get(name);
2282
2386
  if (!e) {
2283
- this._emitters.set(name, new Emitter());
2284
- e = this._emitters.get(name);
2387
+ e = new Emitter();
2388
+ emitters.set(name, e);
2285
2389
  }
2286
2390
  return e;
2287
2391
  }
@@ -2299,10 +2403,11 @@
2299
2403
  };
2300
2404
  const emitter = this.getOrCreateEmitter(lowerFull);
2301
2405
  const disp = emitter.event((e) => invoke(e));
2302
- let map = this._listenerDisposables.get(lowerFull);
2406
+ const listeners = this._listenerDisposables ??= new Map();
2407
+ let map = listeners.get(lowerFull);
2303
2408
  if (!map) {
2304
2409
  map = new Map();
2305
- this._listenerDisposables.set(lowerFull, map);
2410
+ listeners.set(lowerFull, map);
2306
2411
  }
2307
2412
  const list = map.get(cb);
2308
2413
  if (list) {
@@ -2328,10 +2433,11 @@
2328
2433
  }
2329
2434
  catch { }
2330
2435
  if (disp) {
2331
- let set = this._sourceDisposables.get(lower);
2436
+ const sources = this._sourceDisposables ??= new Map();
2437
+ let set = sources.get(lower);
2332
2438
  if (!set) {
2333
2439
  set = new Set();
2334
- this._sourceDisposables.set(lower, set);
2440
+ sources.set(lower, set);
2335
2441
  }
2336
2442
  set.add(disp);
2337
2443
  this.component.motif.register(disposableCore.toDisposable(() => {
@@ -2350,21 +2456,21 @@
2350
2456
  clear(event) {
2351
2457
  if (event) {
2352
2458
  const lower = event.toLowerCase();
2353
- const srcs = this._sourceDisposables.get(lower);
2459
+ const srcs = this._sourceDisposables?.get(lower);
2354
2460
  srcs?.forEach(d => { try {
2355
2461
  d.dispose();
2356
2462
  }
2357
2463
  catch { } });
2358
- this._sourceDisposables.delete(lower);
2359
- const agg = this._emitters.get(lower);
2464
+ this._sourceDisposables?.delete(lower);
2465
+ const agg = this._emitters?.get(lower);
2360
2466
  try {
2361
2467
  agg?.dispose();
2362
2468
  }
2363
2469
  catch { }
2364
- this._emitters.delete(lower);
2365
- this._listenerDisposables.delete(lower);
2470
+ this._emitters?.delete(lower);
2471
+ this._listenerDisposables?.delete(lower);
2366
2472
  }
2367
- else {
2473
+ else if (this._emitters) {
2368
2474
  for (const key of Array.from(this._emitters.keys())) {
2369
2475
  this.clear(key);
2370
2476
  }
@@ -2372,6 +2478,7 @@
2372
2478
  return this;
2373
2479
  }
2374
2480
  }
2481
+ lazyBindMethods(ComponentEmiter.prototype, ['fire', 'on', 'off', 'createEvent', 'getOrCreateEmitter', 'addSource', 'clear']);
2375
2482
 
2376
2483
  const METHOD_ATTRS = new Set([
2377
2484
  'focus', 'blur', 'click', 'pause', 'submit', 'reset',
@@ -2389,11 +2496,13 @@
2389
2496
  const PROPERTY_FIRST = new Set(['checked', 'selected', 'muted', 'indeterminate', 'srcObject']);
2390
2497
  class controlAttribute {
2391
2498
  _parent;
2392
- _attrMap = new Map();
2393
- _watchers = new Map();
2499
+ _attrMapStore;
2500
+ _watchersStore;
2394
2501
  constructor(parent) {
2395
2502
  this._parent = parent;
2396
2503
  }
2504
+ get _attrMap() { return this._attrMapStore ??= new Map(); }
2505
+ get _watchers() { return this._watchersStore ??= new Map(); }
2397
2506
  /** @deprecated Tek kaynak `_attrMap`; geriye dönük okuma için türetilmiş görünüm. */
2398
2507
  get attributes() {
2399
2508
  return Array.from(this._attrMap.entries(), ([name, value]) => ({ name: String(name), value }));
@@ -2924,10 +3033,13 @@
2924
3033
  constructor(parent) {
2925
3034
  this._parent = parent;
2926
3035
  }
2927
- _counts = new Map();
2928
- _staticSet = new Set();
2929
- _watchers = new Map();
3036
+ _countsStore;
3037
+ _staticSetStore;
3038
+ _watchersStore;
2930
3039
  _watcherSeq = 0;
3040
+ get _counts() { return this._countsStore ??= new Map(); }
3041
+ get _staticSet() { return this._staticSetStore ??= new Set(); }
3042
+ get _watchers() { return this._watchersStore ??= new Map(); }
2931
3043
  add(...values) {
2932
3044
  for (const value of values) {
2933
3045
  if (typeof value === 'function') {
@@ -4214,6 +4326,92 @@
4214
4326
  }
4215
4327
  }
4216
4328
 
4329
+ const contentBlocks = { live: 0 };
4330
+
4331
+ const OPTIONS_OWNER = Symbol('motif.optionsOwner');
4332
+ const TRANSITION_SLOT = Symbol('motif.transition');
4333
+
4334
+ const transitionSettings = { mode: 'concurrent' };
4335
+ const noop = () => { };
4336
+ function createTracker() {
4337
+ const running = new WeakMap();
4338
+ function track(node, resolve, via) {
4339
+ const host = node?.parentNode ?? via?.parentNode;
4340
+ if (!host)
4341
+ return { done: resolve, release: noop };
4342
+ let set = running.get(host);
4343
+ if (!set)
4344
+ running.set(host, (set = new Set()));
4345
+ let finish = noop;
4346
+ const entry = { node: node, via: via ?? null, done: new Promise(r => { finish = r; }) };
4347
+ set.add(entry);
4348
+ let settled = false;
4349
+ const release = () => {
4350
+ if (settled)
4351
+ return;
4352
+ settled = true;
4353
+ set.delete(entry);
4354
+ finish();
4355
+ };
4356
+ return {
4357
+ done: () => {
4358
+ const first = !settled;
4359
+ release();
4360
+ if (first && resolve)
4361
+ resolve();
4362
+ },
4363
+ release,
4364
+ finished: entry.done,
4365
+ };
4366
+ }
4367
+ function pending(host, except) {
4368
+ if (!host)
4369
+ return null;
4370
+ const set = running.get(host);
4371
+ if (!set || set.size === 0)
4372
+ return null;
4373
+ let waits = null;
4374
+ for (const entry of set) {
4375
+ if (entry.node === except)
4376
+ continue;
4377
+ if (entry.node.parentNode !== host && entry.via?.parentNode !== host) {
4378
+ set.delete(entry);
4379
+ continue;
4380
+ }
4381
+ (waits ??= []).push(entry.done);
4382
+ }
4383
+ return waits ? Promise.all(waits).then(noop) : null;
4384
+ }
4385
+ return { track, pending };
4386
+ }
4387
+ const leaves = createTracker();
4388
+ const enters = createTracker();
4389
+ const trackLeave = leaves.track;
4390
+ const pendingLeaves = leaves.pending;
4391
+ const trackEnter = enters.track;
4392
+ const pendingEnters = enters.pending;
4393
+ function deferUntilEntered(node, run, play) {
4394
+ const host = node.parentNode;
4395
+ const handle = {
4396
+ finished: run.finished ?? Promise.resolve(),
4397
+ playState: 'pending',
4398
+ addEventListener: noop,
4399
+ removeEventListener: noop,
4400
+ cancel: noop,
4401
+ };
4402
+ queueMicrotask(() => {
4403
+ const wait = pendingEnters(host, node);
4404
+ if (wait)
4405
+ wait.then(() => { play(); });
4406
+ else
4407
+ play();
4408
+ });
4409
+ return handle;
4410
+ }
4411
+ function isTransitionMode(value) {
4412
+ return value === 'concurrent' || value === 'out-in' || value === 'in-out';
4413
+ }
4414
+
4217
4415
  /** DI token'ını okunur biçime çevirir (dev uyarıları için). */
4218
4416
  function describeServiceToken$1(t) {
4219
4417
  if (typeof t === 'string')
@@ -4224,9 +4422,12 @@
4224
4422
  return t.name || '[AnonymousClass]';
4225
4423
  return String(t);
4226
4424
  }
4425
+ function peekTransition(c) {
4426
+ return c?.motif?.options?.[TRANSITION_SLOT];
4427
+ }
4227
4428
  /**WAAPI keyframe (transitionIn) YA DA CSS class transition (name/classes) tanımlı olarak enter animasyonu varmı */
4228
4429
  function clearNavDirection(c) {
4229
- const t = c?.motif?.options?.transition;
4430
+ const t = peekTransition(c);
4230
4431
  if (!t?._markedDirection)
4231
4432
  return;
4232
4433
  t._markedDirection = false;
@@ -4235,9 +4436,237 @@
4235
4436
  }
4236
4437
  catch { }
4237
4438
  }
4439
+ function enterModeOf(container) {
4440
+ let c = container;
4441
+ while (c) {
4442
+ const mode = peekTransition(c)?.mode;
4443
+ if (mode)
4444
+ return mode;
4445
+ const node = c.element;
4446
+ if (!node || node.nodeType !== Node.COMMENT_NODE)
4447
+ break;
4448
+ c = c.parent ?? c._base?._leaveContainer;
4449
+ }
4450
+ return transitionSettings.mode;
4451
+ }
4452
+ function leaveModeOf(c) {
4453
+ return enterModeOf(c.parent ?? c._base?._leaveContainer);
4454
+ }
4238
4455
  function wantsEnterTransition(c) {
4239
- const t = c?.motif.options?.transition;
4240
- return !!(c?.motif.options?.transitionIn || (t && (t.classes || (t.name && t.name.length > 0))));
4456
+ const o = c?.motif?.options;
4457
+ const t = o?.[TRANSITION_SLOT];
4458
+ return !!(o?.transitionIn || (t && (t.classes || (t.name && t.name.length > 0))));
4459
+ }
4460
+ function createTransitionApi(owner) {
4461
+ const cur = () => owner.motif.options?.[TRANSITION_SLOT] ?? t;
4462
+ const t = {
4463
+ transitionInfo: () => {
4464
+ const s = cur();
4465
+ return {
4466
+ in: getTransitionInfo(owner.element, `${s.name}-enter ${s.name}-enter-start`),
4467
+ out: getTransitionInfo(owner.element, `${s.name}-leave ${s.name}-leave-start`),
4468
+ };
4469
+ },
4470
+ name: '',
4471
+ mode: undefined,
4472
+ classes: undefined,
4473
+ activeCssCancel: null,
4474
+ activeCssPhase: null,
4475
+ cssProps: () => {
4476
+ const s = cur();
4477
+ if (s.classes) {
4478
+ return { name: s.classes.name || s.name || '', ...s.classes };
4479
+ }
4480
+ if (s.name && s.name.length > 0) {
4481
+ return { name: s.name };
4482
+ }
4483
+ return null;
4484
+ },
4485
+ skipNextLeave: false,
4486
+ _suppressEnter: false,
4487
+ _markedDirection: false,
4488
+ in: (op) => {
4489
+ owner.motif.options.transitionIn = op;
4490
+ },
4491
+ out: (op) => {
4492
+ owner.motif.options.transitionOut = op;
4493
+ },
4494
+ enterTransition: (resolve) => {
4495
+ const s = cur();
4496
+ const base = owner._base;
4497
+ const appear = !base._enterPlayed;
4498
+ base._enterPlayed = true;
4499
+ base._enterSeq = (base._enterSeq ?? 0) + 1;
4500
+ if (s._suppressEnter) {
4501
+ resolve && resolve();
4502
+ return shimAnimation;
4503
+ }
4504
+ const attempt = {};
4505
+ base._enterRun = attempt;
4506
+ const enter = trackEnter(owner.element, () => {
4507
+ if (owner._base?._enterRun === attempt) {
4508
+ owner._base._enterRun = null;
4509
+ clearNavDirection(owner);
4510
+ }
4511
+ resolve && resolve();
4512
+ }, owner.motif.options.placeholder);
4513
+ const transitionIn = owner.motif.options.transitionIn;
4514
+ const animation = transitionIn
4515
+ ? s.run(transitionIn.keyframes, transitionIn.options, enter.done)
4516
+ : s._runCss('enter', enter.done, appear);
4517
+ if (animation && animation !== shimAnimation && typeof animation.addEventListener === 'function') {
4518
+ animation.addEventListener('cancel', enter.release);
4519
+ }
4520
+ return animation;
4521
+ },
4522
+ leaveTransition: (resolve) => {
4523
+ const s = cur();
4524
+ const node = owner.element;
4525
+ const leave = trackLeave(node, resolve);
4526
+ const play = () => {
4527
+ const transitionOut = owner.motif.options?.transitionOut;
4528
+ const animation = transitionOut
4529
+ ? s.run(transitionOut.keyframes, transitionOut.options, leave.done)
4530
+ : s._runCss('leave', leave.done);
4531
+ if (animation && animation !== shimAnimation && typeof animation.addEventListener === 'function') {
4532
+ animation.addEventListener('cancel', leave.release);
4533
+ }
4534
+ return animation;
4535
+ };
4536
+ if (leave.finished && leaveModeOf(owner) === 'in-out') {
4537
+ return deferUntilEntered(node, leave, play);
4538
+ }
4539
+ return play();
4540
+ },
4541
+ _runCss: (phase, resolve, appear = false) => {
4542
+ const s = cur();
4543
+ if (phase === 'enter' && s.activeCssPhase === 'leave') {
4544
+ resolve && resolve();
4545
+ return shimAnimation;
4546
+ }
4547
+ const cssProps = s.cssProps();
4548
+ const el = owner.element;
4549
+ if (cssProps && el && el.nodeType === 1 && el.classList) {
4550
+ try {
4551
+ s.activeCssCancel?.();
4552
+ }
4553
+ catch { }
4554
+ const cancel = runCssTransition(el, cssProps, phase, () => {
4555
+ s.activeCssCancel = null;
4556
+ s.activeCssPhase = null;
4557
+ resolve && resolve();
4558
+ }, appear);
4559
+ s.activeCssCancel = cancel;
4560
+ s.activeCssPhase = phase;
4561
+ return shimAnimation;
4562
+ }
4563
+ resolve && resolve();
4564
+ return shimAnimation;
4565
+ },
4566
+ activeAnimations: [],
4567
+ run: (keyframes, options, resolve) => {
4568
+ const s = cur();
4569
+ owner.motif.stopAnimations();
4570
+ const element = owner.element;
4571
+ if (element.animate) {
4572
+ var x = element.animate(keyframes, options);
4573
+ s.activeAnimations.push(x);
4574
+ let cleanedUp = false;
4575
+ const safeCleanup = () => {
4576
+ if (cleanedUp)
4577
+ return;
4578
+ cleanedUp = true;
4579
+ try {
4580
+ if (s.activeAnimations) {
4581
+ s.activeAnimations = s.activeAnimations.filter(a => a !== x);
4582
+ }
4583
+ }
4584
+ catch { }
4585
+ };
4586
+ x.addEventListener('finish', () => {
4587
+ resolve && resolve();
4588
+ safeCleanup();
4589
+ });
4590
+ x.oncancel = () => {
4591
+ safeCleanup();
4592
+ };
4593
+ return x;
4594
+ }
4595
+ else {
4596
+ resolve && resolve();
4597
+ const g = globalThis;
4598
+ if (typeof g.Animation === 'function') {
4599
+ try {
4600
+ return new g.Animation();
4601
+ }
4602
+ catch { /* ignore */ }
4603
+ }
4604
+ return shimAnimation;
4605
+ }
4606
+ }
4607
+ };
4608
+ return t;
4609
+ }
4610
+ class ComponentOptionsImpl {
4611
+ [OPTIONS_OWNER];
4612
+ [TRANSITION_SLOT];
4613
+ constructor(owner) {
4614
+ this[OPTIONS_OWNER] = owner;
4615
+ }
4616
+ get transition() {
4617
+ return this[TRANSITION_SLOT] ??= createTransitionApi(this[OPTIONS_OWNER]);
4618
+ }
4619
+ set transition(value) {
4620
+ this[TRANSITION_SLOT] = value;
4621
+ }
4622
+ set enableRouterClassing(value) {
4623
+ try {
4624
+ const ins = this[OPTIONS_OWNER];
4625
+ const callback = ins.context.onRouterChanged(() => {
4626
+ ComponentHelper.routerClassing.call(ins, value);
4627
+ });
4628
+ ins.motif.register(disposableCore.toDisposable(() => {
4629
+ callback();
4630
+ }));
4631
+ ComponentHelper.routerClassing.call(ins, value);
4632
+ }
4633
+ catch (error) {
4634
+ reportError('MJX105', error);
4635
+ }
4636
+ }
4637
+ getInstance() {
4638
+ return this[OPTIONS_OWNER];
4639
+ }
4640
+ get display() {
4641
+ return this[OPTIONS_OWNER].isVisible;
4642
+ }
4643
+ set display(value) {
4644
+ if (value) {
4645
+ this[OPTIONS_OWNER].motif.show();
4646
+ }
4647
+ else {
4648
+ this[OPTIONS_OWNER].motif.hide();
4649
+ }
4650
+ }
4651
+ hasEvent(name) {
4652
+ return !!this[OPTIONS_OWNER]._eventHandlers?.has(name);
4653
+ }
4654
+ }
4655
+ lazyBindMethods(ComponentOptionsImpl.prototype, ['getInstance', 'hasEvent']);
4656
+ function fireLifecycle(component, name, ev) {
4657
+ const base = component._base;
4658
+ if (base)
4659
+ base.emiters.fire(name, ev);
4660
+ }
4661
+ function hasLifecycleHook(component, hook, listName, lowerName, legacyProp) {
4662
+ if (component[hook])
4663
+ return true;
4664
+ const list = component._base[listName];
4665
+ if (Array.isArray(list) && list.length > 0)
4666
+ return true;
4667
+ if (legacyProp && component[legacyProp])
4668
+ return true;
4669
+ return component._base.emiters.hasListeners(lowerName);
4241
4670
  }
4242
4671
  const ComponentHelper = {
4243
4672
  callInitializeComponent(component) {
@@ -4267,25 +4696,26 @@
4267
4696
  }
4268
4697
  }
4269
4698
  },
4270
- async callDisposing(component) {
4271
- ComponentHelper.backgroundCallback(() => {
4272
- if (!component || component.isDisposed) {
4273
- return;
4274
- }
4275
- const sender = component, ev = { cancel: false };
4276
- if (component.onDisposing) {
4277
- callReported(() => component.onDisposing(sender, ev), 'MJX122', 'onDisposing');
4278
- }
4279
- if (Array.isArray(component._base._onDisposingHandlers)) {
4280
- for (const fn of component._base._onDisposingHandlers) {
4281
- callReported(() => fn(sender, ev), 'MJX122', 'onDisposing');
4282
- }
4283
- }
4284
- if (component.ondisposing) {
4285
- callReported(() => component.ondisposing(sender, ev), 'MJX122', 'ondisposing');
4699
+ callDisposing(component) {
4700
+ if (!component || component.isDisposed) {
4701
+ return;
4702
+ }
4703
+ if (!hasLifecycleHook(component, 'onDisposing', '_onDisposingHandlers', 'ondisposing', 'ondisposing')) {
4704
+ return;
4705
+ }
4706
+ const sender = component, ev = { cancel: false };
4707
+ if (component.onDisposing) {
4708
+ callReported(() => component.onDisposing(sender, ev), 'MJX122', 'onDisposing');
4709
+ }
4710
+ if (Array.isArray(component._base._onDisposingHandlers)) {
4711
+ for (const fn of component._base._onDisposingHandlers) {
4712
+ callReported(() => fn(sender, ev), 'MJX122', 'onDisposing');
4286
4713
  }
4287
- component._base.emiters.fire('ondisposing', ev);
4288
- });
4714
+ }
4715
+ if (component.ondisposing) {
4716
+ callReported(() => component.ondisposing(sender, ev), 'MJX122', 'ondisposing');
4717
+ }
4718
+ fireLifecycle(component, 'ondisposing', ev);
4289
4719
  },
4290
4720
  callActivated(component) {
4291
4721
  if (!component || component.isDisposed) {
@@ -4300,7 +4730,7 @@
4300
4730
  callReported(() => fn(sender, ev), 'MJX122', 'onActivated');
4301
4731
  }
4302
4732
  }
4303
- component._base.emiters.fire('onactivated', ev);
4733
+ fireLifecycle(component, 'onactivated', ev);
4304
4734
  },
4305
4735
  callDeactivated(component) {
4306
4736
  if (!component || component.isDisposed) {
@@ -4315,7 +4745,7 @@
4315
4745
  callReported(() => fn(sender, ev), 'MJX122', 'onDeactivated');
4316
4746
  }
4317
4747
  }
4318
- component._base.emiters.fire('ondeactivated', ev);
4748
+ fireLifecycle(component, 'ondeactivated', ev);
4319
4749
  },
4320
4750
  deactivateTree(component, deep = true) {
4321
4751
  if (!component || component.isDisposed || !component.isBuilt || !component._base || component._base._inactive) {
@@ -4323,7 +4753,7 @@
4323
4753
  }
4324
4754
  component._base._inactive = true;
4325
4755
  ComponentHelper.callDeactivated(component);
4326
- if (!deep) {
4756
+ if (!deep || component.isDisposed) {
4327
4757
  return;
4328
4758
  }
4329
4759
  for (const c of component.controls.items.slice()) {
@@ -4338,7 +4768,7 @@
4338
4768
  }
4339
4769
  component._base._inactive = false;
4340
4770
  ComponentHelper.callActivated(component);
4341
- if (!deep) {
4771
+ if (!deep || component.isDisposed) {
4342
4772
  return;
4343
4773
  }
4344
4774
  for (const c of component.controls.items.slice()) {
@@ -4347,34 +4777,36 @@
4347
4777
  }
4348
4778
  }
4349
4779
  },
4350
- async callDisposed(component) {
4780
+ callDisposed(component) {
4351
4781
  if (!component || !component._base || component._base._disposedFired) {
4352
4782
  return;
4353
4783
  }
4354
4784
  component._base._disposedFired = true;
4355
- const sender = component, ev = { cancel: false };
4356
- if (component.onDisposed) {
4357
- callReported(() => component.onDisposed(sender, ev), 'MJX122', 'onDisposed');
4358
- }
4359
- if (Array.isArray(component._base._onDisposedHandlers)) {
4360
- for (const fn of component._base._onDisposedHandlers) {
4361
- callReported(() => fn(sender, ev), 'MJX122', 'onDisposed');
4785
+ if (hasLifecycleHook(component, 'onDisposed', '_onDisposedHandlers', 'ondisposed', 'ondisposed')) {
4786
+ const sender = component, ev = { cancel: false };
4787
+ if (component.onDisposed) {
4788
+ callReported(() => component.onDisposed(sender, ev), 'MJX122', 'onDisposed');
4362
4789
  }
4790
+ if (Array.isArray(component._base._onDisposedHandlers)) {
4791
+ for (const fn of component._base._onDisposedHandlers) {
4792
+ callReported(() => fn(sender, ev), 'MJX122', 'onDisposed');
4793
+ }
4794
+ }
4795
+ if (component.ondisposed) {
4796
+ callReported(() => component.ondisposed(sender, ev), 'MJX122', 'ondisposed');
4797
+ }
4798
+ fireLifecycle(component, 'ondisposed', ev);
4363
4799
  }
4364
- if (component.ondisposed) {
4365
- callReported(() => component.ondisposed(sender, ev), 'MJX122', 'ondisposed');
4366
- }
4367
- component._base.emiters.fire('ondisposed', ev);
4368
4800
  try {
4369
4801
  globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:disposed', { id: component.id, type: component.constructor?.name });
4370
4802
  }
4371
4803
  catch { }
4372
4804
  },
4373
- async callBuilt(component) {
4374
- ComponentHelper.backgroundCallback(() => {
4375
- if (!component || component.isDisposed) {
4376
- return;
4377
- }
4805
+ callBuilt(component) {
4806
+ if (!component || component.isDisposed) {
4807
+ return;
4808
+ }
4809
+ if (hasLifecycleHook(component, 'onBuilt', '_onBuiltHandlers', 'onbuilt', 'onbuilt')) {
4378
4810
  const sender = component, ev = { cancel: false };
4379
4811
  if (component.onBuilt) {
4380
4812
  callReported(() => component.onBuilt(sender, ev), 'MJX122', 'onBuilt');
@@ -4387,12 +4819,12 @@
4387
4819
  if (component.onbuilt) {
4388
4820
  callReported(() => component.onbuilt(sender, ev), 'MJX122', 'onbuilt');
4389
4821
  }
4390
- component._base.emiters.fire('onbuilt', ev);
4391
- try {
4392
- globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:mounted', { id: component.id, type: component.constructor?.name });
4393
- }
4394
- catch { }
4395
- });
4822
+ fireLifecycle(component, 'onbuilt', ev);
4823
+ }
4824
+ try {
4825
+ globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:mounted', { id: component.id, type: component.constructor?.name });
4826
+ }
4827
+ catch { }
4396
4828
  },
4397
4829
  scheduleMounted(component) {
4398
4830
  if (!component || component.isDisposed || component._base._mountedScheduled) {
@@ -4436,47 +4868,49 @@
4436
4868
  if (component.onmounted) {
4437
4869
  callReported(() => component.onmounted(sender, ev), 'MJX122', 'onmounted');
4438
4870
  }
4439
- component._base.emiters.fire('onmounted', ev);
4871
+ fireLifecycle(component, 'onmounted', ev);
4440
4872
  },
4441
- async callBuilding(component) {
4442
- ComponentHelper.backgroundCallback(() => {
4443
- if (!component || component.isDisposed) {
4444
- return;
4445
- }
4446
- const sender = component, ev = { cancel: false };
4447
- if (component.onBuilding) {
4448
- callReported(() => component.onBuilding(sender, ev), 'MJX122', 'onBuilding');
4449
- }
4450
- if (Array.isArray(component._base._onBuildingHandlers)) {
4451
- for (const fn of component._base._onBuildingHandlers) {
4452
- callReported(() => fn(sender, ev), 'MJX122', 'onBuilding');
4453
- }
4873
+ callBuilding(component) {
4874
+ if (!component || component.isDisposed) {
4875
+ return;
4876
+ }
4877
+ if (!hasLifecycleHook(component, 'onBuilding', '_onBuildingHandlers', 'onbuilding')) {
4878
+ return;
4879
+ }
4880
+ const sender = component, ev = { cancel: false };
4881
+ if (component.onBuilding) {
4882
+ callReported(() => component.onBuilding(sender, ev), 'MJX122', 'onBuilding');
4883
+ }
4884
+ if (Array.isArray(component._base._onBuildingHandlers)) {
4885
+ for (const fn of component._base._onBuildingHandlers) {
4886
+ callReported(() => fn(sender, ev), 'MJX122', 'onBuilding');
4454
4887
  }
4455
- component._base.emiters.fire('onbuilding', ev);
4456
- });
4888
+ }
4889
+ fireLifecycle(component, 'onbuilding', ev);
4457
4890
  },
4458
- async callConfig(component) {
4459
- ComponentHelper.backgroundCallback(() => {
4460
- if (!component || component.isDisposed || component.isConfigured) {
4461
- return;
4462
- }
4463
- component.isConfigured = true;
4464
- if (component.motif.options._preconfig) {
4465
- safeCallSilent(() => component.motif.options._preconfig(component), 'Component._preconfig');
4466
- }
4467
- const sender = component, ev = { cancel: false };
4468
- if (component.onConfig) {
4469
- callReported(() => component.onConfig(sender, ev), 'MJX122', 'onConfig');
4470
- }
4471
- if (Array.isArray(component._base._onConfigHandlers)) {
4472
- for (const fn of component._base._onConfigHandlers) {
4473
- callReported(() => fn(sender, ev), 'MJX122', 'onConfig');
4474
- }
4891
+ callConfig(component) {
4892
+ if (!component || component.isDisposed || component.isConfigured) {
4893
+ return;
4894
+ }
4895
+ component.isConfigured = true;
4896
+ if (component.motif.options._preconfig) {
4897
+ safeCallSilent(() => component.motif.options._preconfig(component), 'Component._preconfig');
4898
+ }
4899
+ if (!hasLifecycleHook(component, 'onConfig', '_onConfigHandlers', 'onconfig')) {
4900
+ return;
4901
+ }
4902
+ const sender = component, ev = { cancel: false };
4903
+ if (component.onConfig) {
4904
+ callReported(() => component.onConfig(sender, ev), 'MJX122', 'onConfig');
4905
+ }
4906
+ if (Array.isArray(component._base._onConfigHandlers)) {
4907
+ for (const fn of component._base._onConfigHandlers) {
4908
+ callReported(() => fn(sender, ev), 'MJX122', 'onConfig');
4475
4909
  }
4476
- component._base.emiters.fire('onconfig', ev);
4477
- });
4910
+ }
4911
+ fireLifecycle(component, 'onconfig', ev);
4478
4912
  },
4479
- async callConfigured(component) {
4913
+ callConfigured(component) {
4480
4914
  if (component.motif.options && component.motif.options._postconfigdone) {
4481
4915
  return;
4482
4916
  }
@@ -4484,73 +4918,77 @@
4484
4918
  ComponentHelper.callConfig(component);
4485
4919
  }
4486
4920
  component.motif.options._postconfigdone = true;
4487
- ComponentHelper.backgroundCallback(() => {
4488
- if (!component || component.isDisposed) {
4489
- return;
4490
- }
4491
- const sender = component, ev = { cancel: false };
4492
- if (component.onConfigured) {
4493
- callReported(() => component.onConfigured(sender, ev), 'MJX122', 'onConfigured');
4494
- }
4495
- if (Array.isArray(component._base._onConfiguredHandlers)) {
4496
- for (const fn of component._base._onConfiguredHandlers) {
4497
- callReported(() => fn(sender, ev), 'MJX122', 'onConfigured');
4498
- }
4921
+ if (!component || component.isDisposed) {
4922
+ return;
4923
+ }
4924
+ if (!hasLifecycleHook(component, 'onConfigured', '_onConfiguredHandlers', 'onconfigured')) {
4925
+ return;
4926
+ }
4927
+ const sender = component, ev = { cancel: false };
4928
+ if (component.onConfigured) {
4929
+ callReported(() => component.onConfigured(sender, ev), 'MJX122', 'onConfigured');
4930
+ }
4931
+ if (Array.isArray(component._base._onConfiguredHandlers)) {
4932
+ for (const fn of component._base._onConfiguredHandlers) {
4933
+ callReported(() => fn(sender, ev), 'MJX122', 'onConfigured');
4499
4934
  }
4500
- component._base.emiters.fire('onconfigured', ev);
4501
- });
4935
+ }
4936
+ fireLifecycle(component, 'onconfigured', ev);
4502
4937
  },
4503
- async callOnInitialized(component) {
4504
- ComponentHelper.backgroundCallback(() => {
4505
- if (!component || component.isDisposed) {
4506
- return;
4507
- }
4508
- component.isInitialized = true;
4509
- const sender = component, ev = { cancel: false };
4510
- if (component.onInitialized) {
4511
- callReported(() => component.onInitialized(sender, ev), 'MJX122', 'onInitialized');
4512
- }
4513
- if (Array.isArray(component._base._onInitializedHandlers)) {
4514
- for (const fn of component._base._onInitializedHandlers) {
4515
- callReported(() => fn(sender, ev), 'MJX122', 'onInitialized');
4516
- }
4938
+ callOnInitialized(component) {
4939
+ if (!component || component.isDisposed) {
4940
+ return;
4941
+ }
4942
+ component.isInitialized = true;
4943
+ if (!hasLifecycleHook(component, 'onInitialized', '_onInitializedHandlers', 'oninitialized')) {
4944
+ return;
4945
+ }
4946
+ const sender = component, ev = { cancel: false };
4947
+ if (component.onInitialized) {
4948
+ callReported(() => component.onInitialized(sender, ev), 'MJX122', 'onInitialized');
4949
+ }
4950
+ if (Array.isArray(component._base._onInitializedHandlers)) {
4951
+ for (const fn of component._base._onInitializedHandlers) {
4952
+ callReported(() => fn(sender, ev), 'MJX122', 'onInitialized');
4517
4953
  }
4518
- component._base.emiters.fire('oninitialized', ev);
4519
- });
4954
+ }
4955
+ fireLifecycle(component, 'oninitialized', ev);
4520
4956
  },
4521
- async callOnInitializing(component) {
4522
- ComponentHelper.backgroundCallback(() => {
4523
- if (!component || component.isDisposed) {
4524
- return;
4525
- }
4526
- const sender = component, ev = { cancel: false };
4527
- if (component.onInitializing) {
4528
- callReported(() => component.onInitializing(sender, ev), 'MJX122', 'onInitializing');
4529
- }
4530
- if (Array.isArray(component._base._onInitializingHandlers)) {
4531
- for (const fn of component._base._onInitializingHandlers) {
4532
- callReported(() => fn(sender, ev), 'MJX122', 'onInitializing');
4533
- }
4957
+ callOnInitializing(component) {
4958
+ if (!component || component.isDisposed) {
4959
+ return;
4960
+ }
4961
+ if (!hasLifecycleHook(component, 'onInitializing', '_onInitializingHandlers', 'oninitializing')) {
4962
+ return;
4963
+ }
4964
+ const sender = component, ev = { cancel: false };
4965
+ if (component.onInitializing) {
4966
+ callReported(() => component.onInitializing(sender, ev), 'MJX122', 'onInitializing');
4967
+ }
4968
+ if (Array.isArray(component._base._onInitializingHandlers)) {
4969
+ for (const fn of component._base._onInitializingHandlers) {
4970
+ callReported(() => fn(sender, ev), 'MJX122', 'onInitializing');
4534
4971
  }
4535
- component._base.emiters.fire('oninitializing', ev);
4536
- });
4972
+ }
4973
+ fireLifecycle(component, 'oninitializing', ev);
4537
4974
  },
4538
- async callVisibilityChanged(component) {
4539
- ComponentHelper.backgroundCallback(() => {
4540
- if (!component || component.isDisposed) {
4541
- return;
4542
- }
4543
- const sender = component, ev = { cancel: false };
4544
- if (component.onVisibilityChanged) {
4545
- callReported(() => component.onVisibilityChanged(sender, ev), 'MJX122', 'onVisibilityChanged');
4546
- }
4547
- if (Array.isArray(component._base._onVisibilityChangedHandlers)) {
4548
- for (const fn of component._base._onVisibilityChangedHandlers) {
4549
- callReported(() => fn(sender, ev), 'MJX122', 'onVisibilityChanged');
4550
- }
4975
+ callVisibilityChanged(component) {
4976
+ if (!component || component.isDisposed) {
4977
+ return;
4978
+ }
4979
+ if (!hasLifecycleHook(component, 'onVisibilityChanged', '_onVisibilityChangedHandlers', 'onvisibilitychanged')) {
4980
+ return;
4981
+ }
4982
+ const sender = component, ev = { cancel: false };
4983
+ if (component.onVisibilityChanged) {
4984
+ callReported(() => component.onVisibilityChanged(sender, ev), 'MJX122', 'onVisibilityChanged');
4985
+ }
4986
+ if (Array.isArray(component._base._onVisibilityChangedHandlers)) {
4987
+ for (const fn of component._base._onVisibilityChangedHandlers) {
4988
+ callReported(() => fn(sender, ev), 'MJX122', 'onVisibilityChanged');
4551
4989
  }
4552
- component._base.emiters.fire('onvisibilitychanged', ev);
4553
- });
4990
+ }
4991
+ fireLifecycle(component, 'onvisibilitychanged', ev);
4554
4992
  },
4555
4993
  findFragmentContent(c) {
4556
4994
  const controlElement = c.element.nodeType == Node.COMMENT_NODE
@@ -4576,6 +5014,8 @@
4576
5014
  return;
4577
5015
  }
4578
5016
  ComponentHelper.callConfigured(c);
5017
+ if (c.isDisposed)
5018
+ return;
4579
5019
  c._base._activatePreBindings();
4580
5020
  if (c.isWait)
4581
5021
  return;
@@ -4603,8 +5043,11 @@
4603
5043
  return;
4604
5044
  }
4605
5045
  }
5046
+ if (c.isDisposed || this.isDisposed)
5047
+ return;
4606
5048
  c.parent = this;
4607
- const currentIndex = this.controls.items.indexOf(c);
5049
+ const ownItems = this.controls.items;
5050
+ const currentIndex = ownItems.length > 0 && ownItems[ownItems.length - 1] === c ? ownItems.length - 1 : ownItems.indexOf(c);
4608
5051
  const appendableElement = findAppendableComponent(this);
4609
5052
  var controlElement = c.element.nodeType == Node.COMMENT_NODE
4610
5053
  ? c.motif.options.cache
@@ -4655,6 +5098,18 @@
4655
5098
  return;
4656
5099
  }
4657
5100
  }
5101
+ if (insertHost && enterModeOf(this) === 'out-in') {
5102
+ const wait = pendingLeaves(insertHost, controlElement);
5103
+ if (wait) {
5104
+ c._base._enterSeq = (c._base._enterSeq ?? 0) + 1;
5105
+ wait.then(() => {
5106
+ if (this.isDisposed || c.isDisposed || c.parent !== this)
5107
+ return;
5108
+ ComponentHelper.internalBuild.call(this, c);
5109
+ });
5110
+ return;
5111
+ }
5112
+ }
4658
5113
  const parentNode = appendableElement?.element;
4659
5114
  if (controlElement && parentNode && (controlElement === parentNode || controlElement.contains(parentNode))) {
4660
5115
  reportWarning('MJX104', []);
@@ -4736,712 +5191,627 @@
4736
5191
  }
4737
5192
  }
4738
5193
  };
4739
- const fragmentCloseMarkers = new WeakMap();
4740
- const LIFECYCLE_X_EVENTS = new Set([
4741
- 'building', 'built', 'initializing', 'initialized', 'disposing', 'disposed',
4742
- 'config', 'configured', 'visibilitychanged', 'activated', 'deactivated'
4743
- ]);
4744
- const RAW_APPLICATION = Symbol('motif.rawApplication');
4745
- const SCOPED_SUBSCRIBERS = new Set(['on', 'onRouterChanged']);
4746
- /**
4747
- * Uygulamanın bileşene bağlı görünümü. `on`/`onRouterChanged` aboneliklerini sahibin ömrüne
4748
- * kaydeder; diğer tüm üyeler (alanlar, metotlar, atamalar) uygulamanın kendisine yönlenir.
4749
- */
4750
- function createScopedContext(app, owner) {
4751
- const cache = new Map();
4752
- return new Proxy(app, {
4753
- get(target, prop) {
4754
- if (prop === RAW_APPLICATION) {
4755
- return target;
4756
- }
4757
- const value = Reflect.get(target, prop, target);
4758
- if (typeof value !== 'function') {
4759
- return value;
4760
- }
4761
- const hit = cache.get(prop);
4762
- if (hit && hit.fn === value) {
4763
- return hit.bound;
4764
- }
4765
- const bound = SCOPED_SUBSCRIBERS.has(prop)
4766
- ? (...args) => owner._trackContextSubscription(value.apply(target, args))
4767
- : value.bind(target);
4768
- cache.set(prop, { fn: value, bound });
4769
- return bound;
4770
- },
4771
- set(target, prop, value) {
4772
- return Reflect.set(target, prop, value, target);
4773
- },
4774
- });
4775
- }
4776
- class ComponentBase extends Disposable {
4777
- motif = new ComponentMotif(this, {
4778
- transition: {
4779
- transitionInfo: () => {
4780
- return {
4781
- in: getTransitionInfo(this.element, `${this.motif.options.transition.name}-enter ${this.motif.options.transition.name}-enter-start`),
4782
- out: getTransitionInfo(this.element, `${this.motif.options.transition.name}-leave ${this.motif.options.transition.name}-leave-start`),
4783
- };
4784
- },
4785
- name: '',
4786
- classes: undefined,
4787
- activeCssCancel: null,
4788
- activeCssPhase: null,
4789
- cssProps: () => {
4790
- const t = this.motif.options.transition;
4791
- if (t.classes) {
4792
- return { name: t.classes.name || t.name || '', ...t.classes };
4793
- }
4794
- if (t.name && t.name.length > 0) {
4795
- return { name: t.name };
4796
- }
4797
- return null;
4798
- },
4799
- skipNextLeave: false,
4800
- _suppressEnter: false,
4801
- _markedDirection: false,
4802
- in: (op) => {
4803
- this.motif.options.transitionIn = op;
4804
- },
4805
- out: (op) => {
4806
- this.motif.options.transitionOut = op;
4807
- },
4808
- enterTransition: (resolve) => {
4809
- const t = this.motif.options.transition;
4810
- const appear = !this._base._enterPlayed;
4811
- this._base._enterPlayed = true;
4812
- this._base._enterSeq = (this._base._enterSeq ?? 0) + 1;
4813
- if (t._suppressEnter) {
4814
- resolve && resolve();
4815
- return shimAnimation;
4816
- }
4817
- const attempt = {};
4818
- this._base._enterRun = attempt;
4819
- const done = () => {
4820
- if (this._base?._enterRun === attempt) {
4821
- this._base._enterRun = null;
4822
- clearNavDirection(this);
4823
- }
4824
- resolve && resolve();
4825
- };
4826
- if (this.motif.options.transitionIn) {
4827
- return t.run(this.motif.options.transitionIn.keyframes, this.motif.options.transitionIn.options, done);
4828
- }
4829
- return t._runCss('enter', done, appear);
4830
- },
4831
- leaveTransition: (resolve) => {
4832
- if (this.motif.options.transitionOut) {
4833
- return this.motif.options.transition.run(this.motif.options.transitionOut.keyframes, this.motif.options.transitionOut.options, resolve);
4834
- }
4835
- return this.motif.options.transition._runCss('leave', resolve);
4836
- },
4837
- _runCss: (phase, resolve, appear = false) => {
4838
- const t = this.motif.options.transition;
4839
- if (phase === 'enter' && t.activeCssPhase === 'leave') {
4840
- resolve && resolve();
4841
- return shimAnimation;
4842
- }
4843
- const cssProps = t.cssProps();
4844
- const el = this.element;
4845
- if (cssProps && el && el.nodeType === 1 && el.classList) {
4846
- try {
4847
- t.activeCssCancel?.();
4848
- }
4849
- catch { }
4850
- const cancel = runCssTransition(el, cssProps, phase, () => {
4851
- if (this.motif.options?.transition) {
4852
- this.motif.options.transition.activeCssCancel = null;
4853
- this.motif.options.transition.activeCssPhase = null;
4854
- }
4855
- resolve && resolve();
4856
- }, appear);
4857
- t.activeCssCancel = cancel;
4858
- t.activeCssPhase = phase;
4859
- return shimAnimation;
4860
- }
4861
- resolve && resolve();
4862
- return shimAnimation;
4863
- },
4864
- activeAnimations: [],
4865
- run: (keyframes, options, resolve) => {
4866
- this.motif.stopAnimations();
4867
- const element = this.element;
4868
- if (element.animate) {
4869
- var x = element.animate(keyframes, options);
4870
- this.motif.options.transition.activeAnimations.push(x);
4871
- let cleanedUp = false;
4872
- const safeCleanup = () => {
4873
- if (cleanedUp)
4874
- return;
4875
- cleanedUp = true;
4876
- try {
4877
- if (this?.motif.options?.transition?.activeAnimations) {
4878
- this.motif.options.transition.activeAnimations = this.motif.options.transition.activeAnimations.filter(a => a !== x);
4879
- }
4880
- }
4881
- catch { }
4882
- };
4883
- x.addEventListener('finish', () => {
4884
- resolve && resolve();
4885
- safeCleanup();
4886
- });
4887
- x.oncancel = () => {
4888
- safeCleanup();
4889
- };
4890
- return x;
4891
- }
4892
- else {
4893
- resolve && resolve();
4894
- const g = globalThis;
4895
- if (typeof g.Animation === 'function') {
4896
- try {
4897
- return new g.Animation();
4898
- }
4899
- catch { /* ignore */ }
4900
- }
4901
- return shimAnimation;
5194
+ function removeComponentDom(c, node, alsoPlaceholder) {
5195
+ const opts = c.motif?.options;
5196
+ const parent = node.parentNode;
5197
+ if (node.nodeType === Node.COMMENT_NODE) {
5198
+ if (!parent)
5199
+ return;
5200
+ const close = opts?.closeFragment || null;
5201
+ if (close) {
5202
+ let current = node;
5203
+ while (current) {
5204
+ const after = current.nextSibling;
5205
+ try {
5206
+ parent.removeChild(current);
4902
5207
  }
5208
+ catch { }
5209
+ if (current === close)
5210
+ break;
5211
+ current = after;
4903
5212
  }
4904
- },
4905
- set enableRouterClassing(value) {
5213
+ }
5214
+ else {
4906
5215
  try {
4907
- var ins = this.getInstance();
4908
- const callback = ins.context.onRouterChanged(() => {
4909
- ComponentHelper.routerClassing.call(ins, value);
4910
- });
4911
- ins.motif.register(disposableCore.toDisposable(() => {
4912
- callback();
4913
- }));
4914
- ComponentHelper.routerClassing.call(ins, value);
4915
- }
4916
- catch (error) {
4917
- reportError('MJX105', error);
4918
- }
4919
- },
4920
- getInstance: () => {
4921
- return this;
4922
- },
4923
- get display() {
4924
- return this.getInstance().isVisible;
4925
- },
4926
- set display(value) {
4927
- if (value) {
4928
- this.getInstance().motif.show();
5216
+ parent.removeChild(node);
4929
5217
  }
4930
- else {
4931
- this.getInstance().motif.hide();
4932
- }
4933
- },
4934
- hasEvent: (name) => {
4935
- const ins = this._eventHandlers?.has(name);
4936
- if (ins)
4937
- return true;
4938
- return false;
5218
+ catch { }
4939
5219
  }
4940
- });
4941
- element;
4942
- props;
4943
- isBuilt = false;
4944
- isInitialized = false;
4945
- isDisposed = false;
4946
- isConfigured = false;
4947
- isPainting = false;
4948
- isPainted = false;
4949
- isVisible = true;
4950
- controls = new ControlCollection(this);
4951
- _eventHandlers;
4952
- _isWait = false;
4953
- class = new controlClass(this);
4954
- attr = new controlAttribute(this);
4955
- bindings = new BindingCollection(this);
4956
- /** style(fn) izleyicisi: tek tek tutulur, yeniden çağrıda önceki durdurulur. */
4957
- _styleFx;
4958
- useModel(modelCtor) {
4959
- return reactive(modelCtor);
5220
+ if (!alsoPlaceholder)
5221
+ return;
4960
5222
  }
4961
- _computeHideStrategy() {
4962
- const cfg = this.motif.options?.hideStrategy ?? 'auto';
4963
- if (cfg === 'placeholder')
4964
- return 'placeholder';
4965
- if (cfg === 'detach')
4966
- return 'detach';
4967
- if (this.motif.options?.__fromList || typeof this.motif.options?.indexkey !== 'undefined' || typeof this.motif.options?.__key !== 'undefined') {
4968
- return 'detach';
5223
+ else if (parent) {
5224
+ try {
5225
+ parent.removeChild(node);
4969
5226
  }
4970
- return 'placeholder';
5227
+ catch { }
5228
+ if (!alsoPlaceholder)
5229
+ return;
4971
5230
  }
4972
- _isInDom() {
5231
+ const placeholder = opts?.placeholder;
5232
+ if (placeholder && placeholder.parentNode) {
4973
5233
  try {
4974
- if (!this.element)
4975
- return false;
4976
- const node = this.element;
4977
- if (node.nodeType === Node.COMMENT_NODE) {
4978
- return !!node.parentNode;
4979
- }
4980
- return !!node.parentNode;
4981
- }
4982
- catch {
4983
- return false;
5234
+ placeholder.parentNode.removeChild(placeholder);
4984
5235
  }
5236
+ catch { }
4985
5237
  }
4986
- set isWait(value) {
4987
- this._isWait = value;
4988
- if (this.isBuilt) {
4989
- if (value) {
4990
- this.motif.hide();
4991
- }
4992
- else {
4993
- this.motif.show();
4994
- }
5238
+ }
5239
+ function detachDomWithAnimation(c) {
5240
+ const node = c.element;
5241
+ if (!node)
5242
+ return;
5243
+ const opts = c.motif.options;
5244
+ const t = opts?.[TRANSITION_SLOT];
5245
+ try {
5246
+ const skip = t?.skipNextLeave === true || c._forceInstantDetach === true;
5247
+ if (skip) {
5248
+ if (t)
5249
+ t.skipNextLeave = false;
5250
+ c._forceInstantDetach = false;
5251
+ removeComponentDom(c, node, true);
4995
5252
  return;
4996
5253
  }
4997
- if (value === false && this.parent && this.parent.isBuilt) {
4998
- ComponentHelper.internalBuild.call(this.parent, this);
4999
- }
5000
5254
  }
5001
- get isWait() {
5002
- return this._isWait;
5255
+ catch { }
5256
+ if (!t && !opts?.transitionOut) {
5257
+ removeComponentDom(c, node, false);
5258
+ return;
5003
5259
  }
5004
- constructor(element, props = {}) {
5005
- super();
5006
- recordServiceOwner(this);
5007
- if (this.onElementCreating) {
5008
- this.element = this.onElementCreating.call(this);
5260
+ try {
5261
+ opts.transition.leaveTransition(() => {
5262
+ removeComponentDom(c, node, false);
5263
+ });
5264
+ }
5265
+ catch {
5266
+ removeComponentDom(c, node, false);
5267
+ }
5268
+ }
5269
+ async function detachDomWithAnimationAsync(c) {
5270
+ const node = c.element;
5271
+ if (!node)
5272
+ return;
5273
+ const opts = c.motif.options;
5274
+ const t = opts?.[TRANSITION_SLOT];
5275
+ try {
5276
+ const skip = t?.skipNextLeave === true || c._forceInstantDetach === true;
5277
+ if (skip) {
5278
+ if (t)
5279
+ t.skipNextLeave = false;
5280
+ c._forceInstantDetach = false;
5281
+ removeComponentDom(c, node, true);
5282
+ return;
5009
5283
  }
5010
- else if (props?.onElementCreating) {
5011
- this.element = props.onElementCreating.call(this);
5284
+ }
5285
+ catch { }
5286
+ if (!t && !opts?.transitionOut) {
5287
+ removeComponentDom(c, node, false);
5288
+ return;
5289
+ }
5290
+ return new Promise((resolve) => {
5291
+ try {
5292
+ opts.transition.leaveTransition(() => {
5293
+ removeComponentDom(c, node, false);
5294
+ resolve();
5295
+ });
5012
5296
  }
5013
- else {
5014
- this.element = element;
5297
+ catch {
5298
+ removeComponentDom(c, node, false);
5299
+ resolve();
5015
5300
  }
5016
- if (props) {
5017
- for (const fn of takePendingRefs(this, extractRefs(props, this))) {
5018
- callReported(() => fn(this), 'MJX122', 'ref');
5301
+ });
5302
+ }
5303
+ function disposeShallow(c) {
5304
+ if (c.isDisposed)
5305
+ return;
5306
+ ComponentHelper.callDisposing.call(c, c);
5307
+ try {
5308
+ c._base._offAll();
5309
+ }
5310
+ catch {
5311
+ }
5312
+ c.motif.stopAnimations();
5313
+ c._base._deactivateBindings();
5314
+ if (c.controls?.items?.length) {
5315
+ for (const child of c.controls.items) {
5316
+ try {
5317
+ child._base._disposeShallow();
5318
+ }
5319
+ catch {
5019
5320
  }
5020
5321
  }
5021
- props && ParseProps(props, this);
5022
- applyComponentOptions(props?.options, this);
5023
- this.props = props;
5024
- // (class/style/id/tabindex/role/aria-*/data-*) kök düğüme (root node) düşer, prop'lar this.props'ta kalır.
5025
- if (props) {
5026
- const ctor0 = new.target;
5027
- const plain = ctor0 === ComponentBase || Object.getPrototypeOf(ctor0) === ComponentBase;
5028
- if (plain)
5029
- applyPlainElementProps(props, this);
5030
- else
5031
- applyFallthroughProps(props, this);
5322
+ }
5323
+ ComponentHelper.callDisposed.call(c, c);
5324
+ safeCall(() => { c._base.emiters.clear(); }, 'disposeShallow.emiters');
5325
+ c.isDisposed = true;
5326
+ Disposable.prototype.dispose.call(c);
5327
+ }
5328
+ function deepCleanup(c) {
5329
+ try {
5330
+ c.parent = null;
5331
+ }
5332
+ catch { }
5333
+ try {
5334
+ c._eventHandlers?.clear();
5335
+ }
5336
+ catch {
5337
+ }
5338
+ c._eventHandlers = undefined;
5339
+ try {
5340
+ c.class?._countsStore?.clear();
5341
+ }
5342
+ catch { }
5343
+ try {
5344
+ c.class?._watchersStore?.clear();
5345
+ }
5346
+ catch { }
5347
+ try {
5348
+ c.attr?._attrMapStore?.clear();
5349
+ }
5350
+ catch { }
5351
+ try {
5352
+ c.attr?._watchersStore?.clear();
5353
+ }
5354
+ catch { }
5355
+ try {
5356
+ if (c.motif.options) {
5357
+ c.motif.options.cache = undefined;
5358
+ c.motif.options.closeFragment = undefined;
5359
+ c.motif.options.placeholder = undefined;
5032
5360
  }
5033
- ComponentHelper.callOnInitializing(this);
5034
- this.controls.onAdd = (c) => {
5035
- this.motif.trigger('controladded', { control: c });
5036
- if (this.isWait || this.parent?.isWait)
5037
- return;
5038
- ComponentHelper.internalBuild.call(this, c);
5039
- };
5040
- this.controls.onAddBeforeBuild = (c) => {
5041
- this.motif.trigger('controladded', { control: c });
5042
- };
5043
- this.controls.onRemove = (c) => {
5044
- this.motif.trigger('controlremoved', { control: c });
5045
- };
5046
- ComponentHelper.callOnInitialized(this);
5047
- const ctor = new.target;
5048
- const isBaseCtor = ctor === ComponentBase || Object.getPrototypeOf(ctor) === ComponentBase;
5049
- if (isBaseCtor) {
5050
- ComponentHelper.callConfig(this);
5361
+ }
5362
+ catch {
5363
+ }
5364
+ try {
5365
+ c.element = null;
5366
+ }
5367
+ catch { }
5368
+ try {
5369
+ c.props = undefined;
5370
+ }
5371
+ catch { }
5372
+ try {
5373
+ c.childs = undefined;
5374
+ }
5375
+ catch { }
5376
+ try {
5377
+ c.class = undefined;
5378
+ }
5379
+ catch { }
5380
+ try {
5381
+ c.attr = undefined;
5382
+ }
5383
+ catch { }
5384
+ try {
5385
+ c.parent = null;
5386
+ }
5387
+ catch { }
5388
+ try {
5389
+ c.motif.options = undefined;
5390
+ }
5391
+ catch { }
5392
+ const keys = Object.keys(c);
5393
+ for (let i = 0; i < keys.length; i++) {
5394
+ const key = keys[i];
5395
+ if (key === 'motif')
5396
+ continue;
5397
+ try {
5398
+ c[key] = undefined;
5051
5399
  }
5052
- else {
5053
- this._base._configDeferred = true;
5400
+ catch { }
5401
+ }
5402
+ c.isDisposed = true;
5403
+ }
5404
+ const DISPOSE_STARTED = Promise.resolve();
5405
+ function subtreeDisposesSync(c, root) {
5406
+ if (!root && c._disposing && !c.isDisposed)
5407
+ return false;
5408
+ if (c.disposeAsync !== ComponentBase.prototype.disposeAsync)
5409
+ return false;
5410
+ const opts = c.motif?.options;
5411
+ if (opts) {
5412
+ if (opts.transitionOut)
5413
+ return false;
5414
+ const t = opts[TRANSITION_SLOT];
5415
+ if (t) {
5416
+ if (t.activeAnimations && t.activeAnimations.length > 0)
5417
+ return false;
5418
+ if (t.activeCssCancel)
5419
+ return false;
5420
+ if (t.classes || (t.name && t.name.length > 0))
5421
+ return false;
5054
5422
  }
5055
5423
  }
5056
- childs;
5057
- _base = {
5058
- prebinding_Activated: false,
5059
- _offAll: () => {
5060
- if (!this._eventHandlers)
5061
- return;
5062
- for (const [full, set] of this._eventHandlers) {
5063
- const name = full.split(":")[0];
5064
- const evt = name.startsWith("on") ? name.slice(2).toLowerCase() : name.toLowerCase();
5065
- for (const rec of set) {
5066
- if (!rec || !rec.wrapped) {
5067
- continue;
5068
- }
5069
- if (rec.domEvent === false) {
5070
- continue;
5071
- }
5072
- const cap = rec.capture === true;
5424
+ const items = c.controls?.items;
5425
+ if (items) {
5426
+ for (let i = 0; i < items.length; i++) {
5427
+ const child = items[i];
5428
+ if (child && !child.isDisposed && !subtreeDisposesSync(child, false))
5429
+ return false;
5430
+ }
5431
+ }
5432
+ return true;
5433
+ }
5434
+ function disposePrefix(c, options, asChild) {
5435
+ const ctx = asChild ? 'disposeAsync' : 'dispose';
5436
+ if (!asChild && options?.skipLeaveTransition) {
5437
+ c.motif.options.transition.skipNextLeave = true;
5438
+ }
5439
+ safeCall(() => { ComponentHelper.callDisposing.call(c, c); }, ctx + '.callDisposing');
5440
+ c._base._offAll();
5441
+ c._base._deactivateBindings();
5442
+ safeCall(() => { c.parent?.controls?.silentDetach?.(c, true); }, ctx + '.silentDetach');
5443
+ }
5444
+ function disposeFinish(c, options, asChild) {
5445
+ c.isDisposed = true;
5446
+ Disposable.prototype.dispose.call(c);
5447
+ if (asChild) {
5448
+ c.controls.items = [];
5449
+ safeCall(() => { ComponentHelper.callDisposed.call(c, c); }, 'disposeAsync.callDisposed');
5450
+ safeCall(() => { c._base.emiters.clear(); }, 'disposeAsync.emiters');
5451
+ if (options?.deep) {
5452
+ c._base._deepCleanup();
5453
+ }
5454
+ return;
5455
+ }
5456
+ c.element = null;
5457
+ safeCall(() => { ComponentHelper.callDisposed.call(c, c); }, 'dispose.callDisposed');
5458
+ safeCall(() => { c._base.emiters.clear(); }, 'dispose.emiters');
5459
+ c._base._offAll();
5460
+ c._base._deepCleanup();
5461
+ }
5462
+ async function disposeRemainderAsync(c, options, asChild, leave) {
5463
+ if (leave) {
5464
+ await leave;
5465
+ }
5466
+ else {
5467
+ if (asChild) {
5468
+ await c.motif.stopAnimations();
5469
+ }
5470
+ else if (peekTransition(c)?.skipNextLeave) {
5471
+ await c.motif.stopAnimations();
5472
+ }
5473
+ await c._base._detachDomWithAnimationAsync();
5474
+ }
5475
+ if (!asChild && c.constructor.name !== 'TransportTo') {
5476
+ await disposeContentBlocks(c);
5477
+ }
5478
+ const childOptions = { deep: options?.deep };
5479
+ await safeCallAsync(async () => {
5480
+ if (c.isDisposed) {
5481
+ return;
5482
+ }
5483
+ const ctrls = Array.from(c.controls.items);
5484
+ if (ctrls.length) {
5485
+ await Promise.all(ctrls.map(child => asChild
5486
+ ? safeCallAsync(async () => { await child.disposeAsync(childOptions); }, 'disposeAsync.disposeAsyncChildren.handler')
5487
+ : (async () => {
5073
5488
  try {
5074
- this.element.removeEventListener(evt, rec.wrapped, cap);
5489
+ await child.disposeAsync(childOptions);
5075
5490
  }
5076
- catch { }
5077
- try {
5078
- if (rec.capture === undefined) {
5079
- this.element.removeEventListener(evt, rec.wrapped, !cap);
5080
- }
5491
+ catch (error) {
5492
+ reportError('MJX107', error);
5081
5493
  }
5082
- catch { }
5083
- }
5084
- }
5085
- this._eventHandlers.clear();
5086
- this._eventHandlers = undefined;
5087
- },
5088
- _deactivateBindings: () => {
5089
- try {
5090
- this.bindings?.deactivateAll();
5091
- }
5092
- catch { }
5093
- },
5094
- _activateBindings: () => {
5095
- try {
5096
- this.bindings?.activateAll();
5494
+ })()));
5495
+ }
5496
+ }, asChild ? 'disposeAsync.disposeAsyncChildren' : 'dispose.disposeAsync');
5497
+ if (!asChild && c.isDisposed) {
5498
+ return;
5499
+ }
5500
+ disposeFinish(c, options, asChild);
5501
+ }
5502
+ function disposeRemainderSync(root, options, asChild, rootDetached) {
5503
+ const childOptions = { deep: options?.deep };
5504
+ const nodes = [root];
5505
+ const parents = [-1];
5506
+ let pending = null;
5507
+ if (!rootDetached)
5508
+ detachDomWithAnimation(root);
5509
+ for (let n = 0; n < nodes.length; n++) {
5510
+ const node = nodes[n];
5511
+ if (node.isDisposed)
5512
+ continue;
5513
+ const items = node.controls?.items;
5514
+ if (!items || items.length === 0)
5515
+ continue;
5516
+ const ctrls = Array.from(items);
5517
+ for (let j = 0; j < ctrls.length; j++) {
5518
+ const child = ctrls[j];
5519
+ if (child.isDisposed)
5520
+ continue;
5521
+ if (child._disposing) {
5522
+ (pending ??= []).push(child._disposing);
5523
+ continue;
5097
5524
  }
5098
- catch { }
5099
- },
5100
- _reactivateBindings: () => {
5101
5525
  try {
5102
- this.bindings?.reActivateAll();
5526
+ retireServiceOwner(child);
5527
+ child._disposing = root._disposing;
5528
+ disposePrefix(child, childOptions, true);
5529
+ detachDomWithAnimation(child);
5530
+ nodes.push(child);
5531
+ parents.push(n);
5103
5532
  }
5104
- catch { }
5105
- },
5106
- _activatePreBindings: () => {
5107
- if (this._base.prebinding_Activated)
5108
- return;
5109
- this.bindings.items.filter(x => x.propertyName == "isWait" || x.propertyName == "display").forEach(b => {
5110
- b.activate();
5111
- });
5112
- this._base.prebinding_Activated = true;
5113
- },
5114
- _detachDomWithAnimation: () => {
5115
- const node = this.element;
5116
- if (!node)
5117
- return;
5118
- try {
5119
- const skip = this.motif.options.transition.skipNextLeave === true || this?._forceInstantDetach === true;
5120
- if (skip) {
5121
- if (this?.motif.options?.transition)
5122
- this.motif.options.transition.skipNextLeave = false;
5123
- this._forceInstantDetach = false;
5124
- const immediate = () => {
5125
- const parent = node.parentNode;
5126
- if (node.nodeType === Node.COMMENT_NODE) {
5127
- const open = node;
5128
- const close = this.motif.options?.closeFragment || null;
5129
- if (!parent)
5130
- return;
5131
- if (close) {
5132
- let current = open;
5133
- while (current) {
5134
- const after = current.nextSibling;
5135
- try {
5136
- parent.removeChild(current);
5137
- }
5138
- catch { }
5139
- if (current === close)
5140
- break;
5141
- current = after;
5142
- }
5143
- }
5144
- else {
5145
- try {
5146
- parent.removeChild(open);
5147
- }
5148
- catch { }
5149
- }
5150
- }
5151
- else if (parent) {
5152
- try {
5153
- parent.removeChild(node);
5154
- }
5155
- catch { }
5156
- }
5157
- const placeholder = this.motif.options?.placeholder;
5158
- if (placeholder && placeholder.parentNode) {
5159
- try {
5160
- placeholder.parentNode.removeChild(placeholder);
5161
- }
5162
- catch { }
5163
- }
5164
- };
5165
- immediate();
5166
- return;
5167
- }
5533
+ catch (error) {
5534
+ reportError('MJX107', error);
5168
5535
  }
5169
- catch { }
5170
- const removeNow = () => {
5171
- if (node.nodeType === Node.COMMENT_NODE) {
5172
- const open = node;
5173
- const close = this.motif.options?.closeFragment || null;
5174
- const parent = open.parentNode;
5175
- if (!parent)
5176
- return;
5177
- if (close) {
5178
- let current = open;
5179
- while (current) {
5180
- const after = current.nextSibling;
5181
- try {
5182
- parent.removeChild(current);
5183
- }
5184
- catch { }
5185
- if (current === close)
5186
- break;
5187
- current = after;
5188
- }
5189
- }
5190
- else {
5191
- try {
5192
- parent.removeChild(open);
5193
- }
5194
- catch { }
5195
- }
5196
- return;
5197
- }
5198
- const parent = node.parentNode;
5199
- if (parent) {
5200
- try {
5201
- parent.removeChild(node);
5202
- }
5203
- catch { }
5204
- return;
5205
- }
5206
- const placeholder = this.motif.options?.placeholder;
5207
- if (placeholder && placeholder.parentNode) {
5208
- try {
5209
- placeholder.parentNode.removeChild(placeholder);
5210
- }
5211
- catch { }
5212
- }
5213
- };
5536
+ }
5537
+ }
5538
+ const count = nodes.length;
5539
+ if (count > 1) {
5540
+ const heights = new Array(count).fill(0);
5541
+ for (let i = count - 1; i >= 1; i--) {
5542
+ const p = parents[i];
5543
+ if (heights[i] + 1 > heights[p])
5544
+ heights[p] = heights[i] + 1;
5545
+ }
5546
+ const order = [];
5547
+ for (let i = 1; i < count; i++)
5548
+ order.push(i);
5549
+ order.sort((a, b) => heights[a] - heights[b] || a - b);
5550
+ for (let k = 0; k < order.length; k++) {
5214
5551
  try {
5215
- this.motif.options.transition.leaveTransition(() => {
5216
- removeNow();
5217
- });
5552
+ disposeFinish(nodes[order[k]], childOptions, true);
5218
5553
  }
5219
- catch {
5220
- removeNow();
5221
- }
5222
- },
5223
- _detachDomWithAnimationAsync: async () => {
5224
- const node = this.element;
5225
- if (!node)
5226
- return Promise.resolve();
5227
- try {
5228
- const skip = this.motif.options.transition.skipNextLeave === true || this?._forceInstantDetach === true;
5229
- if (skip) {
5230
- if (this.motif.options.transition)
5231
- this.motif.options.transition.skipNextLeave = false;
5232
- this._forceInstantDetach = false;
5233
- const immediateRemove = () => {
5234
- if (node.nodeType === Node.COMMENT_NODE) {
5235
- const open = node;
5236
- const close = this.motif.options?.closeFragment || null;
5237
- const parent = open.parentNode;
5238
- if (!parent)
5239
- return;
5240
- if (close) {
5241
- let current = open;
5242
- while (current) {
5243
- const after = current.nextSibling;
5244
- try {
5245
- parent.removeChild(current);
5246
- }
5247
- catch { }
5248
- if (current === close)
5249
- break;
5250
- current = after;
5251
- }
5252
- }
5253
- else {
5254
- try {
5255
- parent.removeChild(open);
5256
- }
5257
- catch { }
5258
- }
5259
- }
5260
- else {
5261
- const parent = node.parentNode;
5262
- if (parent) {
5263
- try {
5264
- parent.removeChild(node);
5265
- }
5266
- catch { }
5267
- }
5268
- }
5269
- const placeholder = this.motif.options?.placeholder;
5270
- if (placeholder && placeholder.parentNode) {
5271
- try {
5272
- placeholder.parentNode.removeChild(placeholder);
5273
- }
5274
- catch { }
5275
- }
5276
- };
5277
- immediateRemove();
5278
- return Promise.resolve();
5279
- }
5554
+ catch (error) {
5555
+ reportError('MJX107', error);
5280
5556
  }
5281
- catch { }
5282
- const removeNow = () => {
5283
- if (node.nodeType === Node.COMMENT_NODE) {
5284
- const open = node;
5285
- const close = this.motif.options?.closeFragment || null;
5286
- const parent = open.parentNode;
5287
- if (!parent)
5288
- return;
5289
- if (close) {
5290
- let current = open;
5291
- while (current) {
5292
- const after = current.nextSibling;
5293
- try {
5294
- parent.removeChild(current);
5295
- }
5296
- catch { }
5297
- if (current === close)
5298
- break;
5299
- current = after;
5300
- }
5301
- }
5302
- else {
5303
- try {
5304
- parent.removeChild(open);
5305
- }
5306
- catch { }
5307
- }
5308
- return;
5309
- }
5310
- const parent = node.parentNode;
5311
- if (parent) {
5312
- try {
5313
- parent.removeChild(node);
5314
- }
5315
- catch { }
5316
- return;
5557
+ }
5558
+ }
5559
+ if (pending)
5560
+ return pending;
5561
+ if (!asChild && root.isDisposed) {
5562
+ return null;
5563
+ }
5564
+ disposeFinish(root, options, asChild);
5565
+ return null;
5566
+ }
5567
+ const BASE_PROTO = {
5568
+ _offAll() {
5569
+ const c = this.owner;
5570
+ if (!c._eventHandlers)
5571
+ return;
5572
+ for (const [full, set] of c._eventHandlers) {
5573
+ const name = full.split(":")[0];
5574
+ const evt = name.startsWith("on") ? name.slice(2).toLowerCase() : name.toLowerCase();
5575
+ for (const rec of set) {
5576
+ if (!rec || !rec.wrapped) {
5577
+ continue;
5317
5578
  }
5318
- const placeholder = this.motif.options?.placeholder;
5319
- if (placeholder && placeholder.parentNode) {
5320
- try {
5321
- placeholder.parentNode.removeChild(placeholder);
5322
- }
5323
- catch { }
5579
+ if (rec.domEvent === false) {
5580
+ continue;
5324
5581
  }
5325
- };
5326
- return new Promise((resolve) => {
5582
+ const cap = rec.capture === true;
5327
5583
  try {
5328
- this.motif.options.transition.leaveTransition(() => {
5329
- removeNow();
5330
- resolve();
5331
- });
5332
- }
5333
- catch {
5334
- removeNow();
5335
- resolve();
5584
+ c.element.removeEventListener(evt, rec.wrapped, cap);
5336
5585
  }
5337
- });
5338
- },
5339
- _disposeShallow: () => {
5340
- if (this.isDisposed)
5341
- return;
5342
- ComponentHelper.callDisposing.call(this, this);
5343
- try {
5344
- this._base._offAll();
5345
- }
5346
- catch {
5347
- }
5348
- this.motif.stopAnimations();
5349
- this._base._deactivateBindings();
5350
- if (this.controls?.items?.length) {
5351
- for (const c of this.controls.items) {
5352
- try {
5353
- c._base._disposeShallow();
5354
- }
5355
- catch {
5586
+ catch { }
5587
+ try {
5588
+ if (rec.capture === undefined) {
5589
+ c.element.removeEventListener(evt, rec.wrapped, !cap);
5356
5590
  }
5357
5591
  }
5592
+ catch { }
5358
5593
  }
5359
- ComponentHelper.callDisposed.call(this, this);
5360
- safeCall(() => { this._base.emiters.clear(); }, 'disposeShallow.emiters');
5361
- this.isDisposed = true;
5362
- super.dispose();
5363
- },
5364
- _deepCleanup: () => {
5365
- try {
5366
- this.parent = null;
5367
- }
5368
- catch { }
5369
- try {
5370
- this._eventHandlers?.clear();
5371
- }
5372
- catch {
5373
- }
5374
- // for (const c of this.controls.items) {
5375
- // try {
5376
- // } catch {
5377
- this._eventHandlers = undefined;
5378
- try {
5379
- this.class?._counts?.clear();
5380
- }
5381
- catch { }
5382
- try {
5383
- this.class?._watchers?.clear();
5384
- }
5385
- catch { }
5386
- try {
5387
- this.attr?._attrMap?.clear();
5388
- }
5389
- catch { }
5390
- try {
5391
- this.attr?._watchers?.clear();
5392
- }
5393
- catch { }
5394
- try {
5395
- if (this.motif.options) {
5396
- this.motif.options.cache = undefined;
5397
- this.motif.options.closeFragment = undefined;
5398
- this.motif.options.placeholder = undefined;
5399
- }
5400
- }
5401
- catch {
5402
- }
5403
- try {
5404
- this.element = null;
5405
- }
5406
- catch { }
5407
- try {
5408
- this.props = undefined;
5409
- }
5410
- catch { }
5411
- try {
5412
- this.childs = undefined;
5594
+ }
5595
+ c._eventHandlers.clear();
5596
+ c._eventHandlers = undefined;
5597
+ },
5598
+ _deactivateBindings() {
5599
+ const c = this.owner;
5600
+ try {
5601
+ c.bindings?.deactivateAll();
5602
+ }
5603
+ catch { }
5604
+ },
5605
+ _activateBindings() {
5606
+ const c = this.owner;
5607
+ try {
5608
+ c.bindings?.activateAll();
5609
+ }
5610
+ catch { }
5611
+ },
5612
+ _reactivateBindings() {
5613
+ const c = this.owner;
5614
+ try {
5615
+ c.bindings?.reActivateAll();
5616
+ }
5617
+ catch { }
5618
+ },
5619
+ _activatePreBindings() {
5620
+ if (this.prebinding_Activated)
5621
+ return;
5622
+ const c = this.owner;
5623
+ const registered = c.bindings?._items;
5624
+ if (registered && registered.length > 0) {
5625
+ c.bindings.items.filter((x) => x.propertyName == "isWait" || x.propertyName == "display").forEach((b) => {
5626
+ b.activate();
5627
+ });
5628
+ }
5629
+ this.prebinding_Activated = true;
5630
+ },
5631
+ _detachDomWithAnimation() {
5632
+ detachDomWithAnimation(this.owner);
5633
+ },
5634
+ _detachDomWithAnimationAsync() {
5635
+ return detachDomWithAnimationAsync(this.owner);
5636
+ },
5637
+ _disposeShallow() {
5638
+ disposeShallow(this.owner);
5639
+ },
5640
+ _deepCleanup() {
5641
+ deepCleanup(this.owner);
5642
+ },
5643
+ };
5644
+ function createBaseCtx(owner) {
5645
+ const base = Object.create(BASE_PROTO);
5646
+ base.owner = owner;
5647
+ base.prebinding_Activated = false;
5648
+ base.emiters = new ComponentEmiter(owner);
5649
+ return base;
5650
+ }
5651
+ const fragmentCloseMarkers = new WeakMap();
5652
+ const LIFECYCLE_X_EVENTS = new Set([
5653
+ 'building', 'built', 'initializing', 'initialized', 'disposing', 'disposed',
5654
+ 'config', 'configured', 'visibilitychanged', 'activated', 'deactivated'
5655
+ ]);
5656
+ const RAW_APPLICATION = Symbol('motif.rawApplication');
5657
+ const SCOPED_SUBSCRIBERS = new Set(['on', 'onRouterChanged']);
5658
+ /**
5659
+ * Uygulamanın bileşene bağlı görünümü. `on`/`onRouterChanged` aboneliklerini sahibin ömrüne
5660
+ * kaydeder; diğer tüm üyeler (alanlar, metotlar, atamalar) uygulamanın kendisine yönlenir.
5661
+ */
5662
+ function createScopedContext(app, owner) {
5663
+ const cache = new Map();
5664
+ return new Proxy(app, {
5665
+ get(target, prop) {
5666
+ if (prop === RAW_APPLICATION) {
5667
+ return target;
5413
5668
  }
5414
- catch { }
5415
- try {
5416
- this.class = undefined;
5669
+ const value = Reflect.get(target, prop, target);
5670
+ if (typeof value !== 'function') {
5671
+ return value;
5417
5672
  }
5418
- catch { }
5419
- try {
5420
- this.attr = undefined;
5673
+ const hit = cache.get(prop);
5674
+ if (hit && hit.fn === value) {
5675
+ return hit.bound;
5421
5676
  }
5422
- catch { }
5423
- try {
5424
- this.parent = null;
5677
+ const bound = SCOPED_SUBSCRIBERS.has(prop)
5678
+ ? (...args) => owner._trackContextSubscription(value.apply(target, args))
5679
+ : value.bind(target);
5680
+ cache.set(prop, { fn: value, bound });
5681
+ return bound;
5682
+ },
5683
+ set(target, prop, value) {
5684
+ return Reflect.set(target, prop, value, target);
5685
+ },
5686
+ });
5687
+ }
5688
+ class ComponentBase extends Disposable {
5689
+ motif = new ComponentMotif(this, new ComponentOptionsImpl(this));
5690
+ element;
5691
+ props;
5692
+ isBuilt = false;
5693
+ isInitialized = false;
5694
+ isDisposed = false;
5695
+ isConfigured = false;
5696
+ isPainting = false;
5697
+ isPainted = false;
5698
+ isVisible = true;
5699
+ controls = new ControlCollection(this);
5700
+ _eventHandlers;
5701
+ _isWait = false;
5702
+ class = new controlClass(this);
5703
+ attr = new controlAttribute(this);
5704
+ bindings = new BindingCollection(this);
5705
+ /** style(fn) izleyicisi: tek tek tutulur, yeniden çağrıda önceki durdurulur. */
5706
+ _styleFx;
5707
+ useModel(modelCtor) {
5708
+ return reactive(modelCtor);
5709
+ }
5710
+ _computeHideStrategy() {
5711
+ const cfg = this.motif.options?.hideStrategy ?? 'auto';
5712
+ if (cfg === 'placeholder')
5713
+ return 'placeholder';
5714
+ if (cfg === 'detach')
5715
+ return 'detach';
5716
+ if (this.motif.options?.__fromList || typeof this.motif.options?.indexkey !== 'undefined' || typeof this.motif.options?.__key !== 'undefined') {
5717
+ return 'detach';
5718
+ }
5719
+ return 'placeholder';
5720
+ }
5721
+ _isInDom() {
5722
+ try {
5723
+ if (!this.element)
5724
+ return false;
5725
+ const node = this.element;
5726
+ if (node.nodeType === Node.COMMENT_NODE) {
5727
+ return !!node.parentNode;
5425
5728
  }
5426
- catch { }
5427
- try {
5428
- this.motif.options = undefined;
5729
+ return !!node.parentNode;
5730
+ }
5731
+ catch {
5732
+ return false;
5733
+ }
5734
+ }
5735
+ set isWait(value) {
5736
+ this._isWait = value;
5737
+ if (this.isBuilt) {
5738
+ if (value) {
5739
+ this.motif.hide();
5429
5740
  }
5430
- catch { }
5431
- Object.entries(this).forEach(([key, value]) => {
5432
- if (key === 'motif')
5433
- return;
5434
- try {
5435
- this[key] = null;
5436
- delete this[key];
5437
- }
5438
- catch {
5741
+ else {
5742
+ this.motif.show();
5743
+ }
5744
+ return;
5745
+ }
5746
+ if (value === false && this.parent && this.parent.isBuilt) {
5747
+ ComponentHelper.internalBuild.call(this.parent, this);
5748
+ }
5749
+ }
5750
+ get isWait() {
5751
+ return this._isWait;
5752
+ }
5753
+ constructor(element, props = {}) {
5754
+ super();
5755
+ recordServiceOwner(this);
5756
+ if (this.onElementCreating) {
5757
+ this.element = this.onElementCreating.call(this);
5758
+ }
5759
+ else if (props?.onElementCreating) {
5760
+ this.element = props.onElementCreating.call(this);
5761
+ }
5762
+ else {
5763
+ this.element = element;
5764
+ }
5765
+ if (props) {
5766
+ const refs = extractRefs(props, this);
5767
+ if (refs.length > 0) {
5768
+ for (const fn of takePendingRefs(this, refs)) {
5769
+ callReported(() => fn(this), 'MJX122', 'ref');
5439
5770
  }
5440
- });
5441
- this.isDisposed = true;
5442
- },
5443
- emiters: new ComponentEmiter(this)
5444
- };
5771
+ }
5772
+ }
5773
+ props && ParseProps(props, this);
5774
+ applyComponentOptions(props?.options, this);
5775
+ this.props = props;
5776
+ // (class/style/id/tabindex/role/aria-*/data-*) kök düğüme (root node) düşer, prop'lar this.props'ta kalır.
5777
+ if (props) {
5778
+ const ctor0 = new.target;
5779
+ const plain = ctor0 === ComponentBase || Object.getPrototypeOf(ctor0) === ComponentBase;
5780
+ if (plain)
5781
+ applyPlainElementProps(props, this);
5782
+ else
5783
+ applyFallthroughProps(props, this);
5784
+ }
5785
+ ComponentHelper.callOnInitializing(this);
5786
+ if (this.isDisposed)
5787
+ return;
5788
+ this.controls.onAdd = (c) => {
5789
+ if (this._eventHandlers?.has('controladded'))
5790
+ this.motif.trigger('controladded', { control: c });
5791
+ if (this.isWait || this.parent?.isWait)
5792
+ return;
5793
+ ComponentHelper.internalBuild.call(this, c);
5794
+ };
5795
+ this.controls.onAddBeforeBuild = (c) => {
5796
+ if (this._eventHandlers?.has('controladded'))
5797
+ this.motif.trigger('controladded', { control: c });
5798
+ };
5799
+ this.controls.onRemove = (c) => {
5800
+ if (this._eventHandlers?.has('controlremoved'))
5801
+ this.motif.trigger('controlremoved', { control: c });
5802
+ };
5803
+ ComponentHelper.callOnInitialized(this);
5804
+ const ctor = new.target;
5805
+ const isBaseCtor = ctor === ComponentBase || Object.getPrototypeOf(ctor) === ComponentBase;
5806
+ if (isBaseCtor) {
5807
+ ComponentHelper.callConfig(this);
5808
+ }
5809
+ else {
5810
+ this._base._configDeferred = true;
5811
+ }
5812
+ }
5813
+ childs;
5814
+ _base = createBaseCtx(this);
5445
5815
  parent = null;
5446
5816
  _scopedContext;
5447
5817
  get context() {
@@ -5477,6 +5847,9 @@
5477
5847
  return;
5478
5848
  }
5479
5849
  ComponentHelper.callBuilding(this);
5850
+ if (this.isDisposed) {
5851
+ return;
5852
+ }
5480
5853
  var ph = this.element;
5481
5854
  if (building) {
5482
5855
  ph = dom.createDocumentFragment();
@@ -5491,9 +5864,15 @@
5491
5864
  return;
5492
5865
  }
5493
5866
  ComponentHelper.callInitializeComponent(this);
5867
+ if (this.isDisposed) {
5868
+ return;
5869
+ }
5494
5870
  if (this.view) {
5495
5871
  const templ = this.view();
5496
5872
  this.controls.add(templ);
5873
+ if (this.isDisposed) {
5874
+ return;
5875
+ }
5497
5876
  }
5498
5877
  const deferredSelectValue = this.element?.nodeName === 'SELECT'
5499
5878
  ? this.bindings.items.filter(b => b.propertyName === 'value')
@@ -5534,6 +5913,9 @@
5534
5913
  ComponentHelper.activateTree(element);
5535
5914
  }
5536
5915
  }
5916
+ if (this.isDisposed) {
5917
+ return;
5918
+ }
5537
5919
  if (wantsEnterTransition(this)) {
5538
5920
  const node = this.element;
5539
5921
  if (node && node.isConnected) {
@@ -5717,7 +6099,20 @@
5717
6099
  if (this.isVisible) {
5718
6100
  return;
5719
6101
  } /* A*/
5720
- if (this.motif.options?.transition?.activeAnimations?.length) {
6102
+ if (this.parent && enterModeOf(this.parent) === 'out-in') {
6103
+ const showHost = (this.motif.options.placeholder?.parentNode)
6104
+ ?? findAppendableComponent(this.parent)?.element;
6105
+ const wait = pendingLeaves(showHost, this.element);
6106
+ if (wait) {
6107
+ const seq = this._base._showSeq = (this._base._showSeq ?? 0) + 1;
6108
+ return wait.then(() => {
6109
+ if (this.isDisposed || this._base._showSeq !== seq)
6110
+ return;
6111
+ return this._show();
6112
+ });
6113
+ }
6114
+ }
6115
+ if (peekTransition(this)?.activeAnimations?.length) {
5721
6116
  safeCall(async () => {
5722
6117
  await Promise.all(this.motif.options.transition.activeAnimations.map(a => a.finished?.catch(() => { })));
5723
6118
  }, 'show.waitForLeaveAnimations');
@@ -5726,6 +6121,9 @@
5726
6121
  const strategy = this._computeHideStrategy();
5727
6122
  if (strategy === 'detach') {
5728
6123
  ComponentHelper.callVisibilityChanged(this);
6124
+ if (this.isDisposed) {
6125
+ return;
6126
+ }
5729
6127
  const needAttach = !this._isInDom() && this.parent && this.parent.isBuilt && !this.isWait;
5730
6128
  this.isVisible = true;
5731
6129
  if (needAttach) {
@@ -5748,6 +6146,9 @@
5748
6146
  /** A*/
5749
6147
  wantsEnterTransition(this) && this.motif.options.transition.enterTransition(() => { });
5750
6148
  ComponentHelper.callVisibilityChanged(this);
6149
+ if (this.isDisposed) {
6150
+ return;
6151
+ }
5751
6152
  if (this.element.nodeType === Node.COMMENT_NODE) {
5752
6153
  this.controls.forEach(c => {
5753
6154
  c.motif.show();
@@ -5768,12 +6169,16 @@
5768
6169
  if (this.isDisposed || !this.element) {
5769
6170
  return;
5770
6171
  }
6172
+ this._base._showSeq = (this._base._showSeq ?? 0) + 1;
5771
6173
  if (!this.isVisible) {
5772
6174
  return;
5773
6175
  }
5774
6176
  const strategy = this._computeHideStrategy();
5775
6177
  if (strategy === 'detach') {
5776
6178
  ComponentHelper.callVisibilityChanged(this);
6179
+ if (this.isDisposed) {
6180
+ return;
6181
+ }
5777
6182
  await this._base._detachDomWithAnimationAsync();
5778
6183
  this.isVisible = false;
5779
6184
  ComponentHelper.deactivateTree(this);
@@ -5786,6 +6191,9 @@
5786
6191
  transition.skipNextLeave = false;
5787
6192
  const finish = () => {
5788
6193
  ComponentHelper.callVisibilityChanged(this);
6194
+ if (this.isDisposed) {
6195
+ return;
6196
+ }
5789
6197
  if (this.element.nodeType === Node.COMMENT_NODE) {
5790
6198
  this.controls.forEach(c => {
5791
6199
  if (skip && c.isVisible && c.element && !c.isDisposed && c.motif.options?.transition) {
@@ -5995,109 +6403,43 @@
5995
6403
  if (this.isDisposed) {
5996
6404
  return Promise.resolve();
5997
6405
  }
5998
- if (!this._disposing) {
5999
- retireServiceOwner(this);
6000
- }
6001
- return this._disposing ??= this._disposeCore(options);
6002
- }
6003
- async _disposeCore(options) {
6004
- if (options?.skipLeaveTransition) {
6005
- this.motif.options.transition.skipNextLeave = true;
6006
- }
6007
- safeCall(() => {
6008
- ComponentHelper.callDisposing.call(this, this);
6009
- }, 'dispose.callDisposing');
6010
- // DOM dinleyicileri hemen sökülür, aşağıda isDisposed true olunca off() boşa döner,
6011
- // element null'lanınca da _offAll dom'dan sökülemez — DOM'dan çıkmış öğeye sonradan gelen
6012
- this._base._offAll();
6013
- this._base._deactivateBindings();
6014
- safeCall(() => {
6015
- this.parent?.controls?.silentDetach?.(this, true);
6016
- }, 'dispose.silentDetach');
6017
- this.motif.options.transition.skipNextLeave && await this.motif.stopAnimations();
6018
- await this._base._detachDomWithAnimationAsync();
6019
- if (this.constructor.name !== 'TransportTo') {
6020
- await disposeContentBlocks(this);
6021
- }
6022
- await safeCallAsync(async () => {
6023
- if (this.isDisposed) {
6024
- return;
6025
- }
6026
- const ctrls = Array.from(this.controls.items);
6027
- if (ctrls.length) {
6028
- await Promise.all(ctrls.map(async (c) => {
6029
- try {
6030
- await c.disposeAsync({ deep: options?.deep });
6031
- }
6032
- catch (error) {
6033
- reportError('MJX107', error);
6034
- }
6035
- }));
6406
+ if (this._disposing) {
6407
+ return this._disposing;
6408
+ }
6409
+ retireServiceOwner(this);
6410
+ this._disposing = DISPOSE_STARTED;
6411
+ return this._disposing = this._disposeCore(options, false);
6412
+ }
6413
+ async _disposeCore(options, asChild) {
6414
+ disposePrefix(this, options, asChild);
6415
+ let leave;
6416
+ if (!asChild && !peekTransition(this)?.skipNextLeave) {
6417
+ leave = this._base._detachDomWithAnimationAsync();
6418
+ }
6419
+ await undefined;
6420
+ if (contentBlocks.live === 0 && subtreeDisposesSync(this, true)) {
6421
+ const pending = disposeRemainderSync(this, options, asChild, leave !== undefined);
6422
+ if (pending) {
6423
+ await Promise.all(pending);
6424
+ if (!asChild && this.isDisposed) {
6425
+ return;
6426
+ }
6427
+ disposeFinish(this, options, asChild);
6036
6428
  }
6037
- }, 'dispose.disposeAsync');
6038
- if (this.isDisposed) {
6039
6429
  return;
6040
6430
  }
6041
- this.isDisposed = true;
6042
- super.dispose();
6043
- this.element = null;
6044
- //if (options?.deep) {
6045
- safeCall(() => {
6046
- ComponentHelper.callDisposed.call(this, this);
6047
- }, 'dispose.callDisposed');
6048
- safeCall(() => { this._base.emiters.clear(); }, 'dispose.emiters');
6049
- this._base._offAll();
6050
- this._base._deepCleanup();
6051
- // var k = Object.keys(this);
6052
- // for (var i = 0; i < k.length; i++) {
6053
- // try {
6054
- // } catch {
6431
+ await disposeRemainderAsync(this, options, asChild, leave);
6055
6432
  }
6056
6433
  disposeAsync(options = { deep: true }) {
6057
6434
  if (this.isDisposed) {
6058
6435
  return Promise.resolve();
6059
6436
  }
6060
- if (!this._disposing) {
6061
- retireServiceOwner(this);
6062
- }
6063
- return this._disposing ??= this._disposeAsyncCore(options);
6064
- }
6065
- async _disposeAsyncCore(options) {
6066
- safeCall(() => {
6067
- ComponentHelper.callDisposing.call(this, this);
6068
- }, 'disposeAsync.callDisposing');
6069
- this._base._offAll();
6070
- this._base._deactivateBindings();
6071
- safeCall(() => {
6072
- this.parent?.controls?.silentDetach?.(this, true);
6073
- }, 'disposeAsync.silentDetach');
6074
- await this.motif.stopAnimations();
6075
- await this._base._detachDomWithAnimationAsync();
6076
- await safeCallAsync(async () => {
6077
- if (this.isDisposed) {
6078
- return;
6079
- }
6080
- const ctrls = Array.from(this.controls.items);
6081
- if (ctrls.length) {
6082
- await Promise.all(ctrls.map(c => safeCallAsync(async () => {
6083
- await c.disposeAsync({ deep: options?.deep });
6084
- }, 'disposeAsync.disposeAsyncChildren.handler')));
6085
- }
6086
- }, 'disposeAsync.disposeAsyncChildren');
6087
- this.isDisposed = true;
6088
- super.dispose();
6089
- this.controls.items = [];
6090
- safeCall(() => {
6091
- ComponentHelper.callDisposed.call(this, this);
6092
- }, 'disposeAsync.callDisposed');
6093
- safeCall(() => { this._base.emiters.clear(); }, 'disposeAsync.emiters');
6094
- if (options?.deep) {
6095
- this._base._deepCleanup();
6437
+ if (this._disposing) {
6438
+ return this._disposing;
6096
6439
  }
6097
- // var k = Object.keys(this);
6098
- // for (var i = 0; i < k.length; i++) {
6099
- // try {
6100
- // } catch { }
6440
+ retireServiceOwner(this);
6441
+ this._disposing = DISPOSE_STARTED;
6442
+ return this._disposing = this._disposeCore(options, true);
6101
6443
  }
6102
6444
  async _clear() {
6103
6445
  if (this.isDisposed == true) {
@@ -6127,33 +6469,50 @@
6127
6469
  }
6128
6470
  });
6129
6471
  }
6130
- siblings = {
6131
- all: () => { return this.parent?.controls.items; },
6132
- next: () => {
6133
- if (!this.parent)
6134
- return undefined;
6135
- const idx = this.parent.controls.items.indexOf(this);
6136
- return this.parent.controls.items[idx + 1];
6137
- },
6138
- prev: () => {
6139
- if (!this.parent)
6140
- return undefined;
6141
- const idx = this.parent.controls.items.indexOf(this);
6142
- return this.parent.controls.items[idx - 1];
6143
- },
6144
- nextAll: () => {
6145
- if (!this.parent)
6146
- return undefined;
6147
- const idx = this.parent.controls.items.indexOf(this);
6148
- return this.parent.controls.items.slice(idx + 1);
6149
- },
6150
- prevAll: () => {
6151
- if (!this.parent)
6152
- return undefined;
6153
- const idx = this.parent.controls.items.indexOf(this);
6154
- return this.parent.controls.items.slice(0, idx);
6472
+ _siblingsApi;
6473
+ _siblingsSet;
6474
+ get siblings() {
6475
+ if (this._siblingsSet) {
6476
+ return this._siblingsApi;
6155
6477
  }
6156
- };
6478
+ if (this.isDisposed && !this.motif?.options) {
6479
+ return this._siblingsApi;
6480
+ }
6481
+ return this._siblingsApi ??= this._createSiblingsApi();
6482
+ }
6483
+ set siblings(value) {
6484
+ this._siblingsApi = value;
6485
+ this._siblingsSet = true;
6486
+ }
6487
+ _createSiblingsApi() {
6488
+ return {
6489
+ all: () => { return this.parent?.controls.items; },
6490
+ next: () => {
6491
+ if (!this.parent)
6492
+ return undefined;
6493
+ const idx = this.parent.controls.items.indexOf(this);
6494
+ return this.parent.controls.items[idx + 1];
6495
+ },
6496
+ prev: () => {
6497
+ if (!this.parent)
6498
+ return undefined;
6499
+ const idx = this.parent.controls.items.indexOf(this);
6500
+ return this.parent.controls.items[idx - 1];
6501
+ },
6502
+ nextAll: () => {
6503
+ if (!this.parent)
6504
+ return undefined;
6505
+ const idx = this.parent.controls.items.indexOf(this);
6506
+ return this.parent.controls.items.slice(idx + 1);
6507
+ },
6508
+ prevAll: () => {
6509
+ if (!this.parent)
6510
+ return undefined;
6511
+ const idx = this.parent.controls.items.indexOf(this);
6512
+ return this.parent.controls.items.slice(0, idx);
6513
+ }
6514
+ };
6515
+ }
6157
6516
  get serviceProvider() {
6158
6517
  let c = this;
6159
6518
  while (c) {
@@ -6235,14 +6594,15 @@
6235
6594
  return result;
6236
6595
  }
6237
6596
  async _stopAnimations() {
6597
+ const t = peekTransition(this);
6238
6598
  try {
6239
- this.motif.options?.transition?.activeCssCancel?.();
6599
+ t?.activeCssCancel?.();
6240
6600
  }
6241
6601
  catch { }
6242
6602
  try {
6243
- if (this.motif.options?.transition?.activeAnimations?.length) {
6603
+ if (t?.activeAnimations?.length) {
6244
6604
  try {
6245
- await Promise.all(this.motif.options.transition.activeAnimations.map(a => a.finished?.catch(() => { })));
6605
+ await Promise.all(t.activeAnimations.map(a => a.finished?.catch(() => { })));
6246
6606
  }
6247
6607
  catch { /* ignore */ }
6248
6608
  }
@@ -6251,7 +6611,8 @@
6251
6611
  }
6252
6612
  if (this.isDisposed)
6253
6613
  return;
6254
- this.motif.options.transition.activeAnimations = [];
6614
+ if (t)
6615
+ t.activeAnimations = [];
6255
6616
  }
6256
6617
  }
6257
6618
  function findContentBlocks(root, results = []) {
@@ -6266,8 +6627,10 @@
6266
6627
  return results;
6267
6628
  }
6268
6629
  async function disposeContentBlocks(root) {
6269
- const contentBlocks = findContentBlocks(root);
6270
- return await Promise.all(contentBlocks.map(async (block) => {
6630
+ if (contentBlocks.live === 0)
6631
+ return;
6632
+ const contentBlocks$1 = findContentBlocks(root);
6633
+ return await Promise.all(contentBlocks$1.map(async (block) => {
6271
6634
  block.motif.options.transition.skipNextLeave = root.motif.options.transition.skipNextLeave;
6272
6635
  for (const element of block.controls.items) {
6273
6636
  element.motif.options.transition.skipNextLeave = block.motif.options.transition.skipNextLeave;
@@ -6322,7 +6685,7 @@
6322
6685
  runover.ref = component;
6323
6686
  }
6324
6687
  }
6325
- return [].concat(...refs);
6688
+ return refs.length === 0 ? refs : [].concat(...refs);
6326
6689
  }
6327
6690
  const LIFECYCLE_HANDLER_LISTS = {
6328
6691
  'initializecomponent': '_initializeComponentHandlers',
@@ -6365,6 +6728,8 @@
6365
6728
  Object.assign(component.motif.options.props, props);
6366
6729
  }
6367
6730
  var keys = Object.keys(props);
6731
+ if (keys.length === 0)
6732
+ return;
6368
6733
  keys.forEach(key => {
6369
6734
  if (key == 'initializeComponent' || key == 'oninitializeComponent' || key.startsWith('on')) {
6370
6735
  if (collectLifecycleHandlers(component, key.toLowerCase(), props[key])) {
@@ -6435,7 +6800,18 @@
6435
6800
  if (typeof value.name === 'string' && value.name.length > 0) {
6436
6801
  transition.name = value.name;
6437
6802
  }
6438
- transition.classes = value;
6803
+ if (!('mode' in value)) {
6804
+ transition.classes = value;
6805
+ }
6806
+ else {
6807
+ const { mode, ...classes } = value;
6808
+ if (isTransitionMode(mode)) {
6809
+ transition.mode = mode;
6810
+ }
6811
+ if (Object.keys(classes).length > 0) {
6812
+ transition.classes = classes;
6813
+ }
6814
+ }
6439
6815
  }
6440
6816
  else if (live) {
6441
6817
  transition.name = '';
@@ -6487,17 +6863,45 @@
6487
6863
  'ref', 'key', 'indexkey', 'inject', 'options', 'props', 'settings', 'isSvg',
6488
6864
  'childs', 'initializeComponent', 'runover', 'transition', 'preconfig', 'nodes', 'onElementCreating'
6489
6865
  ]);
6866
+ const SPREAD_URL_ATTRIBUTES = new Set(['href', 'src', 'action', 'formaction', 'xlink:href']);
6867
+ const JAVASCRIPT_URL = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;
6868
+ function isJavascriptUrl(value) {
6869
+ if (value === undefined || value === null || typeof value === 'boolean')
6870
+ return false;
6871
+ try {
6872
+ return JAVASCRIPT_URL.test(String(value));
6873
+ }
6874
+ catch {
6875
+ return false;
6876
+ }
6877
+ }
6878
+ function guardSpreadUrl(key, read) {
6879
+ return () => {
6880
+ let value = read();
6881
+ if (typeof value === 'function')
6882
+ value = value();
6883
+ if (typeof value === 'function')
6884
+ value = value();
6885
+ if (!isJavascriptUrl(value))
6886
+ return value;
6887
+ reportWarning('MJX125', [key]);
6888
+ return null;
6889
+ };
6890
+ }
6490
6891
  function applyPlainElementProps(props, component) {
6491
6892
  if (!props || typeof props !== 'object' || component.isDisposed)
6492
6893
  return;
6493
- const attrs = {};
6494
- const applied = appliedDomProps(component);
6495
- for (const key of Object.keys(props)) {
6894
+ const keys = Object.keys(props);
6895
+ if (keys.length === 0)
6896
+ return;
6897
+ let attrs = null;
6898
+ let applied = null;
6899
+ for (const key of keys) {
6496
6900
  if (PLAIN_ELEMENT_SKIP.has(key))
6497
6901
  continue;
6498
6902
  if (key.startsWith('x-') || key.startsWith('x:') || key.startsWith('__'))
6499
6903
  continue;
6500
- const v = props[key];
6904
+ let v = props[key];
6501
6905
  if (v === undefined)
6502
6906
  continue;
6503
6907
  if (/^on/i.test(key)) {
@@ -6507,7 +6911,20 @@
6507
6911
  }
6508
6912
  if (typeof v === 'function' && v.length > 0)
6509
6913
  continue;
6510
- applied.set(key, v);
6914
+ if (key === 'innerHTML') {
6915
+ reportWarning('MJX124', []);
6916
+ continue;
6917
+ }
6918
+ if (SPREAD_URL_ATTRIBUTES.has(key.toLowerCase())) {
6919
+ if (typeof v === 'function') {
6920
+ v = guardSpreadUrl(key, v);
6921
+ }
6922
+ else if (isJavascriptUrl(v)) {
6923
+ reportWarning('MJX125', [key]);
6924
+ continue;
6925
+ }
6926
+ }
6927
+ (applied ??= appliedDomProps(component)).set(key, v);
6511
6928
  if (key === 'class' || key === 'className') {
6512
6929
  component.class.add(v && typeof v === 'object' && !Array.isArray(v) ? [v] : v);
6513
6930
  }
@@ -6518,10 +6935,10 @@
6518
6935
  component.bindings.add(key, v);
6519
6936
  }
6520
6937
  else {
6521
- attrs[key] = v;
6938
+ (attrs ??= {})[key] = v;
6522
6939
  }
6523
6940
  }
6524
- if (Object.keys(attrs).length > 0)
6941
+ if (attrs)
6525
6942
  component.attr.add(attrs);
6526
6943
  }
6527
6944
  const _appliedDomProps = new WeakMap();
@@ -6541,8 +6958,8 @@
6541
6958
  function applyFallthroughProps(props, component) {
6542
6959
  if (!props || typeof props !== 'object' || component.isDisposed)
6543
6960
  return;
6544
- const applied = appliedDomProps(component);
6545
- const subset = {};
6961
+ const applied = _appliedDomProps.get(component);
6962
+ let subset = null;
6546
6963
  for (const key of Object.keys(props)) {
6547
6964
  if (!isFallthroughKey(key))
6548
6965
  continue;
@@ -6551,11 +6968,11 @@
6551
6968
  continue;
6552
6969
  if (typeof v === 'function' && v.length > 0)
6553
6970
  continue;
6554
- if (applied.has(key) && Object.is(applied.get(key), v))
6971
+ if (applied && applied.has(key) && Object.is(applied.get(key), v))
6555
6972
  continue;
6556
- subset[key] = v;
6973
+ (subset ??= {})[key] = v;
6557
6974
  }
6558
- if (Object.keys(subset).length > 0)
6975
+ if (subset)
6559
6976
  applyPlainElementProps(subset, component);
6560
6977
  }
6561
6978
  const componentMethods = {
@@ -7074,7 +7491,6 @@
7074
7491
  }
7075
7492
 
7076
7493
  // import { dom } from "../browser";
7077
- // import { effect } from "../store";
7078
7494
  class ControlCollection {
7079
7495
  owner;
7080
7496
  constructor(owner) {
@@ -7082,9 +7498,16 @@
7082
7498
  }
7083
7499
  items = [];
7084
7500
  add() {
7085
- const args = Array.from(arguments);
7086
- if (args.length === 0)
7501
+ const count = arguments.length;
7502
+ if (count === 0)
7087
7503
  return [];
7504
+ const first = arguments[0];
7505
+ if (count === 1 && first instanceof ComponentBase) {
7506
+ if (first.isDisposed)
7507
+ return [];
7508
+ return [this._insertOne(undefined, first)];
7509
+ }
7510
+ const args = Array.from(arguments);
7088
7511
  if (typeof args[0] === 'number' && args.length > 1) {
7089
7512
  const index = args[0];
7090
7513
  const children = [].concat(...args.slice(1));
@@ -7097,42 +7520,43 @@
7097
7520
  }
7098
7521
  insert(index, ...controls) {
7099
7522
  const flat = [].concat(...controls);
7100
- return flat.filter(x => x != undefined && !x.isDisposed).map(control => {
7101
- control = resolveComponent(control);
7102
- if (typeof control == 'string' || typeof control == 'number' || typeof control == 'boolean' || typeof control == 'bigint') {
7103
- control = new Component(dom.createTextNode(control), null);
7104
- }
7105
- if (control.parent) {
7106
- control.parent.controls.detach(control);
7107
- }
7108
- if (index != undefined && index >= 0) {
7109
- this.items.splice(index, 0, control);
7110
- }
7111
- else {
7112
- this.items.push(control);
7113
- }
7114
- control.parent = this.owner;
7115
- const pendingLeave = control.__pendingLeave;
7116
- if (pendingLeave) {
7117
- if (this.onAddBeforeBuild && !this.owner.isBuilt) {
7118
- this.onAddBeforeBuild(control);
7119
- }
7120
- pendingLeave.promise.then(() => {
7121
- if (control.isDisposed || this.owner.isDisposed || control.parent !== this.owner)
7122
- return;
7123
- if (this.onAdd && this.owner.isBuilt)
7124
- this.onAdd(control);
7125
- });
7126
- return control;
7127
- }
7128
- if (this.onAdd && this.owner.isBuilt) {
7129
- this.onAdd(control);
7130
- }
7523
+ return flat.filter(x => x != undefined && !x.isDisposed).map(control => this._insertOne(index, control));
7524
+ }
7525
+ _insertOne(index, control) {
7526
+ control = resolveComponent(control);
7527
+ if (typeof control == 'string' || typeof control == 'number' || typeof control == 'boolean' || typeof control == 'bigint') {
7528
+ control = new Component(dom.createTextNode(control), null);
7529
+ }
7530
+ if (control.parent) {
7531
+ control.parent.controls.detach(control);
7532
+ }
7533
+ if (index != undefined && index >= 0) {
7534
+ this.items.splice(index, 0, control);
7535
+ }
7536
+ else {
7537
+ this.items.push(control);
7538
+ }
7539
+ control.parent = this.owner;
7540
+ const pendingLeave = control.__pendingLeave;
7541
+ if (pendingLeave) {
7131
7542
  if (this.onAddBeforeBuild && !this.owner.isBuilt) {
7132
7543
  this.onAddBeforeBuild(control);
7133
7544
  }
7545
+ pendingLeave.promise.then(() => {
7546
+ if (control.isDisposed || this.owner.isDisposed || control.parent !== this.owner)
7547
+ return;
7548
+ if (this.onAdd && this.owner.isBuilt)
7549
+ this.onAdd(control);
7550
+ });
7134
7551
  return control;
7135
- });
7552
+ }
7553
+ if (this.onAdd && this.owner.isBuilt) {
7554
+ this.onAdd(control);
7555
+ }
7556
+ if (this.onAddBeforeBuild && !this.owner.isBuilt) {
7557
+ this.onAddBeforeBuild(control);
7558
+ }
7559
+ return control;
7136
7560
  }
7137
7561
  remove(control) {
7138
7562
  var index = this.items.indexOf(control);
@@ -7151,6 +7575,7 @@
7151
7575
  this.items.splice(index, 1);
7152
7576
  if (control.isDisposed)
7153
7577
  return Promise.resolve();
7578
+ control._base && (control._base._leaveContainer = this.owner);
7154
7579
  control.parent = null;
7155
7580
  return runLeaveThenDetach(control, () => { if (this.onRemove)
7156
7581
  this.onRemove(control); });
@@ -7180,6 +7605,7 @@
7180
7605
  if (index === -1)
7181
7606
  return;
7182
7607
  this.items.splice(index, 1);
7608
+ control._base && (control._base._leaveContainer = this.owner);
7183
7609
  control.parent = null;
7184
7610
  }
7185
7611
  async clearAsync() {
@@ -7442,7 +7868,12 @@
7442
7868
  arrive();
7443
7869
  };
7444
7870
  try {
7445
- c.motif.options.transition.leaveTransition(once);
7871
+ const opts = c.motif.options;
7872
+ if (!opts[TRANSITION_SLOT] && !opts.transitionOut) {
7873
+ once();
7874
+ return;
7875
+ }
7876
+ opts.transition.leaveTransition(once);
7446
7877
  }
7447
7878
  catch {
7448
7879
  once();
@@ -7668,7 +8099,7 @@
7668
8099
  frame.navigate(resolveComponent(opts.Fallbackview));
7669
8100
  }
7670
8101
  else {
7671
- errorHandler.reportSuppressed('Lazy.load (no Fallbackview)', err);
8102
+ reportError('MJX126', err);
7672
8103
  try {
7673
8104
  frame.motif.clear().catch(() => { });
7674
8105
  }
@@ -7678,6 +8109,20 @@
7678
8109
  return frame;
7679
8110
  }
7680
8111
 
8112
+ function hasOwnTransition(component, phase) {
8113
+ const options = component?.motif?.options;
8114
+ if (!options)
8115
+ return false;
8116
+ const transition = options.transition;
8117
+ return !!((phase === 'enter' ? options.transitionIn : options.transitionOut) || (transition && (transition.classes || (transition.name && transition.name.length > 0))));
8118
+ }
8119
+ function playsLeave(target) {
8120
+ if (!target)
8121
+ return false;
8122
+ if (Array.isArray(target))
8123
+ return target.some(t => !!t && !t.isDisposed && hasOwnTransition(t, 'leave'));
8124
+ return !target.isDisposed && hasOwnTransition(target, 'leave');
8125
+ }
7681
8126
  function cancelAnimationsDeep(target) {
7682
8127
  if (!target || target.isDisposed)
7683
8128
  return;
@@ -7713,26 +8158,20 @@
7713
8158
  }
7714
8159
  catch { }
7715
8160
  }
7716
- async function disposeNavigationTarget(target) {
8161
+ async function disposeNavigationTarget(target, options = { deep: true }) {
7717
8162
  if (!target)
7718
8163
  return;
7719
- if (Array.isArray(target)) {
7720
- for (const xr of target) {
7721
- try {
7722
- if (xr && !xr.isDisposed) {
7723
- await xr.dispose({ deep: true, skipLeaveTransition: true });
7724
- }
7725
- }
7726
- catch (err) {
7727
- reportError('MJX115', err);
7728
- }
8164
+ const list = Array.isArray(target) ? target : [target];
8165
+ await Promise.all(list.map(async (xr) => {
8166
+ if (!xr || xr.isDisposed)
8167
+ return;
8168
+ try {
8169
+ await xr.dispose(options);
7729
8170
  }
7730
- }
7731
- else {
7732
- if (!target.isDisposed) {
7733
- await target.dispose({ deep: true, skipLeaveTransition: true });
8171
+ catch (err) {
8172
+ reportError('MJX115', err);
7734
8173
  }
7735
- }
8174
+ }));
7736
8175
  }
7737
8176
  async function navigateHost(host, page, keepOldControl = false) {
7738
8177
  if (host.isDisposed || page == null)
@@ -7786,10 +8225,14 @@
7786
8225
  if (oldPage && !keepOldControl) {
7787
8226
  cancelAnimationsDeep(oldPage);
7788
8227
  cancelAnimationsDeep(host);
7789
- try {
7790
- await disposeNavigationTarget(oldPage);
8228
+ const animated = playsLeave(oldPage);
8229
+ const leaving = disposeNavigationTarget(oldPage);
8230
+ if (animated) {
8231
+ leaving.catch(() => { });
8232
+ }
8233
+ else {
8234
+ await leaving;
7791
8235
  }
7792
- catch { }
7793
8236
  }
7794
8237
  try {
7795
8238
  if (page instanceof Promise) {
@@ -7825,9 +8268,9 @@
7825
8268
  this.controls.add(props.childs);
7826
8269
  }
7827
8270
  }
7828
- async dispose() {
7829
- await disposeNavigationTarget(this.current);
7830
- await super.dispose();
8271
+ async dispose(options = { deep: true }) {
8272
+ await disposeNavigationTarget(this.current, options);
8273
+ await super.dispose(options);
7831
8274
  }
7832
8275
  async flush() {
7833
8276
  await disposeNavigationTarget(this.current);
@@ -7867,20 +8310,16 @@
7867
8310
  // } else {
7868
8311
  // var cb = ContentBodyCollectionHandable.get(props.target);
7869
8312
  // if (cb) {
7870
- this.controls.onAdd = (control) => {
7871
- var cb = ContentBodyCollectionHandable.get(this.props.target);
7872
- if (cb) {
7873
- control.motif.options["ownerContentBlock"] = this;
7874
- cb.controls.add(control);
7875
- }
7876
- };
7877
- this.controls.onAddBeforeBuild = (control) => {
8313
+ const forward = (control) => {
8314
+ this.motif.trigger('controladded', { control });
7878
8315
  var cb = ContentBodyCollectionHandable.get(this.props.target);
7879
8316
  if (cb) {
7880
8317
  control.motif.options["ownerContentBlock"] = this;
7881
8318
  cb.controls.add(control);
7882
8319
  }
7883
8320
  };
8321
+ this.controls.onAdd = forward;
8322
+ this.controls.onAddBeforeBuild = forward;
7884
8323
  if (this.childs) {
7885
8324
  this.controls.add(...this.childs);
7886
8325
  }
@@ -7924,7 +8363,9 @@
7924
8363
  this.context.fire(changeBodyCollectionHandler);
7925
8364
  }
7926
8365
  ondisposing(sender) {
7927
- ContentBodyCollectionHandable.delete(this.props.name);
8366
+ if (ContentBodyCollectionHandable.get(this.props.name) === this) {
8367
+ ContentBodyCollectionHandable.delete(this.props.name);
8368
+ }
7928
8369
  }
7929
8370
  }
7930
8371
 
@@ -7956,7 +8397,7 @@
7956
8397
  initializeComponent(sender) {
7957
8398
  TransportRegistry.registerSlot(this.props.name, this);
7958
8399
  this.onDisposing = () => {
7959
- (this.controls.items || []).forEach(child => {
8400
+ [...(this.controls.items || [])].forEach(child => {
7960
8401
  this.controls.remove(child);
7961
8402
  child.dispose?.();
7962
8403
  });
@@ -7964,7 +8405,7 @@
7964
8405
  };
7965
8406
  }
7966
8407
  clearSlot() {
7967
- (this.controls.items || []).forEach(child => {
8408
+ [...(this.controls.items || [])].forEach(child => {
7968
8409
  this.controls.remove(child);
7969
8410
  child.dispose?.();
7970
8411
  });
@@ -7978,7 +8419,7 @@
7978
8419
  if (child.parent === newParent && newParent.controls.items.includes(child))
7979
8420
  return;
7980
8421
  if (child.parent && child.parent !== newParent) {
7981
- child.parent.controls.remove(child);
8422
+ child.parent.controls.silentDetach(child, true);
7982
8423
  }
7983
8424
  if (options.owner) {
7984
8425
  child.motif.options.ownerTransporter = options.owner;
@@ -8041,8 +8482,11 @@
8041
8482
  _slotRegisteredListener;
8042
8483
  _slotUnregisteredListener;
8043
8484
  _transported = [];
8485
+ _countedLive = false;
8044
8486
  constructor(props) {
8045
8487
  super('div', props);
8488
+ contentBlocks.live++;
8489
+ this._countedLive = true;
8046
8490
  }
8047
8491
  _handleSlotChange = (eventArgs) => {
8048
8492
  if (eventArgs.name === this.props.name) {
@@ -8052,9 +8496,17 @@
8052
8496
  }
8053
8497
  const all = [...(this.childs || []), ...this.controls.items];
8054
8498
  Transporter.transportMany(all, slot);
8055
- this._transported = all;
8499
+ this._rememberTransported(all);
8056
8500
  }
8057
8501
  };
8502
+ _rememberTransported(children) {
8503
+ const kept = this._transported.filter(c => !c.isDisposed);
8504
+ for (const child of children) {
8505
+ if (!kept.includes(child))
8506
+ kept.push(child);
8507
+ }
8508
+ this._transported = kept;
8509
+ }
8058
8510
  _clearChildrenFromSlot = (slot) => {
8059
8511
  (this.childs || []).forEach(child => {
8060
8512
  slot.controls.remove(child);
@@ -8073,7 +8525,7 @@
8073
8525
  }
8074
8526
  const all = [...(this.childs || []), ...this.controls.items];
8075
8527
  Transporter.transportMany(all, slot);
8076
- this._transported = all;
8528
+ this._rememberTransported(all);
8077
8529
  }
8078
8530
  this._slotRegisteredListener = Application.main.on(SLOT_REGISTERED_EVENT, this._handleSlotChange);
8079
8531
  this._slotUnregisteredListener = Application.main.on(SLOT_UNREGISTERED_EVENT, (eventArgs) => {
@@ -8082,9 +8534,11 @@
8082
8534
  }
8083
8535
  });
8084
8536
  this._onAddRef = (child) => {
8537
+ this.motif.trigger('controladded', { control: child });
8085
8538
  const currentSlot = TransportRegistry.getSlot(this.props.name);
8086
8539
  if (currentSlot) {
8087
8540
  Transporter.transport(child, currentSlot);
8541
+ this._rememberTransported([child]);
8088
8542
  }
8089
8543
  };
8090
8544
  this._onRemoveRef = (child) => {
@@ -8092,17 +8546,20 @@
8092
8546
  if (currentSlot) {
8093
8547
  currentSlot.controls.remove(child);
8094
8548
  }
8549
+ this._transported = this._transported.filter(c => c !== child);
8095
8550
  };
8096
8551
  this.controls.onAdd = this._onAddRef;
8097
8552
  this.controls.onRemove = this._onRemoveRef;
8098
8553
  }
8099
8554
  onDisposing(sender, e) {
8555
+ if (this._countedLive) {
8556
+ this._countedLive = false;
8557
+ contentBlocks.live--;
8558
+ }
8100
8559
  const currentSlot = TransportRegistry.getSlot(this.props.name);
8101
- if (currentSlot) {
8102
- (this._transported || []).forEach(child => {
8103
- currentSlot.controls.remove(child);
8104
- child.dispose();
8105
- });
8560
+ for (const child of this._transported || []) {
8561
+ currentSlot?.controls.remove(child);
8562
+ child.dispose();
8106
8563
  }
8107
8564
  if (this._slotRegisteredListener) {
8108
8565
  Application.main.off(SLOT_REGISTERED_EVENT, this._handleSlotChange);
@@ -8125,14 +8582,14 @@
8125
8582
  const ARRAY_MUTATORS = new Set(['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort']);
8126
8583
  const NOT_META = Symbol('');
8127
8584
  const metaReaders = new Map([
8128
- ["[__isReactive__]" /* Flags.IS_REACTIVE */, () => true],
8129
- ["[__isReadonly__]" /* Flags.IS_READONLY */, engine => engine.isReadonly],
8130
- ["[__issuperficial__]" /* Flags.IS_SUPERFICIAL */, engine => engine.superficial],
8131
- ["[__get_setup__]" /* Flags.GET_SETUP */, (_engine, target) => target],
8132
- ["[__raw__]" /* Flags.RAW */, (engine, target, receiver) => engine.ReactiveMap().get(target) === receiver ? target : NOT_META],
8585
+ [Flags.IS_REACTIVE, () => true],
8586
+ [Flags.IS_READONLY, engine => engine.isReadonly],
8587
+ [Flags.IS_SUPERFICIAL, engine => engine.superficial],
8588
+ [Flags.GET_SETUP, (_engine, target) => target],
8589
+ [Flags.RAW, (engine, target, receiver) => engine.ReactiveMap().get(target) === receiver ? target : NOT_META],
8133
8590
  ]);
8134
8591
  function readMeta(engine, target, key, receiver) {
8135
- if (typeof key !== 'string' || key.charCodeAt(0) !== 91)
8592
+ if (typeof key !== 'symbol')
8136
8593
  return NOT_META;
8137
8594
  const reader = metaReaders.get(key);
8138
8595
  return reader === undefined ? NOT_META : reader(engine, target, receiver);
@@ -9410,12 +9867,12 @@
9410
9867
  function toggle(force) {
9411
9868
  if (!overlayHost)
9412
9869
  return;
9413
- visible = typeof force === 'boolean' ? force : !visible;
9870
+ visible = !visible;
9414
9871
  overlayHost.style.display = visible ? 'block' : 'none';
9415
9872
  }
9416
9873
  function initOverlayIfEnabled() {
9417
9874
  ensureDevtoolsFlagInitialized();
9418
- if (!isEnabled())
9875
+ if (!isRequestedByFlag())
9419
9876
  return;
9420
9877
  try {
9421
9878
  if (!overlayHost) {
@@ -9433,9 +9890,6 @@
9433
9890
  });
9434
9891
  on((ev) => { if (ev.type === 'warning' && visible)
9435
9892
  render(); });
9436
- const qs = location.search || '';
9437
- if (Application.main.isDevelopmentModeEnabled)
9438
- toggle(true);
9439
9893
  }
9440
9894
  }
9441
9895
  catch { }
@@ -9793,13 +10247,6 @@
9793
10247
  const SLIDE_OFFSET = 30;
9794
10248
  const EASING = 'cubic-bezier(0.2, 0.8, 0.2, 1)';
9795
10249
  const isElement = (node) => !!node && node.nodeType === 1 && !!node.style;
9796
- function hasOwnTransition(component, phase) {
9797
- const options = component?.motif?.options;
9798
- if (!options)
9799
- return false;
9800
- const transition = options.transition;
9801
- return !!((phase === 'enter' ? options.transitionIn : options.transitionOut) || (transition && (transition.classes || (transition.name && transition.name.length > 0))));
9802
- }
9803
10250
  function markDirection(component, direction) {
9804
10251
  const el = component?.element;
9805
10252
  if (!component || component.isDisposed || !isElement(el))
@@ -10182,7 +10629,7 @@
10182
10629
  if (!top || top.isDisposed)
10183
10630
  return;
10184
10631
  try {
10185
- await disposeNavigationTarget(top);
10632
+ await disposeNavigationTarget(top, { deep: true, skipLeaveTransition: true });
10186
10633
  }
10187
10634
  catch (error) {
10188
10635
  reportError('MJX307', error);
@@ -12654,8 +13101,14 @@
12654
13101
  }
12655
13102
  catch { /* ignore */ }
12656
13103
  }, 'Application.dispose.resetUrl');
13104
+ transitionSettings.mode = 'concurrent';
12657
13105
  _globalApplication = null;
12658
13106
  }
13107
+ useTransitions(options) {
13108
+ if (isTransitionMode(options?.mode))
13109
+ transitionSettings.mode = options.mode;
13110
+ return this;
13111
+ }
12659
13112
  use(callback) {
12660
13113
  this._middlewares.push(callback);
12661
13114
  return this;
@@ -12871,6 +13324,7 @@
12871
13324
  this._isDevelopment = isDev;
12872
13325
  errorHandler.setDevelopmentMode(isDev);
12873
13326
  safeCallSilent(() => { globalThis.__MOTIF_DEV__ = isDev; }, 'Application.useDevelopment.flag');
13327
+ safeCallSilent(() => { setDevtoolsEnabled(isDev); }, 'Application.useDevelopment.devtools');
12874
13328
  if (isDev)
12875
13329
  flushCompilerContractWarnings();
12876
13330
  return this;
@@ -13111,7 +13565,7 @@
13111
13565
  super();
13112
13566
  this.tokensPerInterval = opts.tokensPerInterval ?? 1;
13113
13567
  this.intervalMs = opts.intervalMs ?? 1000;
13114
- this.capacity = opts.capacity ?? 1000;
13568
+ this.capacity = opts.capacity ?? this.tokensPerInterval;
13115
13569
  this.tokens = this.capacity;
13116
13570
  this.lastRefill = Date.now();
13117
13571
  }