@angular/core 14.1.0-next.1 → 14.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 (56) hide show
  1. package/esm2020/src/application_ref.mjs +31 -35
  2. package/esm2020/src/change_detection/differs/default_iterable_differ.mjs +3 -5
  3. package/esm2020/src/change_detection/differs/default_keyvalue_differ.mjs +3 -5
  4. package/esm2020/src/change_detection/differs/iterable_differs.mjs +3 -5
  5. package/esm2020/src/change_detection/differs/keyvalue_differs.mjs +2 -5
  6. package/esm2020/src/core.mjs +1 -1
  7. package/esm2020/src/core_render3_private_export.mjs +2 -2
  8. package/esm2020/src/debug/debug_node.mjs +2 -3
  9. package/esm2020/src/di/index.mjs +1 -1
  10. package/esm2020/src/di/injector_compatibility.mjs +16 -16
  11. package/esm2020/src/di/interface/injector.mjs +2 -1
  12. package/esm2020/src/di/jit/util.mjs +3 -2
  13. package/esm2020/src/di/r3_injector.mjs +13 -1
  14. package/esm2020/src/di/reflective_key.mjs +3 -2
  15. package/esm2020/src/errors.mjs +1 -1
  16. package/esm2020/src/i18n/locale_data_api.mjs +3 -2
  17. package/esm2020/src/linker/component_factory.mjs +1 -1
  18. package/esm2020/src/metadata/di.mjs +1 -1
  19. package/esm2020/src/render/api.mjs +2 -11
  20. package/esm2020/src/render3/component.mjs +3 -57
  21. package/esm2020/src/render3/component_ref.mjs +30 -5
  22. package/esm2020/src/render3/features/inherit_definition_feature.mjs +3 -5
  23. package/esm2020/src/render3/index.mjs +3 -3
  24. package/esm2020/src/render3/instructions/element_validation.mjs +4 -1
  25. package/esm2020/src/render3/instructions/listener.mjs +34 -44
  26. package/esm2020/src/render3/instructions/lview_debug.mjs +1 -1
  27. package/esm2020/src/render3/instructions/shared.mjs +22 -59
  28. package/esm2020/src/render3/instructions/styling.mjs +2 -2
  29. package/esm2020/src/render3/interfaces/renderer.mjs +1 -17
  30. package/esm2020/src/render3/interfaces/view.mjs +1 -1
  31. package/esm2020/src/render3/jit/directive.mjs +20 -3
  32. package/esm2020/src/render3/ng_module_ref.mjs +13 -2
  33. package/esm2020/src/render3/node_manipulation.mjs +24 -87
  34. package/esm2020/src/render3/node_manipulation_i18n.mjs +1 -1
  35. package/esm2020/src/render3/util/attrs_utils.mjs +4 -12
  36. package/esm2020/src/render3/util/view_utils.mjs +3 -6
  37. package/esm2020/src/render3/view_ref.mjs +3 -5
  38. package/esm2020/src/sanitization/sanitization.mjs +4 -9
  39. package/esm2020/src/version.mjs +1 -1
  40. package/esm2020/src/zone/ng_zone.mjs +5 -4
  41. package/esm2020/testing/src/logger.mjs +3 -3
  42. package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
  43. package/esm2020/testing/src/r3_test_bed_compiler.mjs +30 -25
  44. package/fesm2015/core.mjs +1871 -2015
  45. package/fesm2015/core.mjs.map +1 -1
  46. package/fesm2015/testing.mjs +1601 -1837
  47. package/fesm2015/testing.mjs.map +1 -1
  48. package/fesm2020/core.mjs +1871 -2015
  49. package/fesm2020/core.mjs.map +1 -1
  50. package/fesm2020/testing.mjs +1601 -1837
  51. package/fesm2020/testing.mjs.map +1 -1
  52. package/index.d.ts +152 -134
  53. package/package.json +1 -1
  54. package/testing/index.d.ts +1 -1
  55. package/schematics/utils/schematics_prompt.d.ts +0 -17
  56. package/schematics/utils/schematics_prompt.js +0 -45
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v14.1.0-next.1
2
+ * @license Angular v14.1.0-next.4
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -863,6 +863,68 @@ const NG_INJ_DEF = getClosureSafeProperty({ ɵinj: getClosureSafeProperty });
863
863
  const NG_INJECTABLE_DEF = getClosureSafeProperty({ ngInjectableDef: getClosureSafeProperty });
864
864
  const NG_INJECTOR_DEF = getClosureSafeProperty({ ngInjectorDef: getClosureSafeProperty });
865
865
 
866
+ /**
867
+ * @license
868
+ * Copyright Google LLC All Rights Reserved.
869
+ *
870
+ * Use of this source code is governed by an MIT-style license that can be
871
+ * found in the LICENSE file at https://angular.io/license
872
+ */
873
+ /**
874
+ * Base URL for the error details page.
875
+ *
876
+ * Keep the files below in full sync:
877
+ * - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts
878
+ * - packages/core/src/error_details_base_url.ts
879
+ */
880
+ const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';
881
+
882
+ /**
883
+ * @license
884
+ * Copyright Google LLC All Rights Reserved.
885
+ *
886
+ * Use of this source code is governed by an MIT-style license that can be
887
+ * found in the LICENSE file at https://angular.io/license
888
+ */
889
+ /**
890
+ * Class that represents a runtime error.
891
+ * Formats and outputs the error message in a consistent way.
892
+ *
893
+ * Example:
894
+ * ```
895
+ * throw new RuntimeError(
896
+ * RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
897
+ * ngDevMode && 'Injector has already been destroyed.');
898
+ * ```
899
+ *
900
+ * Note: the `message` argument contains a descriptive error message as a string in development
901
+ * mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
902
+ * `message` argument becomes `false`, thus we account for it in the typings and the runtime logic.
903
+ */
904
+ class RuntimeError extends Error {
905
+ constructor(code, message) {
906
+ super(formatRuntimeError(code, message));
907
+ this.code = code;
908
+ }
909
+ }
910
+ /**
911
+ * Called to format a runtime error.
912
+ * See additional info on the `message` argument type in the `RuntimeError` class description.
913
+ */
914
+ function formatRuntimeError(code, message) {
915
+ // Error code might be a negative number, which is a special marker that instructs the logic to
916
+ // generate a link to the error details page on angular.io.
917
+ const fullCode = `NG0${Math.abs(code)}`;
918
+ let errorMessage = `${fullCode}${message ? ': ' + message.trim() : ''}`;
919
+ if (ngDevMode && code < 0) {
920
+ const addPeriodSeparator = !errorMessage.match(/[.,;!?]$/);
921
+ const separator = addPeriodSeparator ? '.' : '';
922
+ errorMessage =
923
+ `${errorMessage}${separator} Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;
924
+ }
925
+ return errorMessage;
926
+ }
927
+
866
928
  /**
867
929
  * @license
868
930
  * Copyright Google LLC All Rights Reserved.
@@ -1791,68 +1853,6 @@ function initNgDevMode() {
1791
1853
  return false;
1792
1854
  }
1793
1855
 
1794
- /**
1795
- * @license
1796
- * Copyright Google LLC All Rights Reserved.
1797
- *
1798
- * Use of this source code is governed by an MIT-style license that can be
1799
- * found in the LICENSE file at https://angular.io/license
1800
- */
1801
- /**
1802
- * Base URL for the error details page.
1803
- *
1804
- * Keep the files below in full sync:
1805
- * - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts
1806
- * - packages/core/src/error_details_base_url.ts
1807
- */
1808
- const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';
1809
-
1810
- /**
1811
- * @license
1812
- * Copyright Google LLC All Rights Reserved.
1813
- *
1814
- * Use of this source code is governed by an MIT-style license that can be
1815
- * found in the LICENSE file at https://angular.io/license
1816
- */
1817
- /**
1818
- * Class that represents a runtime error.
1819
- * Formats and outputs the error message in a consistent way.
1820
- *
1821
- * Example:
1822
- * ```
1823
- * throw new RuntimeError(
1824
- * RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
1825
- * ngDevMode && 'Injector has already been destroyed.');
1826
- * ```
1827
- *
1828
- * Note: the `message` argument contains a descriptive error message as a string in development
1829
- * mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
1830
- * `message` argument becomes `false`, thus we account for it in the typings and the runtime logic.
1831
- */
1832
- class RuntimeError extends Error {
1833
- constructor(code, message) {
1834
- super(formatRuntimeError(code, message));
1835
- this.code = code;
1836
- }
1837
- }
1838
- /**
1839
- * Called to format a runtime error.
1840
- * See additional info on the `message` argument type in the `RuntimeError` class description.
1841
- */
1842
- function formatRuntimeError(code, message) {
1843
- // Error code might be a negative number, which is a special marker that instructs the logic to
1844
- // generate a link to the error details page on angular.io.
1845
- const fullCode = `NG0${Math.abs(code)}`;
1846
- let errorMessage = `${fullCode}${message ? ': ' + message.trim() : ''}`;
1847
- if (ngDevMode && code < 0) {
1848
- const addPeriodSeparator = !errorMessage.match(/[.,;!?]$/);
1849
- const separator = addPeriodSeparator ? '.' : '';
1850
- errorMessage =
1851
- `${errorMessage}${separator} Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;
1852
- }
1853
- return errorMessage;
1854
- }
1855
-
1856
1856
  /**
1857
1857
  * @license
1858
1858
  * Copyright Google LLC All Rights Reserved.
@@ -1933,6 +1933,7 @@ function throwProviderNotFoundError(token, injectorName) {
1933
1933
  * Injection flags for DI.
1934
1934
  *
1935
1935
  * @publicApi
1936
+ * @deprecated use an options object for `inject` instead.
1936
1937
  */
1937
1938
  var InjectFlags;
