@nativescript/core 9.1.0-next.3 → 9.1.0-next.4

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.
Files changed (79) hide show
  1. package/accessibility/accessibility-common.d.ts +8 -0
  2. package/accessibility/accessibility-common.js +28 -0
  3. package/accessibility/accessibility-common.js.map +1 -1
  4. package/application/application-common.d.ts +187 -3
  5. package/application/application-common.js +397 -54
  6. package/application/application-common.js.map +1 -1
  7. package/application/application-interfaces.d.ts +59 -1
  8. package/application/application.android.d.ts +21 -0
  9. package/application/application.android.js +189 -7
  10. package/application/application.android.js.map +1 -1
  11. package/application/application.d.ts +121 -66
  12. package/application/application.ios.d.ts +88 -26
  13. package/application/application.ios.js +474 -351
  14. package/application/application.ios.js.map +1 -1
  15. package/application/helpers-common.d.ts +5 -0
  16. package/application/helpers-common.js +23 -1
  17. package/application/helpers-common.js.map +1 -1
  18. package/application/scene-delegate-bridge.d.ts +55 -0
  19. package/application/scene-delegate-bridge.js +122 -0
  20. package/application/scene-delegate-bridge.js.map +1 -0
  21. package/config/config.interface.d.ts +38 -2
  22. package/css/system-classes.d.ts +9 -0
  23. package/css/system-classes.js +23 -0
  24. package/css/system-classes.js.map +1 -1
  25. package/data/observable/index.d.ts +5 -0
  26. package/data/observable/index.js +9 -0
  27. package/data/observable/index.js.map +1 -1
  28. package/global-types.d.ts +39 -33
  29. package/globals/global-utils.d.ts +6 -1
  30. package/globals/global-utils.js +10 -5
  31. package/globals/global-utils.js.map +1 -1
  32. package/index.d.ts +1 -0
  33. package/index.js +1 -0
  34. package/index.js.map +1 -1
  35. package/native-window/index.d.ts +426 -0
  36. package/native-window/index.js +4 -0
  37. package/native-window/index.js.map +1 -0
  38. package/native-window/native-window-common.d.ts +153 -0
  39. package/native-window/native-window-common.js +340 -0
  40. package/native-window/native-window-common.js.map +1 -0
  41. package/native-window/native-window-interfaces.d.ts +186 -0
  42. package/native-window/native-window-interfaces.js +90 -0
  43. package/native-window/native-window-interfaces.js.map +1 -0
  44. package/native-window/native-window.android.d.ts +59 -0
  45. package/native-window/native-window.android.js +175 -0
  46. package/native-window/native-window.android.js.map +1 -0
  47. package/native-window/native-window.ios.d.ts +57 -0
  48. package/native-window/native-window.ios.js +208 -0
  49. package/native-window/native-window.ios.js.map +1 -0
  50. package/native-window/window-base.d.ts +103 -0
  51. package/native-window/window-base.js +78 -0
  52. package/native-window/window-base.js.map +1 -0
  53. package/package.json +1 -1
  54. package/ui/core/view/index.android.js +3 -1
  55. package/ui/core/view/index.android.js.map +1 -1
  56. package/ui/core/view/index.d.ts +25 -0
  57. package/ui/core/view/view-common.d.ts +19 -0
  58. package/ui/core/view/view-common.js +34 -0
  59. package/ui/core/view/view-common.js.map +1 -1
  60. package/ui/core/view-base/index.js +6 -0
  61. package/ui/core/view-base/index.js.map +1 -1
  62. package/ui/frame/frame-common.d.ts +14 -2
  63. package/ui/frame/frame-common.js +17 -5
  64. package/ui/frame/frame-common.js.map +1 -1
  65. package/ui/frame/frame-constants.d.ts +9 -0
  66. package/ui/frame/frame-constants.js +10 -0
  67. package/ui/frame/frame-constants.js.map +1 -0
  68. package/ui/frame/frame-helper-for-android.d.ts +2 -2
  69. package/ui/frame/frame-helper-for-android.js +2 -2
  70. package/ui/frame/frame-helper-for-android.js.map +1 -1
  71. package/ui/frame/frame-interfaces.d.ts +1 -1
  72. package/ui/frame/frame-stack.d.ts +17 -1
  73. package/ui/frame/frame-stack.js +32 -5
  74. package/ui/frame/frame-stack.js.map +1 -1
  75. package/ui/frame/index.android.d.ts +1 -1
  76. package/ui/frame/index.android.js +111 -38
  77. package/ui/frame/index.android.js.map +1 -1
  78. package/ui/frame/index.d.ts +15 -5
  79. package/utils/native-helper.d.ts +2 -2
