@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.
@@ -1,4 +1,373 @@
1
- import { m as motifError, r as reportWarning, M as MotifError, f as formatMotifMessage, u as untracked, e as effect, w as getRaw, a as reportError, x as isDevLike, k as dom, l as errorHandler, y as callReported, S as Signal, o as reactive, s as safeCall, p as safeCallAsync, q as safeCallSilent, z as ensureDevtoolsFlagInitialized, A as isEnabled, B as on, D as safeCallSilentAsync, $, F as setErrorConsoleLogging, G as engine, H as setRoutes, d as configureReactivityLeakMonitor } from './core-BDvHkZLQ.esm.js';
1
+ function rethrowLater(error) {
2
+ setTimeout(() => { throw error; }, 0);
3
+ }
4
+ class ErrorHandler {
5
+ unexpectedErrorHandler = rethrowLater;
6
+ listeners = [];
7
+ _isDevelopment = false;
8
+ _enableConsoleLogging = true;
9
+ setDevelopmentMode(isDev) {
10
+ this._isDevelopment = isDev;
11
+ }
12
+ setConsoleLogging(enabled) {
13
+ this._enableConsoleLogging = enabled;
14
+ }
15
+ isDevelopment() {
16
+ return this._isDevelopment || globalThis.__MOTIF_DEV__ === true;
17
+ }
18
+ reportSuppressed(context, error) {
19
+ this.logIfDev(context, error);
20
+ }
21
+ report(error) {
22
+ if (this._enableConsoleLogging) {
23
+ if (error.cause !== undefined)
24
+ console.error(error.message, error.cause);
25
+ else
26
+ console.error(error.message);
27
+ }
28
+ try {
29
+ const bus = globalThis.__MOTIF_DEVTOOLS_BUS__;
30
+ if (bus && typeof bus.publish === 'function') {
31
+ bus.publish('error:caught', { context: error.code ?? error.name, error: this.serializeError(error) });
32
+ }
33
+ }
34
+ catch { /* ignore */ }
35
+ this.emit(error);
36
+ }
37
+ logIfDev(context, error) {
38
+ if (this.isDevelopment() && this._enableConsoleLogging) {
39
+ console.error(`[motifjs Error - ${context}]`, error);
40
+ }
41
+ try {
42
+ const bus = globalThis.__MOTIF_DEVTOOLS_BUS__;
43
+ if (bus && typeof bus.publish === 'function') {
44
+ bus.publish('error:caught', { context, error: this.serializeError(error) });
45
+ }
46
+ }
47
+ catch { /* ignore */ }
48
+ }
49
+ serializeError(error) {
50
+ if (!error)
51
+ return { message: 'Unknown error' };
52
+ if (error instanceof Error) {
53
+ return {
54
+ name: error.name,
55
+ message: error.message,
56
+ stack: error.stack,
57
+ cause: error.cause ? this.serializeError(error.cause) : undefined
58
+ };
59
+ }
60
+ if (typeof error === 'object') {
61
+ try {
62
+ return JSON.parse(JSON.stringify(error));
63
+ }
64
+ catch {
65
+ return String(error);
66
+ }
67
+ }
68
+ return String(error);
69
+ }
70
+ addListener(listener) {
71
+ this.listeners.push(listener);
72
+ return () => {
73
+ const index = this.listeners.indexOf(listener);
74
+ if (index !== -1) {
75
+ this.listeners.splice(index, 1);
76
+ }
77
+ };
78
+ }
79
+ emit(error) {
80
+ for (const listener of this.listeners.slice()) {
81
+ listener(error);
82
+ }
83
+ }
84
+ setUnexpectedErrorHandler(handler) {
85
+ this.unexpectedErrorHandler = handler;
86
+ }
87
+ getUnexpectedErrorHandler() {
88
+ return this.unexpectedErrorHandler;
89
+ }
90
+ onUnexpectedError(error) {
91
+ this.unexpectedErrorHandler(error);
92
+ this.emit(error);
93
+ }
94
+ safeCall(fn, context, fallback) {
95
+ try {
96
+ return fn();
97
+ }
98
+ catch (error) {
99
+ this.logIfDev(context, error);
100
+ this.onUnexpectedError(error);
101
+ return fallback;
102
+ }
103
+ }
104
+ async safeCallAsync(fn, context, fallback) {
105
+ try {
106
+ return await fn();
107
+ }
108
+ catch (error) {
109
+ this.logIfDev(context, error);
110
+ this.onUnexpectedError(error);
111
+ return fallback;
112
+ }
113
+ }
114
+ safeCallSilent(fn, context) {
115
+ try {
116
+ fn();
117
+ }
118
+ catch (error) {
119
+ this.logIfDev(context, error);
120
+ }
121
+ }
122
+ async safeCallSilentAsync(fn, context) {
123
+ try {
124
+ return await fn();
125
+ }
126
+ catch (error) {
127
+ this.logIfDev(context, error);
128
+ }
129
+ }
130
+ wrapSafe(fn, context) {
131
+ return (...args) => {
132
+ try {
133
+ return fn(...args);
134
+ }
135
+ catch (error) {
136
+ this.logIfDev(context, error);
137
+ this.onUnexpectedError(error);
138
+ return undefined;
139
+ }
140
+ };
141
+ }
142
+ wrapSafeAsync(fn, context) {
143
+ return async (...args) => {
144
+ try {
145
+ return await fn(...args);
146
+ }
147
+ catch (error) {
148
+ this.logIfDev(context, error);
149
+ this.onUnexpectedError(error);
150
+ return undefined;
151
+ }
152
+ };
153
+ }
154
+ }
155
+ const errorHandler = new ErrorHandler();
156
+ function setErrorConsoleLogging(enabled) {
157
+ errorHandler.setConsoleLogging(enabled);
158
+ }
159
+ function safeCall(fn, context, fallback) {
160
+ return errorHandler.safeCall(fn, context, fallback);
161
+ }
162
+ function safeCallAsync(fn, context, fallback) {
163
+ return errorHandler.safeCallAsync(fn, context, fallback);
164
+ }
165
+ function safeCallSilent(fn, context) {
166
+ errorHandler.safeCallSilent(fn, context);
167
+ }
168
+ function safeCallSilentAsync(fn, context) {
169
+ return errorHandler.safeCallSilentAsync(fn, context);
170
+ }
171
+ function setUnexpectedErrorHandler(handler) {
172
+ errorHandler.setUnexpectedErrorHandler(handler);
173
+ }
174
+
175
+ const state = {
176
+ enabled: false,
177
+ listeners: new Set(),
178
+ warnings: [],
179
+ routes: null,
180
+ };
181
+ /** Dev modu: devtools açık ya da `globalThis.__MOTIF_DEV__ === true`. */
182
+ function isDevLike() {
183
+ return state.enabled || globalThis.__MOTIF_DEV__ === true;
184
+ }
185
+ function isRequestedByFlag() {
186
+ try {
187
+ if (typeof window === 'undefined')
188
+ return false;
189
+ const w = window;
190
+ if (w.__motif_DEVTOOLS === true)
191
+ return true;
192
+ if (globalThis.__MOTIF_DEVTOOLS__ === true)
193
+ return true;
194
+ if (globalThis.__MOTIF_DEVTOOLS_FLAG === true)
195
+ return true;
196
+ return false;
197
+ }
198
+ catch {
199
+ return false;
200
+ }
201
+ }
202
+ function exposeBus(visible) {
203
+ try {
204
+ if (visible)
205
+ window.__motifDevBus = { on, emit, warn, getWarnings, isEnabled, setRoutes, getRoutes };
206
+ else
207
+ delete window.__motifDevBus;
208
+ }
209
+ catch { }
210
+ }
211
+ function ensureDevtoolsFlagInitialized() {
212
+ if (state.enabled)
213
+ return;
214
+ state.enabled = isRequestedByFlag();
215
+ if (state.enabled)
216
+ exposeBus(true);
217
+ }
218
+ function setDevtoolsEnabled(enabled) {
219
+ state.enabled = enabled || isRequestedByFlag();
220
+ exposeBus(state.enabled);
221
+ }
222
+ function isEnabled() { return state.enabled; }
223
+ function on(listener) {
224
+ state.listeners.add(listener);
225
+ return () => { state.listeners.delete(listener); };
226
+ }
227
+ function emit(type, payload) {
228
+ const ev = { type, payload };
229
+ for (const l of state.listeners) {
230
+ try {
231
+ l(ev);
232
+ }
233
+ catch { }
234
+ }
235
+ try {
236
+ const bus = globalThis.__MOTIF_DEVTOOLS_BUS__;
237
+ if (bus && typeof bus.publish === 'function') {
238
+ bus.publish('devtools:' + type, payload);
239
+ }
240
+ }
241
+ catch { }
242
+ }
243
+ function warn(code, message, details) {
244
+ if (!isDevLike())
245
+ return;
246
+ const w = { code, message, details };
247
+ state.warnings.push(w);
248
+ try {
249
+ if (typeof console !== 'undefined')
250
+ details === undefined ? console.warn(`[motifjs] ${code}: ${message}`) : console.warn(`[motifjs] ${code}: ${message}`, details);
251
+ }
252
+ catch { }
253
+ emit('warning', w);
254
+ }
255
+ function getWarnings() { return state.warnings.slice(); }
256
+ function setRoutes(routes) { state.routes = routes; }
257
+ function getRoutes() { return state.routes; }
258
+
259
+ const motifMessages = {
260
+ MJX101: (tag) => `dom.createElement('${tag}'): no document is available (no DOM environment).`,
261
+ MJX102: (description) => `Invalid element selector "${description}".`,
262
+ MJX103: (tag) => `dom.createElementNS('${tag}') failed.`,
263
+ MJX104: () => `Skipped inserting a component into the DOM because it contains its own parent.`,
264
+ MJX105: () => `Applying router link classes failed.`,
265
+ MJX106: () => `The placeholder parent changed; rebuilding the component.`,
266
+ MJX107: () => `Disposing a child component failed.`,
267
+ MJX108: () => `Component is disposed; the result of doWork was discarded.`,
268
+ MJX109: () => `A content block child was removed because its content body is being disposed.`,
269
+ MJX110: (ms) => `Lazy timeout: the component did not load within ${ms} ms.`,
270
+ MJX111: () => `Lazy aborted: loading the component was cancelled.`,
271
+ MJX112: (depth) => `resolveComponent: the factory chain exceeded ${depth} levels; a factory may be returning itself.`,
272
+ MJX113: () => `The transport slot has no parent; mount the slot before transporting into it.`,
273
+ MJX114: () => `Placing the navigation target into its host failed.`,
274
+ MJX115: () => `Disposing the previous navigation target failed.`,
275
+ MJX116: (ms) => `Timeout: the listener guard did not settle within ${ms} ms.`,
276
+ MJX117: () => `Detaching a control failed.`,
277
+ MJX118: () => `The onRemove callback failed while detaching a control.`,
278
+ MJX119: () => `Moving a fragment's DOM range stopped: its end marker was not found (possible infinite loop).`,
279
+ MJX120: () => `Scanning a fragment's DOM range stopped: its end marker was not found (possible infinite loop).`,
280
+ 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
+ MJX122: (hook) => `The component ${hook} hook threw.`,
282
+ MJX123: (event) => `The '${event}' event handler threw.`,
283
+ MJX124: () => `A spread object on a DOM tag cannot set innerHTML; the key was ignored. Use x-html for trusted HTML.`,
284
+ 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.`,
285
+ MJX126: () => `Lazy: loading the component failed and no Fallbackview is set; the host was cleared.`,
286
+ MJX201: () => `ListBinding: renderFn must return a component instance, a component class, or a factory function.`,
287
+ 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.`,
288
+ 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(...).`,
289
+ MJX204: () => `A component reached a text binding and was not written to the DOM. For a template prop that can change later, write a getter: {() => props.tpl}. Templates that are ready at setup also work as {props.tpl}.`,
290
+ MJX205: () => `Virtualization: the watch callback threw.`,
291
+ MJX206: () => `Virtualization: autoRefresh stopped; dataRequest may be changing the reactive data it reads on every refresh.`,
292
+ MJX207: () => `Virtualization: loading data failed.`,
293
+ MJX208: () => `An effect threw.`,
294
+ MJX301: (outlet, ms) => `RouterView outlet '${outlet}' was not built within ${ms} ms, so the route chain cannot be mounted. Does the layout component render a <RouterView>?`,
295
+ MJX302: (name) => `Named route '${name}' was not found.`,
296
+ MJX303: (chain) => `Redirect loop or too many redirects: ${chain}`,
297
+ MJX304: () => `Route execution failed.`,
298
+ MJX305: () => `The error fallback route failed.`,
299
+ MJX306: (hook) => `The ${hook} hook threw.`,
300
+ MJX307: () => `Disposing a route component failed.`,
301
+ MJX308: () => `The stack navigation transition failed.`,
302
+ MJX309: () => `Router is not initialized. Call useRouter() before navigating.`,
303
+ MJX310: (parentPath) => `Route path cannot be empty; use '/' for the default child. Under parent "${parentPath}".`,
304
+ MJX311: (path, parentPath) => `Child route path should start with '/': "${path}" under parent "${parentPath}".`,
305
+ MJX312: (full) => `Child route path resolves to the same full path as its parent: "${full}".`,
306
+ MJX313: (full) => `Multiple routes resolve to the same full path: "${full}".`,
307
+ MJX314: (alias, parentPath) => `Child route alias should start with '/': "${alias}" under parent "${parentPath}".`,
308
+ MJX315: (alias) => `Route alias resolves to the route's own path: "${alias}".`,
309
+ MJX316: (alias) => `Multiple routes use the same alias: "${alias}".`,
310
+ MJX401: (token) => `Service not registered for token: ${token}`,
311
+ MJX402: (token) => `Async factory used with get() for token ${token}; use getAsync().`,
312
+ MJX403: () => `Invalid service descriptor.`,
313
+ MJX404: (chain) => `Cyclic dependency detected: ${chain}`,
314
+ MJX405: () => `Only one ApplicationBuilder instance is allowed.`,
315
+ MJX406: (selector) => `Application.run: host not found for selector: ${selector}`,
316
+ MJX407: (token) => `getService: no ServiceProvider found for token '${token}'.`,
317
+ MJX408: (token, reason) => `getService failed for token '${token}': ${reason}`,
318
+ MJX409: (token) => `inject(${token}) was called outside a service construction; call it in a field initializer or constructor of a class the ServiceProvider creates.`,
319
+ MJX410: (token, sources) => `Multiple sources provided for token '${token}': ${sources}. Resolution order is useValue > useFactory > useClass.`,
320
+ MJX411: (token) => `'deps' must be an array for token '${token}'; the invalid deps are ignored.`,
321
+ MJX413: (token) => `Service '${token}' is registered with a function that cannot be constructed. Use { useValue: fn } to provide the function itself or { useFactory: fn } to create the service.`,
322
+ MJX414: (token, reason) => `FromService failed for token '${token}': ${reason}`,
323
+ MJX501: () => `Disposable already disposed.`,
324
+ MJX502: () => `Cannot register a disposable on itself.`,
325
+ MJX503: () => `Errors were thrown while disposing a store.`,
326
+ MJX504: () => `A disposable was added to a DisposableStore that is already disposed; the added object will leak.`,
327
+ MJX505: () => `Cannot dispose a disposable on itself.`,
328
+ MJX507: (name, limit, count) => `[${name}] potential listener LEAK: ${limit} listeners already; most frequent stack (${count}):`,
329
+ MJX601: () => `Sequence contains no elements.`,
330
+ MJX602: () => `Circuit is open.`,
331
+ MJX603: () => `Bulkhead queue is full.`,
332
+ MJX604: () => `Rate limit exceeded.`,
333
+ MJX605: () => `Operation timed out.`,
334
+ MJX607: () => `A history must be created with at least one entry.`,
335
+ MJX608: () => `Method not implemented.`,
336
+ MJX609: () => `OperationRunner: the operation threw.`,
337
+ MJX610: () => `Matching the request path failed.`,
338
+ MJX611: () => `The devtools panel failed to load.`,
339
+ };
340
+ class MotifError extends Error {
341
+ code;
342
+ constructor(code, message, options) {
343
+ super(message, options);
344
+ this.name = 'MotifError';
345
+ this.code = code;
346
+ }
347
+ }
348
+ function formatMotifMessage(code, ...args) {
349
+ return `[motifjs] ${code}: ${motifMessages[code](...args)}`;
350
+ }
351
+ function motifError(code, ...args) {
352
+ return new MotifError(code, formatMotifMessage(code, ...args));
353
+ }
354
+ function reportError(code, cause, ...args) {
355
+ errorHandler.report(new MotifError(code, formatMotifMessage(code, ...args), { cause }));
356
+ }
357
+ function callReported(fn, code, ...args) {
358
+ try {
359
+ const result = fn();
360
+ if (result && typeof result.then === 'function') {
361
+ result.then(undefined, (error) => reportError(code, error, ...args));
362
+ }
363
+ }
364
+ catch (error) {
365
+ reportError(code, error, ...args);
366
+ }
367
+ }
368
+ function reportWarning(code, args, details) {
369
+ warn(code, motifMessages[code](...args), details);
370
+ }
2
371
 
3
372
  class DisposableCore {
4
373
  disposableTracker = null;
@@ -124,6 +493,95 @@ class Disposable {
124
493
  }
125
494
  }
126
495
 