1938
1939
  (function (InjectFlags) {
@@ -2046,10 +2047,8 @@ function setCurrentInjector(injector) {
2046
2047
  }
2047
2048
  function injectInjectorOnly(token, flags = InjectFlags.Default) {
2048
2049
  if (_currentInjector === undefined) {
2049
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
2050
- `inject() must be called from an injection context (a constructor, a factory function or a field initializer)` :
2051
- '';
2052
- throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, errorMessage);
2050
+ throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode &&
2051
+ `inject() must be called from an injection context (a constructor, a factory function or a field initializer)`);
2053
2052
  }
2054
2053
  else if (_currentInjector === null) {
2055
2054
  return injectRootLimpMode(token, undefined, flags);
@@ -2065,22 +2064,17 @@ function ɵɵinject(token, flags = InjectFlags.Default) {
2065
2064
  * Throws an error indicating that a factory function could not be generated by the compiler for a
2066
2065
  * particular class.
2067
2066
  *
2068
- * This instruction allows the actual error message to be optimized away when ngDevMode is turned
2069
- * off, saving bytes of generated code while still providing a good experience in dev mode.
2070
- *
2071
2067
  * The name of the class is not mentioned here, but will be in the generated factory function name
2072
2068
  * and thus in the stack trace.
2073
2069
  *
2074
2070
  * @codeGenApi
2075
2071
  */
2076
2072
  function ɵɵinvalidFactoryDep(index) {
2077
- const msg = ngDevMode ?
2073
+ throw new RuntimeError(202 /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */, ngDevMode &&
2078
2074
  `This constructor is not compatible with Angular Dependency Injection because its dependency at index ${index} of the parameter list is invalid.
2079
2075
  This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
2080
2076
 
2081
- Please check that 1) the type for the parameter at index ${index} is correct and 2) the correct Angular decorators are defined for this class and its ancestors.` :
2082
- 'invalid';
2083
- throw new Error(msg);
2077
+ Please check that 1) the type for the parameter at index ${index} is correct and 2) the correct Angular decorators are defined for this class and its ancestors.`);
2084
2078
  }
2085
2079
  /**
2086
2080
  * Injects a token from the currently active injector.
@@ -2147,6 +2141,16 @@ Please check that 1) the type for the parameter at index ${index} is correct and
2147
2141
  * @publicApi
2148
2142
  */
2149
2143
  function inject$1(token, flags = InjectFlags.Default) {
2144
+ if (typeof flags !== 'number') {
2145
+ // While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
2146
+ // JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
2147
+ // `InjectOptions` to `InjectFlags`.
2148
+ flags = (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
2149
+ (flags.optional && 8 /* InternalInjectFlags.Optional */) |
2150
+ (flags.host && 1 /* InternalInjectFlags.Host */) |
2151
+ (flags.self && 2 /* InternalInjectFlags.Self */) |
2152
+ (flags.skipSelf && 4 /* InternalInjectFlags.SkipSelf */));
2153
+ }
2150
2154
  return ɵɵinject(token, flags);
2151
2155
  }
2152
2156
  function injectArgs(types) {
@@ -2155,10 +2159,7 @@ function injectArgs(types) {
2155
2159
  const arg = resolveForwardRef(types[i]);
2156
2160
  if (Array.isArray(arg)) {
2157
2161
  if (arg.length === 0) {
2158
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
2159
- 'Arguments array must have arguments.' :
2160
- '';
2161
- throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, errorMessage);
2162
+ throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && 'Arguments array must have arguments.');
2162
2163
  }
2163
2164
  let type = undefined;
2164
2165
  let flags = InjectFlags.Default;
@@ -3193,87 +3194,6 @@ function getNamespaceUri(namespace) {
3193
3194
  (name === MATH_ML_NAMESPACE ? MATH_ML_NAMESPACE_URI : null);
3194
3195
  }
3195
3196
 
3196
- /**
3197
- * @license
3198
- * Copyright Google LLC All Rights Reserved.
3199
- *
3200
- * Use of this source code is governed by an MIT-style license that can be
3201
- * found in the LICENSE file at https://angular.io/license
3202
- */
3203
- /**
3204
- * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
3205
- * inject the `DOCUMENT` token and are done.
3206
- *
3207
- * Ivy is special because it does not rely upon the DI and must get hold of the document some other
3208
- * way.
3209
- *
3210
- * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
3211
- * Wherever ivy needs the global document, it calls `getDocument()` instead.
3212
- *
3213
- * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
3214
- * tell ivy what the global `document` is.
3215
- *
3216
- * Angular does this for us in each of the standard platforms (`Browser`, `Server`, and `WebWorker`)
3217
- * by calling `setDocument()` when providing the `DOCUMENT` token.
3218
- */
3219
- let DOCUMENT = undefined;
3220
- /**
3221
- * Tell ivy what the `document` is for this platform.
3222
- *
3223
- * It is only necessary to call this if the current platform is not a browser.
3224
- *
3225
- * @param document The object representing the global `document` in this environment.
3226
- */
3227
- function setDocument(document) {
3228
- DOCUMENT = document;
3229
- }
3230
- /**
3231
- * Access the object that represents the `document` for this platform.
3232
- *
3233
- * Ivy calls this whenever it needs to access the `document` object.
3234
- * For example to create the renderer or to do sanitization.
3235
- */
3236
- function getDocument() {
3237
- if (DOCUMENT !== undefined) {
3238
- return DOCUMENT;
3239
- }
3240
- else if (typeof document !== 'undefined') {
3241
- return document;
3242
- }
3243
- // No "document" can be found. This should only happen if we are running ivy outside Angular and
3244
- // the current platform is not a browser. Since this is not a supported scenario at the moment
3245
- // this should not happen in Angular apps.
3246
- // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
3247
- // public API. Meanwhile we just return `undefined` and let the application fail.
3248
- return undefined;
3249
- }
3250
-
3251
- /**
3252
- * @license
3253
- * Copyright Google LLC All Rights Reserved.
3254
- *
3255
- * Use of this source code is governed by an MIT-style license that can be
3256
- * found in the LICENSE file at https://angular.io/license
3257
- */
3258
- // TODO: cleanup once the code is merged in angular/angular
3259
- var RendererStyleFlags3;
3260
- (function (RendererStyleFlags3) {
3261
- RendererStyleFlags3[RendererStyleFlags3["Important"] = 1] = "Important";
3262
- RendererStyleFlags3[RendererStyleFlags3["DashCase"] = 2] = "DashCase";
3263
- })(RendererStyleFlags3 || (RendererStyleFlags3 = {}));
3264
- /** Returns whether the `renderer` is a `ProceduralRenderer3` */
3265
- function isProceduralRenderer(renderer) {
3266
- return !!(renderer.listen);
3267
- }
3268
- const domRendererFactory3 = {
3269
- createRenderer: (hostElement, rendererType) => {
3270
- return getDocument();
3271
- }
3272
- };
3273
- // Note: This hack is necessary so we don't erroneously get a circular dependency
3274
- // failure based on types.
3275
- const unusedValueExportToPlacateAjd$6 = 1;
3276
-
3277
3197
  /**
3278
3198
  * @license
3279
3199
  * Copyright Google LLC All Rights Reserved.
@@ -3356,7 +3276,6 @@ function getNativeByTNode(tNode, lView) {
3356
3276
  ngDevMode && assertTNodeForLView(tNode, lView);
3357
3277
  ngDevMode && assertIndexInRange(lView, tNode.index);
3358
3278
  const node = unwrapRNode(lView[tNode.index]);
3359
- ngDevMode && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
3360
3279
  return node;
3361
3280
  }
3362
3281
  /**
@@ -3372,7 +3291,6 @@ function getNativeByTNodeOrNull(tNode, lView) {
3372
3291
  if (index !== -1) {
3373
3292
  ngDevMode && assertTNodeForLView(tNode, lView);
3374
3293
  const node = unwrapRNode(lView[index]);
3375
- ngDevMode && node !== null && !isProceduralRenderer(lView[RENDERER]) && assertDomNode(node);
3376
3294
  return node;
3377
3295
  }
3378
3296
  return null;
@@ -4321,7 +4239,7 @@ function isFactory(obj) {
4321
4239
  }
4322
4240
  // Note: This hack is necessary so we don't erroneously get a circular dependency
4323
4241
  // failure based on types.
4324
- const unusedValueExportToPlacateAjd$5 = 1;
4242
+ const unusedValueExportToPlacateAjd$6 = 1;
4325
4243
 
4326
4244
  /**
4327
4245
  * Converts `TNodeType` into human readable text.
@@ -4340,7 +4258,7 @@ function toTNodeTypeAsString(tNodeType) {
4340
4258
  }
4341
4259
  // Note: This hack is necessary so we don't erroneously get a circular dependency
4342
4260
  // failure based on types.
4343
- const unusedValueExportToPlacateAjd$4 = 1;
4261
+ const unusedValueExportToPlacateAjd$5 = 1;
4344
4262
  /**
4345
4263
  * Returns `true` if the `TNode` has a directive which has `@Input()` for `class` binding.
4346
4264
  *
@@ -4444,7 +4362,6 @@ function assertPureTNodeType(type) {
4444
4362
  * @returns the index value that was last accessed in the attributes array
4445
4363
  */
4446
4364
  function setUpAttributes(renderer, native, attrs) {
4447
- const isProc = isProceduralRenderer(renderer);
4448
4365
  let i = 0;
4449
4366
  while (i < attrs.length) {
4450
4367
  const value = attrs[i];
@@ -4461,9 +4378,7 @@ function setUpAttributes(renderer, native, attrs) {
4461
4378
  const attrName = attrs[i++];
4462
4379
  const attrVal = attrs[i++];
4463
4380
  ngDevMode && ngDevMode.rendererSetAttribute++;
4464
- isProc ?
4465
- renderer.setAttribute(native, attrName, attrVal, namespaceURI) :
4466
- native.setAttributeNS(namespaceURI, attrName, attrVal);
4381
+ renderer.setAttribute(native, attrName, attrVal, namespaceURI);
4467
4382
  }
4468
4383
  else {
4469
4384
  // attrName is string;
@@ -4472,14 +4387,10 @@ function setUpAttributes(renderer, native, attrs) {
4472
4387
  // Standard attributes
4473
4388
  ngDevMode && ngDevMode.rendererSetAttribute++;
4474
4389
  if (isAnimationProp(attrName)) {
4475
- if (isProc) {
4476
- renderer.setProperty(native, attrName, attrVal);
4477
- }
4390
+ renderer.setProperty(native, attrName, attrVal);
4478
4391
  }
4479
4392
  else {
4480
- isProc ?
4481
- renderer.setAttribute(native, attrName, attrVal) :
4482
- native.setAttribute(attrName, attrVal);
4393
+ renderer.setAttribute(native, attrName, attrVal);
4483
4394
  }
4484
4395
  i++;
4485
4396
  }
@@ -5481,7 +5392,7 @@ function reflectDependency(dep) {
5481
5392
  }
5482
5393
  else if (param instanceof Attribute) {
5483
5394
  if (param.attributeName === undefined) {
5484
- throw new Error(`Attribute name must be defined.`);
5395
+ throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, ngDevMode && `Attribute name must be defined.`);
5485
5396
  }
5486
5397
  meta.attribute = param.attributeName;
5487
5398
  }
@@ -5621,42 +5532,97 @@ function maybeUnwrapFn$1(value) {
5621
5532
  * found in the LICENSE file at https://angular.io/license
5622
5533
  */
5623
5534
  /**
5624
- * The Trusted Types policy, or null if Trusted Types are not
5625
- * enabled/supported, or undefined if the policy has not been created yet.
5535
+ * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
5536
+ * inject the `DOCUMENT` token and are done.
5537
+ *
5538
+ * Ivy is special because it does not rely upon the DI and must get hold of the document some other
5539
+ * way.
5540
+ *
5541
+ * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
5542
+ * Wherever ivy needs the global document, it calls `getDocument()` instead.
5543
+ *
5544
+ * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
5545
+ * tell ivy what the global `document` is.
5546
+ *
5547
+ * Angular does this for us in each of the standard platforms (`Browser`, `Server`, and `WebWorker`)
5548
+ * by calling `setDocument()` when providing the `DOCUMENT` token.
5626
5549
  */
5627
- let policy$1;
5550
+ let DOCUMENT = undefined;
5628
5551
  /**
5629
- * Returns the Trusted Types policy, or null if Trusted Types are not
5630
- * enabled/supported. The first call to this function will create the policy.
5552
+ * Tell ivy what the `document` is for this platform.
5553
+ *
5554
+ * It is only necessary to call this if the current platform is not a browser.
5555
+ *
5556
+ * @param document The object representing the global `document` in this environment.
5631
5557
  */
5632
- function getPolicy$1() {
5633
- if (policy$1 === undefined) {
5634
- policy$1 = null;
5635
- if (_global$1.trustedTypes) {
5636
- try {
5637
- policy$1 = _global$1.trustedTypes.createPolicy('angular', {
5638
- createHTML: (s) => s,
5639
- createScript: (s) => s,
5640
- createScriptURL: (s) => s,
5641
- });
5642
- }
5643
- catch (_a) {
5644
- // trustedTypes.createPolicy throws if called with a name that is
5645
- // already registered, even in report-only mode. Until the API changes,
5646
- // catch the error not to break the applications functionally. In such
5647
- // cases, the code will fall back to using strings.
5648
- }
5649
- }
5650
- }
5651
- return policy$1;
5558
+ function setDocument(document) {
5559
+ DOCUMENT = document;
5652
5560
  }
5653
5561
  /**
5654
- * Unsafely promote a string to a TrustedHTML, falling back to strings when
5655
- * Trusted Types are not available.
5656
- * @security This is a security-sensitive function; any use of this function
5657
- * must go through security review. In particular, it must be assured that the
5658
- * provided string will never cause an XSS vulnerability if used in a context
5659
- * that will be interpreted as HTML by a browser, e.g. when assigning to
5562
+ * Access the object that represents the `document` for this platform.
5563
+ *
5564
+ * Ivy calls this whenever it needs to access the `document` object.
5565
+ * For example to create the renderer or to do sanitization.
5566
+ */
5567
+ function getDocument() {
5568
+ if (DOCUMENT !== undefined) {
5569
+ return DOCUMENT;
5570
+ }
5571
+ else if (typeof document !== 'undefined') {
5572
+ return document;
5573
+ }
5574
+ // No "document" can be found. This should only happen if we are running ivy outside Angular and
5575
+ // the current platform is not a browser. Since this is not a supported scenario at the moment
5576
+ // this should not happen in Angular apps.
5577
+ // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
5578
+ // public API. Meanwhile we just return `undefined` and let the application fail.
5579
+ return undefined;
5580
+ }
5581
+
5582
+ /**
5583
+ * @license
5584
+ * Copyright Google LLC All Rights Reserved.
5585
+ *
5586
+ * Use of this source code is governed by an MIT-style license that can be
5587
+ * found in the LICENSE file at https://angular.io/license
5588
+ */
5589
+ /**
5590
+ * The Trusted Types policy, or null if Trusted Types are not
5591
+ * enabled/supported, or undefined if the policy has not been created yet.
5592
+ */
5593
+ let policy$1;
5594
+ /**
5595
+ * Returns the Trusted Types policy, or null if Trusted Types are not
5596
+ * enabled/supported. The first call to this function will create the policy.
5597
+ */
5598
+ function getPolicy$1() {
5599
+ if (policy$1 === undefined) {
5600
+ policy$1 = null;
5601
+ if (_global$1.trustedTypes) {
5602
+ try {
5603
+ policy$1 = _global$1.trustedTypes.createPolicy('angular', {
5604
+ createHTML: (s) => s,
5605
+ createScript: (s) => s,
5606
+ createScriptURL: (s) => s,
5607
+ });
5608
+ }
5609
+ catch (_a) {
5610
+ // trustedTypes.createPolicy throws if called with a name that is
5611
+ // already registered, even in report-only mode. Until the API changes,
5612
+ // catch the error not to break the applications functionally. In such
5613
+ // cases, the code will fall back to using strings.
5614
+ }
5615
+ }
5616
+ }
5617
+ return policy$1;
5618
+ }
5619
+ /**
5620
+ * Unsafely promote a string to a TrustedHTML, falling back to strings when
5621
+ * Trusted Types are not available.
5622
+ * @security This is a security-sensitive function; any use of this function
5623
+ * must go through security review. In particular, it must be assured that the
5624
+ * provided string will never cause an XSS vulnerability if used in a context
5625
+ * that will be interpreted as HTML by a browser, e.g. when assigning to
5660
5626
  * element.innerHTML.
5661
5627
  */
5662
5628
  function trustedHTMLFromString(html) {
@@ -6489,10 +6455,8 @@ function ɵɵsanitizeResourceUrl(unsafeResourceUrl) {
6489
6455
  if (allowSanitizationBypassAndThrow(unsafeResourceUrl, "ResourceURL" /* BypassType.ResourceUrl */)) {
6490
6456
  return trustedScriptURLFromStringBypass(unwrapSafeValue(unsafeResourceUrl));
6491
6457
  }
6492
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
6493
- 'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)' :
6494
- '';
6495
- throw new RuntimeError(904 /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */, errorMessage);
6458
+ throw new RuntimeError(904 /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */, ngDevMode &&
6459
+ 'unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');
6496
6460
  }
6497
6461
  /**
6498
6462
  * A `script` sanitizer which only lets trusted javascript through.
@@ -6514,10 +6478,7 @@ function ɵɵsanitizeScript(unsafeScript) {
6514
6478
  if (allowSanitizationBypassAndThrow(unsafeScript, "Script" /* BypassType.Script */)) {
6515
6479
  return trustedScriptFromStringBypass(unwrapSafeValue(unsafeScript));
6516
6480
  }
6517
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
6518
- 'unsafe value used in a script context' :
6519
- '';
6520
- throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, errorMessage);
6481
+ throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, ngDevMode && 'unsafe value used in a script context');
6521
6482
  }
6522
6483
  /**
6523
6484
  * A template tag function for promoting the associated constant literal to a
@@ -7293,6 +7254,17 @@ function ensureIcuContainerVisitorLoaded(loader) {
7293
7254
  }
7294
7255
  }
7295
7256
 
7257
+ /**
7258
+ * @license
7259
+ * Copyright Google LLC All Rights Reserved.
7260
+ *
7261
+ * Use of this source code is governed by an MIT-style license that can be
7262
+ * found in the LICENSE file at https://angular.io/license
7263
+ */
7264
+ // Note: This hack is necessary so we don't erroneously get a circular dependency
7265
+ // failure based on types.
7266
+ const unusedValueExportToPlacateAjd$4 = 1;
7267
+
7296
7268
  /**
7297
7269
  * @license
7298
7270
  * Copyright Google LLC All Rights Reserved.
@@ -7375,7 +7347,7 @@ function getNearestLContainer(viewOrContainer) {
7375
7347
  * Use of this source code is governed by an MIT-style license that can be
7376
7348
  * found in the LICENSE file at https://angular.io/license
7377
7349
  */
7378
- const unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$8 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$6 + unusedValueExportToPlacateAjd$7;
7350
+ const unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$8 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd$7;
7379
7351
  /**
7380
7352
  * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7381
7353
  * being passed as an argument.
@@ -7400,7 +7372,6 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7400
7372
  lNodeToHandle = lNodeToHandle[HOST];
7401
7373
  }
7402
7374
  const rNode = unwrapRNode(lNodeToHandle);
7403
- ngDevMode && !isProceduralRenderer(renderer) && assertDomNode(rNode);
7404
7375
  if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
7405
7376
  if (beforeNode == null) {
7406
7377
  nativeAppendChild(renderer, parent, rNode);
@@ -7427,17 +7398,14 @@ function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, befo
7427
7398
  function createTextNode(renderer, value) {
7428
7399
  ngDevMode && ngDevMode.rendererCreateTextNode++;
7429
7400
  ngDevMode && ngDevMode.rendererSetText++;
7430
- return isProceduralRenderer(renderer) ? renderer.createText(value) :
7431
- renderer.createTextNode(value);
7401
+ return renderer.createText(value);
7432
7402
  }
7433
7403
  function updateTextNode(renderer, rNode, value) {
7434
7404
  ngDevMode && ngDevMode.rendererSetText++;
7435
- isProceduralRenderer(renderer) ? renderer.setValue(rNode, value) : rNode.textContent = value;
7405
+ renderer.setValue(rNode, value);
7436
7406
  }
7437
7407
  function createCommentNode(renderer, value) {
7438
7408
  ngDevMode && ngDevMode.rendererCreateComment++;
7439
- // isProceduralRenderer check is not needed because both `Renderer2` and `Renderer3` have the same
7440
- // method name.
7441
7409
  return renderer.createComment(escapeCommentText(value));
7442
7410
  }
7443
7411
  /**
@@ -7449,14 +7417,7 @@ function createCommentNode(renderer, value) {
7449
7417
  */
7450
7418
  function createElementNode(renderer, name, namespace) {
7451
7419
  ngDevMode && ngDevMode.rendererCreateElement++;
7452
- if (isProceduralRenderer(renderer)) {
7453
- return renderer.createElement(name, namespace);
7454
- }
7455
- else {
7456
- const namespaceUri = namespace !== null ? getNamespaceUri(namespace) : null;
7457
- return namespaceUri === null ? renderer.createElement(name) :
7458
- renderer.createElementNS(namespaceUri, name);
7459
- }
7420
+ return renderer.createElement(name, namespace);
7460
7421
  }
7461
7422
  /**
7462
7423
  * Removes all DOM elements associated with a view.
@@ -7688,7 +7649,7 @@ function detachView(lContainer, removeIndex) {
7688
7649
  function destroyLView(tView, lView) {
7689
7650
  if (!(lView[FLAGS] & 128 /* LViewFlags.Destroyed */)) {
7690
7651
  const renderer = lView[RENDERER];
7691
- if (isProceduralRenderer(renderer) && renderer.destroyNode) {
7652
+ if (renderer.destroyNode) {
7692
7653
  applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
7693
7654
  }
7694
7655
  destroyViewTree(lView);
@@ -7716,7 +7677,7 @@ function cleanUpView(tView, lView) {
7716
7677
  executeOnDestroys(tView, lView);
7717
7678
  processCleanups(tView, lView);
7718
7679
  // For component views only, the local renderer is destroyed at clean up time.
7719
- if (lView[TVIEW].type === 1 /* TViewType.Component */ && isProceduralRenderer(lView[RENDERER])) {
7680
+ if (lView[TVIEW].type === 1 /* TViewType.Component */) {
7720
7681
  ngDevMode && ngDevMode.rendererDestroy++;
7721
7682
  lView[RENDERER].destroy();
7722
7683
  }
@@ -7892,30 +7853,17 @@ function getClosestRElement(tView, tNode, lView) {
7892
7853
  }
7893
7854
  }
7894
7855
  /**
7895
- * Inserts a native node before another native node for a given parent using {@link Renderer3}.
7896
- * This is a utility function that can be used when native nodes were determined - it abstracts an
7897
- * actual renderer being used.
7856
+ * Inserts a native node before another native node for a given parent.
7857
+ * This is a utility function that can be used when native nodes were determined.
7898
7858
  */
7899
7859
  function nativeInsertBefore(renderer, parent, child, beforeNode, isMove) {
7900
7860
  ngDevMode && ngDevMode.rendererInsertBefore++;
7901
- if (isProceduralRenderer(renderer)) {
7902
- renderer.insertBefore(parent, child, beforeNode, isMove);
7903
- }
7904
- else {
7905
- const targetParent = isTemplateNode(parent) ? parent.content : parent;
7906
- targetParent.insertBefore(child, beforeNode, isMove);
7907
- }
7861
+ renderer.insertBefore(parent, child, beforeNode, isMove);
7908
7862
  }
7909
7863
  function nativeAppendChild(renderer, parent, child) {
7910
7864
  ngDevMode && ngDevMode.rendererAppendChild++;
7911
7865
  ngDevMode && assertDefined(parent, 'parent node must be defined');
7912
- if (isProceduralRenderer(renderer)) {
7913
- renderer.appendChild(parent, child);
7914
- }
7915
- else {
7916
- const targetParent = isTemplateNode(parent) ? parent.content : parent;
7917
- targetParent.appendChild(child);
7918
- }
7866
+ renderer.appendChild(parent, child);
7919
7867
  }
7920
7868
  function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove) {
7921
7869
  if (beforeNode !== null) {
@@ -7927,12 +7875,7 @@ function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove)
7927
7875
  }
7928
7876
  /** Removes a node from the DOM given its native parent. */
7929
7877
  function nativeRemoveChild(renderer, parent, child, isHostElement) {
7930
- if (isProceduralRenderer(renderer)) {
7931
- renderer.removeChild(parent, child, isHostElement);
7932
- }
7933
- else {
7934
- parent.removeChild(child);
7935
- }
7878
+ renderer.removeChild(parent, child, isHostElement);
7936
7879
  }
7937
7880
  /** Checks if an element is a `<template>` node. */
7938
7881
  function isTemplateNode(node) {
@@ -7942,13 +7885,13 @@ function isTemplateNode(node) {
7942
7885
  * Returns a native parent of a given native node.
7943
7886
  */
7944
7887
  function nativeParentNode(renderer, node) {
7945
- return (isProceduralRenderer(renderer) ? renderer.parentNode(node) : node.parentNode);
7888
+ return renderer.parentNode(node);
7946
7889
  }
7947
7890
  /**
7948
7891
  * Returns a native sibling of a given native node.
7949
7892
  */
7950
7893
  function nativeNextSibling(renderer, node) {
7951
- return isProceduralRenderer(renderer) ? renderer.nextSibling(node) : node.nextSibling;
7894
+ return renderer.nextSibling(node);
7952
7895
  }
7953
7896
  /**
7954
7897
  * Find a node in front of which `currentTNode` should be inserted.
@@ -8257,39 +8200,22 @@ function applyContainer(renderer, action, lContainer, parentRElement, beforeNode
8257
8200
  * otherwise).
8258
8201
  */
8259
8202
  function applyStyling(renderer, isClassBased, rNode, prop, value) {
8260
- const isProcedural = isProceduralRenderer(renderer);
8261
8203
  if (isClassBased) {
8262
8204
  // We actually want JS true/false here because any truthy value should add the class
8263
8205
  if (!value) {
8264
8206
  ngDevMode && ngDevMode.rendererRemoveClass++;
8265
- if (isProcedural) {
8266
- renderer.removeClass(rNode, prop);
8267
- }
8268
- else {
8269
- rNode.classList.remove(prop);
8270
- }
8207
+ renderer.removeClass(rNode, prop);
8271
8208
  }
8272
8209
  else {
8273
8210
  ngDevMode && ngDevMode.rendererAddClass++;
8274
- if (isProcedural) {
8275
- renderer.addClass(rNode, prop);
8276
- }
8277
- else {
8278
- ngDevMode && assertDefined(rNode.classList, 'HTMLElement expected');
8279
- rNode.classList.add(prop);
8280
- }
8211
+ renderer.addClass(rNode, prop);
8281
8212
  }
8282
8213
  }
8283
8214
  else {
8284
8215
  let flags = prop.indexOf('-') === -1 ? undefined : RendererStyleFlags2.DashCase;
8285
8216
  if (value == null /** || value === undefined */) {
8286
8217
  ngDevMode && ngDevMode.rendererRemoveStyle++;
8287
- if (isProcedural) {
8288
- renderer.removeStyle(rNode, prop, flags);
8289
- }
8290
- else {
8291
- rNode.style.removeProperty(prop);
8292
- }
8218
+ renderer.removeStyle(rNode, prop, flags);
8293
8219
  }
8294
8220
  else {
8295
8221
  // A value is important if it ends with `!important`. The style
@@ -8301,13 +8227,7 @@ function applyStyling(renderer, isClassBased, rNode, prop, value) {
8301
8227
  flags |= RendererStyleFlags2.Important;
8302
8228
  }
8303
8229
  ngDevMode && ngDevMode.rendererSetStyle++;
8304
- if (isProcedural) {
8305
- renderer.setStyle(rNode, prop, value, flags);
8306
- }
8307
- else {
8308
- ngDevMode && assertDefined(rNode.style, 'HTMLElement expected');
8309
- rNode.style.setProperty(prop, value, isImportant ? 'important' : '');
8310
- }
8230
+ renderer.setStyle(rNode, prop, value, flags);
8311
8231
  }
8312
8232
  }
8313
8233
  }
@@ -8323,12 +8243,7 @@ function applyStyling(renderer, isClassBased, rNode, prop, value) {
8323
8243
  */
8324
8244
  function writeDirectStyle(renderer, element, newValue) {
8325
8245
  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
8326
- if (isProceduralRenderer(renderer)) {
8327
- renderer.setAttribute(element, 'style', newValue);
8328
- }
8329
- else {
8330
- element.style.cssText = newValue;
8331
- }
8246
+ renderer.setAttribute(element, 'style', newValue);
8332
8247
  ngDevMode && ngDevMode.rendererSetStyle++;
8333
8248
  }
8334
8249
  /**
@@ -8343,17 +8258,12 @@ function writeDirectStyle(renderer, element, newValue) {
8343
8258
  */
8344
8259
  function writeDirectClass(renderer, element, newValue) {
8345
8260
  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
8346
- if (isProceduralRenderer(renderer)) {
8347
- if (newValue === '') {
8348
- // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
8349
- renderer.removeAttribute(element, 'class');
8350
- }
8351
- else {
8352
- renderer.setAttribute(element, 'class', newValue);
8353
- }
8261
+ if (newValue === '') {
8262
+ // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
8263
+ renderer.removeAttribute(element, 'class');
8354
8264
  }
8355
8265
  else {
8356
- element.className = newValue;
8266
+ renderer.setAttribute(element, 'class', newValue);
8357
8267
  }
8358
8268
  ngDevMode && ngDevMode.rendererSetClassName++;
8359
8269
  }
@@ -8403,7 +8313,7 @@ function classIndexOf(className, classToSearch, startingIndex) {
8403
8313
  * Use of this source code is governed by an MIT-style license that can be
8404
8314
  * found in the LICENSE file at https://angular.io/license
8405
8315
  */
8406
- const unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$3;
8316
+ const unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4;
8407
8317
  const NG_TEMPLATE_SELECTOR = 'ng-template';
8408
8318
  /**
8409
8319
  * Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)
@@ -9518,6 +9428,18 @@ class R3Injector extends EnvironmentInjector {
9518
9428
  onDestroy(callback) {
9519
9429
  this._onDestroyHooks.push(callback);
9520
9430
  }
9431
+ runInContext(fn) {
9432
+ this.assertNotDestroyed();
9433
+ const previousInjector = setCurrentInjector(this);
9434
+ const previousInjectImplementation = setInjectImplementation(undefined);
9435
+ try {
9436
+ return fn();
9437
+ }
9438
+ finally {
9439
+ setCurrentInjector(previousInjector);
9440
+ setInjectImplementation(previousInjectImplementation);
9441
+ }
9442
+ }
9521
9443
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
9522
9444
  this.assertNotDestroyed();
9523
9445
  // Set the injection context.
@@ -10129,7 +10051,7 @@ class ReflectiveKey {
10129
10051
  this.token = token;
10130
10052
  this.id = id;
10131
10053
  if (!token) {
10132
- throw new Error('Token must be defined!');
10054
+ throw new RuntimeError(208 /* RuntimeErrorCode.MISSING_INJECTION_TOKEN */, ngDevMode && 'Token must be defined!');
10133
10055
  }
10134
10056
  this.displayName = stringify(this.token);
10135
10057
  }
@@ -10933,6 +10855,9 @@ function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
10933
10855
  `the ${schemas} of this component.`;
10934
10856
  }
10935
10857
  }
10858
+ reportUnknownPropertyError(message);
10859
+ }
10860
+ function reportUnknownPropertyError(message) {
10936
10861
  if (shouldThrowErrorOnUnknownProperty) {
10937
10862
  throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
10938
10863
  }
@@ -11820,6 +11745,13 @@ class LContainerDebug {
11820
11745
  }
11821
11746
  }
11822
11747
 
11748
+ /**
11749
+ * @license
11750
+ * Copyright Google LLC All Rights Reserved.
11751
+ *
11752
+ * Use of this source code is governed by an MIT-style license that can be
11753
+ * found in the LICENSE file at https://angular.io/license
11754
+ */
11823
11755
  /**
11824
11756
  * A permanent marker promise which signifies that the current CD tree is
11825
11757
  * clean.
@@ -11887,7 +11819,7 @@ function refreshChildComponents(hostLView, components) {
11887
11819
  /** Renders child components in the current view (creation mode). */
11888
11820
  function renderChildComponents(hostLView, components) {
11889
11821
  for (let i = 0; i < components.length; i++) {
11890
- renderComponent$1(hostLView, components[i]);
11822
+ renderComponent(hostLView, components[i]);
11891
11823
  }
11892
11824
  }
11893
11825
  function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector, embeddedViewInjector) {
@@ -12405,16 +12337,6 @@ function createViewBlueprint(bindingStartIndex, initialViewLength) {
12405
12337
  function createError(text, token) {
12406
12338
  return new Error(`Renderer: ${text} [${stringifyForError(token)}]`);
12407
12339
  }
12408
- function assertHostNodeExists(rElement, elementOrSelector) {
12409
- if (!rElement) {
12410
- if (typeof elementOrSelector === 'string') {
12411
- throw createError('Host node with selector not found:', elementOrSelector);
12412
- }
12413
- else {
12414
- throw createError('Host node is required:', elementOrSelector);
12415
- }
12416
- }
12417
- }
12418
12340
  /**
12419
12341
  * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
12420
12342
  *
@@ -12423,21 +12345,9 @@ function assertHostNodeExists(rElement, elementOrSelector) {
12423
12345
  * @param encapsulation View Encapsulation defined for component that requests host element.
12424
12346
  */
12425
12347
  function locateHostElement(renderer, elementOrSelector, encapsulation) {
12426
- if (isProceduralRenderer(renderer)) {
12427
- // When using native Shadow DOM, do not clear host element to allow native slot projection
12428
- const preserveContent = encapsulation === ViewEncapsulation.ShadowDom;
12429
- return renderer.selectRootElement(elementOrSelector, preserveContent);
12430
- }
12431
- let rElement = typeof elementOrSelector === 'string' ?
12432
- renderer.querySelector(elementOrSelector) :
12433
- elementOrSelector;
12434
- ngDevMode && assertHostNodeExists(rElement, elementOrSelector);
12435
- // Always clear host element's content when Renderer3 is in use. For procedural renderer case we
12436
- // make it depend on whether ShadowDom encapsulation is used (in which case the content should be
12437
- // preserved to allow native slot projection). ShadowDom encapsulation requires procedural
12438
- // renderer, and procedural renderer case is handled above.
12439
- rElement.textContent = '';
12440
- return rElement;
12348
+ // When using native Shadow DOM, do not clear host element to allow native slot projection
12349
+ const preserveContent = encapsulation === ViewEncapsulation.ShadowDom;
12350
+ return renderer.selectRootElement(elementOrSelector, preserveContent);
12441
12351
  }
12442
12352
  /**
12443
12353
  * Saves context for this cleanup function in LView.cleanupInstances.
@@ -12652,13 +12562,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
12652
12562
  // It is assumed that the sanitizer is only added when the compiler determines that the
12653
12563
  // property is risky, so sanitization can be done without further checks.
12654
12564
  value = sanitizer != null ? sanitizer(value, tNode.value || '', propName) : value;
12655
- if (isProceduralRenderer(renderer)) {
12656
- renderer.setProperty(element, propName, value);
12657
- }
12658
- else if (!isAnimationProp(propName)) {
12659
- element.setProperty ? element.setProperty(propName, value) :
12660
- element[propName] = value;
12661
- }
12565
+ renderer.setProperty(element, propName, value);
12662
12566
  }
12663
12567
  else if (tNode.type & 12 /* TNodeType.AnyContainer */) {
12664
12568
  // If the node is a container and the property didn't
@@ -12682,23 +12586,15 @@ function setNgReflectProperty(lView, element, type, attrName, value) {
12682
12586
  const debugValue = normalizeDebugBindingValue(value);
12683
12587
  if (type & 3 /* TNodeType.AnyRNode */) {
12684
12588
  if (value == null) {
12685
- isProceduralRenderer(renderer) ? renderer.removeAttribute(element, attrName) :
12686
- element.removeAttribute(attrName);
12589
+ renderer.removeAttribute(element, attrName);
12687
12590
  }
12688
12591
  else {
12689
- isProceduralRenderer(renderer) ?
12690
- renderer.setAttribute(element, attrName, debugValue) :
12691
- element.setAttribute(attrName, debugValue);
12592
+ renderer.setAttribute(element, attrName, debugValue);
12692
12593
  }
12693
12594
  }
12694
12595
  else {
12695
12596
  const textContent = escapeCommentText(`bindings=${JSON.stringify({ [attrName]: debugValue }, null, 2)}`);
12696
- if (isProceduralRenderer(renderer)) {
12697
- renderer.setValue(element, textContent);
12698
- }
12699
- else {
12700
- element.textContent = textContent;
12701
- }
12597
+ renderer.setValue(element, textContent);
12702
12598
  }
12703
12599
  }
12704
12600
  function setNgReflectProperties(lView, element, type, dataValue, value) {
@@ -12728,6 +12624,7 @@ function instantiateRootComponent(tView, lView, def) {
12728
12624
  ngDevMode &&
12729
12625
  assertEqual(directiveIndex, rootTNode.directiveStart, 'Because this is a root component the allocated expando should match the TNode component.');
12730
12626
  configureViewWithDirective(tView, rootTNode, lView, directiveIndex, def);
12627
+ initializeInputAndOutputAliases(tView, rootTNode);
12731
12628
  }
12732
12629
  const directive = getNodeInjectable(lView, tView, rootTNode.directiveStart, rootTNode);
12733
12630
  attachPatchData(directive, lView);
@@ -13052,19 +12949,12 @@ function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespac
13052
12949
  function setElementAttribute(renderer, element, namespace, tagName, name, value, sanitizer) {
13053
12950
  if (value == null) {
13054
12951
  ngDevMode && ngDevMode.rendererRemoveAttribute++;
13055
- isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
13056
- element.removeAttribute(name);
12952
+ renderer.removeAttribute(element, name, namespace);
13057
12953
  }
13058
12954
  else {
13059
12955
  ngDevMode && ngDevMode.rendererSetAttribute++;
13060
12956
  const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tagName || '', name);
13061
- if (isProceduralRenderer(renderer)) {
13062
- renderer.setAttribute(element, name, strValue, namespace);
13063
- }
13064
- else {
13065
- namespace ? element.setAttributeNS(namespace, name, strValue) :
13066
- element.setAttribute(name, strValue);
13067
- }
12957
+ renderer.setAttribute(element, name, strValue, namespace);
13068
12958
  }
13069
12959
  }
13070
12960
  /**
@@ -13156,7 +13046,6 @@ const LContainerArray = class LContainer extends Array {
13156
13046
  */
13157
13047
  function createLContainer(hostNative, currentView, native, tNode) {
13158
13048
  ngDevMode && assertLView(currentView);
13159
- ngDevMode && !isProceduralRenderer(currentView[RENDERER]) && assertDomNode(native);
13160
13049
  // https://jsperf.com/array-literal-vs-new-array-really
13161
13050
  const lContainer = new (ngDevMode ? LContainerArray : Array)(hostNative, // host native
13162
13051
  true, // Boolean `true` in this position signifies that this is an `LContainer`
@@ -13272,7 +13161,7 @@ function refreshContainsDirtyView(lView) {
13272
13161
  }
13273
13162
  }
13274
13163
  }
13275
- function renderComponent$1(hostLView, componentHostIdx) {
13164
+ function renderComponent(hostLView, componentHostIdx) {
13276
13165
  ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
13277
13166
  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
13278
13167
  const componentTView = componentView[TVIEW];
@@ -13624,48 +13513,135 @@ function computeStaticStyling(tNode, attrs, writeToHost) {
13624
13513
  * Use of this source code is governed by an MIT-style license that can be
13625
13514
  * found in the LICENSE file at https://angular.io/license
13626
13515
  */
13516
+ // TODO: A hack to not pull in the NullInjector from @angular/core.
13517
+ const NULL_INJECTOR = {
13518
+ get: (token, notFoundValue) => {
13519
+ throwProviderNotFoundError(token, 'NullInjector');
13520
+ }
13521
+ };
13627
13522
  /**
13628
- * Synchronously perform change detection on a component (and possibly its sub-components).
13523
+ * Creates the root component view and the root component node.
13629
13524
  *
13630
- * This function triggers change detection in a synchronous way on a component.
13525
+ * @param rNode Render host element.
13526
+ * @param def ComponentDef
13527
+ * @param rootView The parent view where the host node is stored
13528
+ * @param rendererFactory Factory to be used for creating child renderers.
13529
+ * @param hostRenderer The current renderer
13530
+ * @param sanitizer The sanitizer, if provided
13631
13531
  *
13632
- * @param component The component which the change detection should be performed on.
13532
+ * @returns Component view created
13633
13533
  */
13634
- function detectChanges(component) {
13635
- const view = getComponentViewByInstance(component);
13636
- detectChangesInternal(view[TVIEW], view, component);
13534
+ function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
13535
+ const tView = rootView[TVIEW];
13536
+ const index = HEADER_OFFSET;
13537
+ ngDevMode && assertIndexInRange(rootView, index);
13538
+ rootView[index] = rNode;
13539
+ // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
13540
+ // the same time we want to communicate the debug `TNode` that this is a special `TNode`
13541
+ // representing a host element.
13542
+ const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
13543
+ const mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
13544
+ if (mergedAttrs !== null) {
13545
+ computeStaticStyling(tNode, mergedAttrs, true);
13546
+ if (rNode !== null) {
13547
+ setUpAttributes(hostRenderer, rNode, mergedAttrs);
13548
+ if (tNode.classes !== null) {
13549
+ writeDirectClass(hostRenderer, rNode, tNode.classes);
13550
+ }
13551
+ if (tNode.styles !== null) {
13552
+ writeDirectStyle(hostRenderer, rNode, tNode.styles);
13553
+ }
13554
+ }
13555
+ }
13556
+ const viewRenderer = rendererFactory.createRenderer(rNode, def);
13557
+ const componentView = createLView(rootView, getOrCreateTComponentView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
13558
+ if (tView.firstCreatePass) {
13559
+ diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
13560
+ markAsComponentHost(tView, tNode);
13561
+ initTNodeFlags(tNode, rootView.length, 1);
13562
+ }
13563
+ addToViewTree(rootView, componentView);
13564
+ // Store component view at node index, with node as the HOST
13565
+ return rootView[index] = componentView;
13637
13566
  }
13638
13567
  /**
13639
- * Marks the component as dirty (needing change detection). Marking a component dirty will
13640
- * schedule a change detection on it at some point in the future.
13641
- *
13642
- * Marking an already dirty component as dirty won't do anything. Only one outstanding change
13643
- * detection can be scheduled per component tree.
13644
- *
13645
- * @param component Component to mark as dirty.
13568
+ * Creates a root component and sets it up with features and host bindings. Shared by
13569
+ * renderComponent() and ViewContainerRef.createComponent().
13646
13570
  */
13647
- function markDirty(component) {
13648
- ngDevMode && assertDefined(component, 'component');
13649
- const rootView = markViewDirty(getComponentViewByInstance(component));
13650
- ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
13651
- scheduleTick(rootView[CONTEXT], 1 /* RootContextFlags.DetectChanges */);
13571
+ function createRootComponent(componentView, componentDef, rootLView, rootContext, hostFeatures) {
13572
+ const tView = rootLView[TVIEW];
13573
+ // Create directive instance with factory() and store at next index in viewData
13574
+ const component = instantiateRootComponent(tView, rootLView, componentDef);
13575
+ rootContext.components.push(component);
13576
+ componentView[CONTEXT] = component;
13577
+ if (hostFeatures !== null) {
13578
+ for (const feature of hostFeatures) {
13579
+ feature(component, componentDef);
13580
+ }
13581
+ }
13582
+ // We want to generate an empty QueryList for root content queries for backwards
13583
+ // compatibility with ViewEngine.
13584
+ if (componentDef.contentQueries) {
13585
+ const tNode = getCurrentTNode();
13586
+ ngDevMode && assertDefined(tNode, 'TNode expected');
13587
+ componentDef.contentQueries(1 /* RenderFlags.Create */, component, tNode.directiveStart);
13588
+ }
13589
+ const rootTNode = getCurrentTNode();
13590
+ ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
13591
+ if (tView.firstCreatePass &&
13592
+ (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
13593
+ setSelectedIndex(rootTNode.index);
13594
+ const rootTView = rootLView[TVIEW];
13595
+ registerHostBindingOpCodes(rootTView, rootTNode, rootLView, rootTNode.directiveStart, rootTNode.directiveEnd, componentDef);
13596
+ invokeHostBindingsInCreationMode(componentDef, component);
13597
+ }
13598
+ return component;
13599
+ }
13600
+ function createRootContext(scheduler, playerHandler) {
13601
+ return {
13602
+ components: [],
13603
+ scheduler: scheduler || defaultScheduler,
13604
+ clean: CLEAN_PROMISE,
13605
+ playerHandler: playerHandler || null,
13606
+ flags: 0 /* RootContextFlags.Empty */
13607
+ };
13652
13608
  }
13653
13609
  /**
13654
- * Used to perform change detection on the whole application.
13610
+ * Used to enable lifecycle hooks on the root component.
13655
13611
  *
13656
- * This is equivalent to `detectChanges`, but invoked on root component. Additionally, `tick`
13657
- * executes lifecycle hooks and conditionally checks components based on their
13658
- * `ChangeDetectionStrategy` and dirtiness.
13612
+ * Include this feature when calling `renderComponent` if the root component
13613
+ * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
13614
+ * be called properly.
13659
13615
  *
13660
- * The preferred way to trigger change detection is to call `markDirty`. `markDirty` internally
13661
- * schedules `tick` using a scheduler in order to coalesce multiple `markDirty` calls into a
13662
- * single change detection run. By default, the scheduler is `requestAnimationFrame`, but can
13663
- * be changed when calling `renderComponent` and providing the `scheduler` option.
13616
+ * Example:
13617
+ *
13618
+ * ```
13619
+ * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
13620
+ * ```
13664
13621
  */
13665
- function tick(component) {
13666
- const rootView = getRootView(component);
13667
- const rootContext = rootView[CONTEXT];
13668
- tickRootContext(rootContext);
13622
+ function LifecycleHooksFeature() {
13623
+ const tNode = getCurrentTNode();
13624
+ ngDevMode && assertDefined(tNode, 'TNode is required');
13625
+ registerPostOrderHooks(getLView()[TVIEW], tNode);
13626
+ }
13627
+ /**
13628
+ * Wait on component until it is rendered.
13629
+ *
13630
+ * This function returns a `Promise` which is resolved when the component's
13631
+ * change detection is executed. This is determined by finding the scheduler
13632
+ * associated with the `component`'s render tree and waiting until the scheduler
13633
+ * flushes. If nothing is scheduled, the function returns a resolved promise.
13634
+ *
13635
+ * Example:
13636
+ * ```
13637
+ * await whenRendered(myComponent);
13638
+ * ```
13639
+ *
13640
+ * @param component Component to wait upon
13641
+ * @returns Promise which resolves when the component is rendered.
13642
+ */
13643
+ function whenRendered(component) {
13644
+ return getRootContext(component).clean;
13669
13645
  }
13670
13646
 
13671
13647
  /**
@@ -13675,407 +13651,412 @@ function tick(component) {
13675
13651
  * Use of this source code is governed by an MIT-style license that can be
13676
13652
  * found in the LICENSE file at https://angular.io/license
13677
13653
  */
13654
+ function getSuperType(type) {
13655
+ return Object.getPrototypeOf(type.prototype).constructor;
13656
+ }
13678
13657
  /**
13679
- * Retrieves the component instance associated with a given DOM element.
13680
- *
13681
- * @usageNotes
13682
- * Given the following DOM structure:
13683
- *
13684
- * ```html
13685
- * <app-root>
13686
- * <div>
13687
- * <child-comp></child-comp>
13688
- * </div>
13689
- * </app-root>
13690
- * ```
13691
- *
13692
- * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
13693
- * associated with this DOM element.
13694
- *
13695
- * Calling the function on `<app-root>` will return the `MyApp` instance.
13696
- *
13697
- *
13698
- * @param element DOM element from which the component should be retrieved.
13699
- * @returns Component instance associated with the element or `null` if there
13700
- * is no component associated with it.
13658
+ * Merges the definition from a super class to a sub class.
13659
+ * @param definition The definition that is a SubClass of another directive of component
13701
13660
  *
13702
- * @publicApi
13703
- * @globalApi ng
13661
+ * @codeGenApi
13704
13662
  */
13705
- function getComponent$1(element) {
13706
- ngDevMode && assertDomElement(element);
13707
- const context = getLContext(element);
13708
- if (context === null)
13709
- return null;
13710
- if (context.component === undefined) {
13711
- const lView = context.lView;
13712
- if (lView === null) {
13713
- return null;
13663
+ function ɵɵInheritDefinitionFeature(definition) {
13664
+ let superType = getSuperType(definition.type);
13665
+ let shouldInheritFields = true;
13666
+ const inheritanceChain = [definition];
13667
+ while (superType) {
13668
+ let superDef = undefined;
13669
+ if (isComponentDef(definition)) {
13670
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13671
+ superDef = superType.ɵcmp || superType.ɵdir;
13714
13672
  }
13715
- context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
13673
+ else {
13674
+ if (superType.ɵcmp) {
13675
+ throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, ngDevMode &&
13676
+ `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
13677
+ }
13678
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13679
+ superDef = superType.ɵdir;
13680
+ }
13681
+ if (superDef) {
13682
+ if (shouldInheritFields) {
13683
+ inheritanceChain.push(superDef);
13684
+ // Some fields in the definition may be empty, if there were no values to put in them that
13685
+ // would've justified object creation. Unwrap them if necessary.
13686
+ const writeableDef = definition;
13687
+ writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
13688
+ writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
13689
+ writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
13690
+ // Merge hostBindings
13691
+ const superHostBindings = superDef.hostBindings;
13692
+ superHostBindings && inheritHostBindings(definition, superHostBindings);
13693
+ // Merge queries
13694
+ const superViewQuery = superDef.viewQuery;
13695
+ const superContentQueries = superDef.contentQueries;
13696
+ superViewQuery && inheritViewQuery(definition, superViewQuery);
13697
+ superContentQueries && inheritContentQueries(definition, superContentQueries);
13698
+ // Merge inputs and outputs
13699
+ fillProperties(definition.inputs, superDef.inputs);
13700
+ fillProperties(definition.declaredInputs, superDef.declaredInputs);
13701
+ fillProperties(definition.outputs, superDef.outputs);
13702
+ // Merge animations metadata.
13703
+ // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
13704
+ if (isComponentDef(superDef) && superDef.data.animation) {
13705
+ // If super def is a Component, the `definition` is also a Component, since Directives can
13706
+ // not inherit Components (we throw an error above and cannot reach this code).
13707
+ const defData = definition.data;
13708
+ defData.animation = (defData.animation || []).concat(superDef.data.animation);
13709
+ }
13710
+ }
13711
+ // Run parent features
13712
+ const features = superDef.features;
13713
+ if (features) {
13714
+ for (let i = 0; i < features.length; i++) {
13715
+ const feature = features[i];
13716
+ if (feature && feature.ngInherit) {
13717
+ feature(definition);
13718
+ }
13719
+ // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
13720
+ // def already has all the necessary information inherited from its super class(es), so we
13721
+ // can stop merging fields from super classes. However we need to iterate through the
13722
+ // prototype chain to look for classes that might contain other "features" (like
13723
+ // NgOnChanges), which we should invoke for the original `definition`. We set the
13724
+ // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
13725
+ // logic and only invoking functions from the "features" list.
13726
+ if (feature === ɵɵInheritDefinitionFeature) {
13727
+ shouldInheritFields = false;
13728
+ }
13729
+ }
13730
+ }
13731
+ }
13732
+ superType = Object.getPrototypeOf(superType);
13716
13733
  }