@@ -1,4 +1,3 @@
1
- import { CoreTypes } from '../core-types';
2
1
  import { CSSUtils } from '../css/system-classes';
3
2
  import { Device, Screen } from '../platform';
4
3
  import { profile } from '../profiling';
@@ -6,48 +5,76 @@ import { Trace } from '../trace';
6
5
  import { clearResolverCache, prepareAppForModuleResolver, _setResolver } from '../module-name-resolver/helpers';
7
6
  import { Builder } from '../ui/builder';
8
7
  import * as bindableResources from '../ui/core/bindable/bindable-resources';
9
- import { readyInitAccessibilityCssHelper, readyInitFontScale } from '../accessibility/accessibility-common';
10
- import { getAppMainEntry, isAppInBackground, setAppInBackground, setAppMainEntry } from './helpers-common';
8
+ import { applyAccessibilityCssToRoot, readyInitAccessibilityCssHelper, readyInitFontScale } from '../accessibility/accessibility-common';
9
+ import { getActiveWindow, getAppMainEntry, getAutoSystemAppearanceChanged, isAppInBackground, setActiveWindow, setAppInBackground, setAppMainEntry, setAutoSystemAppearanceChanged } from './helpers-common';
11
10
  import { getNativeScriptGlobals } from '../globals/global-utils';
12
11
  import { SDK_VERSION } from '../utils/constants';
13
- // prettier-ignore
14
- const ORIENTATION_CSS_CLASSES = [
15
- `${CSSUtils.CLASS_PREFIX}${CoreTypes.DeviceOrientation.portrait}`,
16
- `${CSSUtils.CLASS_PREFIX}${CoreTypes.DeviceOrientation.landscape}`,
17
- `${CSSUtils.CLASS_PREFIX}${CoreTypes.DeviceOrientation.unknown}`,
18
- ];
19
- // prettier-ignore
20
- const SYSTEM_APPEARANCE_CSS_CLASSES = [
21
- `${CSSUtils.CLASS_PREFIX}${CoreTypes.SystemAppearance.light}`,
22
- `${CSSUtils.CLASS_PREFIX}${CoreTypes.SystemAppearance.dark}`,
23
- ];
24
- // prettier-ignore
25
- const LAYOUT_DIRECTION_CSS_CLASSES = [
26
- `${CSSUtils.CLASS_PREFIX}${CoreTypes.LayoutDirection.ltr}`,
27
- `${CSSUtils.CLASS_PREFIX}${CoreTypes.LayoutDirection.rtl}`,
28
- ];
12
+ import { NativeWindowEvents, WindowEvents } from '../native-window/native-window-interfaces';
13
+ const ORIENTATION_CSS_CLASSES = CSSUtils.ORIENTATION_CSS_CLASSES;
14
+ const SYSTEM_APPEARANCE_CSS_CLASSES = CSSUtils.SYSTEM_APPEARANCE_CSS_CLASSES;
15
+ const LAYOUT_DIRECTION_CSS_CLASSES = CSSUtils.LAYOUT_DIRECTION_CSS_CLASSES;
29
16
  const globalEvents = getNativeScriptGlobals().events;
30
17
  // Scene lifecycle event names
18
+ /**
19
+ * @deprecated Use `NativeWindowEvents` from `@nativescript/core/native-window` instead.
20
+ */
31
21
  export const SceneEvents = {
22
+ /** @deprecated Use `NativeWindowEvents.sceneWillConnect` instead. */
32
23
  sceneWillConnect: 'sceneWillConnect',
24
+ /** @deprecated Use `NativeWindowEvents.sceneDidActivate` instead. */
33
25
  sceneDidActivate: 'sceneDidActivate',
26
+ /** @deprecated Use `NativeWindowEvents.sceneWillResignActive` instead. */
34
27
  sceneWillResignActive: 'sceneWillResignActive',
28
+ /** @deprecated Use `NativeWindowEvents.sceneWillEnterForeground` instead. */
35
29
  sceneWillEnterForeground: 'sceneWillEnterForeground',
30
+ /** @deprecated Use `NativeWindowEvents.sceneDidEnterBackground` instead. */
36
31
  sceneDidEnterBackground: 'sceneDidEnterBackground',
32
+ /** @deprecated Use `NativeWindowEvents.sceneDidDisconnect` instead. */
37
33
  sceneDidDisconnect: 'sceneDidDisconnect',
34
+ /** @deprecated Use the Application 'windowOpen' event and NativeWindow.setContent() instead. */
38
35
  sceneContentSetup: 'sceneContentSetup',
39
36
  };
