@angular/core 16.0.0-next.0 → 16.0.0-next.2

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 (80) hide show
  1. package/esm2020/src/application_config.mjs +21 -0
  2. package/esm2020/src/application_init.mjs +23 -31
  3. package/esm2020/src/application_module.mjs +3 -2
  4. package/esm2020/src/application_ref.mjs +35 -33
  5. package/esm2020/src/application_tokens.mjs +2 -13
  6. package/esm2020/src/change_detection/change_detection.mjs +2 -2
  7. package/esm2020/src/change_detection/change_detector_ref.mjs +3 -2
  8. package/esm2020/src/change_detection/constants.mjs +1 -49
  9. package/esm2020/src/change_detection/differs/iterable_differs.mjs +3 -2
  10. package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +3 -2
  11. package/esm2020/src/console.mjs +3 -2
  12. package/esm2020/src/core.mjs +4 -3
  13. package/esm2020/src/core_private_export.mjs +6 -7
  14. package/esm2020/src/core_render3_private_export.mjs +3 -1
  15. package/esm2020/src/debug/debug_node.mjs +1 -5
  16. package/esm2020/src/di/injector.mjs +3 -2
  17. package/esm2020/src/di/r3_injector.mjs +5 -1
  18. package/esm2020/src/di/reflective_injector.mjs +3 -2
  19. package/esm2020/src/hydration/annotate.mjs +140 -0
  20. package/esm2020/src/hydration/api.mjs +120 -0
  21. package/esm2020/src/hydration/error_handling.mjs +29 -0
  22. package/esm2020/src/hydration/interfaces.mjs +10 -0
  23. package/esm2020/src/hydration/node_lookup_utils.mjs +75 -0
  24. package/esm2020/src/hydration/skip_hydration.mjs +34 -0
  25. package/esm2020/src/hydration/tokens.mjs +25 -0
  26. package/esm2020/src/hydration/utils.mjs +131 -0
  27. package/esm2020/src/linker/compiler.mjs +3 -2
  28. package/esm2020/src/linker/component_factory_resolver.mjs +3 -2
  29. package/esm2020/src/linker/destroy_ref.mjs +41 -0
  30. package/esm2020/src/linker/element_ref.mjs +3 -2
  31. package/esm2020/src/linker/query_list.mjs +6 -7
  32. package/esm2020/src/linker/template_ref.mjs +6 -5
  33. package/esm2020/src/linker/view_container_ref.mjs +3 -2
  34. package/esm2020/src/linker.mjs +2 -1
  35. package/esm2020/src/render/api.mjs +3 -2
  36. package/esm2020/src/render3/component_ref.mjs +16 -9
  37. package/esm2020/src/render3/features/standalone_feature.mjs +1 -1
  38. package/esm2020/src/render3/fields.mjs +10 -1
  39. package/esm2020/src/render3/hooks.mjs +3 -2
  40. package/esm2020/src/render3/i18n/i18n_util.mjs +3 -3
  41. package/esm2020/src/render3/instructions/element.mjs +56 -13
  42. package/esm2020/src/render3/instructions/element_container.mjs +54 -9
  43. package/esm2020/src/render3/instructions/listener.mjs +3 -3
  44. package/esm2020/src/render3/instructions/shared.mjs +40 -24
  45. package/esm2020/src/render3/instructions/template.mjs +2 -2
  46. package/esm2020/src/render3/instructions/text.mjs +36 -5
  47. package/esm2020/src/render3/interfaces/definition.mjs +1 -1
  48. package/esm2020/src/render3/interfaces/node.mjs +1 -1
  49. package/esm2020/src/render3/interfaces/renderer_dom.mjs +1 -1
  50. package/esm2020/src/render3/interfaces/view.mjs +4 -2
  51. package/esm2020/src/render3/jit/directive.mjs +1 -2
  52. package/esm2020/src/render3/node_manipulation.mjs +25 -14
  53. package/esm2020/src/render3/state.mjs +45 -1
  54. package/esm2020/src/render3/util/view_utils.mjs +11 -2
  55. package/esm2020/src/render3/view_ref.mjs +4 -3
  56. package/esm2020/src/sanitization/sanitizer.mjs +3 -2
  57. package/esm2020/src/testability/testability.mjs +5 -3
  58. package/esm2020/src/transfer_state.mjs +153 -0
  59. package/esm2020/src/util/iterable.mjs +6 -7
  60. package/esm2020/src/util/lang.mjs +1 -11
  61. package/esm2020/src/util/ng_dev_mode.mjs +3 -1
  62. package/esm2020/src/version.mjs +1 -1
  63. package/esm2020/testing/src/logger.mjs +6 -5
  64. package/esm2020/testing/src/ng_zone_mock.mjs +6 -5
  65. package/esm2020/testing/src/test_bed.mjs +3 -2
  66. package/fesm2015/core.mjs +1076 -297
  67. package/fesm2015/core.mjs.map +1 -1
  68. package/fesm2015/testing.mjs +747 -159
  69. package/fesm2015/testing.mjs.map +1 -1
  70. package/fesm2020/core.mjs +1066 -295
  71. package/fesm2020/core.mjs.map +1 -1
  72. package/fesm2020/testing.mjs +741 -159
  73. package/fesm2020/testing.mjs.map +1 -1
  74. package/index.d.ts +290 -87
  75. package/package.json +3 -3
  76. package/schematics/migrations/router-link-with-href/bundle.js.map +2 -2
  77. package/schematics/ng-generate/standalone-migration/bundle.js +1044 -1024
  78. package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
  79. package/testing/index.d.ts +1 -1
  80. package/esm2020/src/util/symbol.mjs +0 -30
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v16.0.0-next.0
2
+ * @license Angular v16.0.0-next.2
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1636,6 +1636,8 @@ function ngDevModeResetPerfCounters() {
1636
1636
  rendererAppendChild: 0,
1637
1637
  rendererInsertBefore: 0,
1638
1638
  rendererCreateComment: 0,
1639
+ hydratedNodes: 0,
1640
+ hydratedComponents: 0,
1639
1641
  };
1640
1642
  // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
1641
1643
  const allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
@@ -2115,54 +2117,6 @@ var ChangeDetectionStrategy;
2115
2117
  */
2116
2118
  ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
2117
2119
  })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
2118
- /**
2119
- * Defines the possible states of the default change detector.
2120
- * @see `ChangeDetectorRef`
2121
- */
2122
- var ChangeDetectorStatus;
2123
- (function (ChangeDetectorStatus) {
2124
- /**
2125
- * A state in which, after calling `detectChanges()`, the change detector
2126
- * state becomes `Checked`, and must be explicitly invoked or reactivated.
2127
- */
2128
- ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
2129
- /**
2130
- * A state in which change detection is skipped until the change detector mode
2131
- * becomes `CheckOnce`.
2132
- */
2133
- ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
2134
- /**
2135
- * A state in which change detection continues automatically until explicitly
2136
- * deactivated.
2137
- */
2138
- ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
2139
- /**
2140
- * A state in which a change detector sub tree is not a part of the main tree and
2141
- * should be skipped.
2142
- */
2143
- ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
2144
- /**
2145
- * Indicates that the change detector encountered an error checking a binding
2146
- * or calling a directive lifecycle method and is now in an inconsistent state. Change
2147
- * detectors in this state do not detect changes.
2148
- */
2149
- ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
2150
- /**
2151
- * Indicates that the change detector has been destroyed.
2152
- */
2153
- ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
2154
- })(ChangeDetectorStatus || (ChangeDetectorStatus = {}));
2155
- /**
2156
- * Reports whether a given strategy is currently the default for change detection.
2157
- * @param changeDetectionStrategy The strategy to check.
2158
- * @returns True if the given strategy is the current default, false otherwise.
2159
- * @see `ChangeDetectorStatus`
2160
- * @see `ChangeDetectorRef`
2161
- */
2162
- function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
2163
- return changeDetectionStrategy == null ||
2164
- changeDetectionStrategy === ChangeDetectionStrategy.Default;
2165
- }
2166
2120
 
2167
2121
  /**
2168
2122
  * Defines the CSS styles encapsulation policies for the {@link Component} decorator's
@@ -2234,6 +2188,15 @@ const NG_FACTORY_DEF = getClosureSafeProperty({ ɵfac: getClosureSafeProperty })
2234
2188
  */
2235
2189
  // TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
2236
2190
  const NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafeProperty });
2191
+ /**
2192
+ * The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
2193
+ * getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
2194
+ * strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
2195
+ *
2196
+ * This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
2197
+ * improve tree-shaking.
2198
+ */
2199
+ const NG_ENV_ID = getClosureSafeProperty({ __NG_ENV_ID__: getClosureSafeProperty });
2237
2200
 
2238
2201
  /** Counter used to generate unique IDs for component definitions. */
2239
2202
  let componentDefCount = 0;
@@ -2588,6 +2551,8 @@ const PREORDER_HOOK_FLAGS = 18;
2588
2551
  const QUERIES = 19;
2589
2552
  const ID = 20;
2590
2553
  const EMBEDDED_VIEW_INJECTOR = 21;
