@nativescript/angular 21.0.1-alpha.5 → 21.0.1-alpha.7

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.
@@ -6399,6 +6399,120 @@ function buildNonAnimatedRestoreConfig(original) {
6399
6399
  return cloned;
6400
6400
  }
6401
6401
 
6402
+ /**
6403
+ * Pure helpers that mirror NativeScript's modal-host properties
6404
+ * (`_dialogFragment` on Android, `viewController` on iOS) from the
6405
+ * ContentView wrapper that `attachComponentPortal` presents as the
6406
+ * modal down onto every native-like descendant.
6407
+ *
6408
+ * Why? `parentView.showModal(targetView, ...)` stamps those props on
6409
+ * `targetView` itself — but user template code reads them off the
6410
+ * rendered template root that lives *inside* the wrapper (e.g.
6411
+ * `onLoaded($event)` → `args.object._dialogFragment.getDialog()`).
6412
+ * Without mirroring, every fresh modal open + every HMR
6413
+ * `ɵɵreplaceMetadata` re-render hands the user `undefined`, which is
6414
+ * how we hit:
6415
+ *
6416
+ * Cannot read properties of undefined (reading 'getDialog')
6417
+ * at CheckinComponent.onLoaded
6418
+ *
6419
+ * The helpers live in a standalone module on purpose, mirroring
6420
+ * `dialog-hmr-animation.ts`: they don't pull `@angular/core` or
6421
+ * `@nativescript/core`, so they're trivially unit-testable in the
6422
+ * Jest Node runner without an ESM transform or a NativeScript
6423
+ * runtime stub.
6424
+ */
6425
+ /**
6426
+ * Marker property used to make {@link installPvcModalHostPropPropagation}
6427
+ * idempotent. Exported only so the spec can assert install
6428
+ * idempotency without re-declaring the constant.
6429
+ */
6430
+ const PVC_ADD_VIEW_WRAPPED_MARKER = '__ng_modal_propagate_addview__';
6431
+ /**
6432
+ * Mirror `wrapper`'s modal-host props onto every descendant of
6433
+ * `root` via NativeScript's logical `eachChildView` walk.
6434
+ *
6435
+ * - The wrapper itself is **never** written to. NS core owns that
6436
+ * assignment and we must not shadow the canonical reference.
6437
+ * - Writes are idempotent: a descendant that already holds the same
6438
+ * reference is skipped, so repeat calls (HMR re-renders, multiple
6439
+ * PVC adds in one render pass) stay cheap.
6440
+ * - No-op when the modal isn't shown yet, has already closed, or
6441
+ * when either input is missing. NS clears both props to null on
6442
+ * close, so propagating after that point would only persist stale
6443
+ * references on the descendants.
6444
+ */
6445
+ function propagateModalHostPropsToDescendants(wrapper, root) {
6446
+ if (!wrapper || !root) {
6447
+ return;
6448
+ }
6449
+ const dialogFragment = wrapper._dialogFragment;
6450
+ const viewController = wrapper.viewController;
6451
+ if (dialogFragment == null && viewController == null) {
6452
+ return;
6453
+ }
6454
+ const visit = (view) => {
6455
+ if (!view) {
6456
+ return;
6457
+ }
6458
+ if (view !== wrapper) {
6459
+ if (dialogFragment !== undefined && view._dialogFragment !== dialogFragment) {
6460
+ view._dialogFragment = dialogFragment;
6461
+ }
6462
+ if (viewController !== undefined && view.viewController !== viewController) {
6463
+ view.viewController = viewController;
6464
+ }
6465
+ }
6466
+ view.eachChildView?.((child) => {
6467
+ visit(child);
6468
+ return true;
6469
+ });
6470
+ };
6471
+ visit(root);
6472
+ }
6473
+ /**
6474
+ * Idempotently wrap `host._addView` so every child added after
6475
+ * install — typically the new template root produced by Angular's
6476
+ * `ɵɵreplaceMetadata` HMR cycle — has `wrapper`'s modal-host props
6477
+ * mirrored onto it (and its current subtree) **before** NS attaches
6478
+ * the view.
6479
+ *
6480
+ * Why "before"? `_addView` on a loaded parent synchronously calls
6481
+ * `child.callLoaded()` deep inside, which fires the `loaded` event
6482
+ * chain on the new template root. User code (e.g.
6483
+ * `onLoaded($event)` → `args.object._dialogFragment.getDialog()`)
6484
+ * runs from inside that synchronous call. The props **must** be
6485
+ * present on the child by the time `_addView` runs — pre-hook
6486
+ * position is the only place that guarantees this without
6487
+ * monkey-patching NS internals.
6488
+ *
6489
+ * The wrap reads `wrapper._dialogFragment` / `wrapper.viewController`
6490
+ * lazily (per call) via {@link propagateModalHostPropsToDescendants},
6491
+ * so a wrap installed while the modal is open keeps doing the right
6492
+ * thing if HMR re-render happens later, and gracefully no-ops after
6493
+ * the modal closes (both props become null on the wrapper).
6494
+ *
6495
+ * No-op when `host` lacks `_addView` (e.g. a non-View element) or
6496
+ * when the wrap is already installed (`PVC_ADD_VIEW_WRAPPED_MARKER`
6497
+ * sentinel). The wrap is intentionally NOT removable — the host
6498
+ * lives only as long as the modal, so the wrap is GC'd with it.
6499
+ */
6500
+ function installPvcModalHostPropPropagation(host, wrapper) {
6501
+ if (!host || !wrapper) {
6502
+ return;
6503
+ }
6504
+ const target = host;
6505
+ if (target[PVC_ADD_VIEW_WRAPPED_MARKER] || typeof target._addView !== 'function') {
6506
+ return;
6507
+ }
6508
+ const origAddView = target._addView.bind(target);
6509
+ target._addView = (view, atIndex) => {
6510
+ propagateModalHostPropsToDescendants(wrapper, view);
6511
+ return origAddView(view, atIndex);
6512
+ };
6513
+ target[PVC_ADD_VIEW_WRAPPED_MARKER] = true;
6514
+ }
6515
+
6402
6516
  let NativeModalRef = class NativeModalRef {
6403
6517
  constructor(_config, _injector, location) {
6404
6518
  this._config = _config;
@@ -6528,6 +6642,25 @@ let NativeModalRef = class NativeModalRef {
6528
6642
  },
6529
6643
  cancelable: !this._config.disableClose,
6530
6644
  });