40
37
  export class ApplicationCommon {
38
+ /**
39
+ * Boolean to enable/disable systemAppearanceChanged
40
+ */
41
+ get autoSystemAppearanceChanged() {
42
+ return getAutoSystemAppearanceChanged();
43
+ }
44
+ set autoSystemAppearanceChanged(value) {
45
+ setAutoSystemAppearanceChanged(value);
46
+ }
41
47
  /**
42
48
  * @internal - should not be constructed by the user.
43
49
  */
44
50
  constructor() {
51
+ /**
52
+ * @deprecated Use the 'ready' event for application initialization and Application.setWindowContentResolver() to provide window UI. 'launch' continues to fire before the first window's content is created, and its 'root' property is still honored, for backwards compatibility. It will not fire for additional windows or for background launches.
53
+ */
45
54
  this.launchEvent = 'launch';
55
+ /**
56
+ * Raised once per JS context, as soon as the context is initialized. It is never deferred,
57
+ * so it also fires on a background launch where no window is created.
58
+ *
59
+ * Guaranteed ordering: `ready` -> `windowOpen` -> raw connect/create events -> content
60
+ * resolution (the legacy `launch` bridge runs here, for the first window only) ->
61
+ * `contentLoaded` -> `activate`/`displayed`.
62
+ */
63
+ this.readyEvent = 'ready';
64
+ /**
65
+ * Reflects whole-app state: with multiple windows it is raised once the app itself is
66
+ * no longer in the foreground, not when an individual window backgrounds. Listen on a
67
+ * NativeWindow for per-window state.
68
+ */
46
69
  this.suspendEvent = 'suspend';
47
70
  this.displayedEvent = 'displayed';
48
71
  this.backgroundEvent = 'background';
49
72
  this.foregroundEvent = 'foreground';
50
73
  this.resumeEvent = 'resume';
74
+ /**
75
+ * On Android, raised when the last window closes; the process may stay alive.
76
+ * On iOS, raised when the process itself terminates.
77
+ */
51
78
  this.exitEvent = 'exit';
52
79
  this.lowMemoryEvent = 'lowMemory';
53
80
  this.uncaughtErrorEvent = 'uncaughtError';
@@ -60,6 +87,9 @@ export class ApplicationCommon {
60
87
  this.loadAppCssEvent = 'loadAppCss';
61
88
  this.cssChangedEvent = 'cssChanged';
62
89
  this.initRootViewEvent = 'initRootView';
90
+ this.windowOpenEvent = WindowEvents.windowOpen;
91
+ this.windowCloseEvent = WindowEvents.windowClose;
92
+ this.primaryWindowChangedEvent = WindowEvents.primaryWindowChanged;
63
93
  // Application events go through the global events.
64
94
  this.on = globalEvents.on.bind(globalEvents);
65
95
  this.once = globalEvents.once.bind(globalEvents);
@@ -69,11 +99,15 @@ export class ApplicationCommon {
69
99
  this._inBackground = false;
70
100
  this._suspended = false;
71
101
  this._cssFile = './app.css';
102
+ this._readyNotified = false;
103
+ this._appCssLoaded = false;
104
+ this._launchBridgeConsumed = false;
105
+ this._windowContentResolver = null;
72
106
  this.started = false;
73
- /**
74
- * Boolean to enable/disable systemAppearanceChanged
75
- */
76
- this.autoSystemAppearanceChanged = true;
107
+ // --- NativeWindow registry ---
108
+ this._windows = [];
109
+ // --- Primary window traits ---
110
+ this._traitsWindow = null;
77
111
  getNativeScriptGlobals().appInstanceReady = true;
78
112
  global.__onUncaughtError = (error) => {
79
113
  this.notify({
@@ -151,18 +185,37 @@ export class ApplicationCommon {
151
185
  CSSUtils.removeSystemCssClass(cssClass);
152
186
  rootView.cssClasses.delete(cssClass);
153
187
  }
188
+ /**
189
+ * Same as {@link applyCssClass}, minus the system class list: window-scoped classes
190
+ * must not leak into it, because it seeds every window's root view.
191
+ */
192
+ applyWindowScopedCssClass(rootView, cssClasses, newCssClass) {
193
+ if (rootView.cssClasses.has(newCssClass)) {
194
+ return;
195
+ }
196
+ cssClasses.forEach((cssClass) => rootView.cssClasses.delete(cssClass));
197
+ rootView.cssClasses.add(newCssClass);
198
+ this.increaseStyleScopeApplicationCssSelectorVersion(rootView);
199
+ }
200
+ /**
201
+ * The modal registry is process-wide, so only the modals presented over this root
202
+ * view may follow its window-scoped classes.
203
+ */
204
+ getOwnedModalViews(rootView) {
205
+ return rootView._getRootModalViews().filter((modalView) => modalView._getRootModalHost() === rootView);
206
+ }
154
207
  increaseStyleScopeApplicationCssSelectorVersion(rootView) {
155
208
  const styleScope = rootView._styleScope ?? rootView?.currentPage?._styleScope;
156
209
  if (styleScope) {
157
210
  styleScope._increaseApplicationCssSelectorVersion();
158
211
  }
159
212
  }
160
- setRootViewCSSClasses(rootView) {
213
+ setRootViewCSSClasses(rootView, window) {
161
214
  const platform = Device.os.toLowerCase();
162
215
  const deviceType = Device.deviceType.toLowerCase();
163
- const orientation = this.orientation();
164
- const systemAppearance = this.systemAppearance();
165
- const layoutDirection = this.layoutDirection();
216
+ const orientation = window ? window.orientation() : this.orientation();
217
+ const systemAppearance = window ? window.systemAppearance() : this.systemAppearance();
218
+ const layoutDirection = window ? window.layoutDirection() : this.layoutDirection();
166
219
  if (platform) {
167
220
  CSSUtils.pushToSystemCssClasses(`${CSSUtils.CLASS_PREFIX}${platform}`);
168
221
  // SDK Version CSS classes
@@ -174,18 +227,20 @@ export class ApplicationCommon {
174
227
  if (deviceType) {
175
228
  CSSUtils.pushToSystemCssClasses(`${CSSUtils.CLASS_PREFIX}${deviceType}`);
176
229
  }
230
+ rootView.cssClasses.add(CSSUtils.ROOT_VIEW_CSS_CLASS);
231
+ const rootViewCssClasses = CSSUtils.getSystemCssClasses();
232
+ rootViewCssClasses.forEach((c) => rootView.cssClasses.add(c));
233
+ // Two windows can disagree on these, so they never reach the process-wide
234
+ // system class list — see CSSUtils.WINDOW_SCOPED_CSS_CLASSES.
177
235
  if (orientation) {
178
- CSSUtils.pushToSystemCssClasses(`${CSSUtils.CLASS_PREFIX}${orientation}`);
236
+ rootView.cssClasses.add(`${CSSUtils.CLASS_PREFIX}${orientation}`);
179
237
  }
180
238
  if (systemAppearance) {
181
- CSSUtils.pushToSystemCssClasses(`${CSSUtils.CLASS_PREFIX}${systemAppearance}`);
239
+ rootView.cssClasses.add(`${CSSUtils.CLASS_PREFIX}${systemAppearance}`);
182
240
  }
183
241
  if (layoutDirection) {
184
- CSSUtils.pushToSystemCssClasses(`${CSSUtils.CLASS_PREFIX}${layoutDirection}`);
242
+ rootView.cssClasses.add(`${CSSUtils.CLASS_PREFIX}${layoutDirection}`);
185
243
  }
186
- rootView.cssClasses.add(CSSUtils.ROOT_VIEW_CSS_CLASS);
187
- const rootViewCssClasses = CSSUtils.getSystemCssClasses();
188
- rootViewCssClasses.forEach((c) => rootView.cssClasses.add(c));
189
244
  this.increaseStyleScopeApplicationCssSelectorVersion(rootView);
190
245
  rootView._onCssStateChange();
191
246
  if (Trace.isEnabled()) {
@@ -215,7 +270,286 @@ export class ApplicationCommon {
215
270
  getMainEntry() {
216
271
  return getAppMainEntry();
217
272
  }
273
+ /**
274
+ * Sets the callback that supplies the UI for windows that need content.
275
+ * Pass `null` to remove a previously set resolver.
276
+ */
277
+ setWindowContentResolver(resolver) {
278
+ this._windowContentResolver = resolver ?? null;
279
+ }
280
+ /**
281
+ * @returns The callback currently supplying window content, if any.
282
+ */
283
+ getWindowContentResolver() {
284
+ return this._windowContentResolver;
285
+ }
286
+ /**
287
+ * Get the primary NativeWindow.
288
+ */
289
+ get primaryWindow() {
290
+ return this._windows.find((nw) => nw.isPrimary);
291
+ }
292
+ /**
293
+ * Get the NativeWindow the user is currently interacting with - the one that activated most
294
+ * recently and is still attached. Falls back to the primary window while no window holds
295
+ * activation, which is the case before the first window activates and on a platform that
296
+ * never raises `activate`.
297
+ */
298
+ get activeWindow() {
299
+ const active = getActiveWindow();
300
+ if (active && active.state === 'attached' && this._windows.indexOf(active) !== -1) {
301
+ return active;
302
+ }
303
+ return this.primaryWindow;
304
+ }
305
+ getWindows(role) {
306
+ if (role === 'all') {
307
+ return [...this._windows];
308
+ }
309
+ const roles = role ? (Array.isArray(role) ? role : [role]) : ['application', 'embedded'];
310
+ return this._windows.filter((nw) => roles.indexOf(nw.role) !== -1);
311
+ }
312
+ /**
313
+ * Get a registered NativeWindow by its id.
314
+ */
315
+ getWindowById(id) {
316
+ return this._windows.find((nw) => nw.id === id);
317
+ }
318
+ /**
319
+ * Opens a new window.
320
+ *
321
+ * @param options Options for the new window, including data to hand to it.
322
+ */
323
+ openWindow(options) {
324
+ throw new Error('openWindow() is not supported on this platform.');
325
+ }
326
+ /**
327
+ * @internal - Get all registered NativeWindows, whatever their role.
328
+ */
329
+ _getWindows() {
330
+ return [...this._windows];
331
+ }
332
+ /**
333
+ * @internal - Register a NativeWindow created by the platform lifecycle.
334
+ */
335
+ _registerWindow(nativeWindow) {
336
+ this._windows.push(nativeWindow);
337
+ // A closing window drops its own listeners, so this is never explicitly removed.
338
+ nativeWindow.on(NativeWindowEvents.activate, this.onWindowActivated, this);
339
+ if (nativeWindow.isPrimary) {
340
+ this.trackPrimaryWindowTraits(nativeWindow);
341
+ }
342
+ this._onWindowRegistered(nativeWindow);
343
+ this.notify({
344
+ eventName: this.windowOpenEvent,
345
+ object: this,
346
+ window: nativeWindow,
347
+ });
348
+ }
349
+ /**
350
+ * @internal - Unregister a NativeWindow when its native surface is gone for good.
351
+ */
352
+ _unregisterWindow(nativeWindow) {
353
+ const idx = this._windows.indexOf(nativeWindow);
354
+ if (idx >= 0) {
355
+ this._windows.splice(idx, 1);
356
+ }
357
+ if (getActiveWindow() === nativeWindow) {
358
+ setActiveWindow(undefined);
359
+ }
360
+ this.notify({
361
+ eventName: this.windowCloseEvent,
362
+ object: this,
363
+ window: nativeWindow,
364
+ });
365
+ // If primary was removed, promote the next window that can actually host content
366
+ if (nativeWindow.isPrimary) {
367
+ nativeWindow._setIsPrimary(false);
368
+ const promoted = this.getWindows().find((nw) => nw.state === 'attached');
369
+ this.trackPrimaryWindowTraits(promoted);
370
+ if (promoted) {
371
+ promoted._setIsPrimary(true);
372
+ this._onPrimaryWindowPromoted(promoted);
373
+ this.notify({
374
+ eventName: this.primaryWindowChangedEvent,
375
+ object: this,
376
+ window: promoted,
377
+ });
378
+ }
379
+ }
380
+ nativeWindow._destroy();
381
+ }
382
+ /**
383
+ * Hook for platform-specific bookkeeping right after a window joins the registry,
384
+ * before `windowOpen` is raised.
385
+ */
386
+ _onWindowRegistered(nativeWindow) {
387
+ // noop
388
+ }
389
+ /**
390
+ * Hook for platform-specific bookkeeping right after a window takes over the primary
391
+ * role, before `primaryWindowChanged` is raised.
392
+ */
393
+ _onPrimaryWindowPromoted(nativeWindow) {
394
+ // noop
395
+ }
396
+ /**
397
+ * Points the application-level orientation, appearance and layout direction at the
398
+ * primary window, which owns those values now that each window has its own.
399
+ */
400
+ trackPrimaryWindowTraits(nativeWindow) {
401
+ const target = nativeWindow ?? null;
402
+ if (this._traitsWindow === target) {
403
+ return;
404
+ }
405
+ const previous = this._traitsWindow;
406
+ if (previous) {
407
+ previous.off(NativeWindowEvents.orientationChanged, this.onWindowOrientationChanged, this);
408
+ previous.off(NativeWindowEvents.systemAppearanceChanged, this.onWindowSystemAppearanceChanged, this);
409
+ previous.off(NativeWindowEvents.layoutDirectionChanged, this.onWindowLayoutDirectionChanged, this);
410
+ }
411
+ this._traitsWindow = target;
412
+ if (!target) {
413
+ return;
414
+ }
415
+ target.on(NativeWindowEvents.orientationChanged, this.onWindowOrientationChanged, this);
416
+ target.on(NativeWindowEvents.systemAppearanceChanged, this.onWindowSystemAppearanceChanged, this);
417
+ target.on(NativeWindowEvents.layoutDirectionChanged, this.onWindowLayoutDirectionChanged, this);
418
+ this.syncTraitsFromWindow(target);
419
+ }
420
+ /**
421
+ * Adopts the window's values. The very first window seeds them quietly — there is no
422
+ * previous application state for it to differ from — while a later promotion raises
423
+ * the change events, because app code observed the outgoing window's values.
424
+ */
425
+ syncTraitsFromWindow(nativeWindow) {
426
+ const orientation = nativeWindow.orientation();
427
+ if (orientation) {
428
+ if (this._orientation === undefined) {
429
+ this._orientation = orientation;
430
+ }
431
+ else {
432
+ this.setOrientation(orientation);
433
+ }
434
+ }
435
+ const systemAppearance = nativeWindow.systemAppearance();
436
+ if (systemAppearance) {
437
+ if (this._systemAppearance === undefined) {
438
+ this._systemAppearance = systemAppearance;
439
+ }
440
+ else {
441
+ this.setSystemAppearance(systemAppearance);
442
+ }
443
+ }
444
+ const layoutDirection = nativeWindow.layoutDirection();
445
+ if (layoutDirection) {
446
+ if (this._layoutDirection === undefined) {
447
+ this._layoutDirection = layoutDirection;
448
+ }
449
+ else {
450
+ this.setLayoutDirection(layoutDirection);
451
+ }
452
+ }
453
+ }
454
+ onWindowActivated(data) {
455
+ setActiveWindow(data.window);
456
+ }
457
+ onWindowOrientationChanged(data) {
458
+ this.setOrientation(data.newValue);
459
+ }
460
+ onWindowSystemAppearanceChanged(data) {
461
+ this.setSystemAppearance(data.newValue);
462
+ }
463
+ onWindowLayoutDirectionChanged(data) {
464
+ this.setLayoutDirection(data.newValue);
465
+ }
466
+ /**
467
+ * @internal - raises `ready` at most once per JS context.
468
+ */
469
+ notifyReady() {
470
+ if (this._readyNotified) {
471
+ return;
472
+ }
473
+ this._readyNotified = true;
474
+ getNativeScriptGlobals().setLaunched();
475
+ this.notify({
476
+ eventName: this.readyEvent,
477
+ object: this,
478
+ ios: this.ios,
479
+ android: this.android,
480
+ });
481
+ }
482
+ /**
483
+ * @internal - produces the content for a window that has none.
484
+ *
485
+ * Resolution order: the window content resolver, then the legacy `launch` event
486
+ * (offered to the first window that asks for content and to no other), then the
487
+ * application main entry. A resolver or a `launch` handler returning `null` takes
488
+ * ownership of the content, so nothing else is tried. A missing main entry leaves
489
+ * the window empty instead of throwing, because content can still arrive later
490
+ * through `run()`/`resetRootView()`.
491
+ *
492
+ * @param options.install `false` returns the resolved view instead of applying it,
493
+ * for platform pipelines that install the root view on the native surface themselves.
494
+ * @param options.launchData platform payload merged into the legacy `launch` event args.
495
+ * @returns The resolved view, or `null` when no content was produced.
496
+ */
497
+ _resolveWindowContent(window, request, options) {
498
+ const content = this.resolveWindowContent(request, options?.launchData);
499
+ if (content == null) {
500
+ return null;
501
+ }
502
+ if (options?.install === false) {
503
+ return this.buildContentView(content);
504
+ }
505
+ window.setContent(content);
506
+ return window.rootView;
507
+ }
508
+ resolveWindowContent(request, launchData) {
509
+ const launchBridgeAvailable = !this._launchBridgeConsumed;
510
+ this._launchBridgeConsumed = true;
511
+ const resolver = this._windowContentResolver;
512
+ if (resolver) {
513
+ const resolved = resolver(request);
514
+ // `null` means the resolver supplies the content itself; only `undefined` falls through.
515
+ if (resolved !== undefined) {
516
+ this._ensureAppCssLoaded();
517
+ return resolved;
518
+ }
519
+ }
520
+ if (launchBridgeAvailable) {
521
+ const root = this.notifyLaunch(launchData);
522
+ if (root === null) {
523
+ return null;
524
+ }
525
+ if (root) {
526
+ return root;
527
+ }
528
+ }
529
+ this._ensureAppCssLoaded();
530
+ const mainEntry = getAppMainEntry();
531
+ return mainEntry ? Builder.createViewFromEntry(mainEntry) : undefined;
532
+ }
533
+ buildContentView(content) {
534
+ if (typeof content === 'string') {
535
+ return Builder.createViewFromEntry({ moduleName: content });
536
+ }
537
+ const entry = content;
538
+ return entry.moduleName || entry.create ? Builder.createViewFromEntry(entry) : content;
539
+ }
540
+ /**
541
+ * Loads the app CSS once per JS context. On the legacy `launch` path this has to run
542
+ * after the handlers, which are allowed to call `setCssFileName()`.
543
+ */
544
+ _ensureAppCssLoaded() {
545
+ if (this._appCssLoaded) {
546
+ return;
547
+ }
548
+ this._appCssLoaded = true;
549
+ this.loadAppCss();
550
+ }
218
551
  notifyLaunch(additionalLanchEventData) {
552
+ this._launchBridgeConsumed = true;
219
553
  const launchArgs = {
220
554
  eventName: this.launchEvent,
221
555
  object: this,
@@ -224,7 +558,7 @@ export class ApplicationCommon {
224
558
  ...additionalLanchEventData,
225
559
  };
226
560
  this.notify(launchArgs);
227
- this.loadAppCss();
561
+ this._ensureAppCssLoaded();
228
562
  return launchArgs.root;
229
563
  }
230
564
  createRootView(view, fireLaunchEvent = false, additionalLanchEventData) {
@@ -254,10 +588,15 @@ export class ApplicationCommon {
254
588
  setAppMainEntry(typeof entry === 'string' ? { moduleName: entry } : entry);
255
589
  // rest of implementation is platform specific
256
590
  }
257
- initRootView(rootView) {
258
- this.setRootViewCSSClasses(rootView);
591
+ /**
592
+ * @param window the window the root view belongs to. Supplies the window-scoped CSS
593
+ * classes; without it they come from the primary window.
594
+ */
595
+ initRootView(rootView, window) {
596
+ this.setRootViewCSSClasses(rootView, window);
259
597
  readyInitAccessibilityCssHelper();
260
598
  readyInitFontScale();
599
+ applyAccessibilityCssToRoot(rootView);
261
600
  this.notify({ eventName: this.initRootViewEvent, rootView });
262
601
  }
263
602
  /**
@@ -348,18 +687,20 @@ export class ApplicationCommon {
348
687
  object: this,
349
688
  });
350
689
  }
690
+ /**
691
+ * @deprecated Use Application.primaryWindow?.orientation() - or the NativeWindow of the relevant view - instead. Continues to reflect the primary window.
692
+ */
351
693
  orientation() {
352
- return (this._orientation ?? (this._orientation = this.getOrientation()));
694
+ return this.primaryWindow?.orientation() ?? (this._orientation ?? (this._orientation = this.getOrientation()));
353
695
  }
354
696
  orientationChanged(rootView, newOrientation) {
355
697
  if (!rootView) {
356
698
  return;
357
699
  }
358
700
  const newOrientationCssClass = `${CSSUtils.CLASS_PREFIX}${newOrientation}`;
359
- this.applyCssClass(rootView, ORIENTATION_CSS_CLASSES, newOrientationCssClass, true);
360
- const rootModalViews = rootView._getRootModalViews();
361
- rootModalViews.forEach((rootModalView) => {
362
- this.applyCssClass(rootModalView, ORIENTATION_CSS_CLASSES, newOrientationCssClass, true);
701
+ this.applyWindowScopedCssClass(rootView, ORIENTATION_CSS_CLASSES, newOrientationCssClass);
702
+ this.getOwnedModalViews(rootView).forEach((rootModalView) => {
703
+ this.applyWindowScopedCssClass(rootModalView, ORIENTATION_CSS_CLASSES, newOrientationCssClass);
363
704
  // Trigger state change for root modal view classes and media queries
364
705
  rootModalView._onCssStateChange();
365
706
  });
@@ -391,15 +732,17 @@ export class ApplicationCommon {
391
732
  object: this,
392
733
  });
393
734
  }
735
+ /**
736
+ * @deprecated Use Application.primaryWindow?.systemAppearance() - or the NativeWindow of the relevant view - instead. Continues to reflect the primary window.
737
+ */
394
738
  systemAppearance() {
395
- // return cached value, or get it from the platform specific override
396
- return (this._systemAppearance ?? (this._systemAppearance = this.getSystemAppearance()));
739
+ return this.primaryWindow?.systemAppearance() ?? (this._systemAppearance ?? (this._systemAppearance = this.getSystemAppearance()));
397
740
  }
398
741
  /**
399
742
  * enable/disable systemAppearanceChanged
400
743
  */
401
744
  setAutoSystemAppearanceChanged(value) {
402
- this.autoSystemAppearanceChanged = value;
745
+ setAutoSystemAppearanceChanged(value);
403
746
  }
404
747
  /**
405
748
  * Updates root view classes including those of modals
@@ -411,10 +754,9 @@ export class ApplicationCommon {
411
754
  return;
412
755
  }
413
756
  const newSystemAppearanceCssClass = `${CSSUtils.CLASS_PREFIX}${newSystemAppearance}`;
414
- this.applyCssClass(rootView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass, true);
415
- const rootModalViews = rootView._getRootModalViews();
416
- rootModalViews.forEach((rootModalView) => {
417
- this.applyCssClass(rootModalView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass, true);
757
+ this.applyWindowScopedCssClass(rootView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass);
758
+ this.getOwnedModalViews(rootView).forEach((rootModalView) => {
759
+ this.applyWindowScopedCssClass(rootModalView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass);
418
760
  // Trigger state change for root modal view classes and media queries
419
761
  rootModalView._onCssStateChange();
420
762
  });
@@ -439,9 +781,11 @@ export class ApplicationCommon {
439
781
  object: this,
440
782
  });
441
783
  }
784
+ /**
785
+ * @deprecated Use Application.primaryWindow?.layoutDirection() - or the NativeWindow of the relevant view - instead. Continues to reflect the primary window.
786
+ */
442
787
  layoutDirection() {
443
- // return cached value, or get it from the platform specific override
444
- return (this._layoutDirection ?? (this._layoutDirection = this.getLayoutDirection()));
788
+ return this.primaryWindow?.layoutDirection() ?? (this._layoutDirection ?? (this._layoutDirection = this.getLayoutDirection()));
445
789
  }
446
790
  /**
447
791
  * Updates root view classes including those of modals
@@ -453,10 +797,9 @@ export class ApplicationCommon {
453
797
  return;
454
798
  }
455
799
  const newLayoutDirectionCssClass = `${CSSUtils.CLASS_PREFIX}${newLayoutDirection}`;
456
- this.applyCssClass(rootView, LAYOUT_DIRECTION_CSS_CLASSES, newLayoutDirectionCssClass, true);
457
- const rootModalViews = rootView._getRootModalViews();
458
- rootModalViews.forEach((rootModalView) => {
459
- this.applyCssClass(rootModalView, LAYOUT_DIRECTION_CSS_CLASSES, newLayoutDirectionCssClass, true);
800
+ this.applyWindowScopedCssClass(rootView, LAYOUT_DIRECTION_CSS_CLASSES, newLayoutDirectionCssClass);
801
+ this.getOwnedModalViews(rootView).forEach((rootModalView) => {
802
+ this.applyWindowScopedCssClass(rootModalView, LAYOUT_DIRECTION_CSS_CLASSES, newLayoutDirectionCssClass);
460
803
  // Trigger state change for root modal view classes and media queries
461
804
  rootModalView._onCssStateChange();
462
805
  });