2554
+ const ON_DESTROY_HOOKS = 22;
2555
+ const HYDRATION = 23;
2591
2556
  /**
2592
2557
  * Size of LView's header. Necessary to adjust for it when setting slots.
2593
2558
  *
@@ -2595,7 +2560,7 @@ const EMBEDDED_VIEW_INJECTOR = 21;
2595
2560
  * instruction index into `LView` index. All other indexes should be in the `LView` index space and
2596
2561
  * there should be no need to refer to `HEADER_OFFSET` anywhere else.
2597
2562
  */
2598
- const HEADER_OFFSET = 22;
2563
+ const HEADER_OFFSET = 24;
2599
2564
  // Note: This hack is necessary so we don't erroneously get a circular dependency
2600
2565
  // failure based on types.
2601
2566
  const unusedValueExportToPlacateAjd$3 = 1;
@@ -3033,10 +2998,20 @@ function updateTransplantedViewCount(lContainer, amount) {
3033
2998
  parent = parent[PARENT];
3034
2999
  }
3035
3000
  }
3001
+ /**
3002
+ * Stores a LView-specific destroy callback.
3003
+ */
3004
+ function storeLViewOnDestroy(lView, onDestroyCallback) {
3005
+ if (lView[ON_DESTROY_HOOKS] === null) {
3006
+ lView[ON_DESTROY_HOOKS] = [];
3007
+ }
3008
+ lView[ON_DESTROY_HOOKS].push(onDestroyCallback);
3009
+ }
3036
3010
 
3037
3011
  const instructionState = {
3038
3012
  lFrame: createLFrame(null),
3039
3013
  bindingsEnabled: true,
3014
+ skipHydrationRootTNode: null,
3040
3015
  };
3041
3016
  /**
3042
3017
  * In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
@@ -3067,6 +3042,21 @@ function decreaseElementDepthCount() {
3067
3042
  function getBindingsEnabled() {
3068
3043
  return instructionState.bindingsEnabled;
3069
3044
  }
3045
+ /**
3046
+ * Returns true if currently inside a skip hydration block.
3047
+ * @returns boolean
3048
+ */
3049
+ function isInSkipHydrationBlock() {
3050
+ return instructionState.skipHydrationRootTNode !== null;
3051
+ }
3052
+ /**
3053
+ * Returns true if this is the root TNode of the skip hydration block.
3054
+ * @param tNode the current TNode
3055
+ * @returns boolean
3056
+ */
3057
+ function isSkipHydrationRootTNode(tNode) {
3058
+ return instructionState.skipHydrationRootTNode === tNode;
3059
+ }
3070
3060
  /**
3071
3061
  * Enables directive matching on elements.
3072
3062
  *
@@ -3089,6 +3079,13 @@ function getBindingsEnabled() {
3089
3079
  function ɵɵenableBindings() {
3090
3080
  instructionState.bindingsEnabled = true;
3091
3081
  }
3082
+ /**
3083
+ * Sets a flag to specify that the TNode is in a skip hydration block.
3084
+ * @param tNode the current TNode
3085
+ */
3086
+ function enterSkipHydrationBlock(tNode) {
3087
+ instructionState.skipHydrationRootTNode = tNode;
3088
+ }
3092
3089
  /**
3093
3090
  * Disables directive matching on element.
3094
3091
  *
@@ -3111,6 +3108,12 @@ function ɵɵenableBindings() {
3111
3108
  function ɵɵdisableBindings() {
3112
3109
  instructionState.bindingsEnabled = false;
3113
3110
  }
3111
+ /**
3112
+ * Clears the root skip hydration node when leaving a skip hydration block.
3113
+ */
3114
+ function leaveSkipHydrationBlock() {
3115
+ instructionState.skipHydrationRootTNode = null;
3116
+ }
3114
3117
  /**
3115
3118
  * Return the current `LView`.
3116
3119
  */