6645
+ // After `showModal`, NativeScript core has stamped
6646
+ // `_dialogFragment` (Android) / `viewController` (iOS) on
6647
+ // `targetView` itself — but user template code (`onLoaded($event)`
6648
+ // → `args.object._dialogFragment.getDialog()...`) reads those
6649
+ // props on the rendered template root, which is a *descendant*
6650
+ // of `targetView`, not `targetView` itself. Mirror them down so
6651
+ // the template root (and any nested loaded handler) sees the
6652
+ // real host objects instead of `undefined`, then install a
6653
+ // lazy wrap on the host PVC's `_addView` so future child
6654
+ // additions — typically the new template root produced by
6655
+ // Angular's `ɵɵreplaceMetadata` HMR cycle — get the same
6656
+ // props mirrored *before* NS attaches the view and fires
6657
+ // its `loaded` event chain. See `modal-host-props.ts` for the
6658
+ // full rationale.
6659
+ propagateModalHostPropsToDescendants(targetView, targetView);
6660
+ const hostView = componentRef.location?.nativeElement;
6661
+ if (hostView) {
6662
+ installPvcModalHostPropPropagation(hostView, targetView);
6663
+ }
6531
6664
  return componentRef;
6532
6665
  }
6533
6666
  _startExitAnimation() {
@@ -7447,13 +7580,20 @@ const DEFAULT_INVALIDATE_EVENT = 'ns:cache-invalidate';
7447
7580
  * type is the only one in play; `vite/client`-aware apps still get
7448
7581
  * their own typing on `import.meta.hot` at every call site outside
7449
7582
  * this module.
7583
+ *
7584
+ * Webpack-CommonJS compatibility: every `import.meta` reference here
7585
+ * is a member expression (`import.meta['hot']`). Webpack statically
7586
+ * rewrites both dot- and bracket-style member access to `undefined`
7587
+ * in CommonJS output, so the emitted bundle never carries a literal
7588
+ * bare `import.meta` token. A bare `import.meta` would survive into
7589
+ * the bundle and crash V8 with "Cannot use 'import.meta' outside a
7590
+ * module" the moment the chunk is `require()`d. Vite leaves
7591
+ * `import.meta['hot']` intact and resolves it to the per-module hot
7592
+ * context, so the same code works in both pipelines.
7450
7593
  */
7451
7594
  function readImportMetaHot() {
7452
7595
  try {
7453
- const meta = typeof import.meta !== 'undefined'
7454
- ? import.meta
7455
- : undefined;
7456
- return meta?.hot;
7596
+ return import.meta['hot'];
7457
7597
  }
7458
7598
  catch {
7459
7599
  return undefined;
@@ -7879,10 +8019,12 @@ function getOrCreateSharedStore() {
7879
8019
  }
7880
8020
  function hasImportMetaHot() {
7881
8021
  try {
7882
- const meta = typeof import.meta !== 'undefined'
7883
- ? import.meta
7884
- : undefined;
7885
- return !!meta?.hot;
8022
+ // Member-expression access only — webpack rewrites `import.meta['hot']`
8023
+ // to `undefined` in CommonJS bundles (so `!!undefined` → `false`),
8024
+ // while Vite leaves it as the per-module hot context. A bare
8025
+ // `typeof import.meta` would survive into the bundle and crash V8
8026
+ // with "Cannot use 'import.meta' outside a module" on `require()`.
8027
+ return !!import.meta['hot'];
7886
8028
  }
7887
8029
  catch {
7888
8030
  return false;