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