@@ -3535,6 +3538,21 @@ function namespaceHTMLInternal() {
3535
3538
  function getNamespace$1() {
3536
3539
  return instructionState.lFrame.currentNamespace;
3537
3540
  }
3541
+ let _wasLastNodeCreated = true;
3542
+ /**
3543
+ * Retrieves a global flag that indicates whether the most recent DOM node
3544
+ * was created or hydrated.
3545
+ */
3546
+ function wasLastNodeCreated() {
3547
+ return _wasLastNodeCreated;
3548
+ }
3549
+ /**
3550
+ * Sets a global flag to indicate whether the most recent DOM node
3551
+ * was created or hydrated.
3552
+ */
3553
+ function lastNodeWasCreated(flag) {
3554
+ _wasLastNodeCreated = flag;
3555
+ }
3538
3556
 
3539
3557
  /**
3540
3558
  * Adds all directive lifecycle hooks from the given `DirectiveDef` to the given `TView`.
@@ -3710,8 +3728,9 @@ function callHooks(currentView, arr, initPhase, currentNodeIndex) {
3710
3728
  }
3711
3729
  else {
3712
3730
  const isInitHook = arr[i] < 0;
3713
- if (isInitHook)
3731
+ if (isInitHook) {
3714
3732
  currentView[PREORDER_HOOK_FLAGS] += 65536 /* PreOrderHookFlags.NumberOfInitHooksCalledIncrementer */;
3733
+ }
3715
3734
  if (lastNodeIndexFound < nodeIndexLimit || nodeIndexLimit == -1) {
3716
3735
  callHook(currentView, initPhase, arr, i);
3717
3736
  currentView[PREORDER_HOOK_FLAGS] =
@@ -6243,10 +6262,6 @@ function cleanUpView(tView, lView) {
6243
6262
  function processCleanups(tView, lView) {
6244
6263
  const tCleanup = tView.cleanup;
6245
6264
  const lCleanup = lView[CLEANUP];
6246
- // `LCleanup` contains both share information with `TCleanup` as well as instance specific
6247
- // information appended at the end. We need to know where the end of the `TCleanup` information
6248
- // is, and we track this with `lastLCleanupIndex`.
6249
- let lastLCleanupIndex = -1;
6250
6265
  if (tCleanup !== null) {
6251
6266
  for (let i = 0; i < tCleanup.length - 1; i += 2) {
6252
6267
  if (typeof tCleanup[i] === 'string') {
@@ -6256,29 +6271,33 @@ function processCleanups(tView, lView) {
6256
6271
  ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number');
6257
6272
  if (targetIdx >= 0) {
6258
6273
  // unregister
6259
- lCleanup[lastLCleanupIndex = targetIdx]();
6274
+ lCleanup[targetIdx]();
6260
6275
  }
6261
6276
  else {
6262
6277
  // Subscription
6263
- lCleanup[lastLCleanupIndex = -targetIdx].unsubscribe();
6278
+ lCleanup[-targetIdx].unsubscribe();
6264
6279
  }
6265
6280
  i += 2;
6266
6281
  }
6267
6282
  else {
6268
6283
  // This is a cleanup function that is grouped with the index of its context
6269
- const context = lCleanup[lastLCleanupIndex = tCleanup[i + 1]];
6284
+ const context = lCleanup[tCleanup[i + 1]];
6270
6285
  tCleanup[i].call(context);
6271
6286
  }
6272
6287
  }
6273
6288
  }
6274
6289
  if (lCleanup !== null) {
6275
- for (let i = lastLCleanupIndex + 1; i < lCleanup.length; i++) {
6276
- const instanceCleanupFn = lCleanup[i];
6277
- ngDevMode && assertFunction(instanceCleanupFn, 'Expecting instance cleanup function.');
6278
- instanceCleanupFn();
6279
- }
6280
6290
  lView[CLEANUP] = null;
6281
6291
  }
6292
+ const destroyHooks = lView[ON_DESTROY_HOOKS];
6293
+ if (destroyHooks !== null) {
6294
+ for (let i = 0; i < destroyHooks.length; i++) {
6295
+ const destroyHooksFn = destroyHooks[i];
6296
+ ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
6297
+ destroyHooksFn();
6298
+ }
6299
+ lView[ON_DESTROY_HOOKS] = null;
6300
+ }
6282
6301
  }
6283
6302
  /** Calls onDestroy hooks for this view */
6284
6303
  function executeOnDestroys(tView, lView) {
@@ -6589,6 +6608,17 @@ function nativeRemoveNode(renderer, rNode, isHostElement) {
6589
6608
  nativeRemoveChild(renderer, nativeParent, rNode, isHostElement);
6590
6609
  }
6591
6610
  }
6611
+ /**
6612
+ * Removes the contents of a given RElement using a given renderer.
6613
+ *
6614
+ * @param renderer A renderer to be used
6615
+ * @param rElement the native RElement to be cleared
6616
+ */
6617
+ function clearElementContents(renderer, rElement) {
6618
+ while (rElement.firstChild) {
6619
+ nativeRemoveChild(renderer, rElement, rElement.firstChild, false);
6620
+ }
6621
+ }
6592
6622
  /**
6593
6623
  * Performs the operation of `action` on the node. Typically this involves inserting or removing
6594
6624
  * nodes on the LView or projection boundary.
@@ -8294,6 +8324,9 @@ class R3Injector extends EnvironmentInjector {
8294
8324
  }
8295
8325
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
8296
8326
  this.assertNotDestroyed();
8327
+ if (token.hasOwnProperty(NG_ENV_ID)) {
8328
+ return token[NG_ENV_ID](this);
8329
+ }
8297
8330
  flags = convertToBitFlags(flags);
8298
8331
  // Set the injection context.
8299
8332
  const previousInjector = setCurrentInjector(this);
@@ -8571,6 +8604,331 @@ function forEachSingleProvider(providers, fn) {
8571
8604
  }
8572
8605
  }
8573
8606
 
8607
+ /**
8608
+ * A [DI token](guide/glossary#di-token "DI token definition") representing a unique string ID, used
8609
+ * primarily for prefixing application attributes and CSS styles when
8610
+ * {@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
8611
+ *
8612
+ * BY default, the value is randomly generated and assigned to the application by Angular.
8613
+ * To provide a custom ID value, use a DI provider <!-- TODO: provider --> to configure
8614
+ * the root {@link Injector} that uses this token.
8615
+ *
8616
+ * @publicApi
8617
+ */
8618
+ const APP_ID = new InjectionToken('AppId', {
8619
+ providedIn: 'root',
8620
+ factory: _appIdRandomProviderFactory,
8621
+ });
8622
+ function _appIdRandomProviderFactory() {
8623
+ return `${_randomChar()}${_randomChar()}${_randomChar()}`;
8624
+ }
8625
+ /**
8626
+ * Providers that generate a random `APP_ID_TOKEN`.
8627
+ * @publicApi
8628
+ */
8629
+ const APP_ID_RANDOM_PROVIDER = {
8630
+ provide: APP_ID,
8631
+ useFactory: _appIdRandomProviderFactory,
8632
+ deps: [],
8633
+ };
8634
+ function _randomChar() {
8635
+ return String.fromCharCode(97 + Math.floor(Math.random() * 25));
8636
+ }
8637
+ /**
8638
+ * A function that is executed when a platform is initialized.
8639
+ * @publicApi
8640
+ */
8641
+ const PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
8642
+ /**
8643
+ * A token that indicates an opaque platform ID.
8644
+ * @publicApi
8645
+ */
8646
+ const PLATFORM_ID = new InjectionToken('Platform ID', {
8647
+ providedIn: 'platform',
8648
+ factory: () => 'unknown', // set a default platform name, when none set explicitly
8649
+ });
8650
+ /**
8651
+ * A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
8652
+ * the application
8653
+ * @publicApi
8654
+ */
8655
+ const PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
8656
+ // We keep this token here, rather than the animations package, so that modules that only care
8657
+ // about which animations module is loaded (e.g. the CDK) can retrieve it without having to
8658
+ // include extra dependencies. See #44970 for more context.
8659
+ /**
8660
+ * A [DI token](guide/glossary#di-token "DI token definition") that indicates which animations
8661
+ * module has been loaded.
8662
+ * @publicApi
8663
+ */
8664
+ const ANIMATION_MODULE_TYPE = new InjectionToken('AnimationModuleType');
8665
+
8666
+ function escapeTransferStateContent(text) {
8667
+ const escapedText = {
8668
+ '&': '&a;',
8669
+ '"': '&q;',
8670
+ '\'': '&s;',
8671
+ '<': '&l;',
8672
+ '>': '&g;',
8673
+ };
8674
+ return text.replace(/[&"'<>]/g, s => escapedText[s]);
8675
+ }
8676
+ function unescapeTransferStateContent(text) {
8677
+ const unescapedText = {
8678
+ '&a;': '&',
8679
+ '&q;': '"',
8680
+ '&s;': '\'',
8681
+ '&l;': '<',
8682
+ '&g;': '>',
8683
+ };
8684
+ return text.replace(/&[^;]+;/g, s => unescapedText[s]);
8685
+ }
8686
+ /**
8687
+ * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
8688
+ *
8689
+ * Example:
8690
+ *
8691
+ * ```
8692
+ * const COUNTER_KEY = makeStateKey<number>('counter');
8693
+ * let value = 10;
8694
+ *
8695
+ * transferState.set(COUNTER_KEY, value);
8696
+ * ```
8697
+ *
8698
+ * @publicApi
8699
+ */
8700
+ function makeStateKey(key) {
8701
+ return key;
8702
+ }
8703
+ function initTransferState() {
8704
+ const transferState = new TransferState();
8705
+ transferState.store = retrieveTransferredState(getDocument(), inject$1(APP_ID));
8706
+ return transferState;
8707
+ }
8708
+ /**
8709
+ * A key value store that is transferred from the application on the server side to the application
8710
+ * on the client side.
8711
+ *
8712
+ * The `TransferState` is available as an injectable token.
8713
+ * On the client, just inject this token using DI and use it, it will be lazily initialized.
8714
+ * On the server it's already included if `renderApplication` function is used. Otherwise, import
8715
+ * the `ServerTransferStateModule` module to make the `TransferState` available.
8716
+ *
8717
+ * The values in the store are serialized/deserialized using JSON.stringify/JSON.parse. So only
8718
+ * boolean, number, string, null and non-class objects will be serialized and deserialized in a
8719
+ * non-lossy manner.
8720
+ *
8721
+ * @publicApi
8722
+ */
8723
+ class TransferState {
8724
+ constructor() {
8725
+ /** @internal */
8726
+ this.store = {};
8727
+ this.onSerializeCallbacks = {};
8728
+ }
8729
+ /**
8730
+ * Get the value corresponding to a key. Return `defaultValue` if key is not found.
8731
+ */
8732
+ get(key, defaultValue) {
8733
+ return this.store[key] !== undefined ? this.store[key] : defaultValue;
8734
+ }
8735
+ /**
8736
+ * Set the value corresponding to a key.
8737
+ */
8738
+ set(key, value) {
8739
+ this.store[key] = value;
8740
+ }
8741
+ /**
8742
+ * Remove a key from the store.
8743
+ */
8744
+ remove(key) {
8745
+ delete this.store[key];
8746
+ }
8747
+ /**
8748
+ * Test whether a key exists in the store.
8749
+ */
8750
+ hasKey(key) {
8751
+ return this.store.hasOwnProperty(key);
8752
+ }
8753
+ /**
8754
+ * Indicates whether the state is empty.
8755
+ */
8756
+ get isEmpty() {
8757
+ return Object.keys(this.store).length === 0;
8758
+ }
8759
+ /**
8760
+ * Register a callback to provide the value for a key when `toJson` is called.
8761
+ */
8762
+ onSerialize(key, callback) {
8763
+ this.onSerializeCallbacks[key] = callback;
8764
+ }
8765
+ /**
8766
+ * Serialize the current state of the store to JSON.
8767
+ */
8768
+ toJson() {
8769
+ // Call the onSerialize callbacks and put those values into the store.
8770
+ for (const key in this.onSerializeCallbacks) {
8771
+ if (this.onSerializeCallbacks.hasOwnProperty(key)) {
8772
+ try {
8773
+ this.store[key] = this.onSerializeCallbacks[key]();
8774
+ }
8775
+ catch (e) {
8776
+ console.warn('Exception in onSerialize callback: ', e);
8777
+ }
8778
+ }
8779
+ }
8780
+ return JSON.stringify(this.store);
8781
+ }
8782
+ }
8783
+ /** @nocollapse */
8784
+ TransferState.ɵprov =
8785
+ /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
8786
+ token: TransferState,
8787
+ providedIn: 'root',
8788
+ factory: initTransferState,
8789
+ });
8790
+ function retrieveTransferredState(doc, appId) {
8791
+ // Locate the script tag with the JSON data transferred from the server.
8792
+ // The id of the script tag is set to the Angular appId + 'state'.
8793
+ const script = doc.getElementById(appId + '-state');
8794
+ let initialState = {};
8795
+ if (script && script.textContent) {
8796
+ try {
8797
+ // Avoid using any here as it triggers lint errors in google3 (any is not allowed).
8798
+ initialState = JSON.parse(unescapeTransferStateContent(script.textContent));
8799
+ }
8800
+ catch (e) {
8801
+ console.warn('Exception while restoring TransferState for app ' + appId, e);
8802
+ }
8803
+ }
8804
+ return initialState;
8805
+ }
8806
+
8807
+ /* Represents a key in NghDom that holds information about <ng-container>s. */
8808
+ const ELEMENT_CONTAINERS = 'e';
8809
+
8810
+ /**
8811
+ * The name of the key used in the TransferState collection,
8812
+ * where hydration information is located.
8813
+ */
8814
+ const TRANSFER_STATE_TOKEN_ID = '__ɵnghData__';
8815
+ /**
8816
+ * Lookup key used to reference DOM hydration data (ngh) in `TransferState`.
8817
+ */
8818
+ const NGH_DATA_KEY = makeStateKey(TRANSFER_STATE_TOKEN_ID);
8819
+ /**
8820
+ * The name of the attribute that would be added to host component
8821
+ * nodes and contain a reference to a particular slot in transferred
8822
+ * state that contains the necessary hydration info for this component.
8823
+ */
8824
+ const NGH_ATTR_NAME = 'ngh';
8825
+ /**
8826
+ * Reference to a function that reads `ngh` attribute value from a given RNode
8827
+ * and retrieves hydration information from the TransferState using that value
8828
+ * as an index. Returns `null` by default, when hydration is not enabled.
8829
+ *
8830
+ * @param rNode Component's host element.
8831
+ * @param injector Injector that this component has access to.
8832
+ */
8833
+ let _retrieveHydrationInfoImpl = (rNode, injector) => null;
8834
+ function retrieveHydrationInfoImpl(rNode, injector) {
8835
+ var _a;
8836
+ const nghAttrValue = rNode.getAttribute(NGH_ATTR_NAME);
8837
+ if (nghAttrValue == null)
8838
+ return null;
8839
+ let data = {};
8840
+ // An element might have an empty `ngh` attribute value (e.g. `<comp ngh="" />`),
8841
+ // which means that no special annotations are required. Do not attempt to read
8842
+ // from the TransferState in this case.
8843
+ if (nghAttrValue !== '') {
8844
+ const transferState = injector.get(TransferState, null, { optional: true });
8845
+ if (transferState !== null) {
8846
+ const nghData = transferState.get(NGH_DATA_KEY, []);
8847
+ // The nghAttrValue is always a number referencing an index
8848
+ // in the hydration TransferState data.
8849
+ data = nghData[Number(nghAttrValue)];
8850
+ // If the `ngh` attribute exists and has a non-empty value,
8851
+ // the hydration info *must* be present in the TransferState.
8852
+ // If there is no data for some reasons, this is an error.
8853
+ ngDevMode && assertDefined(data, 'Unable to retrieve hydration info from the TransferState.');
8854
+ }
8855
+ }
8856
+ const dehydratedView = {
8857
+ data,
8858
+ firstChild: (_a = rNode.firstChild) !== null && _a !== void 0 ? _a : null,
8859
+ };
8860
+ // The `ngh` attribute is cleared from the DOM node now
8861
+ // that the data has been retrieved.
8862
+ rNode.removeAttribute(NGH_ATTR_NAME);
8863
+ // Note: don't check whether this node was claimed for hydration,
8864
+ // because this node might've been previously claimed while processing
8865
+ // template instructions.
8866
+ ngDevMode && markRNodeAsClaimedByHydration(rNode, /* checkIfAlreadyClaimed */ false);
8867
+ ngDevMode && ngDevMode.hydratedComponents++;
8868
+ return dehydratedView;
8869
+ }
8870
+ /**
8871
+ * Sets the implementation for the `retrieveNghInfo` function.
8872
+ */
8873
+ function enableRetrieveHydrationInfoImpl() {
8874
+ _retrieveHydrationInfoImpl = retrieveHydrationInfoImpl;
8875
+ }
8876
+ /**
8877
+ * Retrieves hydration info by reading the value from the `ngh` attribute
8878
+ * and accessing a corresponding slot in TransferState storage.
8879
+ */
8880
+ function retrieveHydrationInfo(rNode, injector) {
8881
+ return _retrieveHydrationInfoImpl(rNode, injector);
8882
+ }
8883
+ /**
8884
+ * Retrieves an instance of a component LView from a given ViewRef.
8885
+ * Returns an instance of a component LView or `null` in case of an embedded view.
8886
+ */
8887
+ function getComponentLViewForHydration(viewRef) {
8888
+ // Reading an internal field from `ViewRef` instance.
8889
+ let lView = viewRef._lView;
8890
+ const tView = lView[TVIEW];
8891
+ // A registered ViewRef might represent an instance of an
8892
+ // embedded view, in which case we do not need to annotate it.
8893
+ if (tView.type === 2 /* TViewType.Embedded */) {
8894
+ return null;
8895
+ }
8896
+ // Check if it's a root view and if so, retrieve component's
8897
+ // LView from the first slot after the header.
8898
+ if (isRootView(lView)) {
8899
+ lView = lView[HEADER_OFFSET];
8900
+ }
8901
+ return lView;
8902
+ }
8903
+ /**
8904
+ * Marks a node as "claimed" by hydration process.
8905
+ * This is needed to make assessments in tests whether
8906
+ * the hydration process handled all nodes.
8907
+ */
8908
+ function markRNodeAsClaimedByHydration(node, checkIfAlreadyClaimed = true) {
8909
+ if (!ngDevMode) {
8910
+ throw new Error('Calling `markRNodeAsClaimedByHydration` in prod mode ' +
8911
+ 'is not supported and likely a mistake.');
8912
+ }
8913
+ if (checkIfAlreadyClaimed && isRNodeClaimedForHydration(node)) {
8914
+ throw new Error('Trying to claim a node, which was claimed already.');
8915
+ }
8916
+ node.__claimed = true;
8917
+ ngDevMode.hydratedNodes++;
8918
+ }
8919
+ function isRNodeClaimedForHydration(node) {
8920
+ return !!node.__claimed;
8921
+ }
8922
+ function storeNgContainerInfo(hydrationInfo, index, firstChild) {
8923
+ var _a;
8924
+ (_a = hydrationInfo.ngContainers) !== null && _a !== void 0 ? _a : (hydrationInfo.ngContainers = {});
8925
+ hydrationInfo.ngContainers[index] = { firstChild };
8926
+ }
8927
+ function getNgContainerSize(hydrationInfo, index) {
8928
+ var _a, _b;
8929
+ return (_b = (_a = hydrationInfo.data[ELEMENT_CONTAINERS]) === null || _a === void 0 ? void 0 : _a[index]) !== null && _b !== void 0 ? _b : null;
8930
+ }
8931
+
8574
8932
  /**
8575
8933
  * Represents a component created by a `ComponentFactory`.
8576
8934
  * Provides access to the component instance and related objects,
@@ -8750,7 +9108,7 @@ class Version {
8750
9108
  /**
8751
9109
  * @publicApi
8752
9110
  */
8753
- const VERSION = new Version('16.0.0-next.0');
9111
+ const VERSION = new Version('16.0.0-next.2');
8754
9112
 
8755
9113
  // This default value is when checking the hierarchy for a token.
8756
9114
  //
@@ -8831,6 +9189,23 @@ class ErrorHandler {
8831
9189
  }
8832
9190
  }
8833
9191
 
9192
+ const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
9193
+ /**
9194
+ * Internal token that specifies whether hydration is enabled.
9195
+ */
9196
+ const IS_HYDRATION_FEATURE_ENABLED = new InjectionToken(NG_DEV_MODE ? 'IS_HYDRATION_FEATURE_ENABLED' : '');
9197
+ // By default (in client rendering mode), we remove all the contents
9198
+ // of the host element and render an application after that.
9199
+ const PRESERVE_HOST_CONTENT_DEFAULT = false;
9200
+ /**
9201
+ * Internal token that indicates whether host element content should be
9202
+ * retained during the bootstrap.
9203
+ */
9204
+ const PRESERVE_HOST_CONTENT = new InjectionToken(NG_DEV_MODE ? 'PRESERVE_HOST_CONTENT' : '', {
9205
+ providedIn: 'root',
9206
+ factory: () => PRESERVE_HOST_CONTENT_DEFAULT,
9207
+ });
9208
+
8834
9209
  function normalizeDebugBindingName(name) {
8835
9210
  // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
8836
9211
  name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
@@ -10482,7 +10857,7 @@ function renderChildComponents(hostLView, components) {
10482
10857
  renderComponent(hostLView, components[i]);
10483
10858
  }
10484
10859
  }
10485
- function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector) {
10860
+ function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector, hydrationInfo) {
10486
10861
  const lView = tView.blueprint.slice();
10487
10862
  lView[HOST] = host;
10488
10863
  lView[FLAGS] = flags | 4 /* LViewFlags.CreationMode */ | 64 /* LViewFlags.Attached */ | 8 /* LViewFlags.FirstLViewPass */;
@@ -10502,6 +10877,7 @@ function createLView(parentLView, tView, context, flags, host, tHostNode, render
10502
10877
  lView[INJECTOR$1] = injector || parentLView && parentLView[INJECTOR$1] || null;
10503
10878
  lView[T_HOST] = tHostNode;
10504
10879
  lView[ID] = getUniqueLViewId();
10880
+ lView[HYDRATION] = hydrationInfo;
10505
10881
  lView[EMBEDDED_VIEW_INJECTOR] = embeddedViewInjector;
10506
10882
  ngDevMode &&
10507
10883
  assertEqual(tView.type == 2 /* TViewType.Embedded */ ? parentLView !== null : true, true, 'Embedded views must have parentLView');
@@ -10564,6 +10940,7 @@ function createTNodeAtIndex(tView, index, type, name, attrs) {
10564
10940
  // In the case of i18n the `currentTNode` may already be linked, in which case we don't want
10565
10941
  // to break the links which i18n created.
10566
10942
  currentTNode.next = tNode;
10943
+ tNode.prev = currentTNode;
10567
10944
  }
10568
10945
  }
10569
10946
  }
@@ -10942,10 +11319,19 @@ function createViewBlueprint(bindingStartIndex, initialViewLength) {
10942
11319
  * @param rendererFactory Factory function to create renderer instance.
10943
11320
  * @param elementOrSelector Render element or CSS selector to locate the element.
10944
11321
  * @param encapsulation View Encapsulation defined for component that requests host element.
10945
- */
10946
- function locateHostElement(renderer, elementOrSelector, encapsulation) {
10947
- // When using native Shadow DOM, do not clear host element to allow native slot projection
10948
- const preserveContent = encapsulation === ViewEncapsulation.ShadowDom;
11322
+ * @param injector Root view injector instance.
11323
+ */
11324
+ function locateHostElement(renderer, elementOrSelector, encapsulation, injector) {
11325
+ // Note: we use default value for the `PRESERVE_HOST_CONTENT` here even though it's a
11326
+ // tree-shakable one (providedIn:'root'). This code path can be triggered during dynamic component
11327
+ // creation (after calling ViewContainerRef.createComponent) when an injector instance can be
11328
+ // provided. The injector instance might be disconnected from the main DI tree, thus the
11329
+ // `PRESERVE_HOST_CONTENT` woild not be able to instantiate. In this case, the default value will
11330
+ // be used.
11331
+ const preserveHostContent = injector.get(PRESERVE_HOST_CONTENT, PRESERVE_HOST_CONTENT_DEFAULT);
11332
+ // When using native Shadow DOM, do not clear host element to allow native slot
11333
+ // projection.
11334
+ const preserveContent = preserveHostContent || encapsulation === ViewEncapsulation.ShadowDom;
10949
11335
  return renderer.selectRootElement(elementOrSelector, preserveContent);
10950
11336
  }
10951
11337
  /**
@@ -10954,24 +11340,24 @@ function locateHostElement(renderer, elementOrSelector, encapsulation) {
10954
11340
  * On the first template pass, saves in TView:
10955
11341
  * - Cleanup function
10956
11342
  * - Index of context we just saved in LView.cleanupInstances
10957
- *
10958
- * This function can also be used to store instance specific cleanup fns. In that case the `context`
10959
- * is `null` and the function is store in `LView` (rather than it `TView`).
10960
11343
  */
10961
11344
  function storeCleanupWithContext(tView, lView, context, cleanupFn) {
10962
11345
  const lCleanup = getOrCreateLViewCleanup(lView);
10963
- if (context === null) {
10964
- // If context is null that this is instance specific callback. These callbacks can only be
10965
- // inserted after template shared instances. For this reason in ngDevMode we freeze the TView.
10966
- if (ngDevMode) {
10967
- Object.freeze(getOrCreateTViewCleanup(tView));
10968
- }
10969
- lCleanup.push(cleanupFn);
11346
+ // Historically the `storeCleanupWithContext` was used to register both framework-level and
11347
+ // user-defined cleanup callbacks, but over time those two types of cleanups were separated. This
11348
+ // dev mode checks assures that user-level cleanup callbacks are _not_ stored in data structures
11349
+ // reserved for framework-specific hooks.
11350
+ ngDevMode &&
11351
+ assertDefined(context, 'Cleanup context is mandatory when registering framework-level destroy hooks');
11352
+ lCleanup.push(context);
11353
+ if (tView.firstCreatePass) {
11354
+ getOrCreateTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1);
10970
11355
  }
10971
11356
  else {
10972
- lCleanup.push(context);
10973
- if (tView.firstCreatePass) {
10974
- getOrCreateTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1);
11357
+ // Make sure that no new framework-level cleanup functions are registered after the first
11358
+ // template pass is done (and TView data structures are meant to fully constructed).
11359
+ if (ngDevMode) {
11360
+ Object.freeze(getOrCreateTViewCleanup(tView));
10975
11361
  }
10976
11362
  }
10977
11363
  }
@@ -11002,8 +11388,9 @@ function createTNode(tView, tParent, type, index, value, attrs) {
11002
11388
  initialInputs: undefined,
11003
11389
  inputs: null,
11004
11390
  outputs: null,
11005
- tViews: null,
11391
+ tView: null,
11006
11392
  next: null,
11393
+ prev: null,
11007
11394
  projectionNext: null,
11008
11395
  child: null,
11009
11396
  parent: tParent,
@@ -11213,7 +11600,6 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
11213
11600
  // Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
11214
11601
  // tsickle.
11215
11602
  ngDevMode && assertFirstCreatePass(tView);
11216
- let hasDirectives = false;
11217
11603
  if (getBindingsEnabled()) {
11218
11604
  const exportsMap = localRefs === null ? null : { '': -1 };
11219
11605
  const matchResult = findDirectiveDefMatches(tView, tNode);
@@ -11226,7 +11612,6 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
11226
11612
  [directiveDefs, hostDirectiveDefs] = matchResult;
11227
11613
  }
11228
11614
  if (directiveDefs !== null) {
11229
- hasDirectives = true;
11230
11615
  initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap, hostDirectiveDefs);
11231
11616
  }
11232
11617
  if (exportsMap)
@@ -11234,7 +11619,6 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
11234
11619
  }
11235
11620
  // Merge the template attrs last so that they have the highest priority.
11236
11621
  tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
11237
- return hasDirectives;
11238
11622
  }
11239
11623
  /** Initializes the data structures necessary for a list of directives to be instantiated. */
11240
11624
  function initializeDirectives(tView, lView, tNode, directives, exportsMap, hostDirectiveDefs) {
@@ -11548,7 +11932,7 @@ function addComponentLogic(lView, hostTNode, def) {
11548
11932
  // Only component views should be added to the view tree directly. Embedded views are
11549
11933
  // accessed through their containers because they may be removed / re-added later.
11550
11934
  const rendererFactory = lView[RENDERER_FACTORY];
11551
- const componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, native, hostTNode, rendererFactory, rendererFactory.createRenderer(native, def), null, null, null));
11935
+ const componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, native, hostTNode, rendererFactory, rendererFactory.createRenderer(native, def), null, null, null, null));
11552
11936
  // Component view will always be created before any injected LContainers,