13717
- return context.component;
13734
+ mergeHostAttrsAcrossInheritance(inheritanceChain);
13718
13735
  }
13719
13736
  /**
13720
- * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
13721
- * view that the element is part of. Otherwise retrieves the instance of the component whose view
13722
- * owns the element (in this case, the result is the same as calling `getOwningComponent`).
13723
- *
13724
- * @param element Element for which to get the surrounding component instance.
13725
- * @returns Instance of the component that is around the element or null if the element isn't
13726
- * inside any component.
13737
+ * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
13727
13738
  *
13728
- * @publicApi
13729
- * @globalApi ng
13739
+ * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
13740
+ * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
13741
+ * type.
13730
13742
  */
13731
- function getContext(element) {
13732
- assertDomElement(element);
13733
- const context = getLContext(element);
13734
- const lView = context ? context.lView : null;
13735
- return lView === null ? null : lView[CONTEXT];
13743
+ function mergeHostAttrsAcrossInheritance(inheritanceChain) {
13744
+ let hostVars = 0;
13745
+ let hostAttrs = null;
13746
+ // We process the inheritance order from the base to the leaves here.
13747
+ for (let i = inheritanceChain.length - 1; i >= 0; i--) {
13748
+ const def = inheritanceChain[i];
13749
+ // For each `hostVars`, we need to add the superclass amount.
13750
+ def.hostVars = (hostVars += def.hostVars);
13751
+ // for each `hostAttrs` we need to merge it with superclass.
13752
+ def.hostAttrs =
13753
+ mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
13754
+ }
13736
13755
  }
13737
- /**
13738
- * Retrieves the component instance whose view contains the DOM element.
13739
- *
13740
- * For example, if `<child-comp>` is used in the template of `<app-comp>`
13741
- * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
13742
- * would return `<app-comp>`.
13743
- *
13744
- * @param elementOrDir DOM element, component or directive instance
13745
- * for which to retrieve the root components.
13746
- * @returns Component instance whose view owns the DOM element or null if the element is not
13747
- * part of a component view.
13748
- *
13749
- * @publicApi
13750
- * @globalApi ng
13751
- */
13752
- function getOwningComponent(elementOrDir) {
13753
- const context = getLContext(elementOrDir);
13754
- let lView = context ? context.lView : null;
13755
- if (lView === null)
13756
- return null;
13757
- let parent;
13758
- while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
13759
- lView = parent;
13756
+ function maybeUnwrapEmpty(value) {
13757
+ if (value === EMPTY_OBJ) {
13758
+ return {};
13759
+ }
13760
+ else if (value === EMPTY_ARRAY) {
13761
+ return [];
13762
+ }
13763
+ else {
13764
+ return value;
13765
+ }
13766
+ }
13767
+ function inheritViewQuery(definition, superViewQuery) {
13768
+ const prevViewQuery = definition.viewQuery;
13769
+ if (prevViewQuery) {
13770
+ definition.viewQuery = (rf, ctx) => {
13771
+ superViewQuery(rf, ctx);
13772
+ prevViewQuery(rf, ctx);
13773
+ };
13774
+ }
13775
+ else {
13776
+ definition.viewQuery = superViewQuery;
13777
+ }
13778
+ }
13779
+ function inheritContentQueries(definition, superContentQueries) {
13780
+ const prevContentQueries = definition.contentQueries;
13781
+ if (prevContentQueries) {
13782
+ definition.contentQueries = (rf, ctx, directiveIndex) => {
13783
+ superContentQueries(rf, ctx, directiveIndex);
13784
+ prevContentQueries(rf, ctx, directiveIndex);
13785
+ };
13786
+ }
13787
+ else {
13788
+ definition.contentQueries = superContentQueries;
13789
+ }
13790
+ }
13791
+ function inheritHostBindings(definition, superHostBindings) {
13792
+ const prevHostBindings = definition.hostBindings;
13793
+ if (prevHostBindings) {
13794
+ definition.hostBindings = (rf, ctx) => {
13795
+ superHostBindings(rf, ctx);
13796
+ prevHostBindings(rf, ctx);
13797
+ };
13798
+ }
13799
+ else {
13800
+ definition.hostBindings = superHostBindings;
13760
13801
  }
13761
- return lView[FLAGS] & 256 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
13762
13802
  }
13803
+
13763
13804
  /**
13764
- * Retrieves all root components associated with a DOM element, directive or component instance.
13765
- * Root components are those which have been bootstrapped by Angular.
13766
- *
13767
- * @param elementOrDir DOM element, component or directive instance
13768
- * for which to retrieve the root components.
13769
- * @returns Root components associated with the target object.
13805
+ * @license
13806
+ * Copyright Google LLC All Rights Reserved.
13770
13807
  *
13771
- * @publicApi
13772
- * @globalApi ng
13808
+ * Use of this source code is governed by an MIT-style license that can be
13809
+ * found in the LICENSE file at https://angular.io/license
13773
13810
  */
13774
- function getRootComponents(elementOrDir) {
13775
- const lView = readPatchedLView(elementOrDir);
13776
- return lView !== null ? [...getRootContext(lView).components] : [];
13777
- }
13778
13811
  /**
13779
- * Retrieves an `Injector` associated with an element, component or directive instance.
13780
- *
13781
- * @param elementOrDir DOM element, component or directive instance for which to
13782
- * retrieve the injector.
13783
- * @returns Injector associated with the element, component or directive instance.
13784
- *
13785
- * @publicApi
13786
- * @globalApi ng
13812
+ * Fields which exist on either directive or component definitions, and need to be copied from
13813
+ * parent to child classes by the `ɵɵCopyDefinitionFeature`.
13787
13814
  */
13788
- function getInjector(elementOrDir) {
13789
- const context = getLContext(elementOrDir);
13790
- const lView = context ? context.lView : null;
13791
- if (lView === null)
13792
- return Injector.NULL;
13793
- const tNode = lView[TVIEW].data[context.nodeIndex];
13794
- return new NodeInjector(tNode, lView);
13795
- }
13815
+ const COPY_DIRECTIVE_FIELDS = [
13816
+ // The child class should use the providers of its parent.
13817
+ 'providersResolver',
13818
+ // Not listed here are any fields which are handled by the `ɵɵInheritDefinitionFeature`, such
13819
+ // as inputs, outputs, and host binding functions.
13820
+ ];
13796
13821
  /**
13797
- * Retrieve a set of injection tokens at a given DOM node.
13822
+ * Fields which exist only on component definitions, and need to be copied from parent to child
13823
+ * classes by the `ɵɵCopyDefinitionFeature`.
13798
13824
  *
13799
- * @param element Element for which the injection tokens should be retrieved.
13825
+ * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
13826
+ * since those should go in `COPY_DIRECTIVE_FIELDS` above.
13800
13827
  */
13801
- function getInjectionTokens(element) {
13802
- const context = getLContext(element);
13803
- const lView = context ? context.lView : null;
13804
- if (lView === null)
13805
- return [];
13806
- const tView = lView[TVIEW];
13807
- const tNode = tView.data[context.nodeIndex];
13808
- const providerTokens = [];
13809
- const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
13810
- const endIndex = tNode.directiveEnd;
13811
- for (let i = startIndex; i < endIndex; i++) {
13812
- let value = tView.data[i];
13813
- if (isDirectiveDefHack(value)) {
13814
- // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
13815
- // design flaw. We should always store same type so that we can be monomorphic. The issue
13816
- // is that for Components/Directives we store the def instead the type. The correct behavior
13817
- // is that we should always be storing injectable type in this location.
13818
- value = value.type;
13819
- }
13820
- providerTokens.push(value);
13821
- }
13822
- return providerTokens;
13823
- }
13828
+ const COPY_COMPONENT_FIELDS = [
13829
+ // The child class should use the template function of its parent, including all template
13830
+ // semantics.
13831
+ 'template',
13832
+ 'decls',
13833
+ 'consts',
13834
+ 'vars',
13835
+ 'onPush',
13836
+ 'ngContentSelectors',
13837
+ // The child class should use the CSS styles of its parent, including all styling semantics.
13838
+ 'styles',
13839
+ 'encapsulation',
13840
+ // The child class should be checked by the runtime in the same way as its parent.
13841
+ 'schemas',
13842
+ ];
13824
13843
  /**
13825
- * Retrieves directive instances associated with a given DOM node. Does not include
13826
- * component instances.
13827
- *
13828
- * @usageNotes
13829
- * Given the following DOM structure:
13830
- *
13831
- * ```html
13832
- * <app-root>
13833
- * <button my-button></button>
13834
- * <my-comp></my-comp>
13835
- * </app-root>
13836
- * ```
13844
+ * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
13845
+ * definition.
13837
13846
  *
13838
- * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
13839
- * directive that is associated with the DOM node.
13847
+ * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
13848
+ * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
13849
+ * generates a skeleton definition on the child class, and applies this feature.
13840
13850
  *
13841
- * Calling `getDirectives` on `<my-comp>` will return an empty array.
13851
+ * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
13852
+ * including things like the component template function.
13842
13853
  *
13843
- * @param node DOM node for which to get the directives.
13844
- * @returns Array of directives associated with the node.
13854
+ * @param definition The definition of a child class which inherits from a parent class with its
13855
+ * own definition.
13845
13856
  *
13846
- * @publicApi
13847
- * @globalApi ng
13857
+ * @codeGenApi
13848
13858
  */
13849
- function getDirectives(node) {
13850
- // Skip text nodes because we can't have directives associated with them.
13851
- if (node instanceof Text) {
13852
- return [];
13859
+ function ɵɵCopyDefinitionFeature(definition) {
13860
+ let superType = getSuperType(definition.type);
13861
+ let superDef = undefined;
13862
+ if (isComponentDef(definition)) {
13863
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13864
+ superDef = superType.ɵcmp;
13853
13865
  }
13854
- const context = getLContext(node);
13855
- const lView = context ? context.lView : null;
13856
- if (lView === null) {
13857
- return [];
13866
+ else {
13867
+ // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
13868
+ superDef = superType.ɵdir;
13858
13869
  }
13859
- const tView = lView[TVIEW];
13860
- const nodeIndex = context.nodeIndex;
13861
- if (!(tView === null || tView === void 0 ? void 0 : tView.data[nodeIndex])) {
13862
- return [];
13870
+ // Needed because `definition` fields are readonly.
13871
+ const defAny = definition;
13872
+ // Copy over any fields that apply to either directives or components.
13873
+ for (const field of COPY_DIRECTIVE_FIELDS) {
13874
+ defAny[field] = superDef[field];
13863
13875
  }
13864
- if (context.directives === undefined) {
13865
- context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
13876
+ if (isComponentDef(superDef)) {
13877
+ // Copy over any component-specific fields.
13878
+ for (const field of COPY_COMPONENT_FIELDS) {
13879
+ defAny[field] = superDef[field];
13880
+ }
13866
13881
  }
13867
- // The `directives` in this case are a named array called `LComponentView`. Clone the
13868
- // result so we don't expose an internal data structure in the user's console.
13869
- return context.directives === null ? [] : [...context.directives];
13870
13882
  }
13883
+
13871
13884
  /**
13872
- * Returns the debug (partial) metadata for a particular directive or component instance.
13873
- * The function accepts an instance of a directive or component and returns the corresponding
13874
- * metadata.
13875
- *
13876
- * @param directiveOrComponentInstance Instance of a directive or component
13877
- * @returns metadata of the passed directive or component
13885
+ * @license
13886
+ * Copyright Google LLC All Rights Reserved.
13878
13887
  *
13879
- * @publicApi
13880
- * @globalApi ng
13888
+ * Use of this source code is governed by an MIT-style license that can be
13889
+ * found in the LICENSE file at https://angular.io/license
13881
13890
  */
13882
- function getDirectiveMetadata(directiveOrComponentInstance) {
13883
- const { constructor } = directiveOrComponentInstance;
13884
- if (!constructor) {
13885
- throw new Error('Unable to find the instance constructor');
13886
- }
13887
- // In case a component inherits from a directive, we may have component and directive metadata
13888
- // To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
13889
- const componentDef = getComponentDef$1(constructor);
13890
- if (componentDef) {
13891
- return {
13892
- inputs: componentDef.inputs,
13893
- outputs: componentDef.outputs,
13894
- encapsulation: componentDef.encapsulation,
13895
- changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush :
13896
- ChangeDetectionStrategy.Default
13897
- };
13898
- }
13899
- const directiveDef = getDirectiveDef(constructor);
13900
- if (directiveDef) {
13901
- return { inputs: directiveDef.inputs, outputs: directiveDef.outputs };
13891
+ let _symbolIterator = null;
13892
+ function getSymbolIterator() {
13893
+ if (!_symbolIterator) {
13894
+ const Symbol = _global$1['Symbol'];
13895
+ if (Symbol && Symbol.iterator) {
13896
+ _symbolIterator = Symbol.iterator;
13897
+ }
13898
+ else {
13899
+ // es6-shim specific logic
13900
+ const keys = Object.getOwnPropertyNames(Map.prototype);
13901
+ for (let i = 0; i < keys.length; ++i) {
13902
+ const key = keys[i];
13903
+ if (key !== 'entries' && key !== 'size' &&
13904
+ Map.prototype[key] === Map.prototype['entries']) {
13905
+ _symbolIterator = key;
13906
+ }
13907
+ }
13908
+ }
13902
13909
  }
13903
- return null;
13910
+ return _symbolIterator;
13904
13911
  }
13912
+
13905
13913
  /**
13906
- * Retrieve map of local references.
13907
- *
13908
- * The references are retrieved as a map of local reference name to element or directive instance.
13914
+ * @license
13915
+ * Copyright Google LLC All Rights Reserved.
13909
13916
  *
13910
- * @param target DOM element, component or directive instance for which to retrieve
13911
- * the local references.
13917
+ * Use of this source code is governed by an MIT-style license that can be
13918
+ * found in the LICENSE file at https://angular.io/license
13912
13919
  */
13913
- function getLocalRefs(target) {
13914
- const context = getLContext(target);
13915
- if (context === null)
13916
- return {};
13917
- if (context.localRefs === undefined) {
13918
- const lView = context.lView;
13919
- if (lView === null) {
13920
- return {};
13920
+ function isIterable(obj) {
13921
+ return obj !== null && typeof obj === 'object' && obj[getSymbolIterator()] !== undefined;
13922
+ }
13923
+ function isListLikeIterable(obj) {
13924
+ if (!isJsObject(obj))
13925
+ return false;
13926
+ return Array.isArray(obj) ||
13927
+ (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
13928
+ getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
13929
+ }
13930
+ function areIterablesEqual(a, b, comparator) {
13931
+ const iterator1 = a[getSymbolIterator()]();
13932
+ const iterator2 = b[getSymbolIterator()]();
13933
+ while (true) {
13934
+ const item1 = iterator1.next();
13935
+ const item2 = iterator2.next();
13936
+ if (item1.done && item2.done)
13937
+ return true;
13938
+ if (item1.done || item2.done)
13939
+ return false;
13940
+ if (!comparator(item1.value, item2.value))
13941
+ return false;
13942
+ }
13943
+ }
13944
+ function iterateListLike(obj, fn) {
13945
+ if (Array.isArray(obj)) {
13946
+ for (let i = 0; i < obj.length; i++) {
13947
+ fn(obj[i]);
13948
+ }
13949
+ }
13950
+ else {
13951
+ const iterator = obj[getSymbolIterator()]();
13952
+ let item;
13953
+ while (!((item = iterator.next()).done)) {
13954
+ fn(item.value);
13921
13955
  }
13922
- context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
13923
13956
  }
13924
- return context.localRefs || {};
13925
13957
  }
13926
- /**
13927
- * Retrieves the host element of a component or directive instance.
13928
- * The host element is the DOM element that matched the selector of the directive.
13929
- *
13930
- * @param componentOrDirective Component or directive instance for which the host
13931
- * element should be retrieved.
13932
- * @returns Host element of the target.
13933
- *
13934
- * @publicApi
13935
- * @globalApi ng
13936
- */
13937
- function getHostElement(componentOrDirective) {
13938
- return getLContext(componentOrDirective).native;
13958
+ function isJsObject(o) {
13959
+ return o !== null && (typeof o === 'function' || typeof o === 'object');
13939
13960
  }
13961
+
13940
13962
  /**
13941
- * Retrieves the rendered text for a given component.
13963
+ * @license
13964
+ * Copyright Google LLC All Rights Reserved.
13942
13965
  *
13943
- * This function retrieves the host element of a component and
13944
- * and then returns the `textContent` for that element. This implies
13945
- * that the text returned will include re-projected content of
13946
- * the component as well.
13947
- *
13948
- * @param component The component to return the content text for.
13949
- */
13950
- function getRenderedText(component) {
13951
- const hostElement = getHostElement(component);
13952
- return hostElement.textContent || '';
13953
- }
13954
- /**
13955
- * Retrieves a list of event listeners associated with a DOM element. The list does include host
13956
- * listeners, but it does not include event listeners defined outside of the Angular context
13957
- * (e.g. through `addEventListener`).
13958
- *
13959
- * @usageNotes
13960
- * Given the following DOM structure:
13961
- *
13962
- * ```html
13963
- * <app-root>
13964
- * <div (click)="doSomething()"></div>
13965
- * </app-root>
13966
- * ```
13967
- *
13968
- * Calling `getListeners` on `<div>` will return an object that looks as follows:
13969
- *
13970
- * ```ts
13971
- * {
13972
- * name: 'click',
13973
- * element: <div>,
13974
- * callback: () => doSomething(),
13975
- * useCapture: false
13976
- * }
13977
- * ```
13978
- *
13979
- * @param element Element for which the DOM listeners should be retrieved.
13980
- * @returns Array of event listeners on the DOM element.
13981
- *
13982
- * @publicApi
13983
- * @globalApi ng
13966
+ * Use of this source code is governed by an MIT-style license that can be
13967
+ * found in the LICENSE file at https://angular.io/license
13984
13968
  */
13985
- function getListeners(element) {
13986
- ngDevMode && assertDomElement(element);
13987
- const lContext = getLContext(element);
13988
- const lView = lContext === null ? null : lContext.lView;
13989
- if (lView === null)
13990
- return [];
13991
- const tView = lView[TVIEW];
13992
- const lCleanup = lView[CLEANUP];
13993
- const tCleanup = tView.cleanup;
13994
- const listeners = [];
13995
- if (tCleanup && lCleanup) {
13996
- for (let i = 0; i < tCleanup.length;) {
13997
- const firstParam = tCleanup[i++];
13998
- const secondParam = tCleanup[i++];
13999
- if (typeof firstParam === 'string') {
14000
- const name = firstParam;
14001
- const listenerElement = unwrapRNode(lView[secondParam]);
14002
- const callback = lCleanup[tCleanup[i++]];
14003
- const useCaptureOrIndx = tCleanup[i++];
14004
- // if useCaptureOrIndx is boolean then report it as is.
14005
- // if useCaptureOrIndx is positive number then it in unsubscribe method
14006
- // if useCaptureOrIndx is negative number then it is a Subscription
14007
- const type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
14008
- const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
14009
- if (element == listenerElement) {
14010
- listeners.push({ element, name, callback, useCapture, type });
14011
- }
14012
- }
13969
+ function devModeEqual(a, b) {
13970
+ const isListLikeIterableA = isListLikeIterable(a);
13971
+ const isListLikeIterableB = isListLikeIterable(b);
13972
+ if (isListLikeIterableA && isListLikeIterableB) {
13973
+ return areIterablesEqual(a, b, devModeEqual);
13974
+ }
13975
+ else {
13976
+ const isAObject = a && (typeof a === 'object' || typeof a === 'function');
13977
+ const isBObject = b && (typeof b === 'object' || typeof b === 'function');
13978
+ if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
13979
+ return true;
13980
+ }
13981
+ else {
13982
+ return Object.is(a, b);
14013
13983
  }
14014
13984
  }
14015
- listeners.sort(sortListeners);
14016
- return listeners;
14017
- }
14018
- function sortListeners(a, b) {
14019
- if (a.name == b.name)
14020
- return 0;
14021
- return a.name < b.name ? -1 : 1;
14022
13985
  }
13986
+
14023
13987
  /**
14024
- * This function should not exist because it is megamorphic and only mostly correct.
13988
+ * @license
13989
+ * Copyright Google LLC All Rights Reserved.
14025
13990
  *
14026
- * See call site for more info.
13991
+ * Use of this source code is governed by an MIT-style license that can be
13992
+ * found in the LICENSE file at https://angular.io/license
14027
13993
  */
14028
- function isDirectiveDefHack(obj) {
14029
- return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
13994
+ // TODO(misko): consider inlining
13995
+ /** Updates binding and returns the value. */
13996
+ function updateBinding(lView, bindingIndex, value) {
13997
+ return lView[bindingIndex] = value;
13998
+ }
13999
+ /** Gets the current binding value. */
14000
+ function getBinding(lView, bindingIndex) {
14001
+ ngDevMode && assertIndexInRange(lView, bindingIndex);
14002
+ ngDevMode &&
14003
+ assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
14004
+ return lView[bindingIndex];
14030
14005
  }
14031
14006
  /**
14032
- * Returns the attached `DebugNode` instance for an element in the DOM.
14007
+ * Updates binding if changed, then returns whether it was updated.
14033
14008
  *
14034
- * @param element DOM element which is owned by an existing component's view.
14009
+ * This function also checks the `CheckNoChangesMode` and throws if changes are made.
14010
+ * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
14011
+ * behavior.
14012
+ *
14013
+ * @param lView current `LView`
14014
+ * @param bindingIndex The binding in the `LView` to check
14015
+ * @param value New value to check against `lView[bindingIndex]`
14016
+ * @returns `true` if the bindings has changed. (Throws if binding has changed during
14017
+ * `CheckNoChangesMode`)
14035
14018
  */
14036
- function getDebugNode(element) {
14037
- if (ngDevMode && !(element instanceof Node)) {
14038
- throw new Error('Expecting instance of DOM Element');
14039
- }
14040
- const lContext = getLContext(element);
14041
- const lView = lContext ? lContext.lView : null;
14042
- if (lView === null) {
14043
- return null;
14019
+ function bindingUpdated(lView, bindingIndex, value) {
14020
+ ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
14021
+ ngDevMode &&
14022
+ assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
14023
+ const oldValue = lView[bindingIndex];
14024
+ if (Object.is(oldValue, value)) {
14025
+ return false;
14044
14026
  }
14045
- const nodeIndex = lContext.nodeIndex;
14046
- if (nodeIndex !== -1) {
14047
- const valueInLView = lView[nodeIndex];
14048
- // this means that value in the lView is a component with its own
14049
- // data. In this situation the TNode is not accessed at the same spot.
14050
- const tNode = isLView(valueInLView) ? valueInLView[T_HOST] : getTNode(lView[TVIEW], nodeIndex);
14051
- ngDevMode &&
14052
- assertEqual(tNode.index, nodeIndex, 'Expecting that TNode at index is same as index');
14053
- return buildDebugNode(tNode, lView);
14027
+ else {
14028
+ if (ngDevMode && isInCheckNoChangesMode()) {
14029
+ // View engine didn't report undefined values as changed on the first checkNoChanges pass
14030
+ // (before the change detection was run).
14031
+ const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
14032
+ if (!devModeEqual(oldValueToCompare, value)) {
14033
+ const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
14034
+ throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
14035
+ }
14036
+ // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
14037
+ // For this reason we exit as if no change. The early exit is needed to prevent the changed
14038
+ // value to be written into `LView` (If we would write the new value that we would not see it
14039
+ // as change on next CD.)
14040
+ return false;
14041
+ }
14042
+ lView[bindingIndex] = value;
14043
+ return true;
14054
14044
  }
14055
- return null;
14056
14045
  }
14057
- /**
14058
- * Retrieve the component `LView` from component/element.
14059
- *
14060
- * NOTE: `LView` is a private and should not be leaked outside.
14061
- * Don't export this method to `ng.*` on window.
14062
- *
14063
- * @param target DOM element or component instance for which to retrieve the LView.
14064
- */
14065
- function getComponentLView(target) {
14066
- const lContext = getLContext(target);
14067
- const nodeIndx = lContext.nodeIndex;
14068
- const lView = lContext.lView;
14069
- ngDevMode && assertLView(lView);
14070
- const componentLView = lView[nodeIndx];
14071
- ngDevMode && assertLView(componentLView);
14072
- return componentLView;
14046
+ /** Updates 2 bindings if changed, then returns whether either was updated. */
14047
+ function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
14048
+ const different = bindingUpdated(lView, bindingIndex, exp1);
14049
+ return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
14073
14050
  }
14074
- /** Asserts that a value is a DOM Element. */
14075
- function assertDomElement(value) {
14076
- if (typeof Element !== 'undefined' && !(value instanceof Element)) {
14077
- throw new Error('Expecting instance of DOM Element');
14078
- }
14051
+ /** Updates 3 bindings if changed, then returns whether any was updated. */
14052
+ function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
14053
+ const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14054
+ return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
14055
+ }
14056
+ /** Updates 4 bindings if changed, then returns whether any was updated. */
14057
+ function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
14058
+ const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14059
+ return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
14079
14060
  }
14080
14061
 
14081
14062
  /**
@@ -14086,17 +14067,28 @@ function assertDomElement(value) {
14086
14067
  * found in the LICENSE file at https://angular.io/license
14087
14068
  */
14088
14069
  /**
14089
- * Marks a component for check (in case of OnPush components) and synchronously
14090
- * performs change detection on the application this component belongs to.
14070
+ * Updates the value of or removes a bound attribute on an Element.
14091
14071
  *
14092
- * @param component Component to {@link ChangeDetectorRef#markForCheck mark for check}.
14072
+ * Used in the case of `[attr.title]="value"`
14093
14073
  *
14094
- * @publicApi
14095
- * @globalApi ng
14074
+ * @param name name The name of the attribute.
14075
+ * @param value value The attribute is removed when value is `null` or `undefined`.
14076
+ * Otherwise the attribute value is set to the stringified value.
14077
+ * @param sanitizer An optional function used to sanitize the value.
14078
+ * @param namespace Optional namespace to use when setting the attribute.
14079
+ *
14080
+ * @codeGenApi
14096
14081
  */
14097
- function applyChanges(component) {
14098
- markDirty(component);
14099
- getRootComponents(component).forEach(rootComponent => detectChanges(rootComponent));
14082
+ function ɵɵattribute(name, value, sanitizer, namespace) {
14083
+ const lView = getLView();
14084
+ const bindingIndex = nextBindingIndex();
14085
+ if (bindingUpdated(lView, bindingIndex, value)) {
14086
+ const tView = getTView();
14087
+ const tNode = getSelectedTNode();
14088
+ elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
14089
+ ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
14090
+ }
14091
+ return ɵɵattribute;
14100
14092
  }
14101
14093
 
14102
14094
  /**
@@ -14107,890 +14099,181 @@ function applyChanges(component) {
14107
14099
  * found in the LICENSE file at https://angular.io/license
14108
14100
  */
14109
14101
  /**
14110
- * This file introduces series of globally accessible debug tools
14111
- * to allow for the Angular debugging story to function.
14112
- *
14113
- * To see this in action run the following command:
14102
+ * Create interpolation bindings with a variable number of expressions.
14114
14103
  *
14115
- * bazel run //packages/core/test/bundling/todo:devserver
14104
+ * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
14105
+ * Those are faster because there is no need to create an array of expressions and iterate over it.
14116
14106
  *
14117
- * Then load `localhost:5432` and start using the console tools.
14118
- */
14119
- /**
14120
- * This value reflects the property on the window where the dev
14121
- * tools are patched (window.ng).
14122
- * */
14123
- const GLOBAL_PUBLISH_EXPANDO_KEY = 'ng';
14124
- let _published = false;
14125
- /**
14126
- * Publishes a collection of default debug tools onto`window.ng`.
14107
+ * `values`:
14108
+ * - has static text at even indexes,
14109
+ * - has evaluated expressions at odd indexes.
14127
14110
  *
14128
- * These functions are available globally when Angular is in development
14129
- * mode and are automatically stripped away from prod mode is on.
14111
+ * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
14130
14112
  */
14131
- function publishDefaultGlobalUtils() {
14132
- if (!_published) {
14133
- _published = true;
14134
- /**
14135
- * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
14136
- * The contract of the function might be changed in any release and/or the function can be
14137
- * removed completely.
14138
- */
14139
- publishGlobalUtil('ɵsetProfiler', setProfiler);
14140
- publishGlobalUtil('getDirectiveMetadata', getDirectiveMetadata);
14141
- publishGlobalUtil('getComponent', getComponent$1);
14142
- publishGlobalUtil('getContext', getContext);
14143
- publishGlobalUtil('getListeners', getListeners);
14144
- publishGlobalUtil('getOwningComponent', getOwningComponent);
14145
- publishGlobalUtil('getHostElement', getHostElement);
14146
- publishGlobalUtil('getInjector', getInjector);
14147
- publishGlobalUtil('getRootComponents', getRootComponents);
14148
- publishGlobalUtil('getDirectives', getDirectives);
14149
- publishGlobalUtil('applyChanges', applyChanges);
14113
+ function interpolationV(lView, values) {
14114
+ ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
14115
+ ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
14116
+ let isBindingUpdated = false;
14117
+ let bindingIndex = getBindingIndex();
14118
+ for (let i = 1; i < values.length; i += 2) {
14119
+ // Check if bindings (odd indexes) have changed
14120
+ isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
14150
14121
  }
14151
- }
14152
- /**
14153
- * Publishes the given function to `window.ng` so that it can be
14154
- * used from the browser console when an application is not in production.
14155
- */
14156
- function publishGlobalUtil(name, fn) {
14157
- if (typeof COMPILED === 'undefined' || !COMPILED) {
14158
- // Note: we can't export `ng` when using closure enhanced optimization as:
14159
- // - closure declares globals itself for minified names, which sometimes clobber our `ng` global
14160
- // - we can't declare a closure extern as the namespace `ng` is already used within Google
14161
- // for typings for AngularJS (via `goog.provide('ng....')`).
14162
- const w = _global$1;
14163
- ngDevMode && assertDefined(fn, 'function not defined');
14164
- if (w) {
14165
- let container = w[GLOBAL_PUBLISH_EXPANDO_KEY];
14166
- if (!container) {
14167
- container = w[GLOBAL_PUBLISH_EXPANDO_KEY] = {};
14168
- }
14169
- container[name] = fn;
14170
- }
14122
+ setBindingIndex(bindingIndex);
14123
+ if (!isBindingUpdated) {
14124
+ return NO_CHANGE;
14125
+ }
14126
+ // Build the updated content
14127
+ let content = values[0];
14128
+ for (let i = 1; i < values.length; i += 2) {
14129
+ content += renderStringify(values[i]) + values[i + 1];
14171
14130
  }
14131
+ return content;
14172
14132
  }
14173
-
14174
14133
  /**
14175
- * @license
14176
- * Copyright Google LLC All Rights Reserved.
14134
+ * Creates an interpolation binding with 1 expression.
14177
14135
  *
14178
- * Use of this source code is governed by an MIT-style license that can be
14179
- * found in the LICENSE file at https://angular.io/license
14136
+ * @param prefix static value used for concatenation only.
14137
+ * @param v0 value checked for change.
14138
+ * @param suffix static value used for concatenation only.
14180
14139
  */
14181
- // TODO: A hack to not pull in the NullInjector from @angular/core.
14182
- const NULL_INJECTOR = {
14183
- get: (token, notFoundValue) => {
14184
- throwProviderNotFoundError(token, 'NullInjector');
14185
- }
14186
- };
14140
+ function interpolation1(lView, prefix, v0, suffix) {
14141
+ const different = bindingUpdated(lView, nextBindingIndex(), v0);
14142
+ return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
14143
+ }
14187
14144
  /**
14188
- * Bootstraps a Component into an existing host element and returns an instance
14189
- * of the component.
14190
- *
14191
- * Use this function to bootstrap a component into the DOM tree. Each invocation
14192
- * of this function will create a separate tree of components, injectors and
14193
- * change detection cycles and lifetimes. To dynamically insert a new component
14194
- * into an existing tree such that it shares the same injection, change detection
14195
- * and object lifetime, use {@link ViewContainer#createComponent}.
14196
- *
14197
- * @param componentType Component to bootstrap
14198
- * @param options Optional parameters which control bootstrapping
14199
- */
14200
- function renderComponent(componentType /* Type as workaround for: Microsoft/TypeScript/issues/4881 */, opts = {}) {
14201
- ngDevMode && publishDefaultGlobalUtils();
14202
- ngDevMode && assertComponentType(componentType);
14203
- const rendererFactory = opts.rendererFactory || domRendererFactory3;
14204
- const sanitizer = opts.sanitizer || null;
14205
- const componentDef = getComponentDef$1(componentType);
14206
- if (componentDef.type != componentType)
14207
- componentDef.type = componentType;
14208
- // The first index of the first selector is the tag name.
14209
- const componentTag = componentDef.selectors[0][0];
14210
- const hostRenderer = rendererFactory.createRenderer(null, null);
14211
- const hostRNode = locateHostElement(hostRenderer, opts.host || componentTag, componentDef.encapsulation);
14212
- const rootFlags = componentDef.onPush ? 32 /* LViewFlags.Dirty */ | 256 /* LViewFlags.IsRoot */ :
14213
- 16 /* LViewFlags.CheckAlways */ | 256 /* LViewFlags.IsRoot */;
14214
- const rootContext = createRootContext(opts.scheduler, opts.playerHandler);
14215
- const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
14216
- const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null);
14217
- const rootView = createLView(null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, null, opts.injector || null, null);
14218
- enterView(rootView);
14219
- let component;
14220
- try {
14221
- if (rendererFactory.begin)
14222
- rendererFactory.begin();
14223
- const componentView = createRootComponentView(hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
14224
- component = createRootComponent(componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
14225
- // create mode pass
14226
- renderView(rootTView, rootView, null);
14227
- // update mode pass
14228
- refreshView(rootTView, rootView, null, null);
14229
- }
14230
- finally {
14231
- leaveView();
14232
- if (rendererFactory.end)
14233
- rendererFactory.end();
14234
- }
14235
- return component;
14145
+ * Creates an interpolation binding with 2 expressions.
14146
+ */
14147
+ function interpolation2(lView, prefix, v0, i0, v1, suffix) {
14148
+ const bindingIndex = getBindingIndex();
14149
+ const different = bindingUpdated2(lView, bindingIndex, v0, v1);
14150
+ incrementBindingIndex(2);
14151
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
14236
14152
  }
14237
14153
  /**
14238
- * Creates the root component view and the root component node.
14239
- *
14240
- * @param rNode Render host element.
14241
- * @param def ComponentDef
14242
- * @param rootView The parent view where the host node is stored
14243
- * @param rendererFactory Factory to be used for creating child renderers.
14244
- * @param hostRenderer The current renderer
14245
- * @param sanitizer The sanitizer, if provided
14246
- *
14247
- * @returns Component view created
14154
+ * Creates an interpolation binding with 3 expressions.
14248
14155
  */
14249
- function createRootComponentView(rNode, def, rootView, rendererFactory, hostRenderer, sanitizer) {
14250
- const tView = rootView[TVIEW];
14251
- const index = HEADER_OFFSET;
14252
- ngDevMode && assertIndexInRange(rootView, index);
14253
- rootView[index] = rNode;
14254
- // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
14255
- // the same time we want to communicate the debug `TNode` that this is a special `TNode`
14256
- // representing a host element.
14257
- const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
14258
- const mergedAttrs = tNode.mergedAttrs = def.hostAttrs;
14259
- if (mergedAttrs !== null) {
14260
- computeStaticStyling(tNode, mergedAttrs, true);
14261
- if (rNode !== null) {
14262
- setUpAttributes(hostRenderer, rNode, mergedAttrs);
14263
- if (tNode.classes !== null) {
14264
- writeDirectClass(hostRenderer, rNode, tNode.classes);
14265
- }
14266
- if (tNode.styles !== null) {
14267
- writeDirectStyle(hostRenderer, rNode, tNode.styles);
14268
- }
14269
- }
14270
- }
14271
- const viewRenderer = rendererFactory.createRenderer(rNode, def);
14272
- const componentView = createLView(rootView, getOrCreateTComponentView(def), null, def.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
14273
- if (tView.firstCreatePass) {
14274
- diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
14275
- markAsComponentHost(tView, tNode);
14276
- initTNodeFlags(tNode, rootView.length, 1);
14277
- }
14278
- addToViewTree(rootView, componentView);
14279
- // Store component view at node index, with node as the HOST
14280
- return rootView[index] = componentView;
14156
+ function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
14157
+ const bindingIndex = getBindingIndex();
14158
+ const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
14159
+ incrementBindingIndex(3);
14160
+ return different ?
14161
+ prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix :
14162
+ NO_CHANGE;
14281
14163
  }
14282
14164
  /**
14283
- * Creates a root component and sets it up with features and host bindings. Shared by
14284
- * renderComponent() and ViewContainerRef.createComponent().
14165
+ * Create an interpolation binding with 4 expressions.
14285
14166
  */
14286
- function createRootComponent(componentView, componentDef, rootLView, rootContext, hostFeatures) {
14287
- const tView = rootLView[TVIEW];
14288
- // Create directive instance with factory() and store at next index in viewData
14289
- const component = instantiateRootComponent(tView, rootLView, componentDef);
14290
- rootContext.components.push(component);
14291
- componentView[CONTEXT] = component;
14292
- if (hostFeatures !== null) {
14293
- for (const feature of hostFeatures) {
14294
- feature(component, componentDef);
14295
- }
14296
- }
14297
- // We want to generate an empty QueryList for root content queries for backwards
14298
- // compatibility with ViewEngine.
14299
- if (componentDef.contentQueries) {
14300
- const tNode = getCurrentTNode();
14301
- ngDevMode && assertDefined(tNode, 'TNode expected');
14302
- componentDef.contentQueries(1 /* RenderFlags.Create */, component, tNode.directiveStart);
14303
- }
14304
- const rootTNode = getCurrentTNode();
14305
- ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
14306
- if (tView.firstCreatePass &&
14307
- (componentDef.hostBindings !== null || componentDef.hostAttrs !== null)) {
14308
- setSelectedIndex(rootTNode.index);
14309
- const rootTView = rootLView[TVIEW];
14310
- registerHostBindingOpCodes(rootTView, rootTNode, rootLView, rootTNode.directiveStart, rootTNode.directiveEnd, componentDef);
14311
- invokeHostBindingsInCreationMode(componentDef, component);
14312
- }
14313
- return component;
14167
+ function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
14168
+ const bindingIndex = getBindingIndex();
14169
+ const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14170
+ incrementBindingIndex(4);
14171
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14172
+ renderStringify(v2) + i2 + renderStringify(v3) + suffix :
14173
+ NO_CHANGE;
14314
14174
  }
14315
- function createRootContext(scheduler, playerHandler) {
14316
- return {
14317
- components: [],
14318
- scheduler: scheduler || defaultScheduler,
14319
- clean: CLEAN_PROMISE,
14320
- playerHandler: playerHandler || null,
14321
- flags: 0 /* RootContextFlags.Empty */
14322
- };
14175
+ /**
14176
+ * Creates an interpolation binding with 5 expressions.
14177
+ */
14178
+ function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
14179
+ const bindingIndex = getBindingIndex();
14180
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14181
+ different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
14182
+ incrementBindingIndex(5);
14183
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14184
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix :
14185
+ NO_CHANGE;
14323
14186
  }
14324
14187
  /**
14325
- * Used to enable lifecycle hooks on the root component.
14188
+ * Creates an interpolation binding with 6 expressions.
14189
+ */
14190
+ function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
14191
+ const bindingIndex = getBindingIndex();
14192
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14193
+ different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
14194
+ incrementBindingIndex(6);
14195
+ return different ?
14196
+ prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
14197
+ renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix :
14198
+ NO_CHANGE;
14199
+ }
14200
+ /**
14201
+ * Creates an interpolation binding with 7 expressions.
14202
+ */
14203
+ function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
14204
+ const bindingIndex = getBindingIndex();
14205
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14206
+ different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
14207
+ incrementBindingIndex(7);
14208
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14209
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14210
+ renderStringify(v5) + i5 + renderStringify(v6) + suffix :
14211
+ NO_CHANGE;
14212
+ }
14213
+ /**
14214
+ * Creates an interpolation binding with 8 expressions.
14215
+ */
14216
+ function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
14217
+ const bindingIndex = getBindingIndex();
14218
+ let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14219
+ different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
14220
+ incrementBindingIndex(8);
14221
+ return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14222
+ renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14223
+ renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix :
14224
+ NO_CHANGE;
14225
+ }
14226
+
14227
+ /**
14326
14228
  *
14327
- * Include this feature when calling `renderComponent` if the root component
14328
- * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
14329
- * be called properly.
14229
+ * Update an interpolated attribute on an element with single bound value surrounded by text.
14330
14230
  *
14331
- * Example:
14231
+ * Used when the value passed to a property has 1 interpolated value in it:
14332
14232
  *
14233
+ * ```html
14234
+ * <div attr.title="prefix{{v0}}suffix"></div>
14333
14235
  * ```
14334
- * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
14236
+ *
14237
+ * Its compiled representation is::
14238
+ *
14239
+ * ```ts
14240
+ * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
14335
14241
  * ```
14242
+ *
14243
+ * @param attrName The name of the attribute to update
14244
+ * @param prefix Static value used for concatenation only.
14245
+ * @param v0 Value checked for change.
14246
+ * @param suffix Static value used for concatenation only.
14247
+ * @param sanitizer An optional sanitizer function
14248
+ * @returns itself, so that it may be chained.
14249
+ * @codeGenApi
14336
14250
  */
14337
- function LifecycleHooksFeature() {
14338
- const tNode = getCurrentTNode();
14339
- ngDevMode && assertDefined(tNode, 'TNode is required');
14340
- registerPostOrderHooks(getLView()[TVIEW], tNode);
14251
+ function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
14252
+ const lView = getLView();
14253
+ const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
14254
+ if (interpolatedValue !== NO_CHANGE) {
14255
+ const tNode = getSelectedTNode();
14256
+ elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14257
+ ngDevMode &&
14258
+ storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
14259
+ }
14260
+ return ɵɵattributeInterpolate1;
14341
14261
  }
14342
14262
  /**
14343
- * Wait on component until it is rendered.
14344
14263
  *
14345
- * This function returns a `Promise` which is resolved when the component's
14346
- * change detection is executed. This is determined by finding the scheduler
14347
- * associated with the `component`'s render tree and waiting until the scheduler
14348
- * flushes. If nothing is scheduled, the function returns a resolved promise.
14264
+ * Update an interpolated attribute on an element with 2 bound values surrounded by text.
14349
14265
  *
14350
- * Example:
14351
- * ```
14352
- * await whenRendered(myComponent);
14266
+ * Used when the value passed to a property has 2 interpolated values in it:
14267
+ *
14268
+ * ```html
14269
+ * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
14353
14270
  * ```
14354
14271
  *
14355
- * @param component Component to wait upon
14356
- * @returns Promise which resolves when the component is rendered.
14357
- */
14358
- function whenRendered(component) {
14359
- return getRootContext(component).clean;
14360
- }
14361
-
14362
- /**
14363
- * @license
14364
- * Copyright Google LLC All Rights Reserved.
14272
+ * Its compiled representation is::
14365
14273
  *
14366
- * Use of this source code is governed by an MIT-style license that can be
14367
- * found in the LICENSE file at https://angular.io/license
14368
- */
14369
- function getSuperType(type) {
14370
- return Object.getPrototypeOf(type.prototype).constructor;
14371
- }
14372
- /**
14373
- * Merges the definition from a super class to a sub class.
14374
- * @param definition The definition that is a SubClass of another directive of component
14375
- *
14376
- * @codeGenApi
14377
- */
14378
- function ɵɵInheritDefinitionFeature(definition) {
14379
- let superType = getSuperType(definition.type);
14380
- let shouldInheritFields = true;
14381
- const inheritanceChain = [definition];
14382
- while (superType) {
14383
- let superDef = undefined;
14384
- if (isComponentDef(definition)) {
14385
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14386
- superDef = superType.ɵcmp || superType.ɵdir;
14387
- }
14388
- else {
14389
- if (superType.ɵcmp) {
14390
- const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
14391
- `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}` :
14392
- '';
14393
- throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, errorMessage);
14394
- }
14395
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14396
- superDef = superType.ɵdir;
14397
- }
14398
- if (superDef) {
14399
- if (shouldInheritFields) {
14400
- inheritanceChain.push(superDef);
14401
- // Some fields in the definition may be empty, if there were no values to put in them that
14402
- // would've justified object creation. Unwrap them if necessary.
14403
- const writeableDef = definition;
14404
- writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
14405
- writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
14406
- writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
14407
- // Merge hostBindings
14408
- const superHostBindings = superDef.hostBindings;
14409
- superHostBindings && inheritHostBindings(definition, superHostBindings);
14410
- // Merge queries
14411
- const superViewQuery = superDef.viewQuery;
14412
- const superContentQueries = superDef.contentQueries;
14413
- superViewQuery && inheritViewQuery(definition, superViewQuery);
14414
- superContentQueries && inheritContentQueries(definition, superContentQueries);
14415
- // Merge inputs and outputs
14416
- fillProperties(definition.inputs, superDef.inputs);
14417
- fillProperties(definition.declaredInputs, superDef.declaredInputs);
14418
- fillProperties(definition.outputs, superDef.outputs);
14419
- // Merge animations metadata.
14420
- // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
14421
- if (isComponentDef(superDef) && superDef.data.animation) {
14422
- // If super def is a Component, the `definition` is also a Component, since Directives can
14423
- // not inherit Components (we throw an error above and cannot reach this code).
14424
- const defData = definition.data;
14425
- defData.animation = (defData.animation || []).concat(superDef.data.animation);
14426
- }
14427
- }
14428
- // Run parent features
14429
- const features = superDef.features;
14430
- if (features) {
14431
- for (let i = 0; i < features.length; i++) {
14432
- const feature = features[i];
14433
- if (feature && feature.ngInherit) {
14434
- feature(definition);
14435
- }
14436
- // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
14437
- // def already has all the necessary information inherited from its super class(es), so we
14438
- // can stop merging fields from super classes. However we need to iterate through the
14439
- // prototype chain to look for classes that might contain other "features" (like
14440
- // NgOnChanges), which we should invoke for the original `definition`. We set the
14441
- // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
14442
- // logic and only invoking functions from the "features" list.
14443
- if (feature === ɵɵInheritDefinitionFeature) {
14444
- shouldInheritFields = false;
14445
- }
14446
- }
14447
- }
14448
- }
14449
- superType = Object.getPrototypeOf(superType);
14450
- }
14451
- mergeHostAttrsAcrossInheritance(inheritanceChain);
14452
- }
14453
- /**
14454
- * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
14455
- *
14456
- * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
14457
- * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
14458
- * type.
14459
- */
14460
- function mergeHostAttrsAcrossInheritance(inheritanceChain) {
14461
- let hostVars = 0;
14462
- let hostAttrs = null;
14463
- // We process the inheritance order from the base to the leaves here.
14464
- for (let i = inheritanceChain.length - 1; i >= 0; i--) {
14465
- const def = inheritanceChain[i];
14466
- // For each `hostVars`, we need to add the superclass amount.
14467
- def.hostVars = (hostVars += def.hostVars);
14468
- // for each `hostAttrs` we need to merge it with superclass.
14469
- def.hostAttrs =
14470
- mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
14471
- }
14472
- }
14473
- function maybeUnwrapEmpty(value) {
14474
- if (value === EMPTY_OBJ) {
14475
- return {};
14476
- }
14477
- else if (value === EMPTY_ARRAY) {
14478
- return [];
14479
- }
14480
- else {
14481
- return value;
14482
- }
14483
- }
14484
- function inheritViewQuery(definition, superViewQuery) {
14485
- const prevViewQuery = definition.viewQuery;
14486
- if (prevViewQuery) {
14487
- definition.viewQuery = (rf, ctx) => {
14488
- superViewQuery(rf, ctx);
14489
- prevViewQuery(rf, ctx);
14490
- };
14491
- }
14492
- else {
14493
- definition.viewQuery = superViewQuery;
14494
- }
14495
- }
14496
- function inheritContentQueries(definition, superContentQueries) {
14497
- const prevContentQueries = definition.contentQueries;
14498
- if (prevContentQueries) {
14499
- definition.contentQueries = (rf, ctx, directiveIndex) => {
14500
- superContentQueries(rf, ctx, directiveIndex);
14501
- prevContentQueries(rf, ctx, directiveIndex);
14502
- };
14503
- }
14504
- else {
14505
- definition.contentQueries = superContentQueries;
14506
- }
14507
- }
14508
- function inheritHostBindings(definition, superHostBindings) {
14509
- const prevHostBindings = definition.hostBindings;
14510
- if (prevHostBindings) {
14511
- definition.hostBindings = (rf, ctx) => {
14512
- superHostBindings(rf, ctx);
14513
- prevHostBindings(rf, ctx);
14514
- };
14515
- }
14516
- else {
14517
- definition.hostBindings = superHostBindings;
14518
- }
14519
- }
14520
-
14521
- /**
14522
- * @license
14523
- * Copyright Google LLC All Rights Reserved.
14524
- *
14525
- * Use of this source code is governed by an MIT-style license that can be
14526
- * found in the LICENSE file at https://angular.io/license
14527
- */
14528
- /**
14529
- * Fields which exist on either directive or component definitions, and need to be copied from
14530
- * parent to child classes by the `ɵɵCopyDefinitionFeature`.
14531
- */
14532
- const COPY_DIRECTIVE_FIELDS = [
14533
- // The child class should use the providers of its parent.
14534
- 'providersResolver',
14535
- // Not listed here are any fields which are handled by the `ɵɵInheritDefinitionFeature`, such
14536
- // as inputs, outputs, and host binding functions.
14537
- ];
14538
- /**
14539
- * Fields which exist only on component definitions, and need to be copied from parent to child
14540
- * classes by the `ɵɵCopyDefinitionFeature`.
14541
- *
14542
- * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
14543
- * since those should go in `COPY_DIRECTIVE_FIELDS` above.
14544
- */
14545
- const COPY_COMPONENT_FIELDS = [
14546
- // The child class should use the template function of its parent, including all template
14547
- // semantics.
14548
- 'template',
14549
- 'decls',
14550
- 'consts',
14551
- 'vars',
14552
- 'onPush',
14553
- 'ngContentSelectors',
14554
- // The child class should use the CSS styles of its parent, including all styling semantics.
14555
- 'styles',
14556
- 'encapsulation',
14557
- // The child class should be checked by the runtime in the same way as its parent.
14558
- 'schemas',
14559
- ];
14560
- /**
14561
- * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
14562
- * definition.
14563
- *
14564
- * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
14565
- * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
14566
- * generates a skeleton definition on the child class, and applies this feature.
14567
- *
14568
- * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
14569
- * including things like the component template function.
14570
- *
14571
- * @param definition The definition of a child class which inherits from a parent class with its
14572
- * own definition.
14573
- *
14574
- * @codeGenApi
14575
- */
14576
- function ɵɵCopyDefinitionFeature(definition) {
14577
- let superType = getSuperType(definition.type);
14578
- let superDef = undefined;
14579
- if (isComponentDef(definition)) {
14580
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14581
- superDef = superType.ɵcmp;
14582
- }
14583
- else {
14584
- // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
14585
- superDef = superType.ɵdir;
14586
- }
14587
- // Needed because `definition` fields are readonly.
14588
- const defAny = definition;
14589
- // Copy over any fields that apply to either directives or components.
14590
- for (const field of COPY_DIRECTIVE_FIELDS) {
14591
- defAny[field] = superDef[field];
14592
- }
14593
- if (isComponentDef(superDef)) {
14594
- // Copy over any component-specific fields.
14595
- for (const field of COPY_COMPONENT_FIELDS) {
14596
- defAny[field] = superDef[field];
14597
- }
14598
- }
14599
- }
14600
-
14601
- /**
14602
- * @license
14603
- * Copyright Google LLC All Rights Reserved.
14604
- *
14605
- * Use of this source code is governed by an MIT-style license that can be
14606
- * found in the LICENSE file at https://angular.io/license
14607
- */
14608
- let _symbolIterator = null;
14609
- function getSymbolIterator() {
14610
- if (!_symbolIterator) {
14611
- const Symbol = _global$1['Symbol'];
14612
- if (Symbol && Symbol.iterator) {
14613
- _symbolIterator = Symbol.iterator;
14614
- }
14615
- else {
14616
- // es6-shim specific logic
14617
- const keys = Object.getOwnPropertyNames(Map.prototype);
14618
- for (let i = 0; i < keys.length; ++i) {
14619
- const key = keys[i];
14620
- if (key !== 'entries' && key !== 'size' &&
14621
- Map.prototype[key] === Map.prototype['entries']) {
14622
- _symbolIterator = key;
14623
- }
14624
- }
14625
- }
14626
- }
14627
- return _symbolIterator;
14628
- }
14629
-
14630
- /**
14631
- * @license
14632
- * Copyright Google LLC All Rights Reserved.
14633
- *
14634
- * Use of this source code is governed by an MIT-style license that can be
14635
- * found in the LICENSE file at https://angular.io/license
14636
- */
14637
- function isIterable(obj) {
14638
- return obj !== null && typeof obj === 'object' && obj[getSymbolIterator()] !== undefined;
14639
- }
14640
- function isListLikeIterable(obj) {
14641
- if (!isJsObject(obj))
14642
- return false;
14643
- return Array.isArray(obj) ||
14644
- (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
14645
- getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
14646
- }
14647
- function areIterablesEqual(a, b, comparator) {
14648
- const iterator1 = a[getSymbolIterator()]();
14649
- const iterator2 = b[getSymbolIterator()]();
14650
- while (true) {
14651
- const item1 = iterator1.next();
14652
- const item2 = iterator2.next();
14653
- if (item1.done && item2.done)
14654
- return true;
14655
- if (item1.done || item2.done)
14656
- return false;
14657
- if (!comparator(item1.value, item2.value))
14658
- return false;
14659
- }
14660
- }
14661
- function iterateListLike(obj, fn) {
14662
- if (Array.isArray(obj)) {
14663
- for (let i = 0; i < obj.length; i++) {
14664
- fn(obj[i]);
14665
- }
14666
- }
14667
- else {
14668
- const iterator = obj[getSymbolIterator()]();
14669
- let item;
14670
- while (!((item = iterator.next()).done)) {
14671
- fn(item.value);
14672
- }
14673
- }
14674
- }
14675
- function isJsObject(o) {
14676
- return o !== null && (typeof o === 'function' || typeof o === 'object');
14677
- }
14678
-
14679
- /**
14680
- * @license
14681
- * Copyright Google LLC All Rights Reserved.
14682
- *
14683
- * Use of this source code is governed by an MIT-style license that can be
14684
- * found in the LICENSE file at https://angular.io/license
14685
- */
14686
- function devModeEqual(a, b) {
14687
- const isListLikeIterableA = isListLikeIterable(a);
14688
- const isListLikeIterableB = isListLikeIterable(b);
14689
- if (isListLikeIterableA && isListLikeIterableB) {
14690
- return areIterablesEqual(a, b, devModeEqual);
14691
- }
14692
- else {
14693
- const isAObject = a && (typeof a === 'object' || typeof a === 'function');
14694
- const isBObject = b && (typeof b === 'object' || typeof b === 'function');
14695
- if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
14696
- return true;
14697
- }
14698
- else {
14699
- return Object.is(a, b);
14700
- }
14701
- }
14702
- }
14703
-
14704
- /**
14705
- * @license
14706
- * Copyright Google LLC All Rights Reserved.
14707
- *
14708
- * Use of this source code is governed by an MIT-style license that can be
14709
- * found in the LICENSE file at https://angular.io/license
14710
- */
14711
- // TODO(misko): consider inlining
14712
- /** Updates binding and returns the value. */
14713
- function updateBinding(lView, bindingIndex, value) {
14714
- return lView[bindingIndex] = value;
14715
- }
14716
- /** Gets the current binding value. */
14717
- function getBinding(lView, bindingIndex) {
14718
- ngDevMode && assertIndexInRange(lView, bindingIndex);
14719
- ngDevMode &&
14720
- assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
14721
- return lView[bindingIndex];
14722
- }
14723
- /**
14724
- * Updates binding if changed, then returns whether it was updated.
14725
- *
14726
- * This function also checks the `CheckNoChangesMode` and throws if changes are made.
14727
- * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
14728
- * behavior.
14729
- *
14730
- * @param lView current `LView`
14731
- * @param bindingIndex The binding in the `LView` to check
14732
- * @param value New value to check against `lView[bindingIndex]`
14733
- * @returns `true` if the bindings has changed. (Throws if binding has changed during
14734
- * `CheckNoChangesMode`)
14735
- */
14736
- function bindingUpdated(lView, bindingIndex, value) {
14737
- ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
14738
- ngDevMode &&
14739
- assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
14740
- const oldValue = lView[bindingIndex];
14741
- if (Object.is(oldValue, value)) {
14742
- return false;
14743
- }
14744
- else {
14745
- if (ngDevMode && isInCheckNoChangesMode()) {
14746
- // View engine didn't report undefined values as changed on the first checkNoChanges pass
14747
- // (before the change detection was run).
14748
- const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
14749
- if (!devModeEqual(oldValueToCompare, value)) {
14750
- const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
14751
- throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName);
14752
- }
14753
- // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
14754
- // For this reason we exit as if no change. The early exit is needed to prevent the changed
14755
- // value to be written into `LView` (If we would write the new value that we would not see it
14756
- // as change on next CD.)
14757
- return false;
14758
- }
14759
- lView[bindingIndex] = value;
14760
- return true;
14761
- }
14762
- }
14763
- /** Updates 2 bindings if changed, then returns whether either was updated. */
14764
- function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
14765
- const different = bindingUpdated(lView, bindingIndex, exp1);
14766
- return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
14767
- }
14768
- /** Updates 3 bindings if changed, then returns whether any was updated. */
14769
- function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
14770
- const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14771
- return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
14772
- }
14773
- /** Updates 4 bindings if changed, then returns whether any was updated. */
14774
- function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
14775
- const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
14776
- return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
14777
- }
14778
-
14779
- /**
14780
- * @license
14781
- * Copyright Google LLC All Rights Reserved.
14782
- *
14783
- * Use of this source code is governed by an MIT-style license that can be
14784
- * found in the LICENSE file at https://angular.io/license
14785
- */
14786
- /**
14787
- * Updates the value of or removes a bound attribute on an Element.
14788
- *
14789
- * Used in the case of `[attr.title]="value"`
14790
- *
14791
- * @param name name The name of the attribute.
14792
- * @param value value The attribute is removed when value is `null` or `undefined`.
14793
- * Otherwise the attribute value is set to the stringified value.
14794
- * @param sanitizer An optional function used to sanitize the value.
14795
- * @param namespace Optional namespace to use when setting the attribute.
14796
- *
14797
- * @codeGenApi
14798
- */
14799
- function ɵɵattribute(name, value, sanitizer, namespace) {
14800
- const lView = getLView();
14801
- const bindingIndex = nextBindingIndex();
14802
- if (bindingUpdated(lView, bindingIndex, value)) {
14803
- const tView = getTView();
14804
- const tNode = getSelectedTNode();
14805
- elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
14806
- ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
14807
- }
14808
- return ɵɵattribute;
14809
- }
14810
-
14811
- /**
14812
- * @license
14813
- * Copyright Google LLC All Rights Reserved.
14814
- *
14815
- * Use of this source code is governed by an MIT-style license that can be
14816
- * found in the LICENSE file at https://angular.io/license
14817
- */
14818
- /**
14819
- * Create interpolation bindings with a variable number of expressions.
14820
- *
14821
- * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
14822
- * Those are faster because there is no need to create an array of expressions and iterate over it.
14823
- *
14824
- * `values`:
14825
- * - has static text at even indexes,
14826
- * - has evaluated expressions at odd indexes.
14827
- *
14828
- * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
14829
- */
14830
- function interpolationV(lView, values) {
14831
- ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
14832
- ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
14833
- let isBindingUpdated = false;
14834
- let bindingIndex = getBindingIndex();
14835
- for (let i = 1; i < values.length; i += 2) {
14836
- // Check if bindings (odd indexes) have changed
14837
- isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
14838
- }
14839
- setBindingIndex(bindingIndex);
14840
- if (!isBindingUpdated) {
14841
- return NO_CHANGE;
14842
- }
14843
- // Build the updated content
14844
- let content = values[0];
14845
- for (let i = 1; i < values.length; i += 2) {
14846
- content += renderStringify(values[i]) + values[i + 1];
14847
- }
14848
- return content;
14849
- }
14850
- /**
14851
- * Creates an interpolation binding with 1 expression.
14852
- *
14853
- * @param prefix static value used for concatenation only.
14854
- * @param v0 value checked for change.
14855
- * @param suffix static value used for concatenation only.
14856
- */
14857
- function interpolation1(lView, prefix, v0, suffix) {
14858
- const different = bindingUpdated(lView, nextBindingIndex(), v0);
14859
- return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
14860
- }
14861
- /**
14862
- * Creates an interpolation binding with 2 expressions.
14863
- */
14864
- function interpolation2(lView, prefix, v0, i0, v1, suffix) {
14865
- const bindingIndex = getBindingIndex();
14866
- const different = bindingUpdated2(lView, bindingIndex, v0, v1);
14867
- incrementBindingIndex(2);
14868
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
14869
- }
14870
- /**
14871
- * Creates an interpolation binding with 3 expressions.
14872
- */
14873
- function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
14874
- const bindingIndex = getBindingIndex();
14875
- const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
14876
- incrementBindingIndex(3);
14877
- return different ?
14878
- prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix :
14879
- NO_CHANGE;
14880
- }
14881
- /**
14882
- * Create an interpolation binding with 4 expressions.
14883
- */
14884
- function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
14885
- const bindingIndex = getBindingIndex();
14886
- const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14887
- incrementBindingIndex(4);
14888
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14889
- renderStringify(v2) + i2 + renderStringify(v3) + suffix :
14890
- NO_CHANGE;
14891
- }
14892
- /**
14893
- * Creates an interpolation binding with 5 expressions.
14894
- */
14895
- function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
14896
- const bindingIndex = getBindingIndex();
14897
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14898
- different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
14899
- incrementBindingIndex(5);
14900
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14901
- renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix :
14902
- NO_CHANGE;
14903
- }
14904
- /**
14905
- * Creates an interpolation binding with 6 expressions.
14906
- */
14907
- function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
14908
- const bindingIndex = getBindingIndex();
14909
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14910
- different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
14911
- incrementBindingIndex(6);
14912
- return different ?
14913
- prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
14914
- renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix :
14915
- NO_CHANGE;
14916
- }
14917
- /**
14918
- * Creates an interpolation binding with 7 expressions.
14919
- */
14920
- function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
14921
- const bindingIndex = getBindingIndex();
14922
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14923
- different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
14924
- incrementBindingIndex(7);
14925
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14926
- renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14927
- renderStringify(v5) + i5 + renderStringify(v6) + suffix :
14928
- NO_CHANGE;
14929
- }
14930
- /**
14931
- * Creates an interpolation binding with 8 expressions.
14932
- */
14933
- function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
14934
- const bindingIndex = getBindingIndex();
14935
- let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
14936
- different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
14937
- incrementBindingIndex(8);
14938
- return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 +
14939
- renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 +
14940
- renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix :
14941
- NO_CHANGE;
14942
- }
14943
-
14944
- /**
14945
- *
14946
- * Update an interpolated attribute on an element with single bound value surrounded by text.
14947
- *
14948
- * Used when the value passed to a property has 1 interpolated value in it:
14949
- *
14950
- * ```html
14951
- * <div attr.title="prefix{{v0}}suffix"></div>
14952
- * ```
14953
- *
14954
- * Its compiled representation is::
14955
- *
14956
- * ```ts
14957
- * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
14958
- * ```
14959
- *
14960
- * @param attrName The name of the attribute to update
14961
- * @param prefix Static value used for concatenation only.
14962
- * @param v0 Value checked for change.
14963
- * @param suffix Static value used for concatenation only.
14964
- * @param sanitizer An optional sanitizer function
14965
- * @returns itself, so that it may be chained.
14966
- * @codeGenApi
14967
- */
14968
- function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
14969
- const lView = getLView();
14970
- const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
14971
- if (interpolatedValue !== NO_CHANGE) {
14972
- const tNode = getSelectedTNode();
14973
- elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
14974
- ngDevMode &&
14975
- storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
14976
- }
14977
- return ɵɵattributeInterpolate1;
14978
- }
14979
- /**
14980
- *
14981
- * Update an interpolated attribute on an element with 2 bound values surrounded by text.
14982
- *
14983
- * Used when the value passed to a property has 2 interpolated values in it:
14984
- *
14985
- * ```html
14986
- * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
14987
- * ```
14988
- *
14989
- * Its compiled representation is::
14990
- *
14991
- * ```ts
14992
- * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
14993
- * ```
14274
+ * ```ts
14275
+ * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
14276
+ * ```
14994
14277
  *
14995
14278
  * @param attrName The name of the attribute to update
14996
14279
  * @param prefix Static value used for concatenation only.
@@ -15326,6 +14609,57 @@ function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
15326
14609
  return ɵɵattributeInterpolateV;
15327
14610
  }
15328
14611
 
14612
+ /**
14613
+ * @license
14614
+ * Copyright Google LLC All Rights Reserved.
14615
+ *
14616
+ * Use of this source code is governed by an MIT-style license that can be
14617
+ * found in the LICENSE file at https://angular.io/license
14618
+ */
14619
+ /**
14620
+ * Synchronously perform change detection on a component (and possibly its sub-components).
14621
+ *
14622
+ * This function triggers change detection in a synchronous way on a component.
14623
+ *
14624
+ * @param component The component which the change detection should be performed on.
14625
+ */
14626
+ function detectChanges(component) {
14627
+ const view = getComponentViewByInstance(component);
14628
+ detectChangesInternal(view[TVIEW], view, component);
14629
+ }
14630
+ /**
14631
+ * Marks the component as dirty (needing change detection). Marking a component dirty will
14632
+ * schedule a change detection on it at some point in the future.
14633
+ *
14634
+ * Marking an already dirty component as dirty won't do anything. Only one outstanding change
14635
+ * detection can be scheduled per component tree.
14636
+ *
14637
+ * @param component Component to mark as dirty.
14638
+ */
14639
+ function markDirty(component) {
14640
+ ngDevMode && assertDefined(component, 'component');
14641
+ const rootView = markViewDirty(getComponentViewByInstance(component));
14642
+ ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
14643
+ scheduleTick(rootView[CONTEXT], 1 /* RootContextFlags.DetectChanges */);
14644
+ }
14645
+ /**
14646
+ * Used to perform change detection on the whole application.
14647
+ *
14648
+ * This is equivalent to `detectChanges`, but invoked on root component. Additionally, `tick`
14649
+ * executes lifecycle hooks and conditionally checks components based on their
14650
+ * `ChangeDetectionStrategy` and dirtiness.
14651
+ *
14652
+ * The preferred way to trigger change detection is to call `markDirty`. `markDirty` internally
14653
+ * schedules `tick` using a scheduler in order to coalesce multiple `markDirty` calls into a
14654
+ * single change detection run. By default, the scheduler is `requestAnimationFrame`, but can
14655
+ * be changed when calling `renderComponent` and providing the `scheduler` option.
14656
+ */
14657
+ function tick(component) {
14658
+ const rootView = getRootView(component);
14659
+ const rootContext = rootView[CONTEXT];
14660
+ tickRootContext(rootContext);
14661
+ }
14662
+
15329
14663
  /**
15330
14664
  * @license
15331
14665
  * Copyright Google LLC All Rights Reserved.
@@ -15870,51 +15204,42 @@ function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn,
15870
15204
  tNode.index;
15871
15205
  // In order to match current behavior, native DOM event listeners must be added for all
15872
15206
  // events (including outputs).
15873
- if (isProceduralRenderer(renderer)) {
15874
- // There might be cases where multiple directives on the same element try to register an event
15875
- // handler function for the same event. In this situation we want to avoid registration of
15876
- // several native listeners as each registration would be intercepted by NgZone and
15877
- // trigger change detection. This would mean that a single user action would result in several
15878
- // change detections being invoked. To avoid this situation we want to have only one call to
15879
- // native handler registration (for the same element and same type of event).
15880
- //
15881
- // In order to have just one native event handler in presence of multiple handler functions,
15882
- // we just register a first handler function as a native event listener and then chain
15883
- // (coalesce) other handler functions on top of the first native handler function.
15884
- let existingListener = null;
15885
- // Please note that the coalescing described here doesn't happen for events specifying an
15886
- // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
15887
- // view engine.
15888
- // Also, we don't have to search for existing listeners is there are no directives
15889
- // matching on a given node as we can't register multiple event handlers for the same event in
15890
- // a template (this would mean having duplicate attributes).
15891
- if (!eventTargetResolver && isTNodeDirectiveHost) {
15892
- existingListener = findExistingListener(tView, lView, eventName, tNode.index);
15893
- }
15894
- if (existingListener !== null) {
15895
- // Attach a new listener to coalesced listeners list, maintaining the order in which
15896
- // listeners are registered. For performance reasons, we keep a reference to the last
15897
- // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
15898
- // the entire set each time we need to add a new listener.
15899
- const lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
15900
- lastListenerFn.__ngNextListenerFn__ = listenerFn;
15901
- existingListener.__ngLastListenerFn__ = listenerFn;
15902
- processOutputs = false;
15903
- }
15904
- else {
15905
- listenerFn = wrapListener(tNode, lView, context, listenerFn, false /** preventDefault */);
15906
- const cleanupFn = renderer.listen(target, eventName, listenerFn);
15907
- ngDevMode && ngDevMode.rendererAddEventListener++;
15908
- lCleanup.push(listenerFn, cleanupFn);
15909
- tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
15910
- }
15207
+ // There might be cases where multiple directives on the same element try to register an event
15208
+ // handler function for the same event. In this situation we want to avoid registration of
15209
+ // several native listeners as each registration would be intercepted by NgZone and
15210
+ // trigger change detection. This would mean that a single user action would result in several
15211
+ // change detections being invoked. To avoid this situation we want to have only one call to
15212
+ // native handler registration (for the same element and same type of event).
15213
+ //
15214
+ // In order to have just one native event handler in presence of multiple handler functions,
15215
+ // we just register a first handler function as a native event listener and then chain
15216
+ // (coalesce) other handler functions on top of the first native handler function.
15217
+ let existingListener = null;
15218
+ // Please note that the coalescing described here doesn't happen for events specifying an
15219
+ // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
15220
+ // view engine.
15221
+ // Also, we don't have to search for existing listeners is there are no directives
15222
+ // matching on a given node as we can't register multiple event handlers for the same event in
15223
+ // a template (this would mean having duplicate attributes).
15224
+ if (!eventTargetResolver && isTNodeDirectiveHost) {
15225
+ existingListener = findExistingListener(tView, lView, eventName, tNode.index);
15226
+ }
15227
+ if (existingListener !== null) {
15228
+ // Attach a new listener to coalesced listeners list, maintaining the order in which
15229
+ // listeners are registered. For performance reasons, we keep a reference to the last
15230
+ // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
15231
+ // the entire set each time we need to add a new listener.
15232
+ const lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
15233
+ lastListenerFn.__ngNextListenerFn__ = listenerFn;
15234
+ existingListener.__ngLastListenerFn__ = listenerFn;
15235
+ processOutputs = false;
15911
15236
  }
15912
15237
  else {
15913
- listenerFn = wrapListener(tNode, lView, context, listenerFn, true /** preventDefault */);
15914
- target.addEventListener(eventName, listenerFn, useCapture);
15238
+ listenerFn = wrapListener(tNode, lView, context, listenerFn, false /** preventDefault */);
15239
+ const cleanupFn = renderer.listen(target, eventName, listenerFn);
15915
15240
  ngDevMode && ngDevMode.rendererAddEventListener++;
15916
- lCleanup.push(listenerFn);
15917
- tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, useCapture);
15241
+ lCleanup.push(listenerFn, cleanupFn);
15242
+ tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
15918
15243
  }
15919
15244
  }
15920
15245
  else {
@@ -17988,7 +17313,7 @@ function findStylingValue(tData, tNode, lView, prop, index, isClassBased) {
17988
17313
  valueAtLViewIndex = isStylingMap ? EMPTY_ARRAY : undefined;
17989
17314
  }
17990
17315
  let currentValue = isStylingMap ? keyValueArrayGet(valueAtLViewIndex, prop) :
17991
- key === prop ? valueAtLViewIndex : undefined;
17316
+ (key === prop ? valueAtLViewIndex : undefined);
17992
17317
  if (containsStatics && !isStylingValuePresent(currentValue)) {
17993
17318
  currentValue = keyValueArrayGet(rawKey, prop);
17994
17319
  }
@@ -19511,7 +18836,7 @@ function findLocaleData(locale) {
19511
18836
  if (parentLocale === 'en') {
19512
18837
  return localeEn;
19513
18838
  }
19514
- throw new Error(`Missing locale data for the locale "${locale}".`);
18839
+ throw new RuntimeError(701 /* RuntimeErrorCode.MISSING_LOCALE_DATA */, ngDevMode && `Missing locale data for the locale "${locale}".`);
19515
18840
  }
19516
18841
  /**
19517
18842
  * Retrieves the default currency code for the given locale.
@@ -21841,7 +21166,7 @@ function noComponentFactoryError(component) {
21841
21166
  return error;
21842
21167
  }
21843
21168
  const ERROR_COMPONENT = 'ngComponent';
21844
- function getComponent(error) {
21169
+ function getComponent$1(error) {
21845
21170
  return error[ERROR_COMPONENT];
21846
21171
  }
21847
21172
  class _NullComponentFactoryResolver {
@@ -22025,14 +21350,6 @@ class Renderer2 {
22025
21350
  * @nocollapse
22026
21351
  */
22027
21352
  Renderer2.__NG_ELEMENT_ID__ = () => injectRenderer2();
22028
- /** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */
22029
- function getOrCreateRenderer2(lView) {
22030
- const renderer = lView[RENDERER];
22031
- if (ngDevMode && !isProceduralRenderer(renderer)) {
22032
- throw new Error('Cannot inject Renderer2 when the application uses Renderer3!');
22033
- }
22034
- return renderer;
22035
- }
22036
21353
  /** Injects a Renderer2 for the current component. */
22037
21354
  function injectRenderer2() {
22038
21355
  // We need the Renderer to be based on the component that it's being injected into, however since
@@ -22040,7 +21357,7 @@ function injectRenderer2() {
22040
21357
  const lView = getLView();
22041
21358
  const tNode = getCurrentTNode();
22042
21359
  const nodeAtIndex = getComponentLViewByIndex(tNode.index, lView);
22043
- return getOrCreateRenderer2(isLView(nodeAtIndex) ? nodeAtIndex : lView);
21360
+ return (isLView(nodeAtIndex) ? nodeAtIndex : lView)[RENDERER];
22044
21361
  }
22045
21362
 
22046
21363
  /**
@@ -22087,7 +21404,7 @@ class Version {
22087
21404
  /**
22088
21405
  * @publicApi
22089
21406
  */
22090
- const VERSION = new Version('14.1.0-next.1');
21407
+ const VERSION = new Version('14.1.0-next.4');
22091
21408
 
22092
21409
  /**
22093
21410
  * @license
@@ -22425,8 +21742,7 @@ class ViewRef {
22425
21742
  }
22426
21743
  attachToViewContainerRef() {
22427
21744
  if (this._appRef) {
22428
- const errorMessage = ngDevMode ? 'This view is already attached directly to the ApplicationRef!' : '';
22429
- throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, errorMessage);
21745
+ throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached directly to the ApplicationRef!');
22430
21746
  }
22431
21747
  this._attachedToViewContainer = true;
22432
21748
  }
@@ -22436,8 +21752,7 @@ class ViewRef {
22436
21752
  }
22437
21753
  attachToAppRef(appRef) {
22438
21754
  if (this._attachedToViewContainer) {
22439
- const errorMessage = ngDevMode ? 'This view is already attached to a ViewContainer!' : '';
22440
- throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, errorMessage);
21755
+ throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached to a ViewContainer!');
22441
21756
  }
22442
21757
  this._appRef = appRef;
22443
21758
  }
@@ -22553,7 +21868,13 @@ class ComponentFactory extends ComponentFactory$1 {
22553
21868
  realEnvironmentInjector;
22554
21869
  }
22555
21870
  const rootViewInjector = realEnvironmentInjector ? new ChainedInjector(injector, realEnvironmentInjector) : injector;
22556
- const rendererFactory = rootViewInjector.get(RendererFactory2, domRendererFactory3);
21871
+ const rendererFactory = rootViewInjector.get(RendererFactory2, null);
21872
+ if (rendererFactory === null) {
21873
+ throw new RuntimeError(407 /* RuntimeErrorCode.RENDERER_NOT_FOUND */, ngDevMode &&
21874
+ 'Angular was not able to inject a renderer (RendererFactory2). ' +
21875
+ 'Likely this is due to a broken DI hierarchy. ' +
21876
+ 'Make sure that any injector used to create this component has a correct parent.');
21877
+ }
22557
21878
  const sanitizer = rootViewInjector.get(Sanitizer, null);
22558
21879
  const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
22559
21880
  // Determine a tag name used for creating host elements when this component is created
@@ -22617,218 +21938,656 @@ class ComponentFactory extends ComponentFactory$1 {
22617
21938
  finally {
22618
21939
  leaveView();
22619
21940
  }
22620
- return new ComponentRef(this.componentType, component, createElementRef(tElementNode, rootLView), rootLView, tElementNode);
21941
+ return new ComponentRef(this.componentType, component, createElementRef(tElementNode, rootLView), rootLView, tElementNode);
21942
+ }
21943
+ }
21944
+ const componentFactoryResolver = new ComponentFactoryResolver();
21945
+ /**
21946
+ * Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
21947
+ * ComponentFactoryResolver
21948
+ * already exists, retrieves the existing ComponentFactoryResolver.
21949
+ *
21950
+ * @returns The ComponentFactoryResolver instance to use
21951
+ */
21952
+ function injectComponentFactoryResolver() {
21953
+ return componentFactoryResolver;
21954
+ }
21955
+ /**
21956
+ * Represents an instance of a Component created via a {@link ComponentFactory}.
21957
+ *
21958
+ * `ComponentRef` provides access to the Component Instance as well other objects related to this
21959
+ * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
21960
+ * method.
21961
+ *
21962
+ */
21963
+ class ComponentRef extends ComponentRef$1 {
21964
+ constructor(componentType, instance, location, _rootLView, _tNode) {
21965
+ super();
21966
+ this.location = location;
21967
+ this._rootLView = _rootLView;
21968
+ this._tNode = _tNode;
21969
+ this.instance = instance;
21970
+ this.hostView = this.changeDetectorRef = new RootViewRef(_rootLView);
21971
+ this.componentType = componentType;
21972
+ }
21973
+ setInput(name, value) {
21974
+ const inputData = this._tNode.inputs;
21975
+ let dataValue;
21976
+ if (inputData !== null && (dataValue = inputData[name])) {
21977
+ const lView = this._rootLView;
21978
+ setInputsForProperty(lView[TVIEW], lView, dataValue, name, value);
21979
+ markDirtyIfOnPush(lView, this._tNode.index);
21980
+ }
21981
+ else {
21982
+ if (ngDevMode) {
21983
+ const cmpNameForError = stringifyForError(this.componentType);
21984
+ let message = `Can't set value of the '${name}' input on the '${cmpNameForError}' component. `;
21985
+ message += `Make sure that the '${name}' property is annotated with @Input() or a mapped @Input('${name}') exists.`;
21986
+ reportUnknownPropertyError(message);
21987
+ }
21988
+ }
21989
+ }
21990
+ get injector() {
21991
+ return new NodeInjector(this._tNode, this._rootLView);
21992
+ }
21993
+ destroy() {
21994
+ this.hostView.destroy();
21995
+ }
21996
+ onDestroy(callback) {
21997
+ this.hostView.onDestroy(callback);
21998
+ }
21999
+ }
22000
+
22001
+ /**
22002
+ * @license
22003
+ * Copyright Google LLC All Rights Reserved.
22004
+ *
22005
+ * Use of this source code is governed by an MIT-style license that can be
22006
+ * found in the LICENSE file at https://angular.io/license
22007
+ */
22008
+ /**
22009
+ * Returns a new NgModuleRef instance based on the NgModule class and parent injector provided.
22010
+ * @param ngModule NgModule class.
22011
+ * @param parentInjector Optional injector instance to use as a parent for the module injector. If
22012
+ * not provided, `NullInjector` will be used instead.
22013
+ * @publicApi
22014
+ */
22015
+ function createNgModuleRef(ngModule, parentInjector) {
22016
+ return new NgModuleRef(ngModule, parentInjector !== null && parentInjector !== void 0 ? parentInjector : null);
22017
+ }
22018
+ class NgModuleRef extends NgModuleRef$1 {
22019
+ constructor(ngModuleType, _parent) {
22020
+ super();
22021
+ this._parent = _parent;
22022
+ // tslint:disable-next-line:require-internal-with-underscore
22023
+ this._bootstrapComponents = [];
22024
+ this.injector = this;
22025
+ this.destroyCbs = [];
22026
+ // When bootstrapping a module we have a dependency graph that looks like this:
22027
+ // ApplicationRef -> ComponentFactoryResolver -> NgModuleRef. The problem is that if the
22028
+ // module being resolved tries to inject the ComponentFactoryResolver, it'll create a
22029
+ // circular dependency which will result in a runtime error, because the injector doesn't
22030
+ // exist yet. We work around the issue by creating the ComponentFactoryResolver ourselves
22031
+ // and providing it, rather than letting the injector resolve it.
22032
+ this.componentFactoryResolver = new ComponentFactoryResolver(this);
22033
+ const ngModuleDef = getNgModuleDef(ngModuleType);
22034
+ ngDevMode &&
22035
+ assertDefined(ngModuleDef, `NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
22036
+ this._bootstrapComponents = maybeUnwrapFn$1(ngModuleDef.bootstrap);
22037
+ this._r3Injector = createInjectorWithoutInjectorInstances(ngModuleType, _parent, [
22038
+ { provide: NgModuleRef$1, useValue: this }, {
22039
+ provide: ComponentFactoryResolver$1,
22040
+ useValue: this.componentFactoryResolver
22041
+ }
22042
+ ], stringify(ngModuleType), new Set(['environment']));
22043
+ // We need to resolve the injector types separately from the injector creation, because
22044
+ // the module might be trying to use this ref in its constructor for DI which will cause a
22045
+ // circular error that will eventually error out, because the injector isn't created yet.
22046
+ this._r3Injector.resolveInjectorInitializers();
22047
+ this.instance = this.get(ngModuleType);
22048
+ }
22049
+ get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, injectFlags = InjectFlags.Default) {
22050
+ if (token === Injector || token === NgModuleRef$1 || token === INJECTOR) {
22051
+ return this;
22052
+ }
22053
+ return this._r3Injector.get(token, notFoundValue, injectFlags);
22054
+ }
22055
+ runInContext(fn) {
22056
+ return this.injector.runInContext(fn);
22057
+ }
22058
+ destroy() {
22059
+ ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22060
+ const injector = this._r3Injector;
22061
+ !injector.destroyed && injector.destroy();
22062
+ this.destroyCbs.forEach(fn => fn());
22063
+ this.destroyCbs = null;
22064
+ }
22065
+ onDestroy(callback) {
22066
+ ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22067
+ this.destroyCbs.push(callback);
22068
+ }
22069
+ }
22070
+ class NgModuleFactory extends NgModuleFactory$1 {
22071
+ constructor(moduleType) {
22072
+ super();
22073
+ this.moduleType = moduleType;
22074
+ }
22075
+ create(parentInjector) {
22076
+ return new NgModuleRef(this.moduleType, parentInjector);
22077
+ }
22078
+ }
22079
+ class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
22080
+ constructor(providers, parent, source) {
22081
+ super();
22082
+ this.componentFactoryResolver = new ComponentFactoryResolver(this);
22083
+ this.instance = null;
22084
+ const injector = new R3Injector([
22085
+ ...providers,
22086
+ { provide: NgModuleRef$1, useValue: this },
22087
+ { provide: ComponentFactoryResolver$1, useValue: this.componentFactoryResolver },
22088
+ ], parent || getNullInjector(), source, new Set(['environment']));
22089
+ this.injector = injector;
22090
+ injector.resolveInjectorInitializers();
22091
+ }
22092
+ destroy() {
22093
+ this.injector.destroy();
22094
+ }
22095
+ onDestroy(callback) {
22096
+ this.injector.onDestroy(callback);
22097
+ }
22098
+ }
22099
+ /**
22100
+ * Create a new environment injector.
22101
+ *
22102
+ * Learn more about environment injectors in
22103
+ * [this guide](guide/standalone-components#environment-injectors).
22104
+ *
22105
+ * @param providers An array of providers.
22106
+ * @param parent A parent environment injector.
22107
+ * @param debugName An optional name for this injector instance, which will be used in error
22108
+ * messages.
22109
+ *
22110
+ * @publicApi
22111
+ * @developerPreview
22112
+ */
22113
+ function createEnvironmentInjector(providers, parent, debugName = null) {
22114
+ const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
22115
+ return adapter.injector;
22116
+ }
22117
+
22118
+ /**
22119
+ * @license
22120
+ * Copyright Google LLC All Rights Reserved.
22121
+ *
22122
+ * Use of this source code is governed by an MIT-style license that can be
22123
+ * found in the LICENSE file at https://angular.io/license
22124
+ */
22125
+ /**
22126
+ * A service used by the framework to create instances of standalone injectors. Those injectors are
22127
+ * created on demand in case of dynamic component instantiation and contain ambient providers
22128
+ * collected from the imports graph rooted at a given standalone component.
22129
+ */
22130
+ class StandaloneService {
22131
+ constructor(_injector) {
22132
+ this._injector = _injector;
22133
+ this.cachedInjectors = new Map();
22134
+ }
22135
+ getOrCreateStandaloneInjector(componentDef) {
22136
+ if (!componentDef.standalone) {
22137
+ return null;
22138
+ }
22139
+ if (!this.cachedInjectors.has(componentDef.id)) {
22140
+ const providers = internalImportProvidersFrom(false, componentDef.type);
22141
+ const standaloneInjector = providers.length > 0 ?
22142
+ createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
22143
+ null;
22144
+ this.cachedInjectors.set(componentDef.id, standaloneInjector);
22145
+ }
22146
+ return this.cachedInjectors.get(componentDef.id);
22147
+ }
22148
+ ngOnDestroy() {
22149
+ try {
22150
+ for (const injector of this.cachedInjectors.values()) {
22151
+ if (injector !== null) {
22152
+ injector.destroy();
22153
+ }
22154
+ }
22155
+ }
22156
+ finally {
22157
+ this.cachedInjectors.clear();
22158
+ }
22159
+ }
22160
+ }
22161
+ /** @nocollapse */
22162
+ StandaloneService.ɵprov = ɵɵdefineInjectable({
22163
+ token: StandaloneService,
22164
+ providedIn: 'environment',
22165
+ factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
22166
+ });
22167
+ /**
22168
+ * A feature that acts as a setup code for the {@link StandaloneService}.
22169
+ *
22170
+ * The most important responsaibility of this feature is to expose the "getStandaloneInjector"
22171
+ * function (an entry points to a standalone injector creation) on a component definition object. We
22172
+ * go through the features infrastructure to make sure that the standalone injector creation logic
22173
+ * is tree-shakable and not included in applications that don't use standalone components.
22174
+ *
22175
+ * @codeGenApi
22176
+ */
22177
+ function ɵɵStandaloneFeature(definition) {
22178
+ definition.getStandaloneInjector = (parentInjector) => {
22179
+ return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
22180
+ };
22181
+ }
22182
+
22183
+ /**
22184
+ * @license
22185
+ * Copyright Google LLC All Rights Reserved.
22186
+ *
22187
+ * Use of this source code is governed by an MIT-style license that can be
22188
+ * found in the LICENSE file at https://angular.io/license
22189
+ */
22190
+ /**
22191
+ * Retrieves the component instance associated with a given DOM element.
22192
+ *
22193
+ * @usageNotes
22194
+ * Given the following DOM structure:
22195
+ *
22196
+ * ```html
22197
+ * <app-root>
22198
+ * <div>
22199
+ * <child-comp></child-comp>
22200
+ * </div>
22201
+ * </app-root>
22202
+ * ```
22203
+ *
22204
+ * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
22205
+ * associated with this DOM element.
22206
+ *
22207
+ * Calling the function on `<app-root>` will return the `MyApp` instance.
22208
+ *
22209
+ *
22210
+ * @param element DOM element from which the component should be retrieved.
22211
+ * @returns Component instance associated with the element or `null` if there
22212
+ * is no component associated with it.
22213
+ *
22214
+ * @publicApi
22215
+ * @globalApi ng
22216
+ */
22217
+ function getComponent(element) {
22218
+ ngDevMode && assertDomElement(element);
22219
+ const context = getLContext(element);
22220
+ if (context === null)
22221
+ return null;
22222
+ if (context.component === undefined) {
22223
+ const lView = context.lView;
22224
+ if (lView === null) {
22225
+ return null;
22226
+ }
22227
+ context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
22621
22228
  }
22229
+ return context.component;
22622
22230
  }
22623
- const componentFactoryResolver = new ComponentFactoryResolver();
22624
22231
  /**
22625
- * Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
22626
- * ComponentFactoryResolver
22627
- * already exists, retrieves the existing ComponentFactoryResolver.
22232
+ * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
22233
+ * view that the element is part of. Otherwise retrieves the instance of the component whose view
22234
+ * owns the element (in this case, the result is the same as calling `getOwningComponent`).
22628
22235
  *
22629
- * @returns The ComponentFactoryResolver instance to use
22236
+ * @param element Element for which to get the surrounding component instance.
22237
+ * @returns Instance of the component that is around the element or null if the element isn't
22238
+ * inside any component.
22239
+ *
22240
+ * @publicApi
22241
+ * @globalApi ng
22630
22242
  */
22631
- function injectComponentFactoryResolver() {
22632
- return componentFactoryResolver;
22243
+ function getContext(element) {
22244
+ assertDomElement(element);
22245
+ const context = getLContext(element);
22246
+ const lView = context ? context.lView : null;
22247
+ return lView === null ? null : lView[CONTEXT];
22633
22248
  }
22634
22249
  /**
22635
- * Represents an instance of a Component created via a {@link ComponentFactory}.
22250
+ * Retrieves the component instance whose view contains the DOM element.
22636
22251
  *
22637
- * `ComponentRef` provides access to the Component Instance as well other objects related to this
22638
- * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
22639
- * method.
22252
+ * For example, if `<child-comp>` is used in the template of `<app-comp>`
22253
+ * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
22254
+ * would return `<app-comp>`.
22255
+ *
22256
+ * @param elementOrDir DOM element, component or directive instance
22257
+ * for which to retrieve the root components.
22258
+ * @returns Component instance whose view owns the DOM element or null if the element is not
22259
+ * part of a component view.
22640
22260
  *
22261
+ * @publicApi
22262
+ * @globalApi ng
22641
22263
  */
22642
- class ComponentRef extends ComponentRef$1 {
22643
- constructor(componentType, instance, location, _rootLView, _tNode) {
22644
- super();
22645
- this.location = location;
22646
- this._rootLView = _rootLView;
22647
- this._tNode = _tNode;
22648
- this.instance = instance;
22649
- this.hostView = this.changeDetectorRef = new RootViewRef(_rootLView);
22650
- this.componentType = componentType;
22651
- }
22652
- get injector() {
22653
- return new NodeInjector(this._tNode, this._rootLView);
22654
- }
22655
- destroy() {
22656
- this.hostView.destroy();
22657
- }
22658
- onDestroy(callback) {
22659
- this.hostView.onDestroy(callback);
22264
+ function getOwningComponent(elementOrDir) {
22265
+ const context = getLContext(elementOrDir);
22266
+ let lView = context ? context.lView : null;
22267
+ if (lView === null)
22268
+ return null;
22269
+ let parent;
22270
+ while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
22271
+ lView = parent;
22660
22272
  }
22273
+ return lView[FLAGS] & 256 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
22661
22274
  }
22662
-
22663
22275
  /**
22664
- * @license
22665
- * Copyright Google LLC All Rights Reserved.
22276
+ * Retrieves all root components associated with a DOM element, directive or component instance.
22277
+ * Root components are those which have been bootstrapped by Angular.
22666
22278
  *
22667
- * Use of this source code is governed by an MIT-style license that can be
22668
- * found in the LICENSE file at https://angular.io/license
22279
+ * @param elementOrDir DOM element, component or directive instance
22280
+ * for which to retrieve the root components.
22281
+ * @returns Root components associated with the target object.
22282
+ *
22283
+ * @publicApi
22284
+ * @globalApi ng
22669
22285
  */
22286
+ function getRootComponents(elementOrDir) {
22287
+ const lView = readPatchedLView(elementOrDir);
22288
+ return lView !== null ? [...getRootContext(lView).components] : [];
22289
+ }
22670
22290
  /**
22671
- * Returns a new NgModuleRef instance based on the NgModule class and parent injector provided.
22672
- * @param ngModule NgModule class.
22673
- * @param parentInjector Optional injector instance to use as a parent for the module injector. If
22674
- * not provided, `NullInjector` will be used instead.
22291
+ * Retrieves an `Injector` associated with an element, component or directive instance.
22292
+ *
22293
+ * @param elementOrDir DOM element, component or directive instance for which to
22294
+ * retrieve the injector.
22295
+ * @returns Injector associated with the element, component or directive instance.
22296
+ *
22675
22297
  * @publicApi
22298
+ * @globalApi ng
22676
22299
  */
22677
- function createNgModuleRef(ngModule, parentInjector) {
22678
- return new NgModuleRef(ngModule, parentInjector !== null && parentInjector !== void 0 ? parentInjector : null);
22300
+ function getInjector(elementOrDir) {
22301
+ const context = getLContext(elementOrDir);
22302
+ const lView = context ? context.lView : null;
22303
+ if (lView === null)
22304
+ return Injector.NULL;
22305
+ const tNode = lView[TVIEW].data[context.nodeIndex];
22306
+ return new NodeInjector(tNode, lView);
22679
22307
  }
22680
- class NgModuleRef extends NgModuleRef$1 {
22681
- constructor(ngModuleType, _parent) {
22682
- super();
22683
- this._parent = _parent;
22684
- // tslint:disable-next-line:require-internal-with-underscore
22685
- this._bootstrapComponents = [];
22686
- this.injector = this;
22687
- this.destroyCbs = [];
22688
- // When bootstrapping a module we have a dependency graph that looks like this:
22689
- // ApplicationRef -> ComponentFactoryResolver -> NgModuleRef. The problem is that if the
22690
- // module being resolved tries to inject the ComponentFactoryResolver, it'll create a
22691
- // circular dependency which will result in a runtime error, because the injector doesn't
22692
- // exist yet. We work around the issue by creating the ComponentFactoryResolver ourselves
22693
- // and providing it, rather than letting the injector resolve it.
22694
- this.componentFactoryResolver = new ComponentFactoryResolver(this);
22695
- const ngModuleDef = getNgModuleDef(ngModuleType);
22696
- ngDevMode &&
22697
- assertDefined(ngModuleDef, `NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
22698
- this._bootstrapComponents = maybeUnwrapFn$1(ngModuleDef.bootstrap);
22699
- this._r3Injector = createInjectorWithoutInjectorInstances(ngModuleType, _parent, [
22700
- { provide: NgModuleRef$1, useValue: this }, {
22701
- provide: ComponentFactoryResolver$1,
22702
- useValue: this.componentFactoryResolver
22703
- }
22704
- ], stringify(ngModuleType), new Set(['environment']));
22705
- // We need to resolve the injector types separately from the injector creation, because
22706
- // the module might be trying to use this ref in its constructor for DI which will cause a
22707
- // circular error that will eventually error out, because the injector isn't created yet.
22708
- this._r3Injector.resolveInjectorInitializers();
22709
- this.instance = this.get(ngModuleType);
22710
- }
22711
- get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND, injectFlags = InjectFlags.Default) {
22712
- if (token === Injector || token === NgModuleRef$1 || token === INJECTOR) {
22713
- return this;
22308
+ /**
22309
+ * Retrieve a set of injection tokens at a given DOM node.
22310
+ *
22311
+ * @param element Element for which the injection tokens should be retrieved.
22312
+ */
22313
+ function getInjectionTokens(element) {
22314
+ const context = getLContext(element);
22315
+ const lView = context ? context.lView : null;
22316
+ if (lView === null)
22317
+ return [];
22318
+ const tView = lView[TVIEW];
22319
+ const tNode = tView.data[context.nodeIndex];
22320
+ const providerTokens = [];
22321
+ const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
22322
+ const endIndex = tNode.directiveEnd;
22323
+ for (let i = startIndex; i < endIndex; i++) {
22324
+ let value = tView.data[i];
22325
+ if (isDirectiveDefHack(value)) {
22326
+ // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
22327
+ // design flaw. We should always store same type so that we can be monomorphic. The issue
22328
+ // is that for Components/Directives we store the def instead the type. The correct behavior
22329
+ // is that we should always be storing injectable type in this location.
22330
+ value = value.type;
22714
22331
  }
22715
- return this._r3Injector.get(token, notFoundValue, injectFlags);
22332
+ providerTokens.push(value);
22716
22333
  }
22717
- destroy() {
22718
- ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22719
- const injector = this._r3Injector;
22720
- !injector.destroyed && injector.destroy();
22721
- this.destroyCbs.forEach(fn => fn());
22722
- this.destroyCbs = null;
22334
+ return providerTokens;
22335
+ }
22336
+ /**
22337
+ * Retrieves directive instances associated with a given DOM node. Does not include
22338
+ * component instances.
22339
+ *
22340
+ * @usageNotes
22341
+ * Given the following DOM structure:
22342
+ *
22343
+ * ```html
22344
+ * <app-root>
22345
+ * <button my-button></button>
22346
+ * <my-comp></my-comp>
22347
+ * </app-root>
22348
+ * ```
22349
+ *
22350
+ * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
22351
+ * directive that is associated with the DOM node.
22352
+ *
22353
+ * Calling `getDirectives` on `<my-comp>` will return an empty array.
22354
+ *
22355
+ * @param node DOM node for which to get the directives.
22356
+ * @returns Array of directives associated with the node.
22357
+ *
22358
+ * @publicApi
22359
+ * @globalApi ng
22360
+ */
22361
+ function getDirectives(node) {
22362
+ // Skip text nodes because we can't have directives associated with them.
22363
+ if (node instanceof Text) {
22364
+ return [];
22723
22365
  }
22724
- onDestroy(callback) {
22725
- ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
22726
- this.destroyCbs.push(callback);
22366
+ const context = getLContext(node);
22367
+ const lView = context ? context.lView : null;
22368
+ if (lView === null) {
22369
+ return [];
22370
+ }
22371
+ const tView = lView[TVIEW];
22372
+ const nodeIndex = context.nodeIndex;
22373
+ if (!(tView === null || tView === void 0 ? void 0 : tView.data[nodeIndex])) {
22374
+ return [];
22375
+ }
22376
+ if (context.directives === undefined) {
22377
+ context.directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
22378
+ }
22379
+ // The `directives` in this case are a named array called `LComponentView`. Clone the
22380
+ // result so we don't expose an internal data structure in the user's console.
22381
+ return context.directives === null ? [] : [...context.directives];
22382
+ }
22383
+ /**
22384
+ * Returns the debug (partial) metadata for a particular directive or component instance.
22385
+ * The function accepts an instance of a directive or component and returns the corresponding
22386
+ * metadata.
22387
+ *
22388
+ * @param directiveOrComponentInstance Instance of a directive or component
22389
+ * @returns metadata of the passed directive or component
22390
+ *
22391
+ * @publicApi
22392
+ * @globalApi ng
22393
+ */
22394
+ function getDirectiveMetadata(directiveOrComponentInstance) {
22395
+ const { constructor } = directiveOrComponentInstance;
22396
+ if (!constructor) {
22397
+ throw new Error('Unable to find the instance constructor');
22727
22398
  }
22728
- }
22729
- class NgModuleFactory extends NgModuleFactory$1 {
22730
- constructor(moduleType) {
22731
- super();
22732
- this.moduleType = moduleType;
22399
+ // In case a component inherits from a directive, we may have component and directive metadata
22400
+ // To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
22401
+ const componentDef = getComponentDef$1(constructor);
22402
+ if (componentDef) {
22403
+ return {
22404
+ inputs: componentDef.inputs,
22405
+ outputs: componentDef.outputs,
22406
+ encapsulation: componentDef.encapsulation,
22407
+ changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush :
22408
+ ChangeDetectionStrategy.Default
22409
+ };
22733
22410
  }
22734
- create(parentInjector) {
22735
- return new NgModuleRef(this.moduleType, parentInjector);
22411
+ const directiveDef = getDirectiveDef(constructor);
22412
+ if (directiveDef) {
22413
+ return { inputs: directiveDef.inputs, outputs: directiveDef.outputs };
22736
22414
  }
22415
+ return null;
22737
22416
  }
22738
- class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
22739
- constructor(providers, parent, source) {
22740
- super();
22741
- this.componentFactoryResolver = new ComponentFactoryResolver(this);
22742
- this.instance = null;
22743
- const injector = new R3Injector([
22744
- ...providers,
22745
- { provide: NgModuleRef$1, useValue: this },
22746
- { provide: ComponentFactoryResolver$1, useValue: this.componentFactoryResolver },
22747
- ], parent || getNullInjector(), source, new Set(['environment']));
22748
- this.injector = injector;
22749
- injector.resolveInjectorInitializers();
22750
- }
22751
- destroy() {
22752
- this.injector.destroy();
22753
- }
22754
- onDestroy(callback) {
22755
- this.injector.onDestroy(callback);
22417
+ /**
22418
+ * Retrieve map of local references.
22419
+ *
22420
+ * The references are retrieved as a map of local reference name to element or directive instance.
22421
+ *
22422
+ * @param target DOM element, component or directive instance for which to retrieve
22423
+ * the local references.
22424
+ */
22425
+ function getLocalRefs(target) {
22426
+ const context = getLContext(target);
22427
+ if (context === null)
22428
+ return {};
22429
+ if (context.localRefs === undefined) {
22430
+ const lView = context.lView;
22431
+ if (lView === null) {
22432
+ return {};
22433
+ }
22434
+ context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
22756
22435
  }
22436
+ return context.localRefs || {};
22757
22437
  }
22758
22438
  /**
22759
- * Create a new environment injector.
22439
+ * Retrieves the host element of a component or directive instance.
22440
+ * The host element is the DOM element that matched the selector of the directive.
22441
+ *
22442
+ * @param componentOrDirective Component or directive instance for which the host
22443
+ * element should be retrieved.
22444
+ * @returns Host element of the target.
22760
22445
  *
22761
22446
  * @publicApi
22762
- * @developerPreview
22447
+ * @globalApi ng
22763
22448
  */
22764
- function createEnvironmentInjector(providers, parent = null, debugName = null) {
22765
- const adapter = new EnvironmentNgModuleRefAdapter(providers, parent, debugName);
22766
- return adapter.injector;
22449
+ function getHostElement(componentOrDirective) {
22450
+ return getLContext(componentOrDirective).native;
22767
22451
  }
22768
-
22769
22452
  /**
22770
- * @license
22771
- * Copyright Google LLC All Rights Reserved.
22453
+ * Retrieves the rendered text for a given component.
22772
22454
  *
22773
- * Use of this source code is governed by an MIT-style license that can be
22774
- * found in the LICENSE file at https://angular.io/license
22455
+ * This function retrieves the host element of a component and
22456
+ * and then returns the `textContent` for that element. This implies
22457
+ * that the text returned will include re-projected content of
22458
+ * the component as well.
22459
+ *
22460
+ * @param component The component to return the content text for.
22775
22461
  */
22462
+ function getRenderedText(component) {
22463
+ const hostElement = getHostElement(component);
22464
+ return hostElement.textContent || '';
22465
+ }
22776
22466
  /**
22777
- * A service used by the framework to create instances of standalone injectors. Those injectors are
22778
- * created on demand in case of dynamic component instantiation and contain ambient providers
22779
- * collected from the imports graph rooted at a given standalone component.
22467
+ * Retrieves a list of event listeners associated with a DOM element. The list does include host
22468
+ * listeners, but it does not include event listeners defined outside of the Angular context
22469
+ * (e.g. through `addEventListener`).
22470
+ *
22471
+ * @usageNotes
22472
+ * Given the following DOM structure:
22473
+ *
22474
+ * ```html
22475
+ * <app-root>
22476
+ * <div (click)="doSomething()"></div>
22477
+ * </app-root>
22478
+ * ```
22479
+ *
22480
+ * Calling `getListeners` on `<div>` will return an object that looks as follows:
22481
+ *
22482
+ * ```ts
22483
+ * {
22484
+ * name: 'click',
22485
+ * element: <div>,
22486
+ * callback: () => doSomething(),
22487
+ * useCapture: false
22488
+ * }
22489
+ * ```
22490
+ *
22491
+ * @param element Element for which the DOM listeners should be retrieved.
22492
+ * @returns Array of event listeners on the DOM element.
22493
+ *
22494
+ * @publicApi
22495
+ * @globalApi ng
22780
22496
  */
22781
- class StandaloneService {
22782
- constructor(_injector) {
22783
- this._injector = _injector;
22784
- this.cachedInjectors = new Map();
22785
- }
22786
- getOrCreateStandaloneInjector(componentDef) {
22787
- if (!componentDef.standalone) {
22788
- return null;
22789
- }
22790
- if (!this.cachedInjectors.has(componentDef.id)) {
22791
- const providers = internalImportProvidersFrom(false, componentDef.type);
22792
- const standaloneInjector = providers.length > 0 ?
22793
- createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) :
22794
- null;
22795
- this.cachedInjectors.set(componentDef.id, standaloneInjector);
22796
- }
22797
- return this.cachedInjectors.get(componentDef.id);
22798
- }
22799
- ngOnDestroy() {
22800
- try {
22801
- for (const injector of this.cachedInjectors.values()) {
22802
- if (injector !== null) {
22803
- injector.destroy();
22497
+ function getListeners(element) {
22498
+ ngDevMode && assertDomElement(element);
22499
+ const lContext = getLContext(element);
22500
+ const lView = lContext === null ? null : lContext.lView;
22501
+ if (lView === null)
22502
+ return [];
22503
+ const tView = lView[TVIEW];
22504
+ const lCleanup = lView[CLEANUP];
22505
+ const tCleanup = tView.cleanup;
22506
+ const listeners = [];
22507
+ if (tCleanup && lCleanup) {
22508
+ for (let i = 0; i < tCleanup.length;) {
22509
+ const firstParam = tCleanup[i++];
22510
+ const secondParam = tCleanup[i++];
22511
+ if (typeof firstParam === 'string') {
22512
+ const name = firstParam;
22513
+ const listenerElement = unwrapRNode(lView[secondParam]);
22514
+ const callback = lCleanup[tCleanup[i++]];
22515
+ const useCaptureOrIndx = tCleanup[i++];
22516
+ // if useCaptureOrIndx is boolean then report it as is.
22517
+ // if useCaptureOrIndx is positive number then it in unsubscribe method
22518
+ // if useCaptureOrIndx is negative number then it is a Subscription
22519
+ const type = (typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0) ? 'dom' : 'output';
22520
+ const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
22521
+ if (element == listenerElement) {
22522
+ listeners.push({ element, name, callback, useCapture, type });
22804
22523
  }
22805
22524
  }
22806
22525
  }
22807
- finally {
22808
- this.cachedInjectors.clear();
22809
- }
22810
22526
  }
22527
+ listeners.sort(sortListeners);
22528
+ return listeners;
22529
+ }
22530
+ function sortListeners(a, b) {
22531
+ if (a.name == b.name)
22532
+ return 0;
22533
+ return a.name < b.name ? -1 : 1;
22811
22534
  }
22812
- /** @nocollapse */
22813
- StandaloneService.ɵprov = ɵɵdefineInjectable({
22814
- token: StandaloneService,
22815
- providedIn: 'environment',
22816
- factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector)),
22817
- });
22818
22535
  /**
22819
- * A feature that acts as a setup code for the {@link StandaloneService}.
22536
+ * This function should not exist because it is megamorphic and only mostly correct.
22820
22537
  *
22821
- * The most important responsaibility of this feature is to expose the "getStandaloneInjector"
22822
- * function (an entry points to a standalone injector creation) on a component definition object. We
22823
- * go through the features infrastructure to make sure that the standalone injector creation logic
22824
- * is tree-shakable and not included in applications that don't use standalone components.
22538
+ * See call site for more info.
22539
+ */
22540
+ function isDirectiveDefHack(obj) {
22541
+ return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
22542
+ }
22543
+ /**
22544
+ * Returns the attached `DebugNode` instance for an element in the DOM.
22825
22545
  *
22826
- * @codeGenApi
22546
+ * @param element DOM element which is owned by an existing component's view.
22827
22547
  */
22828
- function ɵɵStandaloneFeature(definition) {
22829
- definition.getStandaloneInjector = (parentInjector) => {
22830
- return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
22831
- };
22548
+ function getDebugNode(element) {
22549
+ if (ngDevMode && !(element instanceof Node)) {
22550
+ throw new Error('Expecting instance of DOM Element');
22551
+ }
22552
+ const lContext = getLContext(element);
22553
+ const lView = lContext ? lContext.lView : null;
22554
+ if (lView === null) {
22555
+ return null;
22556
+ }
22557
+ const nodeIndex = lContext.nodeIndex;
22558
+ if (nodeIndex !== -1) {
22559
+ const valueInLView = lView[nodeIndex];
22560
+ // this means that value in the lView is a component with its own
22561
+ // data. In this situation the TNode is not accessed at the same spot.
22562
+ const tNode = isLView(valueInLView) ? valueInLView[T_HOST] : getTNode(lView[TVIEW], nodeIndex);
22563
+ ngDevMode &&
22564
+ assertEqual(tNode.index, nodeIndex, 'Expecting that TNode at index is same as index');
22565
+ return buildDebugNode(tNode, lView);
22566
+ }
22567
+ return null;
22568
+ }
22569
+ /**
22570
+ * Retrieve the component `LView` from component/element.
22571
+ *
22572
+ * NOTE: `LView` is a private and should not be leaked outside.
22573
+ * Don't export this method to `ng.*` on window.
22574
+ *
22575
+ * @param target DOM element or component instance for which to retrieve the LView.
22576
+ */
22577
+ function getComponentLView(target) {
22578
+ const lContext = getLContext(target);
22579
+ const nodeIndx = lContext.nodeIndex;
22580
+ const lView = lContext.lView;
22581
+ ngDevMode && assertLView(lView);
22582
+ const componentLView = lView[nodeIndx];
22583
+ ngDevMode && assertLView(componentLView);
22584
+ return componentLView;
22585
+ }
22586
+ /** Asserts that a value is a DOM Element. */
22587
+ function assertDomElement(value) {
22588
+ if (typeof Element !== 'undefined' && !(value instanceof Element)) {
22589
+ throw new Error('Expecting instance of DOM Element');
22590
+ }
22832
22591
  }
22833
22592
 
22834
22593
  /**
@@ -24049,7 +23808,7 @@ const unusedValueExportToPlacateAjd = 1;
24049
23808
  * Use of this source code is governed by an MIT-style license that can be
24050
23809
  * found in the LICENSE file at https://angular.io/license
24051
23810
  */
24052
- const unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd;
23811
+ const unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$6 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd;
24053
23812
  class LQuery_ {
24054
23813
  constructor(queryList) {
24055
23814
  this.queryList = queryList;
@@ -24716,7 +24475,7 @@ function patchModuleCompilation() {
24716
24475
  function isModuleWithProviders$1(value) {
24717
24476
  return value.ngModule !== undefined;
24718
24477
  }
24719
- function isNgModule(value) {
24478
+ function isNgModule$1(value) {
24720
24479
  return !!getNgModuleDef(value);
24721
24480
  }
24722
24481
 
@@ -25139,7 +24898,7 @@ function patchComponentDefWithScope(componentDef, transitiveScopes) {
25139
24898
  * (either a NgModule or a standalone component / directive / pipe).
25140
24899
  */
25141
24900
  function transitiveScopesFor(type) {
25142
- if (isNgModule(type)) {
24901
+ if (isNgModule$1(type)) {
25143
24902
  return transitiveScopesForNgModule(type);
25144
24903
  }
25145
24904
  else if (isStandalone(type)) {
@@ -25223,7 +24982,7 @@ function transitiveScopesForNgModule(moduleType) {
25223
24982
  const exportedType = exported;
25224
24983
  // Either the type is a module, a pipe, or a component/directive (which may not have a
25225
24984
  // ɵcmp as it might be compiled asynchronously).
25226
- if (isNgModule(exportedType)) {
24985
+ if (isNgModule$1(exportedType)) {
25227
24986
  // When this module exports another, the exported module's exported directives and pipes are
25228
24987
  // added to both the compilation and exported scopes of this module.
25229
24988
  const exportedScope = transitiveScopesFor(exportedType);
@@ -25523,7 +25282,7 @@ class R3TestBedCompiler {
25523
25282
  // module's provider list.
25524
25283
  this.providerOverridesByModule = new Map();
25525
25284
  this.providerOverridesByToken = new Map();
25526
- this.moduleProvidersOverridden = new Set();
25285
+ this.scopesWithOverriddenProviders = new Set();
25527
25286
  this.testModuleRef = null;
25528
25287
  class DynamicTestModule {
25529
25288
  }
@@ -25694,7 +25453,7 @@ class R3TestBedCompiler {
25694
25453
  this.queueTypesFromModulesArray([moduleType]);
25695
25454
  this.compileTypesSync();
25696
25455
  this.applyProviderOverrides();
25697
- this.applyProviderOverridesToModule(moduleType);
25456
+ this.applyProviderOverridesInScope(moduleType);
25698
25457
  this.applyTransitiveScopes();
25699
25458
  }
25700
25459
  /**
@@ -25705,7 +25464,7 @@ class R3TestBedCompiler {
25705
25464
  this.queueTypesFromModulesArray([moduleType]);
25706
25465
  yield this.compileComponents();
25707
25466
  this.applyProviderOverrides();
25708
- this.applyProviderOverridesToModule(moduleType);
25467
+ this.applyProviderOverridesInScope(moduleType);
25709
25468
  this.applyTransitiveScopes();
25710
25469
  });
25711
25470
  }
@@ -25807,51 +25566,53 @@ class R3TestBedCompiler {
25807
25566
  this.seenComponents.clear();
25808
25567
  this.seenDirectives.clear();
25809
25568
  }
25810
- applyProviderOverridesToModule(moduleType) {
25569
+ /**
25570
+ * Applies provider overrides to a given type (either an NgModule or a standalone component)
25571
+ * and all imported NgModules and standalone components recursively.
25572
+ */
25573
+ applyProviderOverridesInScope(type) {
25811
25574
  var _a;
25812
- if (this.moduleProvidersOverridden.has(moduleType)) {
25575
+ const hasScope = isStandaloneComponent(type) || isNgModule(type);
25576
+ // The function can be re-entered recursively while inspecting dependencies
25577
+ // of an NgModule or a standalone component. Exit early if we come across a
25578
+ // type that can not have a scope (directive or pipe) or the type is already
25579
+ // processed earlier.
25580
+ if (!hasScope || this.scopesWithOverriddenProviders.has(type)) {
25813
25581
  return;
25814
25582
  }
25815
- this.moduleProvidersOverridden.add(moduleType);
25583
+ this.scopesWithOverriddenProviders.add(type);
25816
25584
  // NOTE: the line below triggers JIT compilation of the module injector,
25817
25585
  // which also invokes verification of the NgModule semantics, which produces
25818
25586
  // detailed error messages. The fact that the code relies on this line being
25819
25587
  // present here is suspicious and should be refactored in a way that the line
25820
25588
  // below can be moved (for ex. after an early exit check below).
25821
- const injectorDef = moduleType[ɵNG_INJ_DEF];
25589
+ const injectorDef = type[ɵNG_INJ_DEF];
25822
25590
  // No provider overrides, exit early.
25823
25591
  if (this.providerOverridesByToken.size === 0)
25824
25592
  return;
25825
- if (isStandaloneComponent(moduleType)) {
25593
+ if (isStandaloneComponent(type)) {
25826
25594
  // Visit all component dependencies and override providers there.
25827
- const def = getComponentDef(moduleType);
25595
+ const def = getComponentDef(type);
25828
25596
  const dependencies = maybeUnwrapFn((_a = def.dependencies) !== null && _a !== void 0 ? _a : []);
25829
25597
  for (const dependency of dependencies) {
25830
- // Proceed with examining dependencies recursively
25831
- // when a dependency is a standalone component or an NgModule.
25832
- // In AOT, the `dependencies` might also contain regular (NgModule-based)
25833
- // Component, Directive and Pipes. Skip them here, they are handled in a
25834
- // different location (in the `configureTestingModule` function).
25835
- if (isStandaloneComponent(dependency) || hasNgModuleDef(dependency)) {
25836
- this.applyProviderOverridesToModule(dependency);
25837
- }
25598
+ this.applyProviderOverridesInScope(dependency);
25838
25599
  }
25839
25600
  }
25840
25601
  else {
25841
25602
  const providers = [
25842
25603
  ...injectorDef.providers,
25843
- ...(this.providerOverridesByModule.get(moduleType) || [])
25604
+ ...(this.providerOverridesByModule.get(type) || [])
25844
25605
  ];
25845
25606
  if (this.hasProviderOverrides(providers)) {
25846
- this.maybeStoreNgDef(ɵNG_INJ_DEF, moduleType);
25847
- this.storeFieldOfDefOnType(moduleType, ɵNG_INJ_DEF, 'providers');
25607
+ this.maybeStoreNgDef(ɵNG_INJ_DEF, type);
25608
+ this.storeFieldOfDefOnType(type, ɵNG_INJ_DEF, 'providers');
25848
25609
  injectorDef.providers = this.getOverriddenProviders(providers);
25849
25610
  }
25850
25611
  // Apply provider overrides to imported modules recursively
25851
- const moduleDef = moduleType[ɵNG_MOD_DEF];
25612
+ const moduleDef = type[ɵNG_MOD_DEF];
25852
25613
  const imports = maybeUnwrapFn(moduleDef.imports);
25853
25614
  for (const importedModule of imports) {
25854
- this.applyProviderOverridesToModule(importedModule);
25615
+ this.applyProviderOverridesInScope(importedModule);
25855
25616
  }
25856
25617
  // Also override the providers on any ModuleWithProviders imports since those don't appear in
25857
25618
  // the moduleDef.
@@ -26089,7 +25850,7 @@ class R3TestBedCompiler {
26089
25850
  });
26090
25851
  });
26091
25852
  this.initialNgDefs.clear();
26092
- this.moduleProvidersOverridden.clear();
25853
+ this.scopesWithOverriddenProviders.clear();
26093
25854
  this.restoreComponentResolutionQueue();
26094
25855
  // Restore the locale ID to the default value, this shouldn't be necessary but we never know
26095
25856
  ɵsetLocaleId(ɵDEFAULT_LOCALE_ID);
@@ -26116,7 +25877,7 @@ class R3TestBedCompiler {
26116
25877
  providers,
26117
25878
  }, /* allowDuplicateDeclarationsInRoot */ true);
26118
25879
  // clang-format on
26119
- this.applyProviderOverridesToModule(this.testModuleType);
25880
+ this.applyProviderOverridesInScope(this.testModuleType);
26120
25881
  }
26121
25882
  get injector() {
26122
25883
  if (this._injector !== null) {
@@ -26217,6 +25978,9 @@ function getComponentDef(value) {
26217
25978
  function hasNgModuleDef(value) {
26218
25979
  return value.hasOwnProperty('ɵmod');
26219
25980
  }
25981
+ function isNgModule(value) {
25982
+ return hasNgModuleDef(value);
25983
+ }
26220
25984
  function maybeUnwrapFn(maybeFn) {
26221
25985
  return maybeFn instanceof Function ? maybeFn() : maybeFn;
26222
25986
  }