496
+ const Flags = {
497
+ IS_REACTIVE: Symbol.for('motif.isReactive'),
498
+ IS_READONLY: Symbol.for('motif.isReadonly'),
499
+ IS_SUPERFICIAL: Symbol.for('motif.isSuperficial'),
500
+ RAW: Symbol.for('motif.raw'),
501
+ GET_SETUP: Symbol.for('motif.getSetup'),
502
+ };
503
+ const ITERATE_KEY = Symbol('');
504
+ let followTracking = true;
505
+ let arrayScope = { enabled: false, key: '' };
506
+ function getRaw(value) {
507
+ let current = value;
508
+ while (current && current[Flags.RAW]) {
509
+ current = current[Flags.RAW];
510
+ }
511
+ return current;
512
+ }
513
+ function isReadonly(candidate) {
514
+ if (candidate == null)
515
+ return false;
516
+ return Boolean(candidate[Flags.IS_READONLY]);
517
+ }
518
+ function hasOwn(target, key) {
519
+ return Object.prototype.hasOwnProperty.call(target, key);
520
+ }
521
+ function isObject(value) {
522
+ return typeof value === 'object' && value !== null;
523
+ }
524
+ const intrinsicSymbols = new Set(Object.values(Object.getOwnPropertyDescriptors(Symbol))
525
+ .map(descriptor => descriptor.value)
526
+ .filter((value) => typeof value === 'symbol'));
527
+ function isIntrinsicSymbol(key) {
528
+ return typeof key === 'symbol' && intrinsicSymbols.has(key);
529
+ }
530
+ const proxyableTags = new Map([
531
+ ['[object Object]', 1 /* TargetType.COMMON */],
532
+ ['[object Array]', 1 /* TargetType.COMMON */],
533
+ ['[object Map]', 2 /* TargetType.COLLECTION */],
534
+ ['[object Set]', 2 /* TargetType.COLLECTION */],
535
+ ['[object WeakMap]', 2 /* TargetType.COLLECTION */],
536
+ ['[object WeakSet]', 2 /* TargetType.COLLECTION */],
537
+ ]);
538
+ function getTargetType(value) {
539
+ var proto = Object.getPrototypeOf(value);
540
+ var cname = "";
541
+ if (proto && proto.constructor) {
542
+ cname = proto.constructor.name;
543
+ }
544
+ if ((cname === "Control" || cname == "RouteManager" || cname == "ServiceManager")) {
545
+ return 0 /* TargetType.SYSTEM */;
546
+ }
547
+ if (!Object.isExtensible(value)) {
548
+ return 0 /* TargetType.INVALID */;
549
+ }
550
+ return proxyableTags.get(Object.prototype.toString.call(value)) ?? 0 /* TargetType.INVALID */;
551
+ }
552
+ const canonicalIndex = /^(?:0|[1-9]\d*)$/;
553
+ const isNumericKey = (key) => typeof key === 'string' && canonicalIndex.test(key) && String(Number(key)) === key;
554
+ const savedTracking = [];
555
+ let trackingDepth = 0;
556
+ function enterTracking(enabled) {
557
+ savedTracking[trackingDepth++] = followTracking;
558
+ followTracking = enabled;
559
+ }
560
+ function pauseTracking() {
561
+ enterTracking(false);
562
+ }
563
+ function enableTracking() {
564
+ enterTracking(true);
565
+ }
566
+ function resetTracking() {
567
+ followTracking = trackingDepth > 0 ? savedTracking[--trackingDepth] : true;
568
+ }
569
+ const arrayStack = [];
570
+ function addArrayStack(key) {
571
+ arrayStack.push(arrayScope);
572
+ arrayScope.enabled = true;
573
+ arrayScope.key = key;
574
+ }
575
+ function removeArrayStack() {
576
+ const last = arrayStack.pop();
577
+ if (arrayStack.length > 0) {
578
+ arrayScope = last === undefined ? { enabled: false, key: '' } : last;
579
+ }
580
+ else {
581
+ arrayScope = { enabled: false, key: '' };
582
+ }
583
+ }
584
+
127
585
  class ListBinding {
128
586
  component;
129
587
  itemsFn;
@@ -243,13 +701,28 @@ class ListBinding {
243
701
  }
244
702
  _setupBinding() {
245
703
  const update = () => {
246
- const items = this._toArray(this.itemsFn());
704
+ const source = this._toArray(this.itemsFn());
705
+ const rawSource = getRaw(source);
706
+ const count = source.length;
707
+ let items;
708
+ if (rawSource === source) {
709
+ items = source;
710
+ }
711
+ else {
712
+ items = new Array(count);
713
+ for (let i = 0; i < count; i++) {
714
+ if (i in rawSource)
715
+ items[i] = source[i];
716
+ else
717
+ void source[i];
718
+ }
719
+ }
247
720
  const prevItems = this.olditems;
248
721
  const prevComponents = this._rendered;
249
722
  if (this.olditems.length > 0) {
250
723
  const currentRaws = new Set();
251
- for (const it of items)
252
- currentRaws.add(getRaw(it));
724
+ for (let i = 0; i < count; i++)
725
+ currentRaws.add(getRaw(items[i]));
253
726
  for (const old of this.olditems) {
254
727
  const raw = getRaw(old);
255
728
  if (!currentRaws.has(raw)) {
@@ -366,8 +839,8 @@ class ListBinding {
366
839
  });
367
840
  this._syncContainer(newComponents);
368
841
  this._rendered = newComponents;
369
- this.olditems = items.slice();
370
- return items.length;
842
+ this.olditems = items === source ? source.slice() : items;
843
+ return count;
371
844
  };
372
845
  this._effectCleanup = effect(() => update());
373
846
  }
@@ -383,6 +856,34 @@ class ListBinding {
383
856
  }
384
857
  return;
385
858
  }
859
+ if (newComponents.length >= items.length) {
860
+ let appendOnly = true;
861
+ for (let i = 0; i < items.length; i++) {
862
+ if (newComponents[i] !== items[i]) {
863
+ appendOnly = false;
864
+ break;
865
+ }
866
+ }
867
+ if (appendOnly && newComponents.length > items.length) {
868
+ const existing = new Set(items);
869
+ for (let i = items.length; i < newComponents.length; i++) {
870
+ if (existing.has(newComponents[i])) {
871
+ appendOnly = false;
872
+ break;
873
+ }
874
+ existing.add(newComponents[i]);
875
+ }
876
+ }
877
+ if (appendOnly) {
878
+ for (let i = items.length; i < newComponents.length; i++) {
879
+ try {
880
+ controls.add(newComponents[i]);
881
+ }
882
+ catch { }
883
+ }
884
+ return;
885
+ }
886
+ }
386
887
  const oldIndex = new Map();
387
888
  items.forEach((c, i) => oldIndex.set(c, i));
388
889
  const sources = newComponents.map(c => {
@@ -498,6 +999,108 @@ function findAppendableComponent$1(component) {
498
999
  return null;
499
1000
  }
500
1001
 
1002
+ class LeakMonitor {
1003
+ threshold;
1004
+ name;
1005
+ _origins = new Map();
1006
+ _quietChecks = 0;
1007
+ constructor(threshold, name) {
1008
+ this.threshold = threshold;
1009
+ this.name = name;
1010
+ }
1011
+ check(size) {
1012
+ if (this.threshold <= 0 || size < this.threshold) {
1013
+ return undefined;
1014
+ }
1015
+ const origin = new Error().stack ?? '';
1016
+ this._origins.set(origin, (this._origins.get(origin) ?? 0) + 1);
1017
+ this._quietChecks--;
1018
+ if (this._quietChecks <= 0) {
1019
+ this._quietChecks = this.threshold / 2;
1020
+ const [stack, count] = this._busiestOrigin();
1021
+ reportWarning('MJX507', [this.name, size, count], stack);
1022
+ }
1023
+ return () => {
1024
+ this._origins.set(origin, (this._origins.get(origin) ?? 0) - 1);
1025
+ };
1026
+ }
1027
+ _busiestOrigin() {
1028
+ let busiest = ['', 0];
1029
+ for (const entry of this._origins) {
1030
+ if (entry[1] > busiest[1]) {
1031
+ busiest = entry;
1032
+ }
1033
+ }
1034
+ return busiest;
1035
+ }
1036
+ }
1037
+
1038
+ function createRing() {
1039
+ const ring = { value: undefined, linked: false };
1040
+ ring.before = ring;
1041
+ ring.after = ring;
1042
+ return ring;
1043
+ }
1044
+ class LinkedList {
1045
+ _ring = createRing();
1046
+ _count = 0;
1047
+ get size() {
1048
+ return this._count;
1049
+ }
1050
+ isEmpty() {
1051
+ return this._count === 0;
1052
+ }
1053
+ push(value) {
1054
+ return this._link(value, this._ring.before);
1055
+ }
1056
+ unshift(value) {
1057
+ return this._link(value, this._ring);
1058
+ }
1059
+ pop() {
1060
+ return this._take(this._ring.before);
1061
+ }
1062
+ shift() {
1063
+ return this._take(this._ring.after);
1064
+ }
1065
+ clear() {
1066
+ for (let link = this._ring.after; link !== this._ring; link = link.after) {
1067
+ link.linked = false;
1068
+ }
1069
+ this._ring = createRing();
1070
+ this._count = 0;
1071
+ }
1072
+ *[Symbol.iterator]() {
1073
+ const ring = this._ring;
1074
+ for (let link = ring.after; link !== ring; link = link.after) {
1075
+ yield link.value;
1076
+ }
1077
+ }
1078
+ _link(value, previous) {
1079
+ const link = { value, before: previous, after: previous.after, linked: true };
1080
+ previous.after.before = link;
1081
+ previous.after = link;
1082
+ this._count++;
1083
+ return () => this._unlink(link);
1084
+ }
1085
+ _take(link) {
1086
+ if (link === this._ring) {
1087
+ return undefined;
1088
+ }
1089
+ const value = link.value;
1090
+ this._unlink(link);
1091
+ return value;
1092
+ }
1093
+ _unlink(link) {
1094
+ if (!link.linked) {
1095
+ return;
1096
+ }
1097
+ link.linked = false;
1098
+ link.before.after = link.after;
1099
+ link.after.before = link.before;
1100
+ this._count--;
1101
+ }
1102
+ }
1103
+
501
1104
  const COMPILER_CONTRACT = 1;
502
1105
  const reported = new Set();
503
1106
  const pending = new Set();
@@ -517,50 +1120,297 @@ function flushCompilerContractWarnings() {
517
1120
  motifCompiled(contract);
518
1121
  }
519
1122
 
520
- function isCheckedInput(el) {
521
- if (!el || el.tagName !== 'INPUT')
522
- return false;
523
- const t = String(el.type || '').toLowerCase();
524
- return t === 'checkbox' || t === 'radio';
1123
+ var NodeTypes;
1124
+ (function (NodeTypes) {
1125
+ NodeTypes[NodeTypes["ELEMENT_NODE"] = 1] = "ELEMENT_NODE";
1126
+ NodeTypes[NodeTypes["ATTRIBUTE_NODE"] = 2] = "ATTRIBUTE_NODE";
1127
+ NodeTypes[NodeTypes["TEXT_NODE"] = 3] = "TEXT_NODE";
1128
+ NodeTypes[NodeTypes["CDATA_SECTION_NODE"] = 4] = "CDATA_SECTION_NODE";
1129
+ NodeTypes[NodeTypes["ENTITY_REFERENCE_NODE"] = 5] = "ENTITY_REFERENCE_NODE";
1130
+ /**deprecated */
1131
+ NodeTypes[NodeTypes["ENTITY_NODE"] = 6] = "ENTITY_NODE";
1132
+ /**deprecated */
1133
+ NodeTypes[NodeTypes["PROCESSING_INSTRUCTION_NODE"] = 7] = "PROCESSING_INSTRUCTION_NODE";
1134
+ NodeTypes[NodeTypes["COMMENT_NODE"] = 8] = "COMMENT_NODE";
1135
+ NodeTypes[NodeTypes["DOCUMENT_NODE"] = 9] = "DOCUMENT_NODE";
1136
+ NodeTypes[NodeTypes["DOCUMENT_TYPE_NODE"] = 10] = "DOCUMENT_TYPE_NODE";
1137
+ NodeTypes[NodeTypes["DOCUMENT_FRAGMENT_NODE"] = 11] = "DOCUMENT_FRAGMENT_NODE";
1138
+ /**deprecated */
1139
+ NodeTypes[NodeTypes["NOTATION_NODE"] = 12] = "NOTATION_NODE";
1140
+ })(NodeTypes || (NodeTypes = {}));
1141
+
1142
+ class Effect {
1143
+ fn;
1144
+ callback;
1145
+ deps = [];
1146
+ active = true;
1147
+ running = false;
1148
+ scheduler;
1149
+ constructor(fn, callback) {
1150
+ this.fn = fn;
1151
+ this.callback = callback;
1152
+ }
1153
+ run() {
1154
+ let value;
1155
+ if (!this.active || this.running)
1156
+ return;
1157
+ cleanup(this);
1158
+ effectStack.push(this);
1159
+ this.running = true;
1160
+ try {
1161
+ value = this.fn();
1162
+ }
1163
+ finally {
1164
+ effectStack.pop();
1165
+ this.running = false;
1166
+ if (this.callback) {
1167
+ this.callback(value);
1168
+ }
1169
+ }
1170
+ }
1171
+ stop() {
1172
+ this.active = false;
1173
+ cleanup(this);
1174
+ }
525
1175
  }
526
- function isNumericInput(el) {
527
- if (!el || el.tagName !== 'INPUT')
528
- return false;
529
- const t = String(el.type || '').toLowerCase();
530
- return t === 'number' || t === 'range';
1176
+ const depMap = new WeakMap();
1177
+ const effectStack = [];
1178
+ const effectQueue = new Set();
1179
+ let isFlushing = false;
1180
+ let leakEnabled = false;
1181
+ let leakThreshold = -1;
1182
+ let leakMonitor;
1183
+ const leakCleanups = new WeakMap();
1184
+ function configureReactivityLeakMonitor(opts = {}) {
1185
+ leakEnabled = !!opts.enabled;
1186
+ leakThreshold = typeof opts.threshold === 'number' ? opts.threshold : (leakEnabled ? 200 : -1);
1187
+ leakMonitor = leakEnabled && leakThreshold > 0 ? new LeakMonitor(leakThreshold, opts.name ?? 'reactivity-core') : undefined;
531
1188
  }
532
- function readModelValue(el) {
533
- if (!el)
534
- return undefined;
535
- if (isCheckedInput(el))
536
- return !!el.checked;
537
- if (isNumericInput(el)) {
538
- const raw = el.value;
539
- if (raw === '' || raw == null)
540
- return null;
541
- const n = typeof el.valueAsNumber === 'number' ? el.valueAsNumber : Number(raw);
542
- return Number.isFinite(n) ? n : null;
1189
+ function track(target, key) {
1190
+ if (!followTracking)
1191
+ return;
1192
+ const rawTarget = getRaw(target);
1193
+ const effect = effectStack[effectStack.length - 1];
1194
+ if (!effect || !effect.active)
1195
+ return;
1196
+ let deps = depMap.get(rawTarget);
1197
+ if (!deps)
1198
+ depMap.set(rawTarget, (deps = new Map()));
1199
+ let dep = deps.get(key);
1200
+ if (!dep)
1201
+ deps.set(key, (dep = new Set()));
1202
+ if (!dep.has(effect)) {
1203
+ dep.add(effect);
1204
+ effect.deps.push([rawTarget, key]);
1205
+ if (leakEnabled && leakMonitor && leakThreshold > 0) {
1206
+ try {
1207
+ const cleanup = leakMonitor.check(dep.size);
1208
+ if (cleanup) {
1209
+ let m = leakCleanups.get(dep);
1210
+ if (!m) {
1211
+ m = new Map();
1212
+ leakCleanups.set(dep, m);
1213
+ }
1214
+ m.set(effect, cleanup);
1215
+ }
1216
+ }
1217
+ catch { }
1218
+ }
543
1219
  }
544
- return el.value;
545
1220
  }
546
- class Binding {
547
- propertyName;
548
- dataSource;
549
- dataMember;
550
- formatString;
551
- converter;
552
- converterBack;
553
- setter;
554
- formatInfo;
555
- updateMode = 'onPropertyChanged';
556
- _isActive = false;
557
- _component;
558
- _effectCleanup;
559
- _memberPath = null;
560
- _memberPathSource;
561
- constructor(component, propertyName, dataSource, dataMember, formatString, formatInfo) {
562
- this._component = component;
563
- this.propertyName = propertyName;
1221
+ function trigger(target, key) {
1222
+ const rawTarget = getRaw(target);
1223
+ const deps = depMap.get(rawTarget);
1224
+ if (!deps)
1225
+ return;
1226
+ const effects = deps.get(key);
1227
+ if (!effects)
1228
+ return;
1229
+ let queued = false;
1230
+ effects.forEach(effect => {
1231
+ if (!effect.active)
1232
+ return;
1233
+ if (effect.scheduler) {
1234
+ runReported(effect.scheduler);
1235
+ return;
1236
+ }
1237
+ effectQueue.add(effect);
1238
+ queued = true;
1239
+ });
1240
+ if (queued)
1241
+ flushEffects();
1242
+ }
1243
+ function runReported(fn) {
1244
+ try {
1245
+ fn();
1246
+ }
1247
+ catch (error) {
1248
+ reportError('MJX208', error);
1249
+ }
1250
+ }
1251
+ const MAX_EFFECT_RUNS_PER_FLUSH = 50;
1252
+ function flushEffects() {
1253
+ if (isFlushing)
1254
+ return;
1255
+ isFlushing = true;
1256
+ Promise.resolve().then(() => {
1257
+ const runCounts = new Map();
1258
+ try {
1259
+ while (effectQueue.size > 0) {
1260
+ const batch = Array.from(effectQueue);
1261
+ effectQueue.clear();
1262
+ for (const e of batch) {
1263
+ const runs = (runCounts.get(e) ?? 0) + 1;
1264
+ runCounts.set(e, runs);
1265
+ if (runs > MAX_EFFECT_RUNS_PER_FLUSH) {
1266
+ if (runs === MAX_EFFECT_RUNS_PER_FLUSH + 1) {
1267
+ reportWarning('MJX203', [MAX_EFFECT_RUNS_PER_FLUSH], { fn: String(e.fn).slice(0, 200) });
1268
+ }
1269
+ continue;
1270
+ }
1271
+ runReported(() => e.run());
1272
+ }
1273
+ }
1274
+ }
1275
+ finally {
1276
+ effectQueue.clear();
1277
+ isFlushing = false;
1278
+ }
1279
+ });
1280
+ }
1281
+ function cleanup(effect) {
1282
+ for (const [target, key] of effect.deps) {
1283
+ const keyMap = depMap.get(target);
1284
+ if (!keyMap)
1285
+ continue;
1286
+ const depSet = keyMap.get(key);
1287
+ if (!depSet)
1288
+ continue;
1289
+ depSet.delete(effect);
1290
+ try {
1291
+ const map = leakCleanups.get(depSet);
1292
+ const fn = map?.get(effect);
1293
+ if (fn) {
1294
+ try {
1295
+ fn();
1296
+ }
1297
+ catch { }
1298
+ map.delete(effect);
1299
+ }
1300
+ }
1301
+ catch { }
1302
+ if (depSet.size === 0) {
1303
+ keyMap.delete(key);
1304
+ }
1305
+ if (keyMap.size === 0) {
1306
+ depMap.delete(target);
1307
+ }
1308
+ }
1309
+ effect.deps = [];
1310
+ }
1311
+ function effect(fn, onValueChanged) {
1312
+ const e = new Effect(fn, onValueChanged);
1313
+ runReported(() => e.run());
1314
+ return () => e.stop();
1315
+ }
1316
+ function createScheduledEffect(fn, scheduler) {
1317
+ const e = new Effect(fn);
1318
+ e.scheduler = scheduler;
1319
+ return {
1320
+ run: () => { runReported(() => e.run()); },
1321
+ stop: () => e.stop(),
1322
+ };
1323
+ }
1324
+ function popAsyncTracking(t) {
1325
+ if (!t.pushed)
1326
+ return;
1327
+ t.pushed = false;
1328
+ const i = effectStack.lastIndexOf(t.effect);
1329
+ if (i >= 0)
1330
+ effectStack.splice(i, 1);
1331
+ }
1332
+ const asyncTracking = {
1333
+ capture() {
1334
+ return { effect: effectStack[effectStack.length - 1], pushed: false };
1335
+ },
1336
+ suspend(t, value) {
1337
+ popAsyncTracking(t);
1338
+ return value;
1339
+ },
1340
+ resume(t, value) {
1341
+ if (t.effect && t.effect.active && !t.pushed) {
1342
+ effectStack.push(t.effect);
1343
+ t.pushed = true;
1344
+ }
1345
+ return value;
1346
+ },
1347
+ end(t) {
1348
+ popAsyncTracking(t);
1349
+ },
1350
+ };
1351
+ const UNTRACKED_SENTINEL = new Effect(() => { });
1352
+ UNTRACKED_SENTINEL.active = false;
1353
+ function untracked(fn) {
1354
+ effectStack.push(UNTRACKED_SENTINEL);
1355
+ try {
1356
+ return fn();
1357
+ }
1358
+ finally {
1359
+ effectStack.pop();
1360
+ }
1361
+ }
1362
+ function debugGetDeps(target) {
1363
+ const rawTarget = getRaw(target);
1364
+ return depMap.get(rawTarget);
1365
+ }
1366
+ function debugGetDepMap() {
1367
+ return depMap;
1368
+ }
1369
+
1370
+ function isCheckedInput(el) {
1371
+ if (!el || el.tagName !== 'INPUT')
1372
+ return false;
1373
+ const t = String(el.type || '').toLowerCase();
1374
+ return t === 'checkbox' || t === 'radio';
1375
+ }
1376
+ function isNumericInput(el) {
1377
+ if (!el || el.tagName !== 'INPUT')
1378
+ return false;
1379
+ const t = String(el.type || '').toLowerCase();
1380
+ return t === 'number' || t === 'range';
1381
+ }
1382
+ function readModelValue(el) {
1383
+ if (!el)
1384
+ return undefined;
1385
+ if (isCheckedInput(el))
1386
+ return !!el.checked;
1387
+ if (isNumericInput(el)) {
1388
+ const raw = el.value;
1389
+ if (raw === '' || raw == null)
1390
+ return null;
1391
+ const n = typeof el.valueAsNumber === 'number' ? el.valueAsNumber : Number(raw);
1392
+ return Number.isFinite(n) ? n : null;
1393
+ }
1394
+ return el.value;
1395
+ }
1396
+ class Binding {
1397
+ propertyName;
1398
+ dataSource;
1399
+ dataMember;
1400
+ formatString;
1401
+ converter;
1402
+ converterBack;
1403
+ setter;
1404
+ formatInfo;
1405
+ updateMode = 'onPropertyChanged';
1406
+ _isActive = false;
1407
+ _component;
1408
+ _effectCleanup;
1409
+ _memberPath = null;
1410
+ _memberPathSource;
1411
+ constructor(component, propertyName, dataSource, dataMember, formatString, formatInfo) {
1412
+ this._component = component;
1413
+ this.propertyName = propertyName;
564
1414
  this.dataSource = dataSource;
565
1415
  this.dataMember = dataMember;
566
1416
  this.formatString = formatString;
@@ -754,27 +1604,64 @@ class Binding {
754
1604
  }
755
1605
  }
756
1606
 
1607
+ const RAW_KEY = Flags.RAW;
1608
+ function isPrototypeObject(o) {
1609
+ return Object.prototype.hasOwnProperty.call(o, 'constructor') && typeof o.constructor === 'function' && o.constructor.prototype === o;
1610
+ }
1611
+ function overridesBelow(instance, proto, name) {
1612
+ let p = Object.getPrototypeOf(instance);
1613
+ while (p && p !== proto) {
1614
+ if (Object.prototype.hasOwnProperty.call(p, name))
1615
+ return true;
1616
+ p = Object.getPrototypeOf(p);
1617
+ }
1618
+ return false;
1619
+ }
1620
+ function lazyBindMethods(proto, names) {
1621
+ for (const name of names) {
1622
+ let fn = proto[name];
1623
+ if (typeof fn !== 'function')
1624
+ continue;
1625
+ Object.defineProperty(proto, name, {
1626
+ configurable: true,
1627
+ enumerable: false,
1628
+ get() {
1629
+ if (this === proto || isPrototypeObject(this))
1630
+ return fn;
1631
+ const target = this[RAW_KEY] ?? this;
1632
+ const bound = fn.bind(target);
1633
+ if (!overridesBelow(target, proto, name)) {
1634
+ try {
1635
+ Object.defineProperty(target, name, { value: bound, writable: true, configurable: true, enumerable: true });
1636
+ }
1637
+ catch { }
1638
+ }
1639
+ return bound;
1640
+ },
1641
+ set(value) {
1642
+ if (this === proto && typeof value === 'function') {
1643
+ fn = value;
1644
+ return;
1645
+ }
1646
+ Object.defineProperty(this, name, { value, writable: true, configurable: true, enumerable: true });
1647
+ },
1648
+ });
1649
+ }
1650
+ }
1651
+
1652
+ function isWritablePathKey(target, key) {
1653
+ if (key === '__proto__')
1654
+ return false;
1655
+ if (key === 'constructor' || key === 'prototype')
1656
+ return Object.prototype.hasOwnProperty.call(target, key);
1657
+ return true;
1658
+ }
757
1659
  class BindingCollection {
758
1660
  _items = [];
759
1661
  _component;
760
1662
  _branchScope = null;
761
1663
  constructor(component) {
762
1664
  this._component = component;
763
- this.add = this.add.bind(this);
764
- this.remove = this.remove.bind(this);
765
- this.clear = this.clear.bind(this);
766
- this.activateAll = this.activateAll.bind(this);
767
- this.deactivateAll = this.deactivateAll.bind(this);
768
- this.reActivateAll = this.reActivateAll.bind(this);
769
- this.when = this.when.bind(this);
770
- this.text = this.text.bind(this);
771
- this.value = this.value.bind(this);
772
- this.list = this.list.bind(this);
773
- this.loop = this.loop.bind(this);
774
- this.method = this.method.bind(this);
775
- this.watch = this.watch.bind(this);
776
- this.display = this.display.bind(this);
777
- this.wait = this.wait.bind(this);
778
1665
  }
779
1666
  _own(stop) {
780
1667
  if (this._branchScope) {
@@ -971,12 +1858,12 @@ class BindingCollection {
971
1858
  stopInner();
972
1859
  });
973
1860
  }
974
- ternaryCall = (condFn, onTrue, onFalse) => {
1861
+ ternaryCall(condFn, onTrue, onFalse) {
975
1862
  this._ternarySchedule(condFn, onTrue, onFalse, (run) => queueMicrotask(run));
976
- };
977
- _ternaryCallTop = (condFn, onTrue, onFalse) => {
1863
+ }
1864
+ _ternaryCallTop(condFn, onTrue, onFalse) {
978
1865
  this._ternarySchedule(condFn, onTrue, onFalse, (run) => setTimeout(run, 0));
979
- };
1866
+ }
980
1867
  watch(cb) {
981
1868
  const ef = effect(() => {
982
1869
  cb();
@@ -1063,11 +1950,17 @@ class BindingCollection {
1063
1950
  if (member && source != null) {
1064
1951
  const path = member.split('.');
1065
1952
  let target = source;
1066
- for (let i = 0; i < path.length - 1 && target != null; i++) {
1067
- target = target[path[i]];
1953
+ for (let i = 0; i < path.length && target != null; i++) {
1954
+ const key = path[i];
1955
+ if (!isWritablePathKey(target, key))
1956
+ return;
1957
+ if (i === path.length - 1) {
1958
+ target[key] = value;
1959
+ }
1960
+ else {
1961
+ target = target[key];
1962
+ }
1068
1963
  }
1069
- if (target != null)
1070
- target[path[path.length - 1]] = value;
1071
1964
  }
1072
1965
  else if (source != null && typeof source === 'object' && 'value' in source) {
1073
1966
  source.value = value;
@@ -1136,6 +2029,11 @@ class BindingCollection {
1136
2029
  return null;
1137
2030
  }
1138
2031
  }
2032
+ lazyBindMethods(BindingCollection.prototype, [
2033
+ 'add', 'remove', 'clear', 'activateAll', 'deactivateAll', 'reActivateAll',
2034
+ 'when', 'text', 'value', 'list', 'loop', 'method', 'watch', 'display', 'wait',
2035
+ 'ternaryCall', '_ternaryCallTop'
2036
+ ]);
1139
2037
 
1140
2038
  class Emitter {
1141
2039
  _subscriptions = [];
@@ -1226,18 +2124,14 @@ class Emitter {
1226
2124
 
1227
2125
  class ComponentEmiter {
1228
2126
  component;
1229
- _emitters = new Map();
1230
- _sourceDisposables = new Map();
1231
- _listenerDisposables = new Map();
2127
+ _emitters;
2128
+ _sourceDisposables;
2129
+ _listenerDisposables;
1232
2130
  constructor(component) {
1233
2131
  this.component = component;
1234
- this.fire = this.fire.bind(this);
1235
- this.on = this.on.bind(this);
1236
- this.off = this.off.bind(this);
1237
- this.createEvent = this.createEvent.bind(this);
1238
- this.getOrCreateEmitter = this.getOrCreateEmitter.bind(this);
1239
- this.addSource = this.addSource.bind(this);
1240
- this.clear = this.clear.bind(this);
2132
+ }
2133
+ hasListeners(eventName) {
2134
+ return this._emitters !== undefined && this._emitters.has(eventName);
1241
2135
  }
1242
2136
  fire(eventName, args) {
1243
2137
  try {
@@ -1257,7 +2151,7 @@ class ComponentEmiter {
1257
2151
  }
1258
2152
  off(event, cb) {
1259
2153
  const lower = String(event).toLowerCase();
1260
- const map = this._listenerDisposables.get(lower);
2154
+ const map = this._listenerDisposables?.get(lower);
1261
2155
  if (!map)
1262
2156
  return this;
1263
2157
  const list = map.get(cb);
@@ -1269,10 +2163,11 @@ class ComponentEmiter {
1269
2163
  return this;
1270
2164
  }
1271
2165
  getOrCreateEmitter(name) {
1272
- let e = this._emitters.get(name);
2166
+ const emitters = this._emitters ??= new Map();
2167
+ let e = emitters.get(name);
1273
2168
  if (!e) {
1274
- this._emitters.set(name, new Emitter());
1275
- e = this._emitters.get(name);
2169
+ e = new Emitter();
2170
+ emitters.set(name, e);
1276
2171
  }
1277
2172
  return e;
1278
2173
  }
@@ -1290,10 +2185,11 @@ class ComponentEmiter {
1290
2185
  };
1291
2186
  const emitter = this.getOrCreateEmitter(lowerFull);
1292
2187
  const disp = emitter.event((e) => invoke(e));
1293
- let map = this._listenerDisposables.get(lowerFull);
2188
+ const listeners = this._listenerDisposables ??= new Map();
2189
+ let map = listeners.get(lowerFull);
1294
2190
  if (!map) {
1295
2191
  map = new Map();
1296
- this._listenerDisposables.set(lowerFull, map);
2192
+ listeners.set(lowerFull, map);
1297
2193
  }
1298
2194
  const list = map.get(cb);
1299
2195
  if (list) {
@@ -1319,10 +2215,11 @@ class ComponentEmiter {
1319
2215
  }
1320
2216
  catch { }
1321
2217
  if (disp) {
1322
- let set = this._sourceDisposables.get(lower);
2218
+ const sources = this._sourceDisposables ??= new Map();
2219
+ let set = sources.get(lower);
1323
2220
  if (!set) {
1324
2221
  set = new Set();
1325
- this._sourceDisposables.set(lower, set);
2222
+ sources.set(lower, set);
1326
2223
  }
1327
2224
  set.add(disp);
1328
2225
  this.component.motif.register(disposableCore.toDisposable(() => {
@@ -1341,21 +2238,21 @@ class ComponentEmiter {
1341
2238
  clear(event) {
1342
2239
  if (event) {
1343
2240
  const lower = event.toLowerCase();
1344
- const srcs = this._sourceDisposables.get(lower);
2241
+ const srcs = this._sourceDisposables?.get(lower);
1345
2242
  srcs?.forEach(d => { try {
1346
2243
  d.dispose();
1347
2244
  }
1348
2245
  catch { } });
1349
- this._sourceDisposables.delete(lower);
1350
- const agg = this._emitters.get(lower);
2246
+ this._sourceDisposables?.delete(lower);
2247
+ const agg = this._emitters?.get(lower);
1351
2248
  try {
1352
2249
  agg?.dispose();
1353
2250
  }
1354
2251
  catch { }
1355
- this._emitters.delete(lower);
1356
- this._listenerDisposables.delete(lower);
2252
+ this._emitters?.delete(lower);
2253
+ this._listenerDisposables?.delete(lower);
1357
2254
  }
1358
- else {
2255
+ else if (this._emitters) {
1359
2256
  for (const key of Array.from(this._emitters.keys())) {
1360
2257
  this.clear(key);
1361
2258
  }
@@ -1363,6 +2260,7 @@ class ComponentEmiter {
1363
2260
  return this;
1364
2261
  }
1365
2262
  }
2263
+ lazyBindMethods(ComponentEmiter.prototype, ['fire', 'on', 'off', 'createEvent', 'getOrCreateEmitter', 'addSource', 'clear']);
1366
2264
 
1367
2265
  const METHOD_ATTRS = new Set([
1368
2266
  'focus', 'blur', 'click', 'pause', 'submit', 'reset',
@@ -1380,11 +2278,13 @@ const ARGUMENT_METHODS = new Set(['setSelectionRange', 'setRangeText', 'setPoint
1380
2278
  const PROPERTY_FIRST = new Set(['checked', 'selected', 'muted', 'indeterminate', 'srcObject']);
1381
2279
  class controlAttribute {
1382
2280
  _parent;
1383
- _attrMap = new Map();
1384
- _watchers = new Map();
2281
+ _attrMapStore;
2282
+ _watchersStore;
1385
2283
  constructor(parent) {
1386
2284
  this._parent = parent;
1387
2285
  }
2286
+ get _attrMap() { return this._attrMapStore ??= new Map(); }
2287
+ get _watchers() { return this._watchersStore ??= new Map(); }
1388
2288
  /** @deprecated Tek kaynak `_attrMap`; geriye dönük okuma için türetilmiş görünüm. */
1389
2289
  get attributes() {
1390
2290
  return Array.from(this._attrMap.entries(), ([name, value]) => ({ name: String(name), value }));
@@ -1915,10 +2815,13 @@ class controlClass {
1915
2815
  constructor(parent) {
1916
2816
  this._parent = parent;
1917
2817
  }
1918
- _counts = new Map();
1919
- _staticSet = new Set();
1920
- _watchers = new Map();
2818
+ _countsStore;
2819
+ _staticSetStore;
2820
+ _watchersStore;
1921
2821
  _watcherSeq = 0;
2822
+ get _counts() { return this._countsStore ??= new Map(); }
2823
+ get _staticSet() { return this._staticSetStore ??= new Set(); }
2824
+ get _watchers() { return this._watchersStore ??= new Map(); }
1922
2825
  add(...values) {
1923
2826
  for (const value of values) {
1924
2827
  if (typeof value === 'function') {
@@ -2474,6 +3377,203 @@ class ComponentMotif {
2474
3377
  }
2475
3378
  }
2476
3379
 
3380
+ const SIGNAL_TARGET = Symbol('SignalTarget');
3381
+ const SIGNAL_KEY = Symbol('SignalKey');
3382
+ class Signal {
3383
+ _value;
3384
+ _target;
3385
+ _key;
3386
+ _equals;
3387
+ _disposed = false;
3388
+ static create(initialValue, equals) {
3389
+ return new Signal(initialValue, equals);
3390
+ }
3391
+ constructor(initialValue, equals = Object.is) {
3392
+ this._value = initialValue;
3393
+ this._target = { [SIGNAL_TARGET]: true };
3394
+ this._key = SIGNAL_KEY;
3395
+ this._equals = equals;
3396
+ }
3397
+ get value() {
3398
+ if (!this._disposed) {
3399
+ track(this._target, this._key);
3400
+ }
3401
+ return this._value;
3402
+ }
3403
+ set value(newValue) {
3404
+ if (this._disposed)
3405
+ return;
3406
+ if (!this._equals(this._value, newValue)) {
3407
+ this._value = newValue;
3408
+ trigger(this._target, this._key);
3409
+ }
3410
+ }
3411
+ peek() {
3412
+ return this._value;
3413
+ }
3414
+ update(updater) {
3415
+ this.value = (updater(this._value));
3416
+ }
3417
+ mutate(mutator) {
3418
+ if (this._disposed)
3419
+ return;
3420
+ mutator(this._value);
3421
+ trigger(this._target, this._key);
3422
+ }
3423
+ notify() {
3424
+ if (this._disposed)
3425
+ return;
3426
+ trigger(this._target, this._key);
3427
+ }
3428
+ asReadonly() {
3429
+ const self = this;
3430
+ return {
3431
+ get value() { return self.value; },
3432
+ peek() { return self.peek(); },
3433
+ valueOf() { return self.valueOf(); },
3434
+ toString() { return self.toString(); }
3435
+ };
3436
+ }
3437
+ dispose() {
3438
+ this._disposed = true;
3439
+ }
3440
+ valueOf() {
3441
+ return this.value;
3442
+ }
3443
+ toString() {
3444
+ return String(this.value);
3445
+ }
3446
+ }
3447
+ class Computed {
3448
+ _value;
3449
+ _dirty = true;
3450
+ _computing = false;
3451
+ _target;
3452
+ _key;
3453
+ _getter;
3454
+ _cleanup;
3455
+ constructor(getter) {
3456
+ this._getter = getter;
3457
+ this._target = { [SIGNAL_TARGET]: true };
3458
+ this._key = SIGNAL_KEY;
3459
+ this._cleanup = effect(() => {
3460
+ if (this._computing)
3461
+ return;
3462
+ this._computing = true;
3463
+ try {
3464
+ const newVal = this._getter();
3465
+ const changed = this._dirty || !Object.is(this._value, newVal);
3466
+ this._value = newVal;
3467
+ this._dirty = false;
3468
+ if (changed) {
3469
+ trigger(this._target, this._key);
3470
+ }
3471
+ }
3472
+ finally {
3473
+ this._computing = false;
3474
+ }
3475
+ });
3476
+ }
3477
+ get value() {
3478
+ track(this._target, this._key);
3479
+ if (this._dirty) {
3480
+ this._computing = true;
3481
+ pauseTracking();
3482
+ try {
3483
+ this._value = this._getter();
3484
+ this._dirty = false;
3485
+ }
3486
+ finally {
3487
+ resetTracking();
3488
+ this._computing = false;
3489
+ }
3490
+ }
3491
+ return this._value;
3492
+ }
3493
+ peek() {
3494
+ if (this._dirty) {
3495
+ pauseTracking();
3496
+ try {
3497
+ this._value = this._getter();
3498
+ this._dirty = false;
3499
+ }
3500
+ finally {
3501
+ resetTracking();
3502
+ }
3503
+ }
3504
+ return this._value;
3505
+ }
3506
+ dispose() {
3507
+ if (this._cleanup) {
3508
+ this._cleanup();
3509
+ this._cleanup = undefined;
3510
+ }
3511
+ }
3512
+ valueOf() {
3513
+ return this.value;
3514
+ }
3515
+ toString() {
3516
+ return String(this.value);
3517
+ }
3518
+ }
3519
+ class LazyComputed {
3520
+ _value;
3521
+ _dirty = true;
3522
+ _disposed = false;
3523
+ _target;
3524
+ _key;
3525
+ _getter;
3526
+ _runner;
3527
+ constructor(getter) {
3528
+ this._getter = getter;
3529
+ this._target = { [SIGNAL_TARGET]: true };
3530
+ this._key = SIGNAL_KEY;
3531
+ this._runner = createScheduledEffect(() => { this._value = this._getter(); }, () => {
3532
+ if (this._dirty || this._disposed)
3533
+ return;
3534
+ this._dirty = true;
3535
+ trigger(this._target, this._key);
3536
+ });
3537
+ }
3538
+ get value() {
3539
+ if (!this._disposed) {
3540
+ track(this._target, this._key);
3541
+ }
3542
+ this._refresh();
3543
+ return this._value;
3544
+ }
3545
+ peek() {
3546
+ this._refresh();
3547
+ return this._value;
3548
+ }
3549
+ get isDirty() {
3550
+ return this._dirty;
3551
+ }
3552
+ _refresh() {
3553
+ if (!this._dirty)
3554
+ return;
3555
+ if (this._disposed) {
3556
+ this._value = untracked(this._getter);
3557
+ }
3558
+ else {
3559
+ this._runner.run();
3560
+ }
3561
+ this._dirty = false;
3562
+ }
3563
+ dispose() {
3564
+ if (this._disposed)
3565
+ return;
3566
+ this._disposed = true;
3567
+ this._runner.stop();
3568
+ }
3569
+ valueOf() {
3570
+ return this.value;
3571
+ }
3572
+ toString() {
3573
+ return String(this.value);
3574
+ }
3575
+ }
3576
+
2477
3577
  let activeResolver = null;
2478
3578
  let activeSlot = null;
2479
3579
  let rawScopedIn = null;
@@ -3008,6 +4108,92 @@ class ServiceProvider {
3008
4108
  }
3009
4109
  }
3010
4110
 
4111
+ const contentBlocks = { live: 0 };
4112
+
4113
+ const OPTIONS_OWNER = Symbol('motif.optionsOwner');
4114
+ const TRANSITION_SLOT = Symbol('motif.transition');
4115
+
4116
+ const transitionSettings = { mode: 'concurrent' };
4117
+ const noop = () => { };
4118
+ function createTracker() {
4119
+ const running = new WeakMap();
4120
+ function track(node, resolve, via) {
4121
+ const host = node?.parentNode ?? via?.parentNode;
4122
+ if (!host)
4123
+ return { done: resolve, release: noop };
4124
+ let set = running.get(host);
4125
+ if (!set)
4126
+ running.set(host, (set = new Set()));
4127
+ let finish = noop;
4128
+ const entry = { node: node, via: via ?? null, done: new Promise(r => { finish = r; }) };
4129
+ set.add(entry);
4130
+ let settled = false;
4131
+ const release = () => {
4132
+ if (settled)
4133
+ return;
4134
+ settled = true;
4135
+ set.delete(entry);
4136
+ finish();
4137
+ };
4138
+ return {
4139
+ done: () => {
4140
+ const first = !settled;
4141
+ release();
4142
+ if (first && resolve)
4143
+ resolve();
4144
+ },
4145
+ release,
4146
+ finished: entry.done,
4147
+ };
4148
+ }
4149
+ function pending(host, except) {
4150
+ if (!host)
4151
+ return null;
4152
+ const set = running.get(host);
4153
+ if (!set || set.size === 0)
4154
+ return null;
4155
+ let waits = null;
4156
+ for (const entry of set) {
4157
+ if (entry.node === except)
4158
+ continue;
4159
+ if (entry.node.parentNode !== host && entry.via?.parentNode !== host) {
4160
+ set.delete(entry);
4161
+ continue;
4162
+ }
4163
+ (waits ??= []).push(entry.done);
4164
+ }
4165
+ return waits ? Promise.all(waits).then(noop) : null;
4166
+ }
4167
+ return { track, pending };
4168
+ }
4169
+ const leaves = createTracker();
4170
+ const enters = createTracker();
4171
+ const trackLeave = leaves.track;
4172
+ const pendingLeaves = leaves.pending;
4173
+ const trackEnter = enters.track;
4174
+ const pendingEnters = enters.pending;
4175
+ function deferUntilEntered(node, run, play) {
4176
+ const host = node.parentNode;
4177
+ const handle = {
4178
+ finished: run.finished ?? Promise.resolve(),
4179
+ playState: 'pending',
4180
+ addEventListener: noop,
4181
+ removeEventListener: noop,
4182
+ cancel: noop,
4183
+ };
4184
+ queueMicrotask(() => {
4185
+ const wait = pendingEnters(host, node);
4186
+ if (wait)
4187
+ wait.then(() => { play(); });
4188
+ else
4189
+ play();
4190
+ });
4191
+ return handle;
4192
+ }
4193
+ function isTransitionMode(value) {
4194
+ return value === 'concurrent' || value === 'out-in' || value === 'in-out';
4195
+ }
4196
+
3011
4197
  /** DI token'ını okunur biçime çevirir (dev uyarıları için). */
3012
4198
  function describeServiceToken(t) {
3013
4199
  if (typeof t === 'string')
@@ -3018,9 +4204,12 @@ function describeServiceToken(t) {
3018
4204
  return t.name || '[AnonymousClass]';
3019
4205
  return String(t);
3020
4206
  }
4207
+ function peekTransition(c) {
4208
+ return c?.motif?.options?.[TRANSITION_SLOT];
4209
+ }
3021
4210
  /**WAAPI keyframe (transitionIn) YA DA CSS class transition (name/classes) tanımlı olarak enter animasyonu varmı */
3022
4211
  function clearNavDirection(c) {
3023
- const t = c?.motif?.options?.transition;
4212
+ const t = peekTransition(c);
3024
4213
  if (!t?._markedDirection)
3025
4214
  return;
3026
4215
  t._markedDirection = false;
@@ -3029,57 +4218,286 @@ function clearNavDirection(c) {
3029
4218
  }
3030
4219
  catch { }
3031
4220
  }
3032
- function wantsEnterTransition(c) {
3033
- const t = c?.motif.options?.transition;
3034
- return !!(c?.motif.options?.transitionIn || (t && (t.classes || (t.name && t.name.length > 0))));
4221
+ function enterModeOf(container) {
4222
+ let c = container;
4223
+ while (c) {
4224
+ const mode = peekTransition(c)?.mode;
4225
+ if (mode)
4226
+ return mode;
4227
+ const node = c.element;
4228
+ if (!node || node.nodeType !== Node.COMMENT_NODE)
4229
+ break;
4230
+ c = c.parent ?? c._base?._leaveContainer;
4231
+ }
4232
+ return transitionSettings.mode;
3035
4233
  }
3036
- const ComponentHelper = {
3037
- callInitializeComponent(component) {
3038
- const sender = component;
3039
- const ev = { cancel: false };
3040
- if (!component || component.isDisposed) {
3041
- return;
3042
- }
3043
- // 1) class method initializeComponent
3044
- if (typeof component.initializeComponent === 'function') {
3045
- callReported(() => component.initializeComponent(sender, ev), 'MJX122', 'initializeComponent');
3046
- }
3047
- // 2) aggregated extra initializeComponent handlers (örn, from props)
3048
- if (Array.isArray(component._base._initializeComponentHandlers) && component._base._initializeComponentHandlers.length) {
3049
- for (const fn of component._base._initializeComponentHandlers) {
3050
- callReported(() => fn(sender, ev), 'MJX122', 'initializeComponent');
4234
+ function leaveModeOf(c) {
4235
+ return enterModeOf(c.parent ?? c._base?._leaveContainer);
4236
+ }
4237
+ function wantsEnterTransition(c) {
4238
+ const o = c?.motif?.options;
4239
+ const t = o?.[TRANSITION_SLOT];
4240
+ return !!(o?.transitionIn || (t && (t.classes || (t.name && t.name.length > 0))));
4241
+ }
4242
+ function createTransitionApi(owner) {
4243
+ const cur = () => owner.motif.options?.[TRANSITION_SLOT] ?? t;
4244
+ const t = {
4245
+ transitionInfo: () => {
4246
+ const s = cur();
4247
+ return {
4248
+ in: getTransitionInfo(owner.element, `${s.name}-enter ${s.name}-enter-start`),
4249
+ out: getTransitionInfo(owner.element, `${s.name}-leave ${s.name}-leave-start`),
4250
+ };
4251
+ },
4252
+ name: '',
4253
+ mode: undefined,
4254
+ classes: undefined,
4255
+ activeCssCancel: null,
4256
+ activeCssPhase: null,
4257
+ cssProps: () => {
4258
+ const s = cur();
4259
+ if (s.classes) {
4260
+ return { name: s.classes.name || s.name || '', ...s.classes };
4261
+ }
4262
+ if (s.name && s.name.length > 0) {
4263
+ return { name: s.name };
3051
4264
  }
3052
- }
3053
- // 3) class method oninitializeComponent
3054
- if (typeof component.oninitializeComponent === 'function') {
3055
- callReported(() => component.oninitializeComponent(sender, ev), 'MJX122', 'oninitializeComponent');
3056
- }
3057
- // 4) aggregated extra oninitializeComponent handlers (örn, from props)
3058
- if (Array.isArray(component._base._onInitializeComponentHandlers) && component._base._onInitializeComponentHandlers.length) {
3059
- for (const fn of component._base._onInitializeComponentHandlers) {
3060
- callReported(() => fn(sender, ev), 'MJX122', 'oninitializeComponent');
4265
+ return null;
4266
+ },
4267
+ skipNextLeave: false,
4268
+ _suppressEnter: false,
4269
+ _markedDirection: false,
4270
+ in: (op) => {
4271
+ owner.motif.options.transitionIn = op;
4272
+ },
4273
+ out: (op) => {
4274
+ owner.motif.options.transitionOut = op;
4275
+ },
4276
+ enterTransition: (resolve) => {
4277
+ const s = cur();
4278
+ const base = owner._base;
4279
+ const appear = !base._enterPlayed;
4280
+ base._enterPlayed = true;
4281
+ base._enterSeq = (base._enterSeq ?? 0) + 1;
4282
+ if (s._suppressEnter) {
4283
+ resolve && resolve();
4284
+ return shimAnimation;
3061
4285
  }
3062
- }
3063
- },
3064
- async callDisposing(component) {
3065
- ComponentHelper.backgroundCallback(() => {
3066
- if (!component || component.isDisposed) {
3067
- return;
4286
+ const attempt = {};
4287
+ base._enterRun = attempt;
4288
+ const enter = trackEnter(owner.element, () => {
4289
+ if (owner._base?._enterRun === attempt) {
4290
+ owner._base._enterRun = null;
4291
+ clearNavDirection(owner);
4292
+ }
4293
+ resolve && resolve();
4294
+ }, owner.motif.options.placeholder);
4295
+ const transitionIn = owner.motif.options.transitionIn;
4296
+ const animation = transitionIn
4297
+ ? s.run(transitionIn.keyframes, transitionIn.options, enter.done)
4298
+ : s._runCss('enter', enter.done, appear);
4299
+ if (animation && animation !== shimAnimation && typeof animation.addEventListener === 'function') {
4300
+ animation.addEventListener('cancel', enter.release);
4301
+ }
4302
+ return animation;
4303
+ },
4304
+ leaveTransition: (resolve) => {
4305
+ const s = cur();
4306
+ const node = owner.element;
4307
+ const leave = trackLeave(node, resolve);
4308
+ const play = () => {
4309
+ const transitionOut = owner.motif.options?.transitionOut;
4310
+ const animation = transitionOut
4311
+ ? s.run(transitionOut.keyframes, transitionOut.options, leave.done)
4312
+ : s._runCss('leave', leave.done);
4313
+ if (animation && animation !== shimAnimation && typeof animation.addEventListener === 'function') {
4314
+ animation.addEventListener('cancel', leave.release);
4315
+ }
4316
+ return animation;
4317
+ };
4318
+ if (leave.finished && leaveModeOf(owner) === 'in-out') {
4319
+ return deferUntilEntered(node, leave, play);
3068
4320
  }
3069
- const sender = component, ev = { cancel: false };
3070
- if (component.onDisposing) {
3071
- callReported(() => component.onDisposing(sender, ev), 'MJX122', 'onDisposing');
4321
+ return play();
4322
+ },
4323
+ _runCss: (phase, resolve, appear = false) => {
4324
+ const s = cur();
4325
+ if (phase === 'enter' && s.activeCssPhase === 'leave') {
4326
+ resolve && resolve();
4327
+ return shimAnimation;
3072
4328
  }
3073
- if (Array.isArray(component._base._onDisposingHandlers)) {
3074
- for (const fn of component._base._onDisposingHandlers) {
3075
- callReported(() => fn(sender, ev), 'MJX122', 'onDisposing');
4329
+ const cssProps = s.cssProps();
4330
+ const el = owner.element;
4331
+ if (cssProps && el && el.nodeType === 1 && el.classList) {
4332
+ try {
4333
+ s.activeCssCancel?.();
3076
4334
  }
4335
+ catch { }
4336
+ const cancel = runCssTransition(el, cssProps, phase, () => {
4337
+ s.activeCssCancel = null;
4338
+ s.activeCssPhase = null;
4339
+ resolve && resolve();
4340
+ }, appear);
4341
+ s.activeCssCancel = cancel;
4342
+ s.activeCssPhase = phase;
4343
+ return shimAnimation;
4344
+ }
4345
+ resolve && resolve();
4346
+ return shimAnimation;
4347
+ },
4348
+ activeAnimations: [],
4349
+ run: (keyframes, options, resolve) => {
4350
+ const s = cur();
4351
+ owner.motif.stopAnimations();
4352
+ const element = owner.element;
4353
+ if (element.animate) {
4354
+ var x = element.animate(keyframes, options);
4355
+ s.activeAnimations.push(x);
4356
+ let cleanedUp = false;
4357
+ const safeCleanup = () => {
4358
+ if (cleanedUp)
4359
+ return;
4360
+ cleanedUp = true;
4361
+ try {
4362
+ if (s.activeAnimations) {
4363
+ s.activeAnimations = s.activeAnimations.filter(a => a !== x);
4364
+ }
4365
+ }
4366
+ catch { }
4367
+ };
4368
+ x.addEventListener('finish', () => {
4369
+ resolve && resolve();
4370
+ safeCleanup();
4371
+ });
4372
+ x.oncancel = () => {
4373
+ safeCleanup();
4374
+ };
4375
+ return x;
3077
4376
  }
3078
- if (component.ondisposing) {
3079
- callReported(() => component.ondisposing(sender, ev), 'MJX122', 'ondisposing');
4377
+ else {
4378
+ resolve && resolve();
4379
+ const g = globalThis;
4380
+ if (typeof g.Animation === 'function') {
4381
+ try {
4382
+ return new g.Animation();
4383
+ }
4384
+ catch { /* ignore */ }
4385
+ }
4386
+ return shimAnimation;
3080
4387
  }
3081
- component._base.emiters.fire('ondisposing', ev);
3082
- });
4388
+ }
4389
+ };
4390
+ return t;
4391
+ }
4392
+ class ComponentOptionsImpl {
4393
+ [OPTIONS_OWNER];
4394
+ [TRANSITION_SLOT];
4395
+ constructor(owner) {
4396
+ this[OPTIONS_OWNER] = owner;
4397
+ }
4398
+ get transition() {
4399
+ return this[TRANSITION_SLOT] ??= createTransitionApi(this[OPTIONS_OWNER]);
4400
+ }
4401
+ set transition(value) {
4402
+ this[TRANSITION_SLOT] = value;
4403
+ }
4404
+ set enableRouterClassing(value) {
4405
+ try {
4406
+ const ins = this[OPTIONS_OWNER];
4407
+ const callback = ins.context.onRouterChanged(() => {
4408
+ ComponentHelper.routerClassing.call(ins, value);
4409
+ });
4410
+ ins.motif.register(disposableCore.toDisposable(() => {
4411
+ callback();
4412
+ }));
4413
+ ComponentHelper.routerClassing.call(ins, value);
4414
+ }
4415
+ catch (error) {
4416
+ reportError('MJX105', error);
4417
+ }
4418
+ }
4419
+ getInstance() {
4420
+ return this[OPTIONS_OWNER];
4421
+ }
4422
+ get display() {
4423
+ return this[OPTIONS_OWNER].isVisible;
4424
+ }
4425
+ set display(value) {
4426
+ if (value) {
4427
+ this[OPTIONS_OWNER].motif.show();
4428
+ }
4429
+ else {
4430
+ this[OPTIONS_OWNER].motif.hide();
4431
+ }
4432
+ }
4433
+ hasEvent(name) {
4434
+ return !!this[OPTIONS_OWNER]._eventHandlers?.has(name);
4435
+ }
4436
+ }
4437
+ lazyBindMethods(ComponentOptionsImpl.prototype, ['getInstance', 'hasEvent']);
4438
+ function fireLifecycle(component, name, ev) {
4439
+ const base = component._base;
4440
+ if (base)
4441
+ base.emiters.fire(name, ev);
4442
+ }
4443
+ function hasLifecycleHook(component, hook, listName, lowerName, legacyProp) {
4444
+ if (component[hook])
4445
+ return true;
4446
+ const list = component._base[listName];
4447
+ if (Array.isArray(list) && list.length > 0)
4448
+ return true;
4449
+ if (legacyProp && component[legacyProp])
4450
+ return true;
4451
+ return component._base.emiters.hasListeners(lowerName);
4452
+ }
4453
+ const ComponentHelper = {
4454
+ callInitializeComponent(component) {
4455
+ const sender = component;
4456
+ const ev = { cancel: false };
4457
+ if (!component || component.isDisposed) {
4458
+ return;
4459
+ }
4460
+ // 1) class method initializeComponent
4461
+ if (typeof component.initializeComponent === 'function') {
4462
+ callReported(() => component.initializeComponent(sender, ev), 'MJX122', 'initializeComponent');
4463
+ }
4464
+ // 2) aggregated extra initializeComponent handlers (örn, from props)
4465
+ if (Array.isArray(component._base._initializeComponentHandlers) && component._base._initializeComponentHandlers.length) {
4466
+ for (const fn of component._base._initializeComponentHandlers) {
4467
+ callReported(() => fn(sender, ev), 'MJX122', 'initializeComponent');
4468
+ }
4469
+ }
4470
+ // 3) class method oninitializeComponent
4471
+ if (typeof component.oninitializeComponent === 'function') {
4472
+ callReported(() => component.oninitializeComponent(sender, ev), 'MJX122', 'oninitializeComponent');
4473
+ }
4474
+ // 4) aggregated extra oninitializeComponent handlers (örn, from props)
4475
+ if (Array.isArray(component._base._onInitializeComponentHandlers) && component._base._onInitializeComponentHandlers.length) {
4476
+ for (const fn of component._base._onInitializeComponentHandlers) {
4477
+ callReported(() => fn(sender, ev), 'MJX122', 'oninitializeComponent');
4478
+ }
4479
+ }
4480
+ },
4481
+ callDisposing(component) {
4482
+ if (!component || component.isDisposed) {
4483
+ return;
4484
+ }
4485
+ if (!hasLifecycleHook(component, 'onDisposing', '_onDisposingHandlers', 'ondisposing', 'ondisposing')) {
4486
+ return;
4487
+ }
4488
+ const sender = component, ev = { cancel: false };
4489
+ if (component.onDisposing) {
4490
+ callReported(() => component.onDisposing(sender, ev), 'MJX122', 'onDisposing');
4491
+ }
4492
+ if (Array.isArray(component._base._onDisposingHandlers)) {
4493
+ for (const fn of component._base._onDisposingHandlers) {
4494
+ callReported(() => fn(sender, ev), 'MJX122', 'onDisposing');
4495
+ }
4496
+ }
4497
+ if (component.ondisposing) {
4498
+ callReported(() => component.ondisposing(sender, ev), 'MJX122', 'ondisposing');
4499
+ }
4500
+ fireLifecycle(component, 'ondisposing', ev);
3083
4501
  },
3084
4502
  callActivated(component) {
3085
4503
  if (!component || component.isDisposed) {
@@ -3094,7 +4512,7 @@ const ComponentHelper = {
3094
4512
  callReported(() => fn(sender, ev), 'MJX122', 'onActivated');
3095
4513
  }
3096
4514
  }
3097
- component._base.emiters.fire('onactivated', ev);
4515
+ fireLifecycle(component, 'onactivated', ev);
3098
4516
  },
3099
4517
  callDeactivated(component) {
3100
4518
  if (!component || component.isDisposed) {
@@ -3109,7 +4527,7 @@ const ComponentHelper = {
3109
4527
  callReported(() => fn(sender, ev), 'MJX122', 'onDeactivated');
3110
4528
  }
3111
4529
  }
3112
- component._base.emiters.fire('ondeactivated', ev);
4530
+ fireLifecycle(component, 'ondeactivated', ev);
3113
4531
  },
3114
4532
  deactivateTree(component, deep = true) {
3115
4533
  if (!component || component.isDisposed || !component.isBuilt || !component._base || component._base._inactive) {
@@ -3117,7 +4535,7 @@ const ComponentHelper = {
3117
4535
  }
3118
4536
  component._base._inactive = true;
3119
4537
  ComponentHelper.callDeactivated(component);
3120
- if (!deep) {
4538
+ if (!deep || component.isDisposed) {
3121
4539
  return;
3122
4540
  }
3123
4541
  for (const c of component.controls.items.slice()) {
@@ -3132,7 +4550,7 @@ const ComponentHelper = {
3132
4550
  }
3133
4551
  component._base._inactive = false;
3134
4552
  ComponentHelper.callActivated(component);
3135
- if (!deep) {
4553
+ if (!deep || component.isDisposed) {
3136
4554
  return;
3137
4555
  }
3138
4556
  for (const c of component.controls.items.slice()) {
@@ -3141,34 +4559,36 @@ const ComponentHelper = {
3141
4559
  }
3142
4560
  }
3143
4561
  },
3144
- async callDisposed(component) {
4562
+ callDisposed(component) {
3145
4563
  if (!component || !component._base || component._base._disposedFired) {
3146
4564
  return;
3147
4565
  }
3148
4566
  component._base._disposedFired = true;
3149
- const sender = component, ev = { cancel: false };
3150
- if (component.onDisposed) {
3151
- callReported(() => component.onDisposed(sender, ev), 'MJX122', 'onDisposed');
3152
- }
3153
- if (Array.isArray(component._base._onDisposedHandlers)) {
3154
- for (const fn of component._base._onDisposedHandlers) {
3155
- callReported(() => fn(sender, ev), 'MJX122', 'onDisposed');
4567
+ if (hasLifecycleHook(component, 'onDisposed', '_onDisposedHandlers', 'ondisposed', 'ondisposed')) {
4568
+ const sender = component, ev = { cancel: false };
4569
+ if (component.onDisposed) {
4570
+ callReported(() => component.onDisposed(sender, ev), 'MJX122', 'onDisposed');
3156
4571
  }
4572
+ if (Array.isArray(component._base._onDisposedHandlers)) {
4573
+ for (const fn of component._base._onDisposedHandlers) {
4574
+ callReported(() => fn(sender, ev), 'MJX122', 'onDisposed');
4575
+ }
4576
+ }
4577
+ if (component.ondisposed) {
4578
+ callReported(() => component.ondisposed(sender, ev), 'MJX122', 'ondisposed');
4579
+ }
4580
+ fireLifecycle(component, 'ondisposed', ev);
3157
4581
  }
3158
- if (component.ondisposed) {
3159
- callReported(() => component.ondisposed(sender, ev), 'MJX122', 'ondisposed');
3160
- }
3161
- component._base.emiters.fire('ondisposed', ev);
3162
4582
  try {
3163
4583
  globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:disposed', { id: component.id, type: component.constructor?.name });
3164
4584
  }
3165
4585
  catch { }
3166
4586
  },
3167
- async callBuilt(component) {
3168
- ComponentHelper.backgroundCallback(() => {
3169
- if (!component || component.isDisposed) {
3170
- return;
3171
- }
4587
+ callBuilt(component) {
4588
+ if (!component || component.isDisposed) {
4589
+ return;
4590
+ }
4591
+ if (hasLifecycleHook(component, 'onBuilt', '_onBuiltHandlers', 'onbuilt', 'onbuilt')) {
3172
4592
  const sender = component, ev = { cancel: false };
3173
4593
  if (component.onBuilt) {
3174
4594
  callReported(() => component.onBuilt(sender, ev), 'MJX122', 'onBuilt');
@@ -3181,12 +4601,12 @@ const ComponentHelper = {
3181
4601
  if (component.onbuilt) {
3182
4602
  callReported(() => component.onbuilt(sender, ev), 'MJX122', 'onbuilt');
3183
4603
  }
3184
- component._base.emiters.fire('onbuilt', ev);
3185
- try {
3186
- globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:mounted', { id: component.id, type: component.constructor?.name });
3187
- }
3188
- catch { }
3189
- });
4604
+ fireLifecycle(component, 'onbuilt', ev);
4605
+ }
4606
+ try {
4607
+ globalThis.__MOTIF_DEVTOOLS_BUS__?.publish?.('component:mounted', { id: component.id, type: component.constructor?.name });
4608
+ }
4609
+ catch { }
3190
4610
  },
3191
4611
  scheduleMounted(component) {
3192
4612
  if (!component || component.isDisposed || component._base._mountedScheduled) {
@@ -3230,47 +4650,49 @@ const ComponentHelper = {
3230
4650
  if (component.onmounted) {
3231
4651
  callReported(() => component.onmounted(sender, ev), 'MJX122', 'onmounted');
3232
4652
  }
3233
- component._base.emiters.fire('onmounted', ev);
4653
+ fireLifecycle(component, 'onmounted', ev);
3234
4654
  },
3235
- async callBuilding(component) {
3236
- ComponentHelper.backgroundCallback(() => {
3237
- if (!component || component.isDisposed) {
3238
- return;
3239
- }
3240
- const sender = component, ev = { cancel: false };
3241
- if (component.onBuilding) {
3242
- callReported(() => component.onBuilding(sender, ev), 'MJX122', 'onBuilding');
3243
- }
3244
- if (Array.isArray(component._base._onBuildingHandlers)) {
3245
- for (const fn of component._base._onBuildingHandlers) {
3246
- callReported(() => fn(sender, ev), 'MJX122', 'onBuilding');
3247
- }
4655
+ callBuilding(component) {
4656
+ if (!component || component.isDisposed) {
4657
+ return;
4658
+ }
4659
+ if (!hasLifecycleHook(component, 'onBuilding', '_onBuildingHandlers', 'onbuilding')) {
4660
+ return;
4661
+ }
4662
+ const sender = component, ev = { cancel: false };
4663
+ if (component.onBuilding) {
4664
+ callReported(() => component.onBuilding(sender, ev), 'MJX122', 'onBuilding');
4665
+ }
4666
+ if (Array.isArray(component._base._onBuildingHandlers)) {
4667
+ for (const fn of component._base._onBuildingHandlers) {
4668
+ callReported(() => fn(sender, ev), 'MJX122', 'onBuilding');
3248
4669
  }
3249
- component._base.emiters.fire('onbuilding', ev);
3250
- });
4670
+ }
4671
+ fireLifecycle(component, 'onbuilding', ev);
3251
4672
  },
3252
- async callConfig(component) {
3253
- ComponentHelper.backgroundCallback(() => {
3254
- if (!component || component.isDisposed || component.isConfigured) {
3255
- return;
3256
- }
3257
- component.isConfigured = true;
3258
- if (component.motif.options._preconfig) {
3259
- safeCallSilent(() => component.motif.options._preconfig(component), 'Component._preconfig');
3260
- }
3261
- const sender = component, ev = { cancel: false };
3262
- if (component.onConfig) {
3263
- callReported(() => component.onConfig(sender, ev), 'MJX122', 'onConfig');
3264
- }
3265
- if (Array.isArray(component._base._onConfigHandlers)) {
3266
- for (const fn of component._base._onConfigHandlers) {
3267
- callReported(() => fn(sender, ev), 'MJX122', 'onConfig');
3268
- }
4673
+ callConfig(component) {
4674
+ if (!component || component.isDisposed || component.isConfigured) {
4675
+ return;
4676
+ }
4677
+ component.isConfigured = true;
4678
+ if (component.motif.options._preconfig) {
4679
+ safeCallSilent(() => component.motif.options._preconfig(component), 'Component._preconfig');
4680
+ }
4681
+ if (!hasLifecycleHook(component, 'onConfig', '_onConfigHandlers', 'onconfig')) {
4682
+ return;
4683
+ }
4684
+ const sender = component, ev = { cancel: false };
4685
+ if (component.onConfig) {
4686
+ callReported(() => component.onConfig(sender, ev), 'MJX122', 'onConfig');
4687
+ }
4688
+ if (Array.isArray(component._base._onConfigHandlers)) {
4689
+ for (const fn of component._base._onConfigHandlers) {
4690
+ callReported(() => fn(sender, ev), 'MJX122', 'onConfig');
3269
4691
  }
3270
- component._base.emiters.fire('onconfig', ev);
3271
- });
4692
+ }
4693
+ fireLifecycle(component, 'onconfig', ev);
3272
4694
  },
3273
- async callConfigured(component) {
4695
+ callConfigured(component) {
3274
4696
  if (component.motif.options && component.motif.options._postconfigdone) {
3275
4697
  return;
3276
4698
  }
@@ -3278,73 +4700,77 @@ const ComponentHelper = {
3278
4700
  ComponentHelper.callConfig(component);
3279
4701
  }
3280
4702
  component.motif.options._postconfigdone = true;
3281
- ComponentHelper.backgroundCallback(() => {
3282
- if (!component || component.isDisposed) {
3283
- return;
3284
- }
3285
- const sender = component, ev = { cancel: false };
3286
- if (component.onConfigured) {
3287
- callReported(() => component.onConfigured(sender, ev), 'MJX122', 'onConfigured');
3288
- }
3289
- if (Array.isArray(component._base._onConfiguredHandlers)) {
3290
- for (const fn of component._base._onConfiguredHandlers) {
3291
- callReported(() => fn(sender, ev), 'MJX122', 'onConfigured');
3292
- }
4703
+ if (!component || component.isDisposed) {
4704
+ return;
4705
+ }
4706
+ if (!hasLifecycleHook(component, 'onConfigured', '_onConfiguredHandlers', 'onconfigured')) {
4707
+ return;
4708
+ }
4709
+ const sender = component, ev = { cancel: false };
4710
+ if (component.onConfigured) {
4711
+ callReported(() => component.onConfigured(sender, ev), 'MJX122', 'onConfigured');
4712
+ }
4713
+ if (Array.isArray(component._base._onConfiguredHandlers)) {
4714
+ for (const fn of component._base._onConfiguredHandlers) {
4715
+ callReported(() => fn(sender, ev), 'MJX122', 'onConfigured');
3293
4716
  }
3294
- component._base.emiters.fire('onconfigured', ev);
3295
- });
4717
+ }
4718
+ fireLifecycle(component, 'onconfigured', ev);
3296
4719
  },
3297
- async callOnInitialized(component) {
3298
- ComponentHelper.backgroundCallback(() => {
3299
- if (!component || component.isDisposed) {
3300
- return;
3301
- }
3302
- component.isInitialized = true;
3303
- const sender = component, ev = { cancel: false };
3304
- if (component.onInitialized) {
3305
- callReported(() => component.onInitialized(sender, ev), 'MJX122', 'onInitialized');
3306
- }
3307
- if (Array.isArray(component._base._onInitializedHandlers)) {
3308
- for (const fn of component._base._onInitializedHandlers) {
3309
- callReported(() => fn(sender, ev), 'MJX122', 'onInitialized');
3310
- }
4720
+ callOnInitialized(component) {
4721
+ if (!component || component.isDisposed) {
4722
+ return;
4723
+ }
4724
+ component.isInitialized = true;
4725
+ if (!hasLifecycleHook(component, 'onInitialized', '_onInitializedHandlers', 'oninitialized')) {
4726
+ return;
4727
+ }
4728
+ const sender = component, ev = { cancel: false };
4729
+ if (component.onInitialized) {
4730
+ callReported(() => component.onInitialized(sender, ev), 'MJX122', 'onInitialized');
4731
+ }
4732
+ if (Array.isArray(component._base._onInitializedHandlers)) {
4733
+ for (const fn of component._base._onInitializedHandlers) {
4734
+ callReported(() => fn(sender, ev), 'MJX122', 'onInitialized');
3311
4735
  }
3312
- component._base.emiters.fire('oninitialized', ev);
3313
- });
4736
+ }
4737
+ fireLifecycle(component, 'oninitialized', ev);
3314
4738
  },
3315
- async callOnInitializing(component) {
3316
- ComponentHelper.backgroundCallback(() => {
3317
- if (!component || component.isDisposed) {
3318
- return;
3319
- }
3320
- const sender = component, ev = { cancel: false };
3321
- if (component.onInitializing) {
3322
- callReported(() => component.onInitializing(sender, ev), 'MJX122', 'onInitializing');
3323
- }
3324
- if (Array.isArray(component._base._onInitializingHandlers)) {
3325
- for (const fn of component._base._onInitializingHandlers) {
3326
- callReported(() => fn(sender, ev), 'MJX122', 'onInitializing');
3327
- }
4739
+ callOnInitializing(component) {
4740
+ if (!component || component.isDisposed) {
4741
+ return;
4742
+ }
4743
+ if (!hasLifecycleHook(component, 'onInitializing', '_onInitializingHandlers', 'oninitializing')) {
4744
+ return;
4745
+ }
4746
+ const sender = component, ev = { cancel: false };
4747
+ if (component.onInitializing) {
4748
+ callReported(() => component.onInitializing(sender, ev), 'MJX122', 'onInitializing');
4749
+ }
4750
+ if (Array.isArray(component._base._onInitializingHandlers)) {
4751
+ for (const fn of component._base._onInitializingHandlers) {
4752
+ callReported(() => fn(sender, ev), 'MJX122', 'onInitializing');
3328
4753
  }
3329
- component._base.emiters.fire('oninitializing', ev);
3330
- });
4754
+ }
4755
+ fireLifecycle(component, 'oninitializing', ev);
3331
4756
  },
3332
- async callVisibilityChanged(component) {
3333
- ComponentHelper.backgroundCallback(() => {
3334
- if (!component || component.isDisposed) {
3335
- return;
3336
- }
3337
- const sender = component, ev = { cancel: false };
3338
- if (component.onVisibilityChanged) {
3339
- callReported(() => component.onVisibilityChanged(sender, ev), 'MJX122', 'onVisibilityChanged');
3340
- }
3341
- if (Array.isArray(component._base._onVisibilityChangedHandlers)) {
3342
- for (const fn of component._base._onVisibilityChangedHandlers) {
3343
- callReported(() => fn(sender, ev), 'MJX122', 'onVisibilityChanged');
3344
- }
4757
+ callVisibilityChanged(component) {
4758
+ if (!component || component.isDisposed) {
4759
+ return;
4760
+ }
4761
+ if (!hasLifecycleHook(component, 'onVisibilityChanged', '_onVisibilityChangedHandlers', 'onvisibilitychanged')) {
4762
+ return;
4763
+ }
4764
+ const sender = component, ev = { cancel: false };
4765
+ if (component.onVisibilityChanged) {
4766
+ callReported(() => component.onVisibilityChanged(sender, ev), 'MJX122', 'onVisibilityChanged');
4767
+ }
4768
+ if (Array.isArray(component._base._onVisibilityChangedHandlers)) {
4769
+ for (const fn of component._base._onVisibilityChangedHandlers) {
4770
+ callReported(() => fn(sender, ev), 'MJX122', 'onVisibilityChanged');
3345
4771
  }
3346
- component._base.emiters.fire('onvisibilitychanged', ev);
3347
- });
4772
+ }
4773
+ fireLifecycle(component, 'onvisibilitychanged', ev);
3348
4774
  },
3349
4775
  findFragmentContent(c) {
3350
4776
  const controlElement = c.element.nodeType == Node.COMMENT_NODE
@@ -3370,6 +4796,8 @@ const ComponentHelper = {
3370
4796
  return;
3371
4797
  }
3372
4798
  ComponentHelper.callConfigured(c);
4799
+ if (c.isDisposed)
4800
+ return;
3373
4801
  c._base._activatePreBindings();
3374
4802
  if (c.isWait)
3375
4803
  return;
@@ -3397,8 +4825,11 @@ const ComponentHelper = {
3397
4825
  return;
3398
4826
  }
3399
4827
  }
4828
+ if (c.isDisposed || this.isDisposed)
4829
+ return;
3400
4830
  c.parent = this;
3401
- const currentIndex = this.controls.items.indexOf(c);
4831
+ const ownItems = this.controls.items;
4832
+ const currentIndex = ownItems.length > 0 && ownItems[ownItems.length - 1] === c ? ownItems.length - 1 : ownItems.indexOf(c);
3402
4833
  const appendableElement = findAppendableComponent(this);
3403
4834
  var controlElement = c.element.nodeType == Node.COMMENT_NODE
3404
4835
  ? c.motif.options.cache
@@ -3449,6 +4880,18 @@ const ComponentHelper = {
3449
4880
  return;
3450
4881
  }
3451
4882
  }
4883
+ if (insertHost && enterModeOf(this) === 'out-in') {
4884
+ const wait = pendingLeaves(insertHost, controlElement);
4885
+ if (wait) {
4886
+ c._base._enterSeq = (c._base._enterSeq ?? 0) + 1;
4887
+ wait.then(() => {
4888
+ if (this.isDisposed || c.isDisposed || c.parent !== this)
4889
+ return;
4890
+ ComponentHelper.internalBuild.call(this, c);
4891
+ });
4892
+ return;
4893
+ }
4894
+ }
3452
4895
  const parentNode = appendableElement?.element;
3453
4896
  if (controlElement && parentNode && (controlElement === parentNode || controlElement.contains(parentNode))) {
3454
4897
  reportWarning('MJX104', []);
@@ -3530,712 +4973,627 @@ const ComponentHelper = {
3530
4973
  }
3531
4974
  }
3532
4975
  };
3533
- const fragmentCloseMarkers = new WeakMap();
3534
- const LIFECYCLE_X_EVENTS = new Set([
3535
- 'building', 'built', 'initializing', 'initialized', 'disposing', 'disposed',
3536
- 'config', 'configured', 'visibilitychanged', 'activated', 'deactivated'
3537
- ]);
3538
- const RAW_APPLICATION = Symbol('motif.rawApplication');
3539
- const SCOPED_SUBSCRIBERS = new Set(['on', 'onRouterChanged']);
3540
- /**
3541
- * Uygulamanın bileşene bağlı görünümü. `on`/`onRouterChanged` aboneliklerini sahibin ömrüne
3542
- * kaydeder; diğer tüm üyeler (alanlar, metotlar, atamalar) uygulamanın kendisine yönlenir.
3543
- */
3544
- function createScopedContext(app, owner) {
3545
- const cache = new Map();
3546
- return new Proxy(app, {
3547
- get(target, prop) {
3548
- if (prop === RAW_APPLICATION) {
3549
- return target;
4976
+ function removeComponentDom(c, node, alsoPlaceholder) {
4977
+ const opts = c.motif?.options;
4978
+ const parent = node.parentNode;
4979
+ if (node.nodeType === Node.COMMENT_NODE) {
4980
+ if (!parent)
4981
+ return;
4982
+ const close = opts?.closeFragment || null;
4983
+ if (close) {
4984
+ let current = node;
4985
+ while (current) {
4986
+ const after = current.nextSibling;
4987
+ try {
4988
+ parent.removeChild(current);
4989
+ }
4990
+ catch { }
4991
+ if (current === close)
4992
+ break;
4993
+ current = after;
3550
4994
  }
3551
- const value = Reflect.get(target, prop, target);
3552
- if (typeof value !== 'function') {
3553
- return value;
4995
+ }
4996
+ else {
4997
+ try {
4998
+ parent.removeChild(node);
3554
4999
  }
3555
- const hit = cache.get(prop);
3556
- if (hit && hit.fn === value) {
3557
- return hit.bound;
3558
- }
3559
- const bound = SCOPED_SUBSCRIBERS.has(prop)
3560
- ? (...args) => owner._trackContextSubscription(value.apply(target, args))
3561
- : value.bind(target);
3562
- cache.set(prop, { fn: value, bound });
3563
- return bound;
3564
- },
3565
- set(target, prop, value) {
3566
- return Reflect.set(target, prop, value, target);
3567
- },
3568
- });
5000
+ catch { }
5001
+ }
5002
+ if (!alsoPlaceholder)
5003
+ return;
5004
+ }
5005
+ else if (parent) {
5006
+ try {
5007
+ parent.removeChild(node);
5008
+ }
5009
+ catch { }
5010
+ if (!alsoPlaceholder)
5011
+ return;
5012
+ }
5013
+ const placeholder = opts?.placeholder;
5014
+ if (placeholder && placeholder.parentNode) {
5015
+ try {
5016
+ placeholder.parentNode.removeChild(placeholder);
5017
+ }
5018
+ catch { }
5019
+ }
3569
5020
  }
3570
- class ComponentBase extends Disposable {
3571
- motif = new ComponentMotif(this, {
3572
- transition: {
3573
- transitionInfo: () => {
3574
- return {
3575
- in: getTransitionInfo(this.element, `${this.motif.options.transition.name}-enter ${this.motif.options.transition.name}-enter-start`),
3576
- out: getTransitionInfo(this.element, `${this.motif.options.transition.name}-leave ${this.motif.options.transition.name}-leave-start`),
3577
- };
3578
- },
3579
- name: '',
3580
- classes: undefined,
3581
- activeCssCancel: null,
3582
- activeCssPhase: null,
3583
- cssProps: () => {
3584
- const t = this.motif.options.transition;
3585
- if (t.classes) {
3586
- return { name: t.classes.name || t.name || '', ...t.classes };
3587
- }
3588
- if (t.name && t.name.length > 0) {
3589
- return { name: t.name };
3590
- }
3591
- return null;
3592
- },
3593
- skipNextLeave: false,
3594
- _suppressEnter: false,
3595
- _markedDirection: false,
3596
- in: (op) => {
3597
- this.motif.options.transitionIn = op;
3598
- },
3599
- out: (op) => {
3600
- this.motif.options.transitionOut = op;
3601
- },
3602
- enterTransition: (resolve) => {
3603
- const t = this.motif.options.transition;
3604
- const appear = !this._base._enterPlayed;
3605
- this._base._enterPlayed = true;
3606
- this._base._enterSeq = (this._base._enterSeq ?? 0) + 1;
3607
- if (t._suppressEnter) {
3608
- resolve && resolve();
3609
- return shimAnimation;
3610
- }
3611
- const attempt = {};
3612
- this._base._enterRun = attempt;
3613
- const done = () => {
3614
- if (this._base?._enterRun === attempt) {
3615
- this._base._enterRun = null;
3616
- clearNavDirection(this);
3617
- }
3618
- resolve && resolve();
3619
- };
3620
- if (this.motif.options.transitionIn) {
3621
- return t.run(this.motif.options.transitionIn.keyframes, this.motif.options.transitionIn.options, done);
3622
- }
3623
- return t._runCss('enter', done, appear);
3624
- },
3625
- leaveTransition: (resolve) => {
3626
- if (this.motif.options.transitionOut) {
3627
- return this.motif.options.transition.run(this.motif.options.transitionOut.keyframes, this.motif.options.transitionOut.options, resolve);
3628
- }
3629
- return this.motif.options.transition._runCss('leave', resolve);
3630
- },
3631
- _runCss: (phase, resolve, appear = false) => {
3632
- const t = this.motif.options.transition;
3633
- if (phase === 'enter' && t.activeCssPhase === 'leave') {
3634
- resolve && resolve();
3635
- return shimAnimation;
3636
- }
3637
- const cssProps = t.cssProps();
3638
- const el = this.element;
3639
- if (cssProps && el && el.nodeType === 1 && el.classList) {
3640
- try {
3641
- t.activeCssCancel?.();
3642
- }
3643
- catch { }
3644
- const cancel = runCssTransition(el, cssProps, phase, () => {
3645
- if (this.motif.options?.transition) {
3646
- this.motif.options.transition.activeCssCancel = null;
3647
- this.motif.options.transition.activeCssPhase = null;
3648
- }
3649
- resolve && resolve();
3650
- }, appear);
3651
- t.activeCssCancel = cancel;
3652
- t.activeCssPhase = phase;
3653
- return shimAnimation;
3654
- }
3655
- resolve && resolve();
3656
- return shimAnimation;
3657
- },
3658
- activeAnimations: [],
3659
- run: (keyframes, options, resolve) => {
3660
- this.motif.stopAnimations();
3661
- const element = this.element;
3662
- if (element.animate) {
3663
- var x = element.animate(keyframes, options);
3664
- this.motif.options.transition.activeAnimations.push(x);
3665
- let cleanedUp = false;
3666
- const safeCleanup = () => {
3667
- if (cleanedUp)
3668
- return;
3669
- cleanedUp = true;
3670
- try {
3671
- if (this?.motif.options?.transition?.activeAnimations) {
3672
- this.motif.options.transition.activeAnimations = this.motif.options.transition.activeAnimations.filter(a => a !== x);
3673
- }
3674
- }
3675
- catch { }
3676
- };
3677
- x.addEventListener('finish', () => {
3678
- resolve && resolve();
3679
- safeCleanup();
3680
- });
3681
- x.oncancel = () => {
3682
- safeCleanup();
3683
- };
3684
- return x;
3685
- }
3686
- else {
3687
- resolve && resolve();
3688
- const g = globalThis;
3689
- if (typeof g.Animation === 'function') {
3690
- try {
3691
- return new g.Animation();
3692
- }
3693
- catch { /* ignore */ }
3694
- }
3695
- return shimAnimation;
3696
- }
3697
- }
3698
- },
3699
- set enableRouterClassing(value) {
3700
- try {
3701
- var ins = this.getInstance();
3702
- const callback = ins.context.onRouterChanged(() => {
3703
- ComponentHelper.routerClassing.call(ins, value);
3704
- });
3705
- ins.motif.register(disposableCore.toDisposable(() => {
3706
- callback();
3707
- }));
3708
- ComponentHelper.routerClassing.call(ins, value);
3709
- }
3710
- catch (error) {
3711
- reportError('MJX105', error);
3712
- }
3713
- },
3714
- getInstance: () => {
3715
- return this;
3716
- },
3717
- get display() {
3718
- return this.getInstance().isVisible;
3719
- },
3720
- set display(value) {
3721
- if (value) {
3722
- this.getInstance().motif.show();
3723
- }
3724
- else {
3725
- this.getInstance().motif.hide();
3726
- }
3727
- },
3728
- hasEvent: (name) => {
3729
- const ins = this._eventHandlers?.has(name);
3730
- if (ins)
3731
- return true;
3732
- return false;
5021
+ function detachDomWithAnimation(c) {
5022
+ const node = c.element;
5023
+ if (!node)
5024
+ return;
5025
+ const opts = c.motif.options;
5026
+ const t = opts?.[TRANSITION_SLOT];
5027
+ try {
5028
+ const skip = t?.skipNextLeave === true || c._forceInstantDetach === true;
5029
+ if (skip) {
5030
+ if (t)
5031
+ t.skipNextLeave = false;
5032
+ c._forceInstantDetach = false;
5033
+ removeComponentDom(c, node, true);
5034
+ return;
3733
5035
  }
3734
- });
3735
- element;
3736
- props;
3737
- isBuilt = false;
3738
- isInitialized = false;
3739
- isDisposed = false;
3740
- isConfigured = false;
3741
- isPainting = false;
3742
- isPainted = false;
3743
- isVisible = true;
3744
- controls = new ControlCollection(this);
3745
- _eventHandlers;
3746
- _isWait = false;
3747
- class = new controlClass(this);
3748
- attr = new controlAttribute(this);
3749
- bindings = new BindingCollection(this);
3750
- /** style(fn) izleyicisi: tek tek tutulur, yeniden çağrıda önceki durdurulur. */
3751
- _styleFx;
3752
- useModel(modelCtor) {
3753
- return reactive(modelCtor);
3754
5036
  }
3755
- _computeHideStrategy() {
3756
- const cfg = this.motif.options?.hideStrategy ?? 'auto';
3757
- if (cfg === 'placeholder')
3758
- return 'placeholder';
3759
- if (cfg === 'detach')
3760
- return 'detach';
3761
- if (this.motif.options?.__fromList || typeof this.motif.options?.indexkey !== 'undefined' || typeof this.motif.options?.__key !== 'undefined') {
3762
- return 'detach';
5037
+ catch { }
5038
+ if (!t && !opts?.transitionOut) {
5039
+ removeComponentDom(c, node, false);
5040
+ return;
5041
+ }
5042
+ try {
5043
+ opts.transition.leaveTransition(() => {
5044
+ removeComponentDom(c, node, false);
5045
+ });
5046
+ }
5047
+ catch {
5048
+ removeComponentDom(c, node, false);
5049
+ }
5050
+ }
5051
+ async function detachDomWithAnimationAsync(c) {
5052
+ const node = c.element;
5053
+ if (!node)
5054
+ return;
5055
+ const opts = c.motif.options;
5056
+ const t = opts?.[TRANSITION_SLOT];
5057
+ try {
5058
+ const skip = t?.skipNextLeave === true || c._forceInstantDetach === true;
5059
+ if (skip) {
5060
+ if (t)
5061
+ t.skipNextLeave = false;
5062
+ c._forceInstantDetach = false;
5063
+ removeComponentDom(c, node, true);
5064
+ return;
3763
5065
  }
3764
- return 'placeholder';
3765
5066
  }
3766
- _isInDom() {
5067
+ catch { }
5068
+ if (!t && !opts?.transitionOut) {
5069
+ removeComponentDom(c, node, false);
5070
+ return;
5071
+ }
5072
+ return new Promise((resolve) => {
3767
5073
  try {
3768
- if (!this.element)
3769
- return false;
3770
- const node = this.element;
3771
- if (node.nodeType === Node.COMMENT_NODE) {
3772
- return !!node.parentNode;
3773
- }
3774
- return !!node.parentNode;
5074
+ opts.transition.leaveTransition(() => {
5075
+ removeComponentDom(c, node, false);
5076
+ resolve();
5077
+ });
3775
5078
  }
3776
5079
  catch {
3777
- return false;
5080
+ removeComponentDom(c, node, false);
5081
+ resolve();
3778
5082
  }
5083
+ });
5084
+ }
5085
+ function disposeShallow(c) {
5086
+ if (c.isDisposed)
5087
+ return;
5088
+ ComponentHelper.callDisposing.call(c, c);
5089
+ try {
5090
+ c._base._offAll();
3779
5091
  }
3780
- set isWait(value) {
3781
- this._isWait = value;
3782
- if (this.isBuilt) {
3783
- if (value) {
3784
- this.motif.hide();
5092
+ catch {
5093
+ }
5094
+ c.motif.stopAnimations();
5095
+ c._base._deactivateBindings();
5096
+ if (c.controls?.items?.length) {
5097
+ for (const child of c.controls.items) {
5098
+ try {
5099
+ child._base._disposeShallow();
3785
5100
  }
3786
- else {
3787
- this.motif.show();
5101
+ catch {
3788
5102
  }
3789
- return;
3790
- }
3791
- if (value === false && this.parent && this.parent.isBuilt) {
3792
- ComponentHelper.internalBuild.call(this.parent, this);
3793
5103
  }
3794
5104
  }
3795
- get isWait() {
3796
- return this._isWait;
5105
+ ComponentHelper.callDisposed.call(c, c);
5106
+ safeCall(() => { c._base.emiters.clear(); }, 'disposeShallow.emiters');
5107
+ c.isDisposed = true;
5108
+ Disposable.prototype.dispose.call(c);
5109
+ }
5110
+ function deepCleanup(c) {
5111
+ try {
5112
+ c.parent = null;
3797
5113
  }
3798
- constructor(element, props = {}) {
3799
- super();
3800
- recordServiceOwner(this);
3801
- if (this.onElementCreating) {
3802
- this.element = this.onElementCreating.call(this);
5114
+ catch { }
5115
+ try {
5116
+ c._eventHandlers?.clear();
5117
+ }
5118
+ catch {
5119
+ }
5120
+ c._eventHandlers = undefined;
5121
+ try {
5122
+ c.class?._countsStore?.clear();
5123
+ }
5124
+ catch { }
5125
+ try {
5126
+ c.class?._watchersStore?.clear();
5127
+ }
5128
+ catch { }
5129
+ try {
5130
+ c.attr?._attrMapStore?.clear();
5131
+ }
5132
+ catch { }
5133
+ try {
5134
+ c.attr?._watchersStore?.clear();
5135
+ }
5136
+ catch { }
5137
+ try {
5138
+ if (c.motif.options) {
5139
+ c.motif.options.cache = undefined;
5140
+ c.motif.options.closeFragment = undefined;
5141
+ c.motif.options.placeholder = undefined;
3803
5142
  }
3804
- else if (props?.onElementCreating) {
3805
- this.element = props.onElementCreating.call(this);
5143
+ }
5144
+ catch {
5145
+ }
5146
+ try {
5147
+ c.element = null;
5148
+ }
5149
+ catch { }
5150
+ try {
5151
+ c.props = undefined;
5152
+ }
5153
+ catch { }
5154
+ try {
5155
+ c.childs = undefined;
5156
+ }
5157
+ catch { }
5158
+ try {
5159
+ c.class = undefined;
5160
+ }
5161
+ catch { }
5162
+ try {
5163
+ c.attr = undefined;
5164
+ }
5165
+ catch { }
5166
+ try {
5167
+ c.parent = null;
5168
+ }
5169
+ catch { }
5170
+ try {
5171
+ c.motif.options = undefined;
5172
+ }
5173
+ catch { }
5174
+ const keys = Object.keys(c);
5175
+ for (let i = 0; i < keys.length; i++) {
5176
+ const key = keys[i];
5177
+ if (key === 'motif')
5178
+ continue;
5179
+ try {
5180
+ c[key] = undefined;
3806
5181
  }
3807
- else {
3808
- this.element = element;
5182
+ catch { }
5183
+ }
5184
+ c.isDisposed = true;
5185
+ }
5186
+ const DISPOSE_STARTED = Promise.resolve();
5187
+ function subtreeDisposesSync(c, root) {
5188
+ if (!root && c._disposing && !c.isDisposed)
5189
+ return false;
5190
+ if (c.disposeAsync !== ComponentBase.prototype.disposeAsync)
5191
+ return false;
5192
+ const opts = c.motif?.options;
5193
+ if (opts) {
5194
+ if (opts.transitionOut)
5195
+ return false;
5196
+ const t = opts[TRANSITION_SLOT];
5197
+ if (t) {
5198
+ if (t.activeAnimations && t.activeAnimations.length > 0)
5199
+ return false;
5200
+ if (t.activeCssCancel)
5201
+ return false;
5202
+ if (t.classes || (t.name && t.name.length > 0))
5203
+ return false;
3809
5204
  }
3810
- if (props) {
3811
- for (const fn of takePendingRefs(this, extractRefs(props, this))) {
3812
- callReported(() => fn(this), 'MJX122', 'ref');
3813
- }
5205
+ }
5206
+ const items = c.controls?.items;
5207
+ if (items) {
5208
+ for (let i = 0; i < items.length; i++) {
5209
+ const child = items[i];
5210
+ if (child && !child.isDisposed && !subtreeDisposesSync(child, false))
5211
+ return false;
3814
5212
  }
3815
- props && ParseProps(props, this);
3816
- applyComponentOptions(props?.options, this);
3817
- this.props = props;
3818
- // (class/style/id/tabindex/role/aria-*/data-*) kök düğüme (root node) düşer, prop'lar this.props'ta kalır.
3819
- if (props) {
3820
- const ctor0 = new.target;
3821
- const plain = ctor0 === ComponentBase || Object.getPrototypeOf(ctor0) === ComponentBase;
3822
- if (plain)
3823
- applyPlainElementProps(props, this);
3824
- else
3825
- applyFallthroughProps(props, this);
5213
+ }
5214
+ return true;
5215
+ }
5216
+ function disposePrefix(c, options, asChild) {
5217
+ const ctx = asChild ? 'disposeAsync' : 'dispose';
5218
+ if (!asChild && options?.skipLeaveTransition) {
5219
+ c.motif.options.transition.skipNextLeave = true;
5220
+ }
5221
+ safeCall(() => { ComponentHelper.callDisposing.call(c, c); }, ctx + '.callDisposing');
5222
+ c._base._offAll();
5223
+ c._base._deactivateBindings();
5224
+ safeCall(() => { c.parent?.controls?.silentDetach?.(c, true); }, ctx + '.silentDetach');
5225
+ }
5226
+ function disposeFinish(c, options, asChild) {
5227
+ c.isDisposed = true;
5228
+ Disposable.prototype.dispose.call(c);
5229
+ if (asChild) {
5230
+ c.controls.items = [];
5231
+ safeCall(() => { ComponentHelper.callDisposed.call(c, c); }, 'disposeAsync.callDisposed');
5232
+ safeCall(() => { c._base.emiters.clear(); }, 'disposeAsync.emiters');
5233
+ if (options?.deep) {
5234
+ c._base._deepCleanup();
3826
5235
  }
3827
- ComponentHelper.callOnInitializing(this);
3828
- this.controls.onAdd = (c) => {
3829
- this.motif.trigger('controladded', { control: c });
3830
- if (this.isWait || this.parent?.isWait)
3831
- return;
3832
- ComponentHelper.internalBuild.call(this, c);
3833
- };
3834
- this.controls.onAddBeforeBuild = (c) => {
3835
- this.motif.trigger('controladded', { control: c });
3836
- };
3837
- this.controls.onRemove = (c) => {
3838
- this.motif.trigger('controlremoved', { control: c });
3839
- };
3840
- ComponentHelper.callOnInitialized(this);
3841
- const ctor = new.target;
3842
- const isBaseCtor = ctor === ComponentBase || Object.getPrototypeOf(ctor) === ComponentBase;
3843
- if (isBaseCtor) {
3844
- ComponentHelper.callConfig(this);
5236
+ return;
5237
+ }
5238
+ c.element = null;
5239
+ safeCall(() => { ComponentHelper.callDisposed.call(c, c); }, 'dispose.callDisposed');
5240
+ safeCall(() => { c._base.emiters.clear(); }, 'dispose.emiters');
5241
+ c._base._offAll();
5242
+ c._base._deepCleanup();
5243
+ }
5244
+ async function disposeRemainderAsync(c, options, asChild, leave) {
5245
+ if (leave) {
5246
+ await leave;
5247
+ }
5248
+ else {
5249
+ if (asChild) {
5250
+ await c.motif.stopAnimations();
3845
5251
  }
3846
- else {
3847
- this._base._configDeferred = true;
5252
+ else if (peekTransition(c)?.skipNextLeave) {
5253
+ await c.motif.stopAnimations();
3848
5254
  }
5255
+ await c._base._detachDomWithAnimationAsync();
3849
5256
  }
3850
- childs;
3851
- _base = {
3852
- prebinding_Activated: false,
3853
- _offAll: () => {
3854
- if (!this._eventHandlers)
3855
- return;
3856
- for (const [full, set] of this._eventHandlers) {
3857
- const name = full.split(":")[0];
3858
- const evt = name.startsWith("on") ? name.slice(2).toLowerCase() : name.toLowerCase();
3859
- for (const rec of set) {
3860
- if (!rec || !rec.wrapped) {
3861
- continue;
3862
- }
3863
- if (rec.domEvent === false) {
3864
- continue;
3865
- }
3866
- const cap = rec.capture === true;
5257
+ if (!asChild && c.constructor.name !== 'TransportTo') {
5258
+ await disposeContentBlocks(c);
5259
+ }
5260
+ const childOptions = { deep: options?.deep };
5261
+ await safeCallAsync(async () => {
5262
+ if (c.isDisposed) {
5263
+ return;
5264
+ }
5265
+ const ctrls = Array.from(c.controls.items);
5266
+ if (ctrls.length) {
5267
+ await Promise.all(ctrls.map(child => asChild
5268
+ ? safeCallAsync(async () => { await child.disposeAsync(childOptions); }, 'disposeAsync.disposeAsyncChildren.handler')
5269
+ : (async () => {
3867
5270
  try {
3868
- this.element.removeEventListener(evt, rec.wrapped, cap);
5271
+ await child.disposeAsync(childOptions);
3869
5272
  }
3870
- catch { }
3871
- try {
3872
- if (rec.capture === undefined) {
3873
- this.element.removeEventListener(evt, rec.wrapped, !cap);
3874
- }
5273
+ catch (error) {
5274
+ reportError('MJX107', error);
3875
5275
  }
3876
- catch { }
3877
- }
3878
- }
3879
- this._eventHandlers.clear();
3880
- this._eventHandlers = undefined;
3881
- },
3882
- _deactivateBindings: () => {
3883
- try {
3884
- this.bindings?.deactivateAll();
3885
- }
3886
- catch { }
3887
- },
3888
- _activateBindings: () => {
3889
- try {
3890
- this.bindings?.activateAll();
5276
+ })()));
5277
+ }
5278
+ }, asChild ? 'disposeAsync.disposeAsyncChildren' : 'dispose.disposeAsync');
5279
+ if (!asChild && c.isDisposed) {
5280
+ return;
5281
+ }
5282
+ disposeFinish(c, options, asChild);
5283
+ }
5284
+ function disposeRemainderSync(root, options, asChild, rootDetached) {
5285
+ const childOptions = { deep: options?.deep };
5286
+ const nodes = [root];
5287
+ const parents = [-1];
5288
+ let pending = null;
5289
+ if (!rootDetached)
5290
+ detachDomWithAnimation(root);
5291
+ for (let n = 0; n < nodes.length; n++) {
5292
+ const node = nodes[n];
5293
+ if (node.isDisposed)
5294
+ continue;
5295
+ const items = node.controls?.items;
5296
+ if (!items || items.length === 0)
5297
+ continue;
5298
+ const ctrls = Array.from(items);
5299
+ for (let j = 0; j < ctrls.length; j++) {
5300
+ const child = ctrls[j];
5301
+ if (child.isDisposed)
5302
+ continue;
5303
+ if (child._disposing) {
5304
+ (pending ??= []).push(child._disposing);
5305
+ continue;
3891
5306
  }
3892
- catch { }
3893
- },
3894
- _reactivateBindings: () => {
3895
5307
  try {
3896
- this.bindings?.reActivateAll();
5308
+ retireServiceOwner(child);
5309
+ child._disposing = root._disposing;
5310
+ disposePrefix(child, childOptions, true);
5311
+ detachDomWithAnimation(child);
5312
+ nodes.push(child);
5313
+ parents.push(n);
3897
5314
  }
3898
- catch { }
3899
- },
3900
- _activatePreBindings: () => {
3901
- if (this._base.prebinding_Activated)
3902
- return;
3903
- this.bindings.items.filter(x => x.propertyName == "isWait" || x.propertyName == "display").forEach(b => {
3904
- b.activate();
3905
- });
3906
- this._base.prebinding_Activated = true;
3907
- },
3908
- _detachDomWithAnimation: () => {
3909
- const node = this.element;
3910
- if (!node)
3911
- return;
3912
- try {
3913
- const skip = this.motif.options.transition.skipNextLeave === true || this?._forceInstantDetach === true;
3914
- if (skip) {
3915
- if (this?.motif.options?.transition)
3916
- this.motif.options.transition.skipNextLeave = false;
3917
- this._forceInstantDetach = false;
3918
- const immediate = () => {
3919
- const parent = node.parentNode;
3920
- if (node.nodeType === Node.COMMENT_NODE) {
3921
- const open = node;
3922
- const close = this.motif.options?.closeFragment || null;
3923
- if (!parent)
3924
- return;
3925
- if (close) {
3926
- let current = open;
3927
- while (current) {
3928
- const after = current.nextSibling;
3929
- try {
3930
- parent.removeChild(current);
3931
- }
3932
- catch { }
3933
- if (current === close)
3934
- break;
3935
- current = after;
3936
- }
3937
- }
3938
- else {
3939
- try {
3940
- parent.removeChild(open);
3941
- }
3942
- catch { }
3943
- }
3944
- }
3945
- else if (parent) {
3946
- try {
3947
- parent.removeChild(node);
3948
- }
3949
- catch { }
3950
- }
3951
- const placeholder = this.motif.options?.placeholder;
3952
- if (placeholder && placeholder.parentNode) {
3953
- try {
3954
- placeholder.parentNode.removeChild(placeholder);
3955
- }
3956
- catch { }
3957
- }
3958
- };
3959
- immediate();
3960
- return;
3961
- }
5315
+ catch (error) {
5316
+ reportError('MJX107', error);
3962
5317
  }
3963
- catch { }
3964
- const removeNow = () => {
3965
- if (node.nodeType === Node.COMMENT_NODE) {
3966
- const open = node;
3967
- const close = this.motif.options?.closeFragment || null;
3968
- const parent = open.parentNode;
3969
- if (!parent)
3970
- return;
3971
- if (close) {
3972
- let current = open;
3973
- while (current) {
3974
- const after = current.nextSibling;
3975
- try {
3976
- parent.removeChild(current);
3977
- }
3978
- catch { }
3979
- if (current === close)
3980
- break;
3981
- current = after;
3982
- }
3983
- }
3984
- else {
3985
- try {
3986
- parent.removeChild(open);
3987
- }
3988
- catch { }
3989
- }
3990
- return;
3991
- }
3992
- const parent = node.parentNode;
3993
- if (parent) {
3994
- try {
3995
- parent.removeChild(node);
3996
- }
3997
- catch { }
3998
- return;
3999
- }
4000
- const placeholder = this.motif.options?.placeholder;
4001
- if (placeholder && placeholder.parentNode) {
4002
- try {
4003
- placeholder.parentNode.removeChild(placeholder);
4004
- }
4005
- catch { }
4006
- }
4007
- };
5318
+ }
5319
+ }
5320
+ const count = nodes.length;
5321
+ if (count > 1) {
5322
+ const heights = new Array(count).fill(0);
5323
+ for (let i = count - 1; i >= 1; i--) {
5324
+ const p = parents[i];
5325
+ if (heights[i] + 1 > heights[p])
5326
+ heights[p] = heights[i] + 1;
5327
+ }
5328
+ const order = [];
5329
+ for (let i = 1; i < count; i++)
5330
+ order.push(i);
5331
+ order.sort((a, b) => heights[a] - heights[b] || a - b);
5332
+ for (let k = 0; k < order.length; k++) {
4008
5333
  try {
4009
- this.motif.options.transition.leaveTransition(() => {
4010
- removeNow();
4011
- });
4012
- }
4013
- catch {
4014
- removeNow();
5334
+ disposeFinish(nodes[order[k]], childOptions, true);
4015
5335
  }
4016
- },
4017
- _detachDomWithAnimationAsync: async () => {
4018
- const node = this.element;
4019
- if (!node)
4020
- return Promise.resolve();
4021
- try {
4022
- const skip = this.motif.options.transition.skipNextLeave === true || this?._forceInstantDetach === true;
4023
- if (skip) {
4024
- if (this.motif.options.transition)
4025
- this.motif.options.transition.skipNextLeave = false;
4026
- this._forceInstantDetach = false;
4027
- const immediateRemove = () => {
4028
- if (node.nodeType === Node.COMMENT_NODE) {
4029
- const open = node;
4030
- const close = this.motif.options?.closeFragment || null;
4031
- const parent = open.parentNode;
4032
- if (!parent)
4033
- return;
4034
- if (close) {
4035
- let current = open;
4036
- while (current) {
4037
- const after = current.nextSibling;
4038
- try {
4039
- parent.removeChild(current);
4040
- }
4041
- catch { }
4042
- if (current === close)
4043
- break;
4044
- current = after;
4045
- }
4046
- }
4047
- else {
4048
- try {
4049
- parent.removeChild(open);
4050
- }
4051
- catch { }
4052
- }
4053
- }
4054
- else {
4055
- const parent = node.parentNode;
4056
- if (parent) {
4057
- try {
4058
- parent.removeChild(node);
4059
- }
4060
- catch { }
4061
- }
4062
- }
4063
- const placeholder = this.motif.options?.placeholder;
4064
- if (placeholder && placeholder.parentNode) {
4065
- try {
4066
- placeholder.parentNode.removeChild(placeholder);
4067
- }
4068
- catch { }
4069
- }
4070
- };
4071
- immediateRemove();
4072
- return Promise.resolve();
4073
- }
5336
+ catch (error) {
5337
+ reportError('MJX107', error);
4074
5338
  }
4075
- catch { }
4076
- const removeNow = () => {
4077
- if (node.nodeType === Node.COMMENT_NODE) {
4078
- const open = node;
4079
- const close = this.motif.options?.closeFragment || null;
4080
- const parent = open.parentNode;
4081
- if (!parent)
4082
- return;
4083
- if (close) {
4084
- let current = open;
4085
- while (current) {
4086
- const after = current.nextSibling;
4087
- try {
4088
- parent.removeChild(current);
4089
- }
4090
- catch { }
4091
- if (current === close)
4092
- break;
4093
- current = after;
4094
- }
4095
- }
4096
- else {
4097
- try {
4098
- parent.removeChild(open);
4099
- }
4100
- catch { }
4101
- }
4102
- return;
4103
- }
4104
- const parent = node.parentNode;
4105
- if (parent) {
4106
- try {
4107
- parent.removeChild(node);
4108
- }
4109
- catch { }
4110
- return;
5339
+ }
5340
+ }
5341
+ if (pending)
5342
+ return pending;
5343
+ if (!asChild && root.isDisposed) {
5344
+ return null;
5345
+ }
5346
+ disposeFinish(root, options, asChild);
5347
+ return null;
5348
+ }
5349
+ const BASE_PROTO = {
5350
+ _offAll() {
5351
+ const c = this.owner;
5352
+ if (!c._eventHandlers)
5353
+ return;
5354
+ for (const [full, set] of c._eventHandlers) {
5355
+ const name = full.split(":")[0];
5356
+ const evt = name.startsWith("on") ? name.slice(2).toLowerCase() : name.toLowerCase();
5357
+ for (const rec of set) {
5358
+ if (!rec || !rec.wrapped) {
5359
+ continue;
4111
5360
  }
4112
- const placeholder = this.motif.options?.placeholder;
4113
- if (placeholder && placeholder.parentNode) {
4114
- try {
4115
- placeholder.parentNode.removeChild(placeholder);
4116
- }
4117
- catch { }
5361
+ if (rec.domEvent === false) {
5362
+ continue;
4118
5363
  }
4119
- };
4120
- return new Promise((resolve) => {
5364
+ const cap = rec.capture === true;
4121
5365
  try {
4122
- this.motif.options.transition.leaveTransition(() => {
4123
- removeNow();
4124
- resolve();
4125
- });
5366
+ c.element.removeEventListener(evt, rec.wrapped, cap);
4126
5367
  }
4127
- catch {
4128
- removeNow();
4129
- resolve();
4130
- }
4131
- });
4132
- },
4133
- _disposeShallow: () => {
4134
- if (this.isDisposed)
4135
- return;
4136
- ComponentHelper.callDisposing.call(this, this);
4137
- try {
4138
- this._base._offAll();
4139
- }
4140
- catch {
4141
- }
4142
- this.motif.stopAnimations();
4143
- this._base._deactivateBindings();
4144
- if (this.controls?.items?.length) {
4145
- for (const c of this.controls.items) {
4146
- try {
4147
- c._base._disposeShallow();
4148
- }
4149
- catch {
5368
+ catch { }
5369
+ try {
5370
+ if (rec.capture === undefined) {
5371
+ c.element.removeEventListener(evt, rec.wrapped, !cap);
4150
5372
  }
4151
5373
  }
5374
+ catch { }
4152
5375
  }
4153
- ComponentHelper.callDisposed.call(this, this);
4154
- safeCall(() => { this._base.emiters.clear(); }, 'disposeShallow.emiters');
4155
- this.isDisposed = true;
4156
- super.dispose();
4157
- },
4158
- _deepCleanup: () => {
4159
- try {
4160
- this.parent = null;
4161
- }
4162
- catch { }
4163
- try {
4164
- this._eventHandlers?.clear();
4165
- }
4166
- catch {
4167
- }
4168
- // for (const c of this.controls.items) {
4169
- // try {
4170
- // } catch {
4171
- this._eventHandlers = undefined;
4172
- try {
4173
- this.class?._counts?.clear();
4174
- }
4175
- catch { }
4176
- try {
4177
- this.class?._watchers?.clear();
4178
- }
4179
- catch { }
4180
- try {
4181
- this.attr?._attrMap?.clear();
4182
- }
4183
- catch { }
4184
- try {
4185
- this.attr?._watchers?.clear();
4186
- }
4187
- catch { }
4188
- try {
4189
- if (this.motif.options) {
4190
- this.motif.options.cache = undefined;
4191
- this.motif.options.closeFragment = undefined;
4192
- this.motif.options.placeholder = undefined;
4193
- }
4194
- }
4195
- catch {
4196
- }
4197
- try {
4198
- this.element = null;
4199
- }
4200
- catch { }
4201
- try {
4202
- this.props = undefined;
5376
+ }
5377
+ c._eventHandlers.clear();
5378
+ c._eventHandlers = undefined;
5379
+ },
5380
+ _deactivateBindings() {
5381
+ const c = this.owner;
5382
+ try {
5383
+ c.bindings?.deactivateAll();
5384
+ }
5385
+ catch { }
5386
+ },
5387
+ _activateBindings() {
5388
+ const c = this.owner;
5389
+ try {
5390
+ c.bindings?.activateAll();
5391
+ }
5392
+ catch { }
5393
+ },
5394
+ _reactivateBindings() {
5395
+ const c = this.owner;
5396
+ try {
5397
+ c.bindings?.reActivateAll();
5398
+ }
5399
+ catch { }
5400
+ },
5401
+ _activatePreBindings() {
5402
+ if (this.prebinding_Activated)
5403
+ return;
5404
+ const c = this.owner;
5405
+ const registered = c.bindings?._items;
5406
+ if (registered && registered.length > 0) {
5407
+ c.bindings.items.filter((x) => x.propertyName == "isWait" || x.propertyName == "display").forEach((b) => {
5408
+ b.activate();
5409
+ });
5410
+ }
5411
+ this.prebinding_Activated = true;
5412
+ },
5413
+ _detachDomWithAnimation() {
5414
+ detachDomWithAnimation(this.owner);
5415
+ },
5416
+ _detachDomWithAnimationAsync() {
5417
+ return detachDomWithAnimationAsync(this.owner);
5418
+ },
5419
+ _disposeShallow() {
5420
+ disposeShallow(this.owner);
5421
+ },
5422
+ _deepCleanup() {
5423
+ deepCleanup(this.owner);
5424
+ },
5425
+ };
5426
+ function createBaseCtx(owner) {
5427
+ const base = Object.create(BASE_PROTO);
5428
+ base.owner = owner;
5429
+ base.prebinding_Activated = false;
5430
+ base.emiters = new ComponentEmiter(owner);
5431
+ return base;
5432
+ }
5433
+ const fragmentCloseMarkers = new WeakMap();
5434
+ const LIFECYCLE_X_EVENTS = new Set([
5435
+ 'building', 'built', 'initializing', 'initialized', 'disposing', 'disposed',
5436
+ 'config', 'configured', 'visibilitychanged', 'activated', 'deactivated'
5437
+ ]);
5438
+ const RAW_APPLICATION = Symbol('motif.rawApplication');
5439
+ const SCOPED_SUBSCRIBERS = new Set(['on', 'onRouterChanged']);
5440
+ /**
5441
+ * Uygulamanın bileşene bağlı görünümü. `on`/`onRouterChanged` aboneliklerini sahibin ömrüne
5442
+ * kaydeder; diğer tüm üyeler (alanlar, metotlar, atamalar) uygulamanın kendisine yönlenir.
5443
+ */
5444
+ function createScopedContext(app, owner) {
5445
+ const cache = new Map();
5446
+ return new Proxy(app, {
5447
+ get(target, prop) {
5448
+ if (prop === RAW_APPLICATION) {
5449
+ return target;
4203
5450
  }
4204
- catch { }
4205
- try {
4206
- this.childs = undefined;
5451
+ const value = Reflect.get(target, prop, target);
5452
+ if (typeof value !== 'function') {
5453
+ return value;
4207
5454
  }
4208
- catch { }
4209
- try {
4210
- this.class = undefined;
5455
+ const hit = cache.get(prop);
5456
+ if (hit && hit.fn === value) {
5457
+ return hit.bound;
4211
5458
  }
4212
- catch { }
4213
- try {
4214
- this.attr = undefined;
5459
+ const bound = SCOPED_SUBSCRIBERS.has(prop)
5460
+ ? (...args) => owner._trackContextSubscription(value.apply(target, args))
5461
+ : value.bind(target);
5462
+ cache.set(prop, { fn: value, bound });
5463
+ return bound;
5464
+ },
5465
+ set(target, prop, value) {
5466
+ return Reflect.set(target, prop, value, target);
5467
+ },
5468
+ });
5469
+ }
5470
+ class ComponentBase extends Disposable {
5471
+ motif = new ComponentMotif(this, new ComponentOptionsImpl(this));
5472
+ element;
5473
+ props;
5474
+ isBuilt = false;
5475
+ isInitialized = false;
5476
+ isDisposed = false;
5477
+ isConfigured = false;
5478
+ isPainting = false;
5479
+ isPainted = false;
5480
+ isVisible = true;
5481
+ controls = new ControlCollection(this);
5482
+ _eventHandlers;
5483
+ _isWait = false;
5484
+ class = new controlClass(this);
5485
+ attr = new controlAttribute(this);
5486
+ bindings = new BindingCollection(this);
5487
+ /** style(fn) izleyicisi: tek tek tutulur, yeniden çağrıda önceki durdurulur. */
5488
+ _styleFx;
5489
+ useModel(modelCtor) {
5490
+ return reactive(modelCtor);
5491
+ }
5492
+ _computeHideStrategy() {
5493
+ const cfg = this.motif.options?.hideStrategy ?? 'auto';
5494
+ if (cfg === 'placeholder')
5495
+ return 'placeholder';
5496
+ if (cfg === 'detach')
5497
+ return 'detach';
5498
+ if (this.motif.options?.__fromList || typeof this.motif.options?.indexkey !== 'undefined' || typeof this.motif.options?.__key !== 'undefined') {
5499
+ return 'detach';
5500
+ }
5501
+ return 'placeholder';
5502
+ }
5503
+ _isInDom() {
5504
+ try {
5505
+ if (!this.element)
5506
+ return false;
5507
+ const node = this.element;
5508
+ if (node.nodeType === Node.COMMENT_NODE) {
5509
+ return !!node.parentNode;
4215
5510
  }
4216
- catch { }
4217
- try {
4218
- this.parent = null;
5511
+ return !!node.parentNode;
5512
+ }
5513
+ catch {
5514
+ return false;
5515
+ }
5516
+ }
5517
+ set isWait(value) {
5518
+ this._isWait = value;
5519
+ if (this.isBuilt) {
5520
+ if (value) {
5521
+ this.motif.hide();
4219
5522
  }
4220
- catch { }
4221
- try {
4222
- this.motif.options = undefined;
5523
+ else {
5524
+ this.motif.show();
4223
5525
  }
4224
- catch { }
4225
- Object.entries(this).forEach(([key, value]) => {
4226
- if (key === 'motif')
4227
- return;
4228
- try {
4229
- this[key] = null;
4230
- delete this[key];
4231
- }
4232
- catch {
5526
+ return;
5527
+ }
5528
+ if (value === false && this.parent && this.parent.isBuilt) {
5529
+ ComponentHelper.internalBuild.call(this.parent, this);
5530
+ }
5531
+ }
5532
+ get isWait() {
5533
+ return this._isWait;
5534
+ }
5535
+ constructor(element, props = {}) {
5536
+ super();
5537
+ recordServiceOwner(this);
5538
+ if (this.onElementCreating) {
5539
+ this.element = this.onElementCreating.call(this);
5540
+ }
5541
+ else if (props?.onElementCreating) {
5542
+ this.element = props.onElementCreating.call(this);
5543
+ }
5544
+ else {
5545
+ this.element = element;
5546
+ }
5547
+ if (props) {
5548
+ const refs = extractRefs(props, this);
5549
+ if (refs.length > 0) {
5550
+ for (const fn of takePendingRefs(this, refs)) {
5551
+ callReported(() => fn(this), 'MJX122', 'ref');
4233
5552
  }
4234
- });
4235
- this.isDisposed = true;
4236
- },
4237
- emiters: new ComponentEmiter(this)
4238
- };
5553
+ }
5554
+ }
5555
+ props && ParseProps(props, this);
5556
+ applyComponentOptions(props?.options, this);
5557
+ this.props = props;
5558
+ // (class/style/id/tabindex/role/aria-*/data-*) kök düğüme (root node) düşer, prop'lar this.props'ta kalır.
5559
+ if (props) {
5560
+ const ctor0 = new.target;
5561
+ const plain = ctor0 === ComponentBase || Object.getPrototypeOf(ctor0) === ComponentBase;
5562
+ if (plain)
5563
+ applyPlainElementProps(props, this);
5564
+ else
5565
+ applyFallthroughProps(props, this);
5566
+ }
5567
+ ComponentHelper.callOnInitializing(this);
5568
+ if (this.isDisposed)
5569
+ return;
5570
+ this.controls.onAdd = (c) => {
5571
+ if (this._eventHandlers?.has('controladded'))
5572
+ this.motif.trigger('controladded', { control: c });
5573
+ if (this.isWait || this.parent?.isWait)
5574
+ return;
5575
+ ComponentHelper.internalBuild.call(this, c);
5576
+ };
5577
+ this.controls.onAddBeforeBuild = (c) => {
5578
+ if (this._eventHandlers?.has('controladded'))
5579
+ this.motif.trigger('controladded', { control: c });
5580
+ };
5581
+ this.controls.onRemove = (c) => {
5582
+ if (this._eventHandlers?.has('controlremoved'))
5583
+ this.motif.trigger('controlremoved', { control: c });
5584
+ };
5585
+ ComponentHelper.callOnInitialized(this);
5586
+ const ctor = new.target;
5587
+ const isBaseCtor = ctor === ComponentBase || Object.getPrototypeOf(ctor) === ComponentBase;
5588
+ if (isBaseCtor) {
5589
+ ComponentHelper.callConfig(this);
5590
+ }
5591
+ else {
5592
+ this._base._configDeferred = true;
5593
+ }
5594
+ }
5595
+ childs;
5596
+ _base = createBaseCtx(this);
4239
5597
  parent = null;
4240
5598
  _scopedContext;
4241
5599
  get context() {
@@ -4271,6 +5629,9 @@ class ComponentBase extends Disposable {
4271
5629
  return;
4272
5630
  }
4273
5631
  ComponentHelper.callBuilding(this);
5632
+ if (this.isDisposed) {
5633
+ return;
5634
+ }
4274
5635
  var ph = this.element;
4275
5636
  if (building) {
4276
5637
  ph = dom.createDocumentFragment();
@@ -4285,9 +5646,15 @@ class ComponentBase extends Disposable {
4285
5646
  return;
4286
5647
  }
4287
5648
  ComponentHelper.callInitializeComponent(this);
5649
+ if (this.isDisposed) {
5650
+ return;
5651
+ }
4288
5652
  if (this.view) {
4289
5653
  const templ = this.view();
4290
5654
  this.controls.add(templ);
5655
+ if (this.isDisposed) {
5656
+ return;
5657
+ }
4291
5658
  }
4292
5659
  const deferredSelectValue = this.element?.nodeName === 'SELECT'
4293
5660
  ? this.bindings.items.filter(b => b.propertyName === 'value')
@@ -4328,6 +5695,9 @@ class ComponentBase extends Disposable {
4328
5695
  ComponentHelper.activateTree(element);
4329
5696
  }
4330
5697
  }
5698
+ if (this.isDisposed) {
5699
+ return;
5700
+ }
4331
5701
  if (wantsEnterTransition(this)) {
4332
5702
  const node = this.element;
4333
5703
  if (node && node.isConnected) {
@@ -4511,7 +5881,20 @@ class ComponentBase extends Disposable {
4511
5881
  if (this.isVisible) {
4512
5882
  return;
4513
5883
  } /* A*/
4514
- if (this.motif.options?.transition?.activeAnimations?.length) {
5884
+ if (this.parent && enterModeOf(this.parent) === 'out-in') {
5885
+ const showHost = (this.motif.options.placeholder?.parentNode)
5886
+ ?? findAppendableComponent(this.parent)?.element;
5887
+ const wait = pendingLeaves(showHost, this.element);
5888
+ if (wait) {
5889
+ const seq = this._base._showSeq = (this._base._showSeq ?? 0) + 1;
5890
+ return wait.then(() => {
5891
+ if (this.isDisposed || this._base._showSeq !== seq)
5892
+ return;
5893
+ return this._show();
5894
+ });
5895
+ }
5896
+ }
5897
+ if (peekTransition(this)?.activeAnimations?.length) {
4515
5898
  safeCall(async () => {
4516
5899
  await Promise.all(this.motif.options.transition.activeAnimations.map(a => a.finished?.catch(() => { })));
4517
5900
  }, 'show.waitForLeaveAnimations');
@@ -4520,6 +5903,9 @@ class ComponentBase extends Disposable {
4520
5903
  const strategy = this._computeHideStrategy();
4521
5904
  if (strategy === 'detach') {
4522
5905
  ComponentHelper.callVisibilityChanged(this);
5906
+ if (this.isDisposed) {
5907
+ return;
5908
+ }
4523
5909
  const needAttach = !this._isInDom() && this.parent && this.parent.isBuilt && !this.isWait;
4524
5910
  this.isVisible = true;
4525
5911
  if (needAttach) {
@@ -4542,6 +5928,9 @@ class ComponentBase extends Disposable {
4542
5928
  /** A*/
4543
5929
  wantsEnterTransition(this) && this.motif.options.transition.enterTransition(() => { });
4544
5930
  ComponentHelper.callVisibilityChanged(this);
5931
+ if (this.isDisposed) {
5932
+ return;
5933
+ }
4545
5934
  if (this.element.nodeType === Node.COMMENT_NODE) {
4546
5935
  this.controls.forEach(c => {
4547
5936
  c.motif.show();
@@ -4562,12 +5951,16 @@ class ComponentBase extends Disposable {
4562
5951
  if (this.isDisposed || !this.element) {
4563
5952
  return;
4564
5953
  }
5954
+ this._base._showSeq = (this._base._showSeq ?? 0) + 1;
4565
5955
  if (!this.isVisible) {
4566
5956
  return;
4567
5957
  }
4568
5958
  const strategy = this._computeHideStrategy();
4569
5959
  if (strategy === 'detach') {
4570
5960
  ComponentHelper.callVisibilityChanged(this);
5961
+ if (this.isDisposed) {
5962
+ return;
5963
+ }
4571
5964
  await this._base._detachDomWithAnimationAsync();
4572
5965
  this.isVisible = false;
4573
5966
  ComponentHelper.deactivateTree(this);
@@ -4580,6 +5973,9 @@ class ComponentBase extends Disposable {
4580
5973
  transition.skipNextLeave = false;
4581
5974
  const finish = () => {
4582
5975
  ComponentHelper.callVisibilityChanged(this);
5976
+ if (this.isDisposed) {
5977
+ return;
5978
+ }
4583
5979
  if (this.element.nodeType === Node.COMMENT_NODE) {
4584
5980
  this.controls.forEach(c => {
4585
5981
  if (skip && c.isVisible && c.element && !c.isDisposed && c.motif.options?.transition) {
@@ -4789,109 +6185,43 @@ class ComponentBase extends Disposable {
4789
6185
  if (this.isDisposed) {
4790
6186
  return Promise.resolve();
4791
6187
  }
4792
- if (!this._disposing) {
4793
- retireServiceOwner(this);
4794
- }
4795
- return this._disposing ??= this._disposeCore(options);
4796
- }
4797
- async _disposeCore(options) {
4798
- if (options?.skipLeaveTransition) {
4799
- this.motif.options.transition.skipNextLeave = true;
4800
- }
4801
- safeCall(() => {
4802
- ComponentHelper.callDisposing.call(this, this);
4803
- }, 'dispose.callDisposing');
4804
- // DOM dinleyicileri hemen sökülür, aşağıda isDisposed true olunca off() boşa döner,
4805
- // element null'lanınca da _offAll dom'dan sökülemez — DOM'dan çıkmış öğeye sonradan gelen
4806
- this._base._offAll();
4807
- this._base._deactivateBindings();
4808
- safeCall(() => {
4809
- this.parent?.controls?.silentDetach?.(this, true);
4810
- }, 'dispose.silentDetach');
4811
- this.motif.options.transition.skipNextLeave && await this.motif.stopAnimations();
4812
- await this._base._detachDomWithAnimationAsync();
4813
- if (this.constructor.name !== 'TransportTo') {
4814
- await disposeContentBlocks(this);
4815
- }
4816
- await safeCallAsync(async () => {
4817
- if (this.isDisposed) {
4818
- return;
4819
- }
4820
- const ctrls = Array.from(this.controls.items);
4821
- if (ctrls.length) {
4822
- await Promise.all(ctrls.map(async (c) => {
4823
- try {
4824
- await c.disposeAsync({ deep: options?.deep });
4825
- }
4826
- catch (error) {
4827
- reportError('MJX107', error);
4828
- }
4829
- }));
6188
+ if (this._disposing) {
6189
+ return this._disposing;
6190
+ }
6191
+ retireServiceOwner(this);
6192
+ this._disposing = DISPOSE_STARTED;
6193
+ return this._disposing = this._disposeCore(options, false);
6194
+ }
6195
+ async _disposeCore(options, asChild) {
6196
+ disposePrefix(this, options, asChild);
6197
+ let leave;
6198
+ if (!asChild && !peekTransition(this)?.skipNextLeave) {
6199
+ leave = this._base._detachDomWithAnimationAsync();
6200
+ }
6201
+ await undefined;
6202
+ if (contentBlocks.live === 0 && subtreeDisposesSync(this, true)) {
6203
+ const pending = disposeRemainderSync(this, options, asChild, leave !== undefined);
6204
+ if (pending) {
6205
+ await Promise.all(pending);
6206
+ if (!asChild && this.isDisposed) {
6207
+ return;
6208
+ }
6209
+ disposeFinish(this, options, asChild);
4830
6210
  }
4831
- }, 'dispose.disposeAsync');
4832
- if (this.isDisposed) {
4833
6211
  return;
4834
6212
  }
4835
- this.isDisposed = true;
4836
- super.dispose();
4837
- this.element = null;
4838
- //if (options?.deep) {
4839
- safeCall(() => {
4840
- ComponentHelper.callDisposed.call(this, this);
4841
- }, 'dispose.callDisposed');
4842
- safeCall(() => { this._base.emiters.clear(); }, 'dispose.emiters');
4843
- this._base._offAll();
4844
- this._base._deepCleanup();
4845
- // var k = Object.keys(this);
4846
- // for (var i = 0; i < k.length; i++) {
4847
- // try {
4848
- // } catch {
6213
+ await disposeRemainderAsync(this, options, asChild, leave);
4849
6214
  }
4850
6215
  disposeAsync(options = { deep: true }) {
4851
6216
  if (this.isDisposed) {
4852
6217
  return Promise.resolve();
4853
6218
  }
4854
- if (!this._disposing) {
4855
- retireServiceOwner(this);
4856
- }
4857
- return this._disposing ??= this._disposeAsyncCore(options);
4858
- }
4859
- async _disposeAsyncCore(options) {
4860
- safeCall(() => {
4861
- ComponentHelper.callDisposing.call(this, this);
4862
- }, 'disposeAsync.callDisposing');
4863
- this._base._offAll();
4864
- this._base._deactivateBindings();
4865
- safeCall(() => {
4866
- this.parent?.controls?.silentDetach?.(this, true);
4867
- }, 'disposeAsync.silentDetach');
4868
- await this.motif.stopAnimations();
4869
- await this._base._detachDomWithAnimationAsync();
4870
- await safeCallAsync(async () => {
4871
- if (this.isDisposed) {
4872
- return;
4873
- }
4874
- const ctrls = Array.from(this.controls.items);
4875
- if (ctrls.length) {
4876
- await Promise.all(ctrls.map(c => safeCallAsync(async () => {
4877
- await c.disposeAsync({ deep: options?.deep });
4878
- }, 'disposeAsync.disposeAsyncChildren.handler')));
4879
- }
4880
- }, 'disposeAsync.disposeAsyncChildren');
4881
- this.isDisposed = true;
4882
- super.dispose();
4883
- this.controls.items = [];
4884
- safeCall(() => {
4885
- ComponentHelper.callDisposed.call(this, this);
4886
- }, 'disposeAsync.callDisposed');
4887
- safeCall(() => { this._base.emiters.clear(); }, 'disposeAsync.emiters');
4888
- if (options?.deep) {
4889
- this._base._deepCleanup();
6219
+ if (this._disposing) {
6220
+ return this._disposing;
4890
6221
  }
4891
- // var k = Object.keys(this);
4892
- // for (var i = 0; i < k.length; i++) {
4893
- // try {
4894
- // } catch { }
6222
+ retireServiceOwner(this);
6223
+ this._disposing = DISPOSE_STARTED;
6224
+ return this._disposing = this._disposeCore(options, true);
4895
6225
  }
4896
6226
  async _clear() {
4897
6227
  if (this.isDisposed == true) {
@@ -4921,33 +6251,50 @@ class ComponentBase extends Disposable {
4921
6251
  }
4922
6252
  });
4923
6253
  }
4924
- siblings = {
4925
- all: () => { return this.parent?.controls.items; },
4926
- next: () => {
4927
- if (!this.parent)
4928
- return undefined;
4929
- const idx = this.parent.controls.items.indexOf(this);
4930
- return this.parent.controls.items[idx + 1];
4931
- },
4932
- prev: () => {
4933
- if (!this.parent)
4934
- return undefined;
4935
- const idx = this.parent.controls.items.indexOf(this);
4936
- return this.parent.controls.items[idx - 1];
4937
- },
4938
- nextAll: () => {
4939
- if (!this.parent)
4940
- return undefined;
4941
- const idx = this.parent.controls.items.indexOf(this);
4942
- return this.parent.controls.items.slice(idx + 1);
4943
- },
4944
- prevAll: () => {
4945
- if (!this.parent)
4946
- return undefined;
4947
- const idx = this.parent.controls.items.indexOf(this);
4948
- return this.parent.controls.items.slice(0, idx);
6254
+ _siblingsApi;
6255
+ _siblingsSet;
6256
+ get siblings() {
6257
+ if (this._siblingsSet) {
6258
+ return this._siblingsApi;
4949
6259
  }
4950
- };
6260
+ if (this.isDisposed && !this.motif?.options) {
6261
+ return this._siblingsApi;
6262
+ }
6263
+ return this._siblingsApi ??= this._createSiblingsApi();
6264
+ }
6265
+ set siblings(value) {
6266
+ this._siblingsApi = value;
6267
+ this._siblingsSet = true;
6268
+ }
6269
+ _createSiblingsApi() {
6270
+ return {
6271
+ all: () => { return this.parent?.controls.items; },
6272
+ next: () => {
6273
+ if (!this.parent)
6274
+ return undefined;
6275
+ const idx = this.parent.controls.items.indexOf(this);
6276
+ return this.parent.controls.items[idx + 1];
6277
+ },
6278
+ prev: () => {
6279
+ if (!this.parent)
6280
+ return undefined;
6281
+ const idx = this.parent.controls.items.indexOf(this);
6282
+ return this.parent.controls.items[idx - 1];
6283
+ },
6284
+ nextAll: () => {
6285
+ if (!this.parent)
6286
+ return undefined;
6287
+ const idx = this.parent.controls.items.indexOf(this);
6288
+ return this.parent.controls.items.slice(idx + 1);
6289
+ },
6290
+ prevAll: () => {
6291
+ if (!this.parent)
6292
+ return undefined;
6293
+ const idx = this.parent.controls.items.indexOf(this);
6294
+ return this.parent.controls.items.slice(0, idx);
6295
+ }
6296
+ };
6297
+ }
4951
6298
  get serviceProvider() {
4952
6299
  let c = this;
4953
6300
  while (c) {
@@ -5029,14 +6376,15 @@ class ComponentBase extends Disposable {
5029
6376
  return result;
5030
6377
  }
5031
6378
  async _stopAnimations() {
6379
+ const t = peekTransition(this);
5032
6380
  try {
5033
- this.motif.options?.transition?.activeCssCancel?.();
6381
+ t?.activeCssCancel?.();
5034
6382
  }
5035
6383
  catch { }
5036
6384
  try {
5037
- if (this.motif.options?.transition?.activeAnimations?.length) {
6385
+ if (t?.activeAnimations?.length) {
5038
6386
  try {
5039
- await Promise.all(this.motif.options.transition.activeAnimations.map(a => a.finished?.catch(() => { })));
6387
+ await Promise.all(t.activeAnimations.map(a => a.finished?.catch(() => { })));
5040
6388
  }
5041
6389
  catch { /* ignore */ }
5042
6390
  }
@@ -5045,7 +6393,8 @@ class ComponentBase extends Disposable {
5045
6393
  }
5046
6394
  if (this.isDisposed)
5047
6395
  return;
5048
- this.motif.options.transition.activeAnimations = [];
6396
+ if (t)
6397
+ t.activeAnimations = [];
5049
6398
  }
5050
6399
  }
5051
6400
  function findContentBlocks(root, results = []) {
@@ -5060,8 +6409,10 @@ function findContentBlocks(root, results = []) {
5060
6409
  return results;
5061
6410
  }
5062
6411
  async function disposeContentBlocks(root) {
5063
- const contentBlocks = findContentBlocks(root);
5064
- return await Promise.all(contentBlocks.map(async (block) => {
6412
+ if (contentBlocks.live === 0)
6413
+ return;
6414
+ const contentBlocks$1 = findContentBlocks(root);
6415
+ return await Promise.all(contentBlocks$1.map(async (block) => {
5065
6416
  block.motif.options.transition.skipNextLeave = root.motif.options.transition.skipNextLeave;
5066
6417
  for (const element of block.controls.items) {
5067
6418
  element.motif.options.transition.skipNextLeave = block.motif.options.transition.skipNextLeave;
@@ -5116,7 +6467,7 @@ function extractRefs(props, component) {
5116
6467
  runover.ref = component;
5117
6468
  }
5118
6469
  }
5119
- return [].concat(...refs);
6470
+ return refs.length === 0 ? refs : [].concat(...refs);
5120
6471
  }
5121
6472
  const LIFECYCLE_HANDLER_LISTS = {
5122
6473
  'initializecomponent': '_initializeComponentHandlers',
@@ -5159,6 +6510,8 @@ function ParseProps(props, component) {
5159
6510
  Object.assign(component.motif.options.props, props);
5160
6511
  }
5161
6512
  var keys = Object.keys(props);
6513
+ if (keys.length === 0)
6514
+ return;
5162
6515
  keys.forEach(key => {
5163
6516
  if (key == 'initializeComponent' || key == 'oninitializeComponent' || key.startsWith('on')) {
5164
6517
  if (collectLifecycleHandlers(component, key.toLowerCase(), props[key])) {
@@ -5229,7 +6582,18 @@ function setTransition(component, value, live) {
5229
6582
  if (typeof value.name === 'string' && value.name.length > 0) {
5230
6583
  transition.name = value.name;
5231
6584
  }
5232
- transition.classes = value;
6585
+ if (!('mode' in value)) {
6586
+ transition.classes = value;
6587
+ }
6588
+ else {
6589
+ const { mode, ...classes } = value;
6590
+ if (isTransitionMode(mode)) {
6591
+ transition.mode = mode;
6592
+ }
6593
+ if (Object.keys(classes).length > 0) {
6594
+ transition.classes = classes;
6595
+ }
6596
+ }
5233
6597
  }
5234
6598
  else if (live) {
5235
6599
  transition.name = '';
@@ -5281,17 +6645,45 @@ const PLAIN_ELEMENT_SKIP = new Set([
5281
6645
  'ref', 'key', 'indexkey', 'inject', 'options', 'props', 'settings', 'isSvg',
5282
6646
  'childs', 'initializeComponent', 'runover', 'transition', 'preconfig', 'nodes', 'onElementCreating'
5283
6647
  ]);
6648
+ const SPREAD_URL_ATTRIBUTES = new Set(['href', 'src', 'action', 'formaction', 'xlink:href']);
6649
+ 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;
6650
+ function isJavascriptUrl(value) {
6651
+ if (value === undefined || value === null || typeof value === 'boolean')
6652
+ return false;
6653
+ try {
6654
+ return JAVASCRIPT_URL.test(String(value));
6655
+ }
6656
+ catch {
6657
+ return false;
6658
+ }
6659
+ }
6660
+ function guardSpreadUrl(key, read) {
6661
+ return () => {
6662
+ let value = read();
6663
+ if (typeof value === 'function')
6664
+ value = value();
6665
+ if (typeof value === 'function')
6666
+ value = value();
6667
+ if (!isJavascriptUrl(value))
6668
+ return value;
6669
+ reportWarning('MJX125', [key]);
6670
+ return null;
6671
+ };
6672
+ }
5284
6673
  function applyPlainElementProps(props, component) {
5285
6674
  if (!props || typeof props !== 'object' || component.isDisposed)
5286
6675
  return;
5287
- const attrs = {};
5288
- const applied = appliedDomProps(component);
5289
- for (const key of Object.keys(props)) {
6676
+ const keys = Object.keys(props);
6677
+ if (keys.length === 0)
6678
+ return;
6679
+ let attrs = null;
6680
+ let applied = null;
6681
+ for (const key of keys) {
5290
6682
  if (PLAIN_ELEMENT_SKIP.has(key))
5291
6683
  continue;
5292
6684
  if (key.startsWith('x-') || key.startsWith('x:') || key.startsWith('__'))
5293
6685
  continue;
5294
- const v = props[key];
6686
+ let v = props[key];
5295
6687
  if (v === undefined)
5296
6688
  continue;
5297
6689
  if (/^on/i.test(key)) {
@@ -5301,7 +6693,20 @@ function applyPlainElementProps(props, component) {
5301
6693
  }
5302
6694
  if (typeof v === 'function' && v.length > 0)
5303
6695
  continue;
5304
- applied.set(key, v);
6696
+ if (key === 'innerHTML') {
6697
+ reportWarning('MJX124', []);
6698
+ continue;
6699
+ }
6700
+ if (SPREAD_URL_ATTRIBUTES.has(key.toLowerCase())) {
6701
+ if (typeof v === 'function') {
6702
+ v = guardSpreadUrl(key, v);
6703
+ }
6704
+ else if (isJavascriptUrl(v)) {
6705
+ reportWarning('MJX125', [key]);
6706
+ continue;
6707
+ }
6708
+ }
6709
+ (applied ??= appliedDomProps(component)).set(key, v);
5305
6710
  if (key === 'class' || key === 'className') {
5306
6711
  component.class.add(v && typeof v === 'object' && !Array.isArray(v) ? [v] : v);
5307
6712
  }
@@ -5312,10 +6717,10 @@ function applyPlainElementProps(props, component) {
5312
6717
  component.bindings.add(key, v);
5313
6718
  }
5314
6719
  else {
5315
- attrs[key] = v;
6720
+ (attrs ??= {})[key] = v;
5316
6721
  }
5317
6722
  }
5318
- if (Object.keys(attrs).length > 0)
6723
+ if (attrs)
5319
6724
  component.attr.add(attrs);
5320
6725
  }
5321
6726
  const _appliedDomProps = new WeakMap();
@@ -5335,8 +6740,8 @@ function isFallthroughKey(key) {
5335
6740
  function applyFallthroughProps(props, component) {
5336
6741
  if (!props || typeof props !== 'object' || component.isDisposed)
5337
6742
  return;
5338
- const applied = appliedDomProps(component);
5339
- const subset = {};
6743
+ const applied = _appliedDomProps.get(component);
6744
+ let subset = null;
5340
6745
  for (const key of Object.keys(props)) {
5341
6746
  if (!isFallthroughKey(key))
5342
6747
  continue;
@@ -5345,11 +6750,11 @@ function applyFallthroughProps(props, component) {
5345
6750
  continue;
5346
6751
  if (typeof v === 'function' && v.length > 0)
5347
6752
  continue;
5348
- if (applied.has(key) && Object.is(applied.get(key), v))
6753
+ if (applied && applied.has(key) && Object.is(applied.get(key), v))
5349
6754
  continue;
5350
- subset[key] = v;
6755
+ (subset ??= {})[key] = v;
5351
6756
  }
5352
- if (Object.keys(subset).length > 0)
6757
+ if (subset)
5353
6758
  applyPlainElementProps(subset, component);
5354
6759
  }
5355
6760
  const componentMethods = {
@@ -5718,8 +7123,156 @@ class FragmentNode extends Component {
5718
7123
  }
5719
7124
  }
5720
7125
 
7126
+ const glblths = globalThis;
7127
+ function getCurrentDom() {
7128
+ if (glblths && glblths.motifDom) {
7129
+ return glblths.motifDom.window.document;
7130
+ }
7131
+ return glblths.document;
7132
+ }
7133
+ const dom = {
7134
+ get window() {
7135
+ if (glblths && glblths.window) {
7136
+ return glblths.window;
7137
+ }
7138
+ else if (glblths && glblths) {
7139
+ return glblths.motifDom.window;
7140
+ }
7141
+ else {
7142
+ return glblths;
7143
+ }
7144
+ },
7145
+ _created: new Map(),
7146
+ document: getCurrentDom(),
7147
+ createElement(tagName, options) {
7148
+ const doc = getCurrentDom();
7149
+ if (!doc) {
7150
+ throw motifError('MJX101', tagName);
7151
+ }
7152
+ if (tagName === "text") {
7153
+ return doc.createTextNode('');
7154
+ }
7155
+ if (!this._created.has(tagName)) {
7156
+ const view = doc.createElement(tagName, options);
7157
+ this._created.set(tagName, view);
7158
+ }
7159
+ const tpl = this._created.get(tagName);
7160
+ return tpl.cloneNode(false);
7161
+ },
7162
+ createDocumentFragment() {
7163
+ try {
7164
+ var cd = getCurrentDom();
7165
+ if (cd) {
7166
+ return cd.createDocumentFragment();
7167
+ }
7168
+ }
7169
+ catch (error) {
7170
+ errorHandler.reportSuppressed('dom.createDocumentFragment', error);
7171
+ }
7172
+ },
7173
+ createComment(content) {
7174
+ try {
7175
+ return getCurrentDom()?.createComment(content);
7176
+ }
7177
+ catch (error) {
7178
+ errorHandler.reportSuppressed('dom.createComment', error);
7179
+ }
7180
+ },
7181
+ createTextNode(content) {
7182
+ try {
7183
+ return getCurrentDom()?.createTextNode(content);
7184
+ }
7185
+ catch (error) {
7186
+ errorHandler.reportSuppressed('dom.createTextNode', error);
7187
+ }
7188
+ },
7189
+ querySelectorAll(selectors) {
7190
+ try {
7191
+ return getCurrentDom()?.querySelectorAll(selectors);
7192
+ }
7193
+ catch (error) {
7194
+ errorHandler.reportSuppressed('dom.querySelectorAll', error);
7195
+ }
7196
+ },
7197
+ createElementNS(namepsaceUri, tagName, options) {
7198
+ try {
7199
+ return getCurrentDom()?.createElementNS(namepsaceUri, tagName, options);
7200
+ }
7201
+ catch (error) {
7202
+ reportError('MJX103', error, tagName);
7203
+ }
7204
+ },
7205
+ convertToSvgElement(element) {
7206
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
7207
+ const tagName = element.tagName.toLowerCase();
7208
+ const newSvgElement = document.createElementNS(SVG_NAMESPACE, tagName);
7209
+ for (const attr of element.attributes) {
7210
+ newSvgElement.setAttribute(attr.name, attr.value);
7211
+ }
7212
+ while (element.firstChild) {
7213
+ newSvgElement.appendChild(element.firstChild);
7214
+ }
7215
+ const parent = element.parentNode;
7216
+ if (parent) {
7217
+ parent.replaceChild(newSvgElement, element);
7218
+ }
7219
+ return newSvgElement;
7220
+ },
7221
+ get body() {
7222
+ return getCurrentDom()?.body;
7223
+ }
7224
+ };
7225
+ const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((\.([\w\-]+))*)/;
7226
+ var Namespace;
7227
+ (function (Namespace) {
7228
+ Namespace["HTML"] = "http://www.w3.org/1999/xhtml";
7229
+ Namespace["SVG"] = "http://www.w3.org/2000/svg";
7230
+ })(Namespace || (Namespace = {}));
7231
+ function _$(namespace, description, attrs, ...children) {
7232
+ const match = SELECTOR_REGEX.exec(description);
7233
+ if (!match) {
7234
+ throw motifError('MJX102', description);
7235
+ }
7236
+ const tagName = match[1] || 'div';
7237
+ let result;
7238
+ if (namespace !== Namespace.HTML) {
7239
+ result = dom.createElementNS(namespace, tagName);
7240
+ }
7241
+ else {
7242
+ result = dom.createElement(tagName);
7243
+ }
7244
+ if (match[3]) {
7245
+ result.id = match[3];
7246
+ }
7247
+ if (match[4]) {
7248
+ result.className = match[4].replace(/\./g, ' ').trim();
7249
+ }
7250
+ if (attrs) {
7251
+ Object.entries(attrs).forEach(([name, value]) => {
7252
+ if (typeof value === 'undefined') {
7253
+ return;
7254
+ }
7255
+ if (/^on\w+$/.test(name)) {
7256
+ result[name] = value;
7257
+ }
7258
+ else if (name === 'selected') {
7259
+ if (value) {
7260
+ result.setAttribute(name, 'true');
7261
+ }
7262
+ }
7263
+ else {
7264
+ result.setAttribute(name, value);
7265
+ }
7266
+ });
7267
+ }
7268
+ result.append(...children);
7269
+ return result;
7270
+ }
7271
+ function $(description, attrs, ...children) {
7272
+ return _$(Namespace.HTML, description, attrs, ...children);
7273
+ }
7274
+
5721
7275
  // import { dom } from "../browser";
5722
- // import { effect } from "../store";
5723
7276
  class ControlCollection {
5724
7277
  owner;
5725
7278
  constructor(owner) {
@@ -5727,9 +7280,16 @@ class ControlCollection {
5727
7280
  }
5728
7281
  items = [];
5729
7282
  add() {
5730
- const args = Array.from(arguments);
5731
- if (args.length === 0)
7283
+ const count = arguments.length;
7284
+ if (count === 0)
5732
7285
  return [];
7286
+ const first = arguments[0];
7287
+ if (count === 1 && first instanceof ComponentBase) {
7288
+ if (first.isDisposed)
7289
+ return [];
7290
+ return [this._insertOne(undefined, first)];
7291
+ }
7292
+ const args = Array.from(arguments);
5733
7293
  if (typeof args[0] === 'number' && args.length > 1) {
5734
7294
  const index = args[0];
5735
7295
  const children = [].concat(...args.slice(1));
@@ -5742,42 +7302,43 @@ class ControlCollection {
5742
7302
  }
5743
7303
  insert(index, ...controls) {
5744
7304
  const flat = [].concat(...controls);
5745
- return flat.filter(x => x != undefined && !x.isDisposed).map(control => {
5746
- control = resolveComponent(control);
5747
- if (typeof control == 'string' || typeof control == 'number' || typeof control == 'boolean' || typeof control == 'bigint') {
5748
- control = new Component(dom.createTextNode(control), null);
5749
- }
5750
- if (control.parent) {
5751
- control.parent.controls.detach(control);
5752
- }
5753
- if (index != undefined && index >= 0) {
5754
- this.items.splice(index, 0, control);
5755
- }
5756
- else {
5757
- this.items.push(control);
5758
- }
5759
- control.parent = this.owner;
5760
- const pendingLeave = control.__pendingLeave;
5761
- if (pendingLeave) {
5762
- if (this.onAddBeforeBuild && !this.owner.isBuilt) {
5763
- this.onAddBeforeBuild(control);
5764
- }
5765
- pendingLeave.promise.then(() => {
5766
- if (control.isDisposed || this.owner.isDisposed || control.parent !== this.owner)
5767
- return;
5768
- if (this.onAdd && this.owner.isBuilt)
5769
- this.onAdd(control);
5770
- });
5771
- return control;
5772
- }
5773
- if (this.onAdd && this.owner.isBuilt) {
5774
- this.onAdd(control);
5775
- }
7305
+ return flat.filter(x => x != undefined && !x.isDisposed).map(control => this._insertOne(index, control));
7306
+ }
7307
+ _insertOne(index, control) {
7308
+ control = resolveComponent(control);
7309
+ if (typeof control == 'string' || typeof control == 'number' || typeof control == 'boolean' || typeof control == 'bigint') {
7310
+ control = new Component(dom.createTextNode(control), null);
7311
+ }
7312
+ if (control.parent) {
7313
+ control.parent.controls.detach(control);
7314
+ }
7315
+ if (index != undefined && index >= 0) {
7316
+ this.items.splice(index, 0, control);
7317
+ }
7318
+ else {
7319
+ this.items.push(control);
7320
+ }
7321
+ control.parent = this.owner;
7322
+ const pendingLeave = control.__pendingLeave;
7323
+ if (pendingLeave) {
5776
7324
  if (this.onAddBeforeBuild && !this.owner.isBuilt) {
5777
7325
  this.onAddBeforeBuild(control);
5778
7326
  }
7327
+ pendingLeave.promise.then(() => {
7328
+ if (control.isDisposed || this.owner.isDisposed || control.parent !== this.owner)
7329
+ return;
7330
+ if (this.onAdd && this.owner.isBuilt)
7331
+ this.onAdd(control);
7332
+ });
5779
7333
  return control;
5780
- });
7334
+ }
7335
+ if (this.onAdd && this.owner.isBuilt) {
7336
+ this.onAdd(control);
7337
+ }
7338
+ if (this.onAddBeforeBuild && !this.owner.isBuilt) {
7339
+ this.onAddBeforeBuild(control);
7340
+ }
7341
+ return control;
5781
7342
  }
5782
7343
  remove(control) {
5783
7344
  var index = this.items.indexOf(control);
@@ -5796,6 +7357,7 @@ class ControlCollection {
5796
7357
  this.items.splice(index, 1);
5797
7358
  if (control.isDisposed)
5798
7359
  return Promise.resolve();
7360
+ control._base && (control._base._leaveContainer = this.owner);
5799
7361
  control.parent = null;
5800
7362
  return runLeaveThenDetach(control, () => { if (this.onRemove)
5801
7363
  this.onRemove(control); });
@@ -5825,6 +7387,7 @@ class ControlCollection {
5825
7387
  if (index === -1)
5826
7388
  return;
5827
7389
  this.items.splice(index, 1);
7390
+ control._base && (control._base._leaveContainer = this.owner);
5828
7391
  control.parent = null;
5829
7392
  }
5830
7393
  async clearAsync() {
@@ -6087,7 +7650,12 @@ function runLeaveThenDetach(control, notify) {
6087
7650
  arrive();
6088
7651
  };
6089
7652
  try {
6090
- c.motif.options.transition.leaveTransition(once);
7653
+ const opts = c.motif.options;
7654
+ if (!opts[TRANSITION_SLOT] && !opts.transitionOut) {
7655
+ once();
7656
+ return;
7657
+ }
7658
+ opts.transition.leaveTransition(once);
6091
7659
  }
6092
7660
  catch {
6093
7661
  once();
@@ -6313,7 +7881,7 @@ function Lazy(props) {
6313
7881
  frame.navigate(resolveComponent(opts.Fallbackview));
6314
7882
  }
6315
7883
  else {
6316
- errorHandler.reportSuppressed('Lazy.load (no Fallbackview)', err);
7884
+ reportError('MJX126', err);
6317
7885
  try {
6318
7886
  frame.motif.clear().catch(() => { });
6319
7887
  }
@@ -6323,6 +7891,20 @@ function Lazy(props) {
6323
7891
  return frame;
6324
7892
  }
6325
7893
 
7894
+ function hasOwnTransition(component, phase) {
7895
+ const options = component?.motif?.options;
7896
+ if (!options)
7897
+ return false;
7898
+ const transition = options.transition;
7899
+ return !!((phase === 'enter' ? options.transitionIn : options.transitionOut) || (transition && (transition.classes || (transition.name && transition.name.length > 0))));
7900
+ }
7901
+ function playsLeave(target) {
7902
+ if (!target)
7903
+ return false;
7904
+ if (Array.isArray(target))
7905
+ return target.some(t => !!t && !t.isDisposed && hasOwnTransition(t, 'leave'));
7906
+ return !target.isDisposed && hasOwnTransition(target, 'leave');
7907
+ }
6326
7908
  function cancelAnimationsDeep(target) {
6327
7909
  if (!target || target.isDisposed)
6328
7910
  return;
@@ -6358,26 +7940,20 @@ function cancelAnimationsDeep(target) {
6358
7940
  }
6359
7941
  catch { }
6360
7942
  }
6361
- async function disposeNavigationTarget(target) {
7943
+ async function disposeNavigationTarget(target, options = { deep: true }) {
6362
7944
  if (!target)
6363
7945
  return;
6364
- if (Array.isArray(target)) {
6365
- for (const xr of target) {
6366
- try {
6367
- if (xr && !xr.isDisposed) {
6368
- await xr.dispose({ deep: true, skipLeaveTransition: true });
6369
- }
6370
- }
6371
- catch (err) {
6372
- reportError('MJX115', err);
6373
- }
7946
+ const list = Array.isArray(target) ? target : [target];
7947
+ await Promise.all(list.map(async (xr) => {
7948
+ if (!xr || xr.isDisposed)
7949
+ return;
7950
+ try {
7951
+ await xr.dispose(options);
6374
7952
  }
6375
- }
6376
- else {
6377
- if (!target.isDisposed) {
6378
- await target.dispose({ deep: true, skipLeaveTransition: true });
7953
+ catch (err) {
7954
+ reportError('MJX115', err);
6379
7955
  }
6380
- }
7956
+ }));
6381
7957
  }
6382
7958
  async function navigateHost(host, page, keepOldControl = false) {
6383
7959
  if (host.isDisposed || page == null)
@@ -6431,10 +8007,14 @@ async function navigateHost(host, page, keepOldControl = false) {
6431
8007
  if (oldPage && !keepOldControl) {
6432
8008
  cancelAnimationsDeep(oldPage);
6433
8009
  cancelAnimationsDeep(host);
6434
- try {
6435
- await disposeNavigationTarget(oldPage);
8010
+ const animated = playsLeave(oldPage);
8011
+ const leaving = disposeNavigationTarget(oldPage);
8012
+ if (animated) {
8013
+ leaving.catch(() => { });
8014
+ }
8015
+ else {
8016
+ await leaving;
6436
8017
  }
6437
- catch { }
6438
8018
  }
6439
8019
  try {
6440
8020
  if (page instanceof Promise) {
@@ -6470,9 +8050,9 @@ class Frame extends Component {
6470
8050
  this.controls.add(props.childs);
6471
8051
  }
6472
8052
  }
6473
- async dispose() {
6474
- await disposeNavigationTarget(this.current);
6475
- await super.dispose();
8053
+ async dispose(options = { deep: true }) {
8054
+ await disposeNavigationTarget(this.current, options);
8055
+ await super.dispose(options);
6476
8056
  }
6477
8057
  async flush() {
6478
8058
  await disposeNavigationTarget(this.current);
@@ -6490,6 +8070,466 @@ class Frame extends Component {
6490
8070
  }
6491
8071
  }
6492
8072
 
8073
+ const ARRAY_MUTATORS = new Set(['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort']);
8074
+ const NOT_META = Symbol('');
8075
+ const metaReaders = new Map([
8076
+ [Flags.IS_REACTIVE, () => true],
8077
+ [Flags.IS_READONLY, engine => engine.isReadonly],
8078
+ [Flags.IS_SUPERFICIAL, engine => engine.superficial],
8079
+ [Flags.GET_SETUP, (_engine, target) => target],
8080
+ [Flags.RAW, (engine, target, receiver) => engine.ReactiveMap().get(target) === receiver ? target : NOT_META],
8081
+ ]);
8082
+ function readMeta(engine, target, key, receiver) {
8083
+ if (typeof key !== 'symbol')
8084
+ return NOT_META;
8085
+ const reader = metaReaders.get(key);
8086
+ return reader === undefined ? NOT_META : reader(engine, target, receiver);
8087
+ }
8088
+ function createGetter(engine) {
8089
+ return function (target, p, receiver) {
8090
+ const meta = readMeta(engine, target, p, receiver);
8091
+ if (meta !== NOT_META)
8092
+ return meta;
8093
+ if (Array.isArray(target) && !engine.isReadonly) {
8094
+ const patched = engine.arrayMethods.get;
8095
+ if (hasOwn(patched, p)) {
8096
+ const method = patched[p];
8097
+ if (ARRAY_MUTATORS.has(p))
8098
+ addArrayStack(p);
8099
+ else
8100
+ track(target, p);
8101
+ return method;
8102
+ }
8103
+ }
8104
+ const value = Reflect.get(target, p, receiver);
8105
+ if (p === '__proto__' || isIntrinsicSymbol(p))
8106
+ return value;
8107
+ if (!engine.isReadonly)
8108
+ track(target, p);
8109
+ if (engine.superficial || !isObject(value))
8110
+ return value;
8111
+ return engine.reactive(value);
8112
+ };
8113
+ }
8114
+
8115
+ function createSetter(engine) {
8116
+ return function (target, p, newValue, receiver) {
8117
+ if (isReadonly(target)) {
8118
+ return false;
8119
+ }
8120
+ const isArray = Array.isArray(target);
8121
+ const oldValue = target[p];
8122
+ const oldLength = isArray ? target.length : 0;
8123
+ const numeric = isArray && isNumericKey(p);
8124
+ const hadKey = numeric ? Number(p) < oldLength : hasOwn(target, p);
8125
+ const res = Reflect.set(target, p, newValue, receiver);
8126
+ if (engine.onValueChanged) {
8127
+ try {
8128
+ engine.onValueChanged({ raw: target, proxy: receiver }, p);
8129
+ }
8130
+ catch { }
8131
+ }
8132
+ if (getRaw(target) !== getRaw(receiver)) {
8133
+ return res;
8134
+ }
8135
+ if (!isArray && hadKey && Object.is(newValue, oldValue)) {
8136
+ return res;
8137
+ }
8138
+ trigger(target, p);
8139
+ if (!isArray && !hadKey) {
8140
+ trigger(target, ITERATE_KEY);
8141
+ }
8142
+ if (numeric && !hadKey) {
8143
+ trigger(target, 'length');
8144
+ }
8145
+ if (isArray && p === 'length') {
8146
+ const newLength = Number(newValue);
8147
+ for (let i = newLength; i < oldLength; i++) {
8148
+ trigger(target, String(i));
8149
+ }
8150
+ }
8151
+ removeArrayStack();
8152
+ return res;
8153
+ };
8154
+ }
8155
+
8156
+ function createOwn(engine) {
8157
+ return function ownKeys(target) {
8158
+ const shapeKey = Array.isArray(target) ? 'length' : ITERATE_KEY;
8159
+ track(target, shapeKey);
8160
+ return Reflect.ownKeys(target);
8161
+ };
8162
+ }
8163
+ function createHas(engine) {
8164
+ return function has(target, p) {
8165
+ const found = Reflect.has(target, p);
8166
+ if (isIntrinsicSymbol(p))
8167
+ return found;
8168
+ track(target, p);
8169
+ return found;
8170
+ };
8171
+ }
8172
+ function createDelete(engine) {
8173
+ return function deleteProperty(target, p) {
8174
+ pauseTracking();
8175
+ try {
8176
+ const isOwned = hasOwn(target, p);
8177
+ const result = Reflect.deleteProperty(target, p);
8178
+ if (isOwned) {
8179
+ if (Array.isArray(target)) {
8180
+ trigger(target, 'length');
8181
+ }
8182
+ else {
8183
+ trigger(target, p);
8184
+ trigger(target, ITERATE_KEY);
8185
+ }
8186
+ }
8187
+ return result;
8188
+ }
8189
+ finally {
8190
+ resetTracking();
8191
+ }
8192
+ };
8193
+ }
8194
+
8195
+ const PATCHED_ARRAY_METHODS = [
8196
+ ['includes', 'lookup'],
8197
+ ['indexOf', 'lookup'],
8198
+ ['lastIndexOf', 'lookup'],
8199
+ ['sort', 'order'],
8200
+ ['concat', 'join'],
8201
+ ['push', 'structural'],
8202
+ ['pop', 'structural'],
8203
+ ['shift', 'structural'],
8204
+ ['unshift', 'structural'],
8205
+ ['splice', 'structural'],
8206
+ ['reverse', 'structural'],
8207
+ ];
8208
+ const isLookupMiss = (outcome) => outcome === false || outcome === -1;
8209
+ class ArrayMethods {
8210
+ engine;
8211
+ constructor(engine) {
8212
+ this.engine = engine;
8213
+ }
8214
+ get = this.createArrayMethods();
8215
+ createArrayMethods() {
8216
+ const table = {};
8217
+ for (const [name, kind] of PATCHED_ARRAY_METHODS) {
8218
+ table[name] = this.patch(name, kind);
8219
+ }
8220
+ return table;
8221
+ }
8222
+ patch(name, kind) {
8223
+ const owner = this;
8224
+ switch (kind) {
8225
+ case 'lookup':
8226
+ return function (...needles) {
8227
+ const source = getRaw(this);
8228
+ owner.engine.track(source, 'length');
8229
+ const direct = source[name](...needles);
8230
+ if (!isLookupMiss(direct))
8231
+ return direct;
8232
+ return source[name](...needles.map(needle => getRaw(needle)));
8233
+ };
8234
+ case 'order':
8235
+ return function (...args) {
8236
+ const source = getRaw(this);
8237
+ const size = this.length;
8238
+ for (let index = 0; index < size; index++) {
8239
+ owner.engine.track(source, String(index));
8240
+ }
8241
+ const sorted = source[name].apply(this, args);
8242
+ owner.engine.track(source, name);
8243
+ return sorted;
8244
+ };
8245
+ case 'join':
8246
+ return function (...args) {
8247
+ return Array.prototype.concat.apply(this, args);
8248
+ };
8249
+ default:
8250
+ return function (...args) {
8251
+ pauseTracking();
8252
+ const source = getRaw(this);
8253
+ try {
8254
+ return source[name].apply(this, args);
8255
+ }
8256
+ finally {
8257
+ resetTracking();
8258
+ }
8259
+ };
8260
+ }
8261
+ }
8262
+ }
8263
+
8264
+ const ReactiveEngineMapper = new WeakSet();
8265
+ const AllreactiveMap = new WeakMap();
8266
+ function armgetter() { return AllreactiveMap; }
8267
+ class ReactiveEngine {
8268
+ _gci;
8269
+ startGc(_intervalMs = 10000) { }
8270
+ stopGc() { if (this._gci) {
8271
+ try {
8272
+ clearInterval(this._gci);
8273
+ }
8274
+ catch { }
8275
+ this._gci = undefined;
8276
+ } }
8277
+ constructor() {
8278
+ ReactiveEngineMapper.add(this);
8279
+ this.startGc();
8280
+ }
8281
+ DisposeMapper = new LinkedList();
8282
+ arrayTriggerCache = new Map();
8283
+ ReactiveMap = () => armgetter();
8284
+ activeCallback;
8285
+ isReadonly = false;
8286
+ superficial = false;
8287
+ arrayMethods = new ArrayMethods(this);
8288
+ arrayHandler = {
8289
+ get: createGetter(this),
8290
+ set: createSetter(this),
8291
+ has: createHas(),
8292
+ deleteProperty: createDelete(),
8293
+ ownKeys: createOwn()
8294
+ };
8295
+ deepHandler = {
8296
+ get: createGetter(this),
8297
+ set: createSetter(this),
8298
+ has: createHas(),
8299
+ deleteProperty: createDelete(),
8300
+ ownKeys: createOwn()
8301
+ };
8302
+ reactive(model) {
8303
+ if (!isObject(model)) {
8304
+ model = { value: model };
8305
+ }
8306
+ const targetType = getTargetType(model);
8307
+ if (targetType === 0 /* TargetType.SYSTEM */ || targetType === 2 /* TargetType.COLLECTION */ || 0 /* TargetType.INVALID */) {
8308
+ return model;
8309
+ }
8310
+ let existingProxy = AllreactiveMap.get(model);
8311
+ if (existingProxy) {
8312
+ return existingProxy;
8313
+ }
8314
+ existingProxy = AllreactiveMap.get(getRaw(model));
8315
+ if (existingProxy) {
8316
+ return existingProxy;
8317
+ }
8318
+ // if (targetType === TargetType.INVALID) {
8319
+ if (Array.isArray(model)) {
8320
+ var proxy = new Proxy(model, this.arrayHandler);
8321
+ // var original = Object.getPrototypeOf(proxy);
8322
+ // original["copy"] = () => { return model; }
8323
+ // return "copied";
8324
+ AllreactiveMap.set(model, proxy);
8325
+ // try { this.startGc(); } catch { }
8326
+ return proxy;
8327
+ }
8328
+ else {
8329
+ var proxy = new Proxy(model, this.deepHandler);
8330
+ AllreactiveMap.set(model, proxy);
8331
+ // try { this.startGc(); } catch { }
8332
+ return proxy;
8333
+ }
8334
+ }
8335
+ clearModel(model) {
8336
+ if (model != null && model != undefined) {
8337
+ Object.keys(model).forEach((key) => {
8338
+ if (typeof model[key] === 'object') {
8339
+ if (AllreactiveMap.has(model[key]) || AllreactiveMap.has(getRaw(model[key]))) {
8340
+ this.clearModel(model[key]);
8341
+ }
8342
+ }
8343
+ AllreactiveMap.delete(getRaw(model[key]));
8344
+ AllreactiveMap.delete(model[key]);
8345
+ });
8346
+ AllreactiveMap.delete(getRaw(model));
8347
+ AllreactiveMap.delete(model);
8348
+ }
8349
+ }
8350
+ track(model, key) {
8351
+ track(model, key);
8352
+ }
8353
+ trigger(model, key, value) {
8354
+ trigger(model, key);
8355
+ }
8356
+ ArrayTrigger(target, key, ...args) {
8357
+ this.trigger(target, key, args);
8358
+ }
8359
+ onValueChanged;
8360
+ toRaw(item) {
8361
+ return JSON.parse(JSON.stringify(this.deepClone(item)));
8362
+ }
8363
+ deepClone(item) {
8364
+ var self = this;
8365
+ if (!item) {
8366
+ return item;
8367
+ }
8368
+ var types = [Number, String, Boolean], result;
8369
+ types.forEach(function (type) {
8370
+ if (item instanceof type) {
8371
+ result = type(item);
8372
+ }
8373
+ });
8374
+ if (typeof result == "undefined") {
8375
+ if (Object.prototype.toString.call(item) === "[object Array]") {
8376
+ result = [];
8377
+ item.forEach(function (child, index, array) {
8378
+ result[index] = self.deepClone(child);
8379
+ });
8380
+ }
8381
+ else if (typeof item == "object") {
8382
+ if (item.nodeType && typeof item.cloneNode == "function") {
8383
+ result = item.cloneNode(true);
8384
+ }
8385
+ else if (!item.prototype) {
8386
+ if (item instanceof Date) {
8387
+ result = new Date(item);
8388
+ }
8389
+ else {
8390
+ result = {};
8391
+ for (var i in item) {
8392
+ result[i] = self.deepClone(item[i]);
8393
+ }
8394
+ }
8395
+ }
8396
+ else {
8397
+ {
8398
+ result = item;
8399
+ }
8400
+ }
8401
+ }
8402
+ else {
8403
+ result = item;
8404
+ }
8405
+ }
8406
+ return result;
8407
+ }
8408
+ pauseTracking() {
8409
+ pauseTracking();
8410
+ }
8411
+ enableTracking() {
8412
+ enableTracking();
8413
+ }
8414
+ resetTracking() {
8415
+ resetTracking();
8416
+ }
8417
+ dispose() {
8418
+ var cnt = true;
8419
+ this.stopGc();
8420
+ while (cnt == true) {
8421
+ if (this.DisposeMapper.size > 0) {
8422
+ const element = this.DisposeMapper.pop();
8423
+ // if (ApplicationService.current?.Options?.onReactiveEffectRun) {
8424
+ AllreactiveMap.delete(element);
8425
+ }
8426
+ else {
8427
+ cnt = false;
8428
+ }
8429
+ }
8430
+ this.DisposeMapper.clear();
8431
+ ReactiveEngineMapper.delete(this);
8432
+ // if (ApplicationService.current?.Options?.onReactiveEffectRun) {
8433
+ }
8434
+ }
8435
+
8436
+ const engine = new ReactiveEngine();
8437
+ /* @DEV-ONLY */ const reactiveRegistry = [];
8438
+ const isDevRegistryEnabled = () => {
8439
+ try {
8440
+ const g = globalThis;
8441
+ if (!g.__MOTIF_DEV__)
8442
+ return false;
8443
+ if (g.__MOTIF_STORE_REGISTRY__ !== reactiveRegistry)
8444
+ g.__MOTIF_STORE_REGISTRY__ = reactiveRegistry;
8445
+ return true;
8446
+ }
8447
+ catch {
8448
+ return false;
8449
+ }
8450
+ };
8451
+ // export * from "./IStoreBinder";
8452
+ // export function reactiveListeners(model?: any) {
8453
+ // if (model) {
8454
+ // /* @DEV-ONLY */return debugGetDeps(model) ?? new Map();
8455
+ // return debugGetDepMap();
8456
+ function reactive(model) {
8457
+ const result = engine.reactive(model);
8458
+ /* @DEV-ONLY */ try {
8459
+ /* @DEV-ONLY */ if (isDevRegistryEnabled()) {
8460
+ /* @DEV-ONLY */ const name = model?.constructor?.name || 'reactive';
8461
+ /* @DEV-ONLY */ reactiveRegistry.push({ name, value: result, type: 'reactive' });
8462
+ /* @DEV-ONLY */ if (reactiveRegistry.length > 200)
8463
+ reactiveRegistry.shift();
8464
+ /* @DEV-ONLY */ }
8465
+ /* @DEV-ONLY */
8466
+ /* @DEV-ONLY */ }
8467
+ catch { }
8468
+ return result;
8469
+ }
8470
+ function useModel(model) {
8471
+ const result = engine.reactive(model);
8472
+ /* @DEV-ONLY */ try {
8473
+ /* @DEV-ONLY */ if (isDevRegistryEnabled()) {
8474
+ /* @DEV-ONLY */ const name = model?.constructor?.name || 'useModel';
8475
+ /* @DEV-ONLY */ reactiveRegistry.push({ name, value: result, type: 'reactive' });
8476
+ /* @DEV-ONLY */ if (reactiveRegistry.length > 200)
8477
+ reactiveRegistry.shift();
8478
+ /* @DEV-ONLY */ }
8479
+ /* @DEV-ONLY */
8480
+ /* @DEV-ONLY */ }
8481
+ catch { }
8482
+ return result;
8483
+ }
8484
+ function clearModel(model) {
8485
+ return engine.clearModel(model);
8486
+ }
8487
+ function deepClone(item) {
8488
+ return engine.deepClone(item);
8489
+ }
8490
+ function createSignal(initialValue) {
8491
+ const sig = new Signal(initialValue);
8492
+ /* @DEV-ONLY */ try {
8493
+ /* @DEV-ONLY */ if (isDevRegistryEnabled()) {
8494
+ /* @DEV-ONLY */ const name = `signal_${reactiveRegistry.length}`;
8495
+ /* @DEV-ONLY */ reactiveRegistry.push({ name, value: sig.value, type: 'signal' });
8496
+ /* @DEV-ONLY */ if (reactiveRegistry.length > 200)
8497
+ reactiveRegistry.shift();
8498
+ /* @DEV-ONLY */ }
8499
+ /* @DEV-ONLY */
8500
+ /* @DEV-ONLY */ }
8501
+ catch { }
8502
+ return sig;
8503
+ }
8504
+ function createComputed(getter) {
8505
+ const comp = new Computed(getter);
8506
+ /* @DEV-ONLY */ try {
8507
+ /* @DEV-ONLY */ if (isDevRegistryEnabled()) {
8508
+ /* @DEV-ONLY */ const name = `computed_${reactiveRegistry.length}`;
8509
+ /* @DEV-ONLY */ reactiveRegistry.push({ name, value: comp.value, type: 'computed' });
8510
+ /* @DEV-ONLY */ if (reactiveRegistry.length > 200)
8511
+ reactiveRegistry.shift();
8512
+ /* @DEV-ONLY */ }
8513
+ /* @DEV-ONLY */
8514
+ /* @DEV-ONLY */ }
8515
+ catch { }
8516
+ return comp;
8517
+ }
8518
+ function createLazyComputed(getter) {
8519
+ const comp = new LazyComputed(getter);
8520
+ /* @DEV-ONLY */ try {
8521
+ /* @DEV-ONLY */ if (isDevRegistryEnabled()) {
8522
+ /* @DEV-ONLY */ const name = `lazyComputed_${reactiveRegistry.length}`;
8523
+ /* @DEV-ONLY */ reactiveRegistry.push({ name, value: undefined, type: 'computed' });
8524
+ /* @DEV-ONLY */ if (reactiveRegistry.length > 200)
8525
+ reactiveRegistry.shift();
8526
+ /* @DEV-ONLY */ }
8527
+ /* @DEV-ONLY */
8528
+ /* @DEV-ONLY */ }
8529
+ catch { }
8530
+ return comp;
8531
+ }
8532
+
6493
8533
  const autoRegistry = new Map();
6494
8534
 
6495
8535
  function isConstructor(fn) {
@@ -6730,12 +8770,12 @@ function render() {
6730
8770
  function toggle(force) {
6731
8771
  if (!overlayHost)
6732
8772
  return;
6733
- visible = typeof force === 'boolean' ? force : !visible;
8773
+ visible = !visible;
6734
8774
  overlayHost.style.display = visible ? 'block' : 'none';
6735
8775
  }
6736
8776
  function initOverlayIfEnabled() {
6737
8777
  ensureDevtoolsFlagInitialized();
6738
- if (!isEnabled())
8778
+ if (!isRequestedByFlag())
6739
8779
  return;
6740
8780
  try {
6741
8781
  if (!overlayHost) {
@@ -6753,9 +8793,6 @@ function initOverlayIfEnabled() {
6753
8793
  });
6754
8794
  on((ev) => { if (ev.type === 'warning' && visible)
6755
8795
  render(); });
6756
- const qs = location.search || '';
6757
- if (Application.main.isDevelopmentModeEnabled)
6758
- toggle(true);
6759
8796
  }
6760
8797
  }
6761
8798
  catch { }
@@ -7113,13 +9150,6 @@ const STORAGE_KEY = 'motifjs:stack';
7113
9150
  const SLIDE_OFFSET = 30;
7114
9151
  const EASING = 'cubic-bezier(0.2, 0.8, 0.2, 1)';
7115
9152
  const isElement = (node) => !!node && node.nodeType === 1 && !!node.style;
7116
- function hasOwnTransition(component, phase) {
7117
- const options = component?.motif?.options;
7118
- if (!options)
7119
- return false;
7120
- const transition = options.transition;
7121
- return !!((phase === 'enter' ? options.transitionIn : options.transitionOut) || (transition && (transition.classes || (transition.name && transition.name.length > 0))));
7122
- }
7123
9153
  function markDirection(component, direction) {
7124
9154
  const el = component?.element;
7125
9155
  if (!component || component.isDisposed || !isElement(el))
@@ -7502,7 +9532,7 @@ class NavigationStack {
7502
9532
  if (!top || top.isDisposed)
7503
9533
  return;
7504
9534
  try {
7505
- await disposeNavigationTarget(top);
9535
+ await disposeNavigationTarget(top, { deep: true, skipLeaveTransition: true });
7506
9536
  }
7507
9537
  catch (error) {
7508
9538
  reportError('MJX307', error);
@@ -9934,8 +11964,14 @@ class Application {
9934
11964
  }
9935
11965
  catch { /* ignore */ }
9936
11966
  }, 'Application.dispose.resetUrl');
11967
+ transitionSettings.mode = 'concurrent';
9937
11968
  _globalApplication = null;
9938
11969
  }
11970
+ useTransitions(options) {
11971
+ if (isTransitionMode(options?.mode))
11972
+ transitionSettings.mode = options.mode;
11973
+ return this;
11974
+ }
9939
11975
  use(callback) {
9940
11976
  this._middlewares.push(callback);
9941
11977
  return this;
@@ -10151,6 +12187,7 @@ class Application {
10151
12187
  this._isDevelopment = isDev;
10152
12188
  errorHandler.setDevelopmentMode(isDev);
10153
12189
  safeCallSilent(() => { globalThis.__MOTIF_DEV__ = isDev; }, 'Application.useDevelopment.flag');
12190
+ safeCallSilent(() => { setDevtoolsEnabled(isDev); }, 'Application.useDevelopment.devtools');
10154
12191
  if (isDev)
10155
12192
  flushCompilerContractWarnings();
10156
12193
  return this;
@@ -10175,5 +12212,5 @@ function useApplication() {
10175
12212
  };
10176
12213
  }
10177
12214
 
10178
- export { Application as A, Component as C, Disposable as D, Emitter as E, FNComponent as F, Lazy as L, RouterView as R, ServiceCollection as S, UrlRoutingModule as U, ComponentBase as a, autoRegistry as b, ApplicationBuilder as c, ComponentMotif as d, ControlCollection as e, findAppendableComponent$1 as f, disposableCore as g, DisposableStore as h, FragmentNode as i, Frame as j, inject as k, motifComponent as l, motifCompiled as m, notifyDeactivated as n, motifFragment as o, ServiceProvider as p, useNavigation as q, RoutingEngine as r, RouterState as s, toDisposable as t, useApplication as u, createRouter as v, Scanner as w, RouteCollection as x };
10179
- //# sourceMappingURL=core-DxINgP83.esm.js.map
12215
+ export { useApplication as $, Application as A, ErrorHandler as B, Component as C, Disposable as D, Emitter as E, FNComponent as F, FragmentNode as G, Frame as H, inject as I, LazyComputed as J, LinkedList as K, Lazy as L, MotifError as M, motifCompiled as N, motifComponent as O, motifFragment as P, NodeTypes as Q, reactive as R, RouterView as S, safeCall as T, safeCallAsync as U, safeCallSilent as V, ServiceCollection as W, ServiceProvider as X, setUnexpectedErrorHandler as Y, Signal as Z, toDisposable as _, reportError as a, useModel as a0, useNavigation as a1, debugGetDeps as a2, debugGetDepMap as a3, UrlRoutingModule as a4, RoutingEngine as a5, RouterState as a6, createRouter as a7, Scanner as a8, RouteCollection as a9, ComponentBase as b, contentBlocks as c, autoRegistry as d, effect as e, findAppendableComponent$1 as f, formatMotifMessage as g, ApplicationBuilder as h, asyncTracking as i, clearModel as j, ComponentMotif as k, Computed as l, motifError as m, notifyDeactivated as n, configureReactivityLeakMonitor as o, ControlCollection as p, createComputed as q, reportWarning as r, createLazyComputed as s, createSignal as t, untracked as u, deepClone as v, disposableCore as w, DisposableStore as x, dom as y, errorHandler as z };
12216
+ //# sourceMappingURL=core-BGdhUeHu.esm.js.map