11553
11937
  // so this is a regular element, wrap it with the component view
11554
11938
  lView[hostTNode.index] = componentView;
@@ -11793,6 +12177,11 @@ function renderComponent(hostLView, componentHostIdx) {
11793
12177
  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
11794
12178
  const componentTView = componentView[TVIEW];
11795
12179
  syncViewWithBlueprint(componentTView, componentView);
12180
+ const hostRNode = componentView[HOST];
12181
+ // Populate an LView with hydration info retrieved from the DOM via TransferState.
12182
+ if (hostRNode !== null && componentView[HYDRATION] === null) {
12183
+ componentView[HYDRATION] = retrieveHydrationInfo(hostRNode, componentView[INJECTOR$1]);
12184
+ }
11796
12185
  renderView(componentTView, componentView, componentView[CONTEXT]);
11797
12186
  }
11798
12187
  /**
@@ -12166,7 +12555,7 @@ class ViewRef {
12166
12555
  destroyLView(this._lView[TVIEW], this._lView);
12167
12556
  }
12168
12557
  onDestroy(callback) {
12169
- storeCleanupWithContext(this._lView[TVIEW], this._lView, null, callback);
12558
+ storeLViewOnDestroy(this._lView, callback);
12170
12559
  }
12171
12560
  /**
12172
12561
  * Marks a view and all of its ancestors dirty.
@@ -12493,13 +12882,13 @@ class ComponentFactory extends ComponentFactory$1 {
12493
12882
  // dynamically. Default to 'div' if this component did not specify any tag name in its selector.
12494
12883
  const elementName = this.componentDef.selectors[0][0] || 'div';
12495
12884
  const hostRNode = rootSelectorOrNode ?
12496
- locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation) :
12885
+ locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation, rootViewInjector) :
12497
12886
  createElementNode(hostRenderer, elementName, getNamespace(elementName));
12498
12887
  const rootFlags = this.componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
12499
12888
  16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
12500
12889
  // Create the root view. Uses empty TView and ContentTemplate.
12501
12890
  const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
12502
- const rootLView = createLView(null, rootTView, null, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null);
12891
+ const rootLView = createLView(null, rootTView, null, rootFlags, null, null, rendererFactory, hostRenderer, sanitizer, rootViewInjector, null, null);
12503
12892
  // rootView is the parent when bootstrapping
12504
12893
  // TODO(misko): it looks like we are entering view here but we don't really need to as
12505
12894
  // `renderView` does that. However as the code is written it is needed because
@@ -12610,7 +12999,7 @@ function createRootComponentTNode(lView, rNode) {
12610
12999
  /**
12611
13000
  * Creates the root component view and the root component node.
12612
13001
  *
12613
- * @param rNode Render host element.
13002
+ * @param hostRNode Render host element.
12614
13003
  * @param rootComponentDef ComponentDef
12615
13004
  * @param rootView The parent view where the host node is stored
12616
13005
  * @param rendererFactory Factory to be used for creating child renderers.
@@ -12619,11 +13008,17 @@ function createRootComponentTNode(lView, rNode) {
12619
13008
  *
12620
13009
  * @returns Component view created
12621
13010
  */
12622
- function createRootComponentView(tNode, rNode, rootComponentDef, rootDirectives, rootView, rendererFactory, hostRenderer, sanitizer) {
13011
+ function createRootComponentView(tNode, hostRNode, rootComponentDef, rootDirectives, rootView, rendererFactory, hostRenderer, sanitizer) {
12623
13012
  const tView = rootView[TVIEW];
12624
- applyRootComponentStyling(rootDirectives, tNode, rNode, hostRenderer);
12625
- const viewRenderer = rendererFactory.createRenderer(rNode, rootComponentDef);
12626
- const componentView = createLView(rootView, getOrCreateComponentTView(rootComponentDef), null, rootComponentDef.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[tNode.index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
13013
+ applyRootComponentStyling(rootDirectives, tNode, hostRNode, hostRenderer);
13014
+ // Hydration info is on the host element and needs to be retreived
13015
+ // and passed to the component LView.
13016
+ let hydrationInfo = null;
13017
+ if (hostRNode !== null) {
13018
+ hydrationInfo = retrieveHydrationInfo(hostRNode, rootView[INJECTOR$1]);
13019
+ }
13020
+ const viewRenderer = rendererFactory.createRenderer(hostRNode, rootComponentDef);
13021
+ const componentView = createLView(rootView, getOrCreateComponentTView(rootComponentDef), null, rootComponentDef.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[tNode.index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null, hydrationInfo);
12627
13022
  if (tView.firstCreatePass) {
12628
13023
  markAsComponentHost(tView, tNode, rootDirectives.length - 1);
12629
13024
  }
@@ -13101,41 +13496,19 @@ function validateMappings(bindingType, def, hostDirectiveBindings) {
13101
13496
  }
13102
13497
  }
13103
13498
 
13104
- let _symbolIterator = null;
13105
- function getSymbolIterator() {
13106
- if (!_symbolIterator) {
13107
- const Symbol = _global$1['Symbol'];
13108
- if (Symbol && Symbol.iterator) {
13109
- _symbolIterator = Symbol.iterator;
13110
- }
13111
- else {
13112
- // es6-shim specific logic
13113
- const keys = Object.getOwnPropertyNames(Map.prototype);
13114
- for (let i = 0; i < keys.length; ++i) {
13115
- const key = keys[i];
13116
- if (key !== 'entries' && key !== 'size' &&
13117
- Map.prototype[key] === Map.prototype['entries']) {
13118
- _symbolIterator = key;
13119
- }
13120
- }
13121
- }
13122
- }
13123
- return _symbolIterator;
13124
- }
13125
-
13126
13499
  function isIterable(obj) {
13127
- return obj !== null && typeof obj === 'object' && obj[getSymbolIterator()] !== undefined;
13500
+ return obj !== null && typeof obj === 'object' && obj[Symbol.iterator] !== undefined;
13128
13501
  }
13129
13502
  function isListLikeIterable(obj) {
13130
13503
  if (!isJsObject(obj))
13131
13504
  return false;
13132
13505
  return Array.isArray(obj) ||
13133
13506
  (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
13134
- getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
13507
+ Symbol.iterator in obj); // JS Iterable have a Symbol.iterator prop
13135
13508
  }
13136
13509
  function areIterablesEqual(a, b, comparator) {
13137
- const iterator1 = a[getSymbolIterator()]();
13138
- const iterator2 = b[getSymbolIterator()]();
13510
+ const iterator1 = a[Symbol.iterator]();
13511
+ const iterator2 = b[Symbol.iterator]();
13139
13512
  while (true) {
13140
13513
  const item1 = iterator1.next();
13141
13514
  const item2 = iterator2.next();
@@ -13154,7 +13527,7 @@ function iterateListLike(obj, fn) {
13154
13527
  }
13155
13528
  }
13156
13529
  else {
13157
- const iterator = obj[getSymbolIterator()]();
13530
+ const iterator = obj[Symbol.iterator]();
13158
13531
  let item;
13159
13532
  while (!((item = iterator.next()).done)) {
13160
13533
  fn(item.value);
@@ -13807,7 +14180,7 @@ function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, t
13807
14180
  const tNode = getOrCreateTNode(tView, index, 4 /* TNodeType.Container */, tagName || null, getConstant(tViewConsts, attrsIndex));
13808
14181
  resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
13809
14182
  registerPostOrderHooks(tView, tNode);
13810
- const embeddedTView = tNode.tViews = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts);
14183
+ const embeddedTView = tNode.tView = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts);
13811
14184
  if (tView.queries !== null) {
13812
14185
  tView.queries.template(tView, tNode);
13813
14186
  embeddedTView.queries = tView.queries.embeddedTView(tNode);
@@ -13877,6 +14250,122 @@ function ɵɵreference(index) {
13877
14250
  return load(contextLView, HEADER_OFFSET + index);
13878
14251
  }
13879
14252
 
14253
+ /**
14254
+ * Verifies whether a given node matches an expected criteria,
14255
+ * based on internal data structure state.
14256
+ */
14257
+ function validateMatchingNode(node, nodeType, tagName, lView, tNode) {
14258
+ if (node.nodeType !== nodeType ||
14259
+ (node.nodeType === Node.ELEMENT_NODE &&
14260
+ node.tagName.toLowerCase() !== (tagName === null || tagName === void 0 ? void 0 : tagName.toLowerCase()))) {
14261
+ // TODO: improve error message and use RuntimeError instead.
14262
+ throw new Error(`Unexpected node found during hydration.`);
14263
+ }
14264
+ }
14265
+ /**
14266
+ * Verifies whether next sibling node exists.
14267
+ */
14268
+ function validateSiblingNodeExists(node) {
14269
+ if (!node.nextSibling) {
14270
+ // TODO: improve error message and use RuntimeError instead.
14271
+ throw new Error(`Unexpected state: insufficient number of sibling nodes.`);
14272
+ }
14273
+ }
14274
+
14275
+ /** Whether current TNode is a first node in an <ng-container>. */
14276
+ function isFirstElementInNgContainer(tNode) {
14277
+ var _a;
14278
+ return !tNode.prev && ((_a = tNode.parent) === null || _a === void 0 ? void 0 : _a.type) === 8 /* TNodeType.ElementContainer */;
14279
+ }
14280
+ /** Returns first element from a DOM segment that corresponds to this <ng-container>. */
14281
+ function getDehydratedNgContainer(hydrationInfo, tContainerNode) {
14282
+ var _a;
14283
+ const noOffsetIndex = tContainerNode.index - HEADER_OFFSET;
14284
+ const ngContainer = (_a = hydrationInfo.ngContainers) === null || _a === void 0 ? void 0 : _a[noOffsetIndex];
14285
+ ngDevMode &&
14286
+ assertDefined(ngContainer, 'Unexpected state: no hydration info available for a given TNode, ' +
14287
+ 'which represents an element container.');
14288
+ return ngContainer;
14289
+ }
14290
+ /**
14291
+ * Locate a node in DOM tree that corresponds to a given TNode.
14292
+ *
14293
+ * @param hydrationInfo The hydration annotation data
14294
+ * @param tView the current tView
14295
+ * @param lView the current lView
14296
+ * @param tNode the current tNode
14297
+ * @returns an RNode that represents a given tNode
14298
+ */
14299
+ function locateNextRNode(hydrationInfo, tView, lView, tNode) {
14300
+ var _a, _b;
14301
+ let native = null;
14302
+ if (tView.firstChild === tNode) {
14303
+ // We create a first node in this view, so we use a reference
14304
+ // to the first child in this DOM segment.
14305
+ native = hydrationInfo.firstChild;
14306
+ }
14307
+ else {
14308
+ // Locate a node based on a previous sibling or a parent node.
14309
+ const previousTNodeParent = tNode.prev === null;
14310
+ const previousTNode = ((_a = tNode.prev) !== null && _a !== void 0 ? _a : tNode.parent);
14311
+ ngDevMode &&
14312
+ assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' +
14313
+ 'to the previous node or a parent node.');
14314
+ const previousRElement = getNativeByTNode(previousTNode, lView);
14315
+ if (isFirstElementInNgContainer(tNode)) {
14316
+ const ngContainer = getDehydratedNgContainer(hydrationInfo, tNode.parent);
14317
+ native = (_b = ngContainer.firstChild) !== null && _b !== void 0 ? _b : null;
14318
+ }
14319
+ else {
14320
+ if (previousTNodeParent) {
14321
+ native = previousRElement.firstChild;
14322
+ }
14323
+ else {
14324
+ native = previousRElement.nextSibling;
14325
+ }
14326
+ }
14327
+ }
14328
+ return native;
14329
+ }
14330
+ /**
14331
+ * Skips over a specified number of nodes and returns the next sibling node after that.
14332
+ */
14333
+ function siblingAfter(skip, from) {
14334
+ let currentNode = from;
14335
+ for (let i = 0; i < skip; i++) {
14336
+ ngDevMode && validateSiblingNodeExists(currentNode);
14337
+ currentNode = currentNode.nextSibling;
14338
+ }
14339
+ return currentNode;
14340
+ }
14341
+
14342
+ /**
14343
+ * The name of an attribute that can be added to the hydration boundary node
14344
+ * (component host node) to disable hydration for the content within that boundary.
14345
+ */
14346
+ const SKIP_HYDRATION_ATTR_NAME = 'ngSkipHydration';
14347
+ /**
14348
+ * Helper function to check if a given node has the 'ngSkipHydration' attribute
14349
+ */
14350
+ function hasNgSkipHydrationAttr(tNode) {
14351
+ const SKIP_HYDRATION_ATTR_NAME_LOWER_CASE = SKIP_HYDRATION_ATTR_NAME.toLowerCase();
14352
+ const attrs = tNode.mergedAttrs;
14353
+ if (attrs === null)
14354
+ return false;
14355
+ // only ever look at the attribute name and skip the values
14356
+ for (let i = 0; i < attrs.length; i += 2) {
14357
+ const value = attrs[i];
14358
+ // This is a marker, which means that the static attributes section is over,
14359
+ // so we can exit early.
14360
+ if (typeof value === 'number')
14361
+ return false;
14362
+ if (typeof value === 'string' && value.toLowerCase() === SKIP_HYDRATION_ATTR_NAME_LOWER_CASE) {
14363
+ return true;
14364
+ }
14365
+ }
14366
+ return false;
14367
+ }
14368
+
13880
14369
  /**
13881
14370
  * Update a property on a selected element.
13882
14371
  *
@@ -13917,16 +14406,13 @@ function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isCla
13917
14406
  setInputsForProperty(tView, lView, inputs[property], property, value);
13918
14407
  }
13919
14408
 
13920
- function elementStartFirstCreatePass(index, tView, lView, native, name, attrsIndex, localRefsIndex) {
14409
+ function elementStartFirstCreatePass(index, tView, lView, name, attrsIndex, localRefsIndex) {
13921
14410
  ngDevMode && assertFirstCreatePass(tView);
13922
14411
  ngDevMode && ngDevMode.firstCreatePass++;
13923
14412
  const tViewConsts = tView.consts;
13924
14413
  const attrs = getConstant(tViewConsts, attrsIndex);
13925
14414
  const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, name, attrs);
13926
- const hasDirectives = resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
13927
- if (ngDevMode) {
13928
- validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
13929
- }
14415
+ resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
13930
14416
  if (tNode.attrs !== null) {
13931
14417
  computeStaticStyling(tNode, tNode.attrs, false);
13932
14418
  }
@@ -13961,13 +14447,18 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
13961
14447
  assertEqual(getBindingIndex(), tView.bindingStartIndex, 'elements should be created before any bindings');
13962
14448
  ngDevMode && assertIndexInRange(lView, adjustedIndex);
13963
14449
  const renderer = lView[RENDERER];
13964
- const native = lView[adjustedIndex] = createElementNode(renderer, name, getNamespace$1());
13965
14450
  const tNode = tView.firstCreatePass ?
13966
- elementStartFirstCreatePass(adjustedIndex, tView, lView, native, name, attrsIndex, localRefsIndex) :
14451
+ elementStartFirstCreatePass(adjustedIndex, tView, lView, name, attrsIndex, localRefsIndex) :
13967
14452
  tView.data[adjustedIndex];
14453
+ const native = _locateOrCreateElementNode(tView, lView, tNode, renderer, name);
14454
+ lView[adjustedIndex] = native;
14455
+ const hasDirectives = isDirectiveHost(tNode);
14456
+ if (ngDevMode && tView.firstCreatePass) {
14457
+ validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
14458
+ }
13968
14459
  setCurrentTNode(tNode, true);
13969
14460
  setupStaticAttributes(renderer, native, tNode);
13970
- if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
14461
+ if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */ && wasLastNodeCreated()) {
13971
14462
  // In the i18n case, the translation may have removed this element, so only add it if it is not
13972
14463
  // detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
13973
14464
  appendChild(tView, lView, native, tNode);
@@ -13979,7 +14470,7 @@ function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
13979
14470
  attachPatchData(native, lView);
13980
14471
  }
13981
14472
  increaseElementDepthCount();
13982
- if (isDirectiveHost(tNode)) {
14473
+ if (hasDirectives) {
13983
14474
  createDirectivesInstances(tView, lView, tNode);
13984
14475
  executeContentQueries(tView, tNode, lView);
13985
14476
  }
@@ -14007,6 +14498,9 @@ function ɵɵelementEnd() {
14007
14498
  }
14008
14499
  const tNode = currentTNode;
14009
14500
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */);
14501
+ if (isSkipHydrationRootTNode(tNode)) {
14502
+ leaveSkipHydrationBlock();
14503
+ }
14010
14504
  decreaseElementDepthCount();
14011
14505
  const tView = getTView();
14012
14506
  if (tView.firstCreatePass) {
@@ -14039,6 +14533,40 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
14039
14533
  ɵɵelementEnd();
14040
14534
  return ɵɵelement;
14041
14535
  }
14536
+ let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name) => {
14537
+ lastNodeWasCreated(true);
14538
+ return createElementNode(renderer, name, getNamespace$1());
14539
+ };
14540
+ /**
14541
+ * Enables hydration code path (to lookup existing elements in DOM)
14542
+ * in addition to the regular creation mode of element nodes.
14543
+ */
14544
+ function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name) {
14545
+ const hydrationInfo = lView[HYDRATION];
14546
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock();
14547
+ lastNodeWasCreated(isNodeCreationMode);
14548
+ // Regular creation mode.
14549
+ if (isNodeCreationMode) {
14550
+ return createElementNode(renderer, name, getNamespace$1());
14551
+ }
14552
+ // Hydration mode, looking up an existing element in DOM.
14553
+ const native = locateNextRNode(hydrationInfo, tView, lView, tNode);
14554
+ ngDevMode &&
14555
+ validateMatchingNode(native, Node.ELEMENT_NODE, name, lView, tNode);
14556
+ ngDevMode && markRNodeAsClaimedByHydration(native);
14557
+ // Checks if the skip hydration attribute is present during hydration so we know to
14558
+ // skip attempting to hydrate this block.
14559
+ if (hydrationInfo && hasNgSkipHydrationAttr(tNode)) {
14560
+ enterSkipHydrationBlock(tNode);
14561
+ // Since this isn't hydratable, we need to empty the node
14562
+ // so there's no duplicate content after render
14563
+ clearElementContents(renderer, native);
14564
+ }
14565
+ return native;
14566
+ }
14567
+ function enableLocateOrCreateElementNodeImpl() {
14568
+ _locateOrCreateElementNode = locateOrCreateElementNodeImpl;
14569
+ }
14042
14570
 
14043
14571
  function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) {
14044
14572
  ngDevMode && ngDevMode.firstCreatePass++;
@@ -14084,10 +14612,12 @@ function ɵɵelementContainerStart(index, attrsIndex, localRefsIndex) {
14084
14612
  tView.data[adjustedIndex];
14085
14613
  setCurrentTNode(tNode, true);
14086
14614
  ngDevMode && ngDevMode.rendererCreateComment++;
14087
- const native = lView[adjustedIndex] =
14088
- lView[RENDERER].createComment(ngDevMode ? 'ng-container' : '');
14089
- appendChild(tView, lView, native, tNode);
14090
- attachPatchData(native, lView);
14615
+ const comment = _locateOrCreateElementContainerNode(tView, lView, tNode, index);
14616
+ lView[adjustedIndex] = comment;
14617
+ if (wasLastNodeCreated()) {
14618
+ appendChild(tView, lView, comment, tNode);
14619
+ }
14620
+ attachPatchData(comment, lView);
14091
14621
  if (isDirectiveHost(tNode)) {
14092
14622
  createDirectivesInstances(tView, lView, tNode);
14093
14623
  executeContentQueries(tView, tNode, lView);
@@ -14139,6 +14669,46 @@ function ɵɵelementContainer(index, attrsIndex, localRefsIndex) {
14139
14669
  ɵɵelementContainerEnd();
14140
14670
  return ɵɵelementContainer;
14141
14671
  }
14672
+ let _locateOrCreateElementContainerNode = (tView, lView, tNode, index) => {
14673
+ lastNodeWasCreated(true);
14674
+ return createCommentNode(lView[RENDERER], ngDevMode ? 'ng-container' : '');
14675
+ };
14676
+ /**
14677
+ * Enables hydration code path (to lookup existing elements in DOM)
14678
+ * in addition to the regular creation mode of comment nodes that
14679
+ * represent <ng-container>'s anchor.
14680
+ */
14681
+ function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
14682
+ let comment;
14683
+ const hydrationInfo = lView[HYDRATION];
14684
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock();
14685
+ lastNodeWasCreated(isNodeCreationMode);
14686
+ // Regular creation mode.
14687
+ if (isNodeCreationMode) {
14688
+ return createCommentNode(lView[RENDERER], ngDevMode ? 'ng-container' : '');
14689
+ }
14690
+ // Hydration mode, looking up existing elements in DOM.
14691
+ const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
14692
+ const ngContainerSize = getNgContainerSize(hydrationInfo, index);
14693
+ ngDevMode &&
14694
+ assertNumber(ngContainerSize, 'Unexpected state: hydrating an <ng-container>, ' +
14695
+ 'but no hydration info is available.');
14696
+ if (ngContainerSize > 0) {
14697
+ storeNgContainerInfo(hydrationInfo, index, currentRNode);
14698
+ comment = siblingAfter(ngContainerSize, currentRNode);
14699
+ }
14700
+ else {
14701
+ // If <ng-container> has no nodes,
14702
+ // the current node is an anchor (comment) node.
14703
+ comment = currentRNode;
14704
+ }
14705
+ ngDevMode && validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
14706
+ ngDevMode && markRNodeAsClaimedByHydration(comment);
14707
+ return comment;
14708
+ }
14709
+ function enableLocateOrCreateElementContainerNodeImpl() {
14710
+ _locateOrCreateElementContainerNode = locateOrCreateElementContainerNode;
14711
+ }
14142
14712
 
14143
14713
  /**
14144
14714
  * Returns the current OpaqueViewState instance.
@@ -14167,16 +14737,6 @@ function isPromise(obj) {
14167
14737
  function isSubscribable(obj) {
14168
14738
  return !!obj && typeof obj.subscribe === 'function';
14169
14739
  }
14170
- /**
14171
- * Determine if the argument is an Observable
14172
- *
14173
- * Strictly this tests that the `obj` is `Subscribable`, since `Observable`
14174
- * types need additional methods, such as `lift()`. But it is adequate for our
14175
- * needs since within the Angular framework code we only ever need to use the
14176
- * `subscribe()` method, and RxJS has mechanisms to wrap `Subscribable` objects
14177
- * into `Observable` as needed.
14178
- */
14179
- const isObservable = isSubscribable;
14180
14740
 
14181
14741
  /**
14182
14742
  * Adds an event listener to the current node.
@@ -14339,7 +14899,7 @@ function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn,
14339
14899
  const minifiedName = props[i + 1];
14340
14900
  const directiveInstance = lView[index];
14341
14901
  const output = directiveInstance[minifiedName];
14342
- if (ngDevMode && !isObservable(output)) {
14902
+ if (ngDevMode && !isSubscribable(output)) {
14343
14903
  throw new Error(`@Output ${minifiedName} not initialized in '${directiveInstance.constructor.name}'.`);
14344
14904
  }
14345
14905
  const subscription = output.subscribe(listenerFn);
@@ -16483,11 +17043,39 @@ function ɵɵtext(index, value = '') {
16483
17043
  const tNode = tView.firstCreatePass ?
16484
17044
  getOrCreateTNode(tView, adjustedIndex, 1 /* TNodeType.Text */, value, null) :
16485
17045
  tView.data[adjustedIndex];
16486
- const textNative = lView[adjustedIndex] = createTextNode(lView[RENDERER], value);
16487
- appendChild(tView, lView, textNative, tNode);
17046
+ const textNative = _locateOrCreateTextNode(tView, lView, tNode, value);
17047
+ lView[adjustedIndex] = textNative;
17048
+ if (wasLastNodeCreated()) {
17049
+ appendChild(tView, lView, textNative, tNode);
17050
+ }
16488
17051
  // Text nodes are self closing.
16489
17052
  setCurrentTNode(tNode, false);
16490
17053
  }
17054
+ let _locateOrCreateTextNode = (tView, lView, tNode, value) => {
17055
+ lastNodeWasCreated(true);
17056
+ return createTextNode(lView[RENDERER], value);
17057
+ };
17058
+ /**
17059
+ * Enables hydration code path (to lookup existing elements in DOM)
17060
+ * in addition to the regular creation mode of text nodes.
17061
+ */
17062
+ function locateOrCreateTextNodeImpl(tView, lView, tNode, value) {
17063
+ const hydrationInfo = lView[HYDRATION];
17064
+ const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock();
17065
+ lastNodeWasCreated(isNodeCreationMode);
17066
+ // Regular creation mode.
17067
+ if (isNodeCreationMode) {
17068
+ return createTextNode(lView[RENDERER], value);
17069
+ }
17070
+ // Hydration mode, looking up an existing element in DOM.
17071
+ const textNative = locateNextRNode(hydrationInfo, tView, lView, tNode);
17072
+ ngDevMode && validateMatchingNode(textNative, Node.TEXT_NODE, null, lView, tNode);
17073
+ ngDevMode && markRNodeAsClaimedByHydration(textNative);
17074
+ return textNative;
17075
+ }
17076
+ function enableLocateOrCreateTextNodeImpl() {
17077
+ _locateOrCreateTextNode = locateOrCreateTextNodeImpl;
17078
+ }
16491
17079
 
16492
17080
  /**
16493
17081
  *
@@ -18165,7 +18753,7 @@ function getTIcu(tView, index) {
18165
18753
  if (value === null || typeof value === 'string')
18166
18754
  return null;
18167
18755
  if (ngDevMode &&
18168
- !(value.hasOwnProperty('tViews') || value.hasOwnProperty('currentCaseLViewIndex'))) {
18756
+ !(value.hasOwnProperty('tView') || value.hasOwnProperty('currentCaseLViewIndex'))) {
18169
18757
  throwError('We expect to get \'null\'|\'TIcu\'|\'TIcuContainer\', but got: ' + value);
18170
18758
  }
18171
18759
  // Here the `value.hasOwnProperty('currentCaseLViewIndex')` is a polymorphic read as it can be
@@ -18194,7 +18782,7 @@ function getTIcu(tView, index) {
18194
18782
  function setTIcu(tView, index, tIcu) {
18195
18783
  const tNode = tView.data[index];
18196
18784
  ngDevMode &&
18197
- assertEqual(tNode === null || tNode.hasOwnProperty('tViews'), true, 'We expect to get \'null\'|\'TIcuContainer\'');
18785
+ assertEqual(tNode === null || tNode.hasOwnProperty('tView'), true, 'We expect to get \'null\'|\'TIcuContainer\'');
18198
18786
  if (tNode === null) {
18199
18787
  tView.data[index] = tIcu;
18200
18788
  }
@@ -21295,7 +21883,8 @@ function _wrapInTimeout(fn) {
21295
21883
  const EventEmitter = EventEmitter_;
21296
21884
 
21297
21885
  function symbolIterator() {
21298
- return this._results[getSymbolIterator()]();
21886
+ // @ts-expect-error accessing a private member
21887
+ return this._results[Symbol.iterator]();
21299
21888
  }
21300
21889
  /**
21301
21890
  * An unmodifiable list of items that Angular keeps up to date when the state
@@ -21347,11 +21936,10 @@ class QueryList {
21347
21936
  // This function should be declared on the prototype, but doing so there will cause the class
21348
21937
  // declaration to have side-effects and become not tree-shakable. For this reason we do it in
21349
21938
  // the constructor.
21350
- // [getSymbolIterator()](): Iterator<T> { ... }
21351
- const symbol = getSymbolIterator();
21939
+ // [Symbol.iterator](): Iterator<T> { ... }
21352
21940
  const proto = QueryList.prototype;
21353
- if (!proto[symbol])
21354
- proto[symbol] = symbolIterator;
21941
+ if (!proto[Symbol.iterator])
21942
+ proto[Symbol.iterator] = symbolIterator;
21355
21943
  }
21356
21944
  /**
21357
21945
  * Returns the QueryList entry at `index`.
@@ -21490,8 +22078,8 @@ const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
21490
22078
  this.elementRef = elementRef;
21491
22079
  }
21492
22080
  createEmbeddedView(context, injector) {
21493
- const embeddedTView = this._declarationTContainer.tViews;
21494
- const embeddedLView = createLView(this._declarationLView, embeddedTView, context, 16 /* LViewFlags.CheckAlways */, null, embeddedTView.declTNode, null, null, null, null, injector || null);
22081
+ const embeddedTView = this._declarationTContainer.tView;
22082
+ const embeddedLView = createLView(this._declarationLView, embeddedTView, context, 16 /* LViewFlags.CheckAlways */, null, embeddedTView.declTNode, null, null, null, null, injector || null, null);
21495
22083
  const declarationLContainer = this._declarationLView[this._declarationTContainer.index];
21496
22084
  ngDevMode && assertLContainer(declarationLContainer);
21497
22085
  embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
@@ -21520,7 +22108,7 @@ function injectTemplateRef() {
21520
22108
  */
21521
22109
  function createTemplateRef(hostTNode, hostLView) {
21522
22110
  if (hostTNode.type & 4 /* TNodeType.Container */) {
21523
- ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
22111
+ ngDevMode && assertDefined(hostTNode.tView, 'TView must be allocated');
21524
22112
  return new R3TemplateRef(hostLView, hostTNode, createElementRef(hostTNode, hostLView));
21525
22113
  }
21526
22114
  return null;