@angular/core 14.0.0-rc.2 → 14.0.0-rc.3

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v14.0.0-rc.2
2
+ * @license Angular v14.0.0-rc.3
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -2044,9 +2044,9 @@ function setCurrentInjector(injector) {
2044
2044
  function injectInjectorOnly(token, flags = InjectFlags.Default) {
2045
2045
  if (_currentInjector === undefined) {
2046
2046
  const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ?
2047
- `inject() must be called from an injection context` :
2047
+ `inject() must be called from an injection context (a constructor, a factory function or a field initializer)` :
2048
2048
  '';
2049
- throw new RuntimeError(203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, errorMessage);
2049
+ throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, errorMessage);
2050
2050
  }
2051
2051
  else if (_currentInjector === null) {
2052
2052
  return injectRootLimpMode(token, undefined, flags);
@@ -2081,29 +2081,71 @@ Please check that 1) the type for the parameter at index ${index} is correct and
2081
2081
  }
2082
2082
  /**
2083
2083
  * Injects a token from the currently active injector.
2084
- *
2085
- * Must be used in the context of a factory function such as one defined for an
2086
- * `InjectionToken`. Throws an error if not called from such a context.
2087
- *
2088
- * Within such a factory function, using this function to request injection of a dependency
2089
- * is faster and more type-safe than providing an additional array of dependencies
2090
- * (as has been common with `useFactory` providers).
2091
- *
2092
- * @param token The injection token for the dependency to be injected.
2084
+ * `inject` is only supported during instantiation of a dependency by the DI system. It can be used
2085
+ * during:
2086
+ * - Construction (via the `constructor`) of a class being instantiated by the DI system, such
2087
+ * as an `@Injectable` or `@Component`.
2088
+ * - In the initializer for fields of such classes.
2089
+ * - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
2090
+ * - In the `factory` function specified for an `InjectionToken`.
2091
+ *
2092
+ * @param token A token that represents a dependency that should be injected.
2093
2093
  * @param flags Optional flags that control how injection is executed.
2094
2094
  * The flags correspond to injection strategies that can be specified with
2095
2095
  * parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
2096
- * @returns the injected value if injection is successful, `null` otherwise.
2096
+ * @returns the injected value if operation is successful, `null` otherwise.
2097
+ * @throws if called outside of a supported context.
2097
2098
  *
2098
2099
  * @usageNotes
2100
+ * In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
2101
+ * field initializer:
2099
2102
  *
2100
- * ### Example
2103
+ * ```typescript
2104
+ * @Injectable({providedIn: 'root'})
2105
+ * export class Car {
2106
+ * radio: Radio|undefined;
2107
+ * // OK: field initializer
2108
+ * spareTyre = inject(Tyre);
2101
2109
  *
2102
- * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
2110
+ * constructor() {
2111
+ * // OK: constructor body
2112
+ * this.radio = inject(Radio);
2113
+ * }
2114
+ * }
2115
+ * ```
2116
+ *
2117
+ * It is also legal to call `inject` from a provider's factory:
2118
+ *
2119
+ * ```typescript
2120
+ * providers: [
2121
+ * {provide: Car, useFactory: () => {
2122
+ * // OK: a class factory
2123
+ * const engine = inject(Engine);
2124
+ * return new Car(engine);
2125
+ * }}
2126
+ * ]
2127
+ * ```
2128
+ *
2129
+ * Calls to the `inject()` function outside of the class creation context will result in error. Most
2130
+ * notably, calls to `inject()` are disallowed after a class instance was created, in methods
2131
+ * (including lifecycle hooks):
2132
+ *
2133
+ * ```typescript
2134
+ * @Component({ ... })
2135
+ * export class CarComponent {
2136
+ * ngOnInit() {
2137
+ * // ERROR: too late, the component instance was already created
2138
+ * const engine = inject(Engine);
2139
+ * engine.start();
2140
+ * }
2141
+ * }
2142
+ * ```
2103
2143
  *
2104
2144
  * @publicApi
2105
2145
  */
2106
- const inject$1 = ɵɵinject;
2146
+ function inject$1(token, flags = InjectFlags.Default) {
2147
+ return ɵɵinject(token, flags);
2148
+ }
2107
2149
  function injectArgs(types) {
2108
2150
  const args = [];
2109
2151
  for (let i = 0; i < types.length; i++) {
@@ -2519,8 +2561,8 @@ function ɵɵdefineComponent(componentDefinition) {
2519
2561
  */
2520
2562
  function ɵɵsetComponentScope(type, directives, pipes) {
2521
2563
  const def = type.ɵcmp;
2522
- def.directiveDefs = () => directives.map(extractDirectiveDef);
2523
- def.pipeDefs = () => pipes.map(getPipeDef$1);
2564
+ def.directiveDefs = () => (typeof directives === 'function' ? directives() : directives).map(extractDirectiveDef);
2565
+ def.pipeDefs = () => (typeof pipes === 'function' ? pipes() : pipes).map(getPipeDef$1);
2524
2566
  }
2525
2567
  function extractDirectiveDef(type) {
2526
2568
  return getComponentDef$1(type) || getDirectiveDef(type);
@@ -11670,20 +11712,55 @@ function createTNodeAtIndex(tView, index, type, name, attrs) {
11670
11712
  return tNode;
11671
11713
  }
11672
11714
  /**
11673
- * Checks if the current component is declared inside of a standalone component template.
11715
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
11716
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
11717
+ * be too slow for production mode and also it relies on the constructor function being available.
11718
+ *
11719
+ * Gets a reference to the host component def (where a current component is declared).
11674
11720
  *
11675
11721
  * @param lView An `LView` that represents a current component that is being rendered.
11676
11722
  */
11677
- function isHostComponentStandalone(lView) {
11723
+ function getDeclarationComponentDef(lView) {
11678
11724
  !ngDevMode && throwError('Must never be called in production mode');
11679
11725
  const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
11680
11726
  const context = declarationLView[CONTEXT];
11681
- // Unable to obtain a context, fall back to the non-standalone scenario.
11727
+ // Unable to obtain a context.
11682
11728
  if (!context)
11683
- return false;
11684
- const componentDef = getComponentDef$1(context.constructor);
11729
+ return null;
11730
+ return context.constructor ? getComponentDef$1(context.constructor) : null;
11731
+ }
11732
+ /**
11733
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
11734
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
11735
+ * be too slow for production mode.
11736
+ *
11737
+ * Checks if the current component is declared inside of a standalone component template.
11738
+ *
11739
+ * @param lView An `LView` that represents a current component that is being rendered.
11740
+ */
11741
+ function isHostComponentStandalone(lView) {
11742
+ !ngDevMode && throwError('Must never be called in production mode');
11743
+ const componentDef = getDeclarationComponentDef(lView);
11744
+ // Treat host component as non-standalone if we can't obtain the def.
11685
11745
  return !!(componentDef === null || componentDef === void 0 ? void 0 : componentDef.standalone);
11686
11746
  }
11747
+ /**
11748
+ * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
11749
+ * and must **not** be used in production bundles. The function makes megamorphic reads, which might
11750
+ * be too slow for production mode.
11751
+ *
11752
+ * Constructs a string describing the location of the host component template. The function is used
11753
+ * in dev mode to produce error messages.
11754
+ *
11755
+ * @param lView An `LView` that represents a current component that is being rendered.
11756
+ */
11757
+ function getTemplateLocationDetails(lView) {
11758
+ var _a;
11759
+ !ngDevMode && throwError('Must never be called in production mode');
11760
+ const hostComponentDef = getDeclarationComponentDef(lView);
11761
+ const componentClassName = (_a = hostComponentDef === null || hostComponentDef === void 0 ? void 0 : hostComponentDef.type) === null || _a === void 0 ? void 0 : _a.name;
11762
+ return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
11763
+ }
11687
11764
  /**
11688
11765
  * When elements are created dynamically after a view blueprint is created (e.g. through
11689
11766
  * i18nApply()), we need to adjust the blueprint for future
@@ -12352,7 +12429,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
12352
12429
  validateAgainstEventProperties(propName);
12353
12430
  if (!validateProperty(element, tNode.value, propName, tView.schemas)) {
12354
12431
  // Return here since we only log warnings for unknown properties.
12355
- handleUnknownPropertyError(propName, tNode);
12432
+ handleUnknownPropertyError(propName, tNode, lView);
12356
12433
  return;
12357
12434
  }
12358
12435
  ngDevMode.rendererSetProperty++;
@@ -12372,7 +12449,7 @@ function elementPropertyInternal(tView, tNode, lView, propName, value, renderer,
12372
12449
  // If the node is a container and the property didn't
12373
12450
  // match any of the inputs or schemas we should throw.
12374
12451
  if (ngDevMode && !matchingSchemas(tView.schemas, tNode.value)) {
12375
- handleUnknownPropertyError(propName, tNode);
12452
+ handleUnknownPropertyError(propName, tNode, lView);
12376
12453
  }
12377
12454
  }
12378
12455
  }
@@ -12473,12 +12550,20 @@ function matchingSchemas(schemas, tagName) {
12473
12550
  }
12474
12551
  return false;
12475
12552
  }
12553
+ /**
12554
+ * The set of known control flow directives.
12555
+ * We use this set to produce a more precises error message with a note
12556
+ * that the `CommonModule` should also be included.
12557
+ */
12558
+ const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set(['ngIf', 'ngFor', 'ngSwitch', 'ngSwitchCase', 'ngSwitchDefault']);
12476
12559
  /**
12477
12560
  * Logs or throws an error that a property is not supported on an element.
12561
+ *
12478
12562
  * @param propName Name of the invalid property.
12479
- * @param tagName Name of the node on which we encountered the property.
12563
+ * @param tNode A `TNode` that represents a current component that is being rendered.
12564
+ * @param lView An `LView` that represents a current component that is being rendered.
12480
12565
  */
12481
- function handleUnknownPropertyError(propName, tNode) {
12566
+ function handleUnknownPropertyError(propName, tNode, lView) {
12482
12567
  let tagName = tNode.value;
12483
12568
  // Special-case a situation when a structural directive is applied to
12484
12569
  // an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
@@ -12489,7 +12574,36 @@ function handleUnknownPropertyError(propName, tNode) {
12489
12574
  if (!tagName && tNode.type === 4 /* TNodeType.Container */) {
12490
12575
  tagName = 'ng-template';
12491
12576
  }
12492
- const message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'.`;
12577
+ const isHostStandalone = isHostComponentStandalone(lView);
12578
+ const templateLocation = getTemplateLocationDetails(lView);
12579
+ let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
12580
+ const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
12581
+ const importLocation = isHostStandalone ?
12582
+ 'included in the \'@Component.imports\' of this component' :
12583
+ 'a part of an @NgModule where this component is declared';
12584
+ if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
12585
+ // Most likely this is a control flow directive (such as `*ngIf`) used in
12586
+ // a template, but the `CommonModule` is not imported.
12587
+ message += `\nIf the '${propName}' is an Angular control flow directive, ` +
12588
+ `please make sure that the 'CommonModule' is ${importLocation}.`;
12589
+ }
12590
+ else {
12591
+ // May be an Angular component, which is not imported/declared?
12592
+ message += `\n1. If '${tagName}' is an Angular component and it has the ` +
12593
+ `'${propName}' input, then verify that it is ${importLocation}.`;
12594
+ // May be a Web Component?
12595
+ if (tagName && tagName.indexOf('-') > -1) {
12596
+ message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` +
12597
+ `to the ${schemas} of this component to suppress this message.`;
12598
+ message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
12599
+ `the ${schemas} of this component.`;
12600
+ }
12601
+ else {
12602
+ // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
12603
+ message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` +
12604
+ `the ${schemas} of this component.`;
12605
+ }
12606
+ }
12493
12607
  if (shouldThrowErrorOnUnknownProperty) {
12494
12608
  throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
12495
12609
  }
@@ -15275,8 +15389,7 @@ function elementStartFirstCreatePass(index, tView, lView, native, name, attrsInd
15275
15389
  const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, name, attrs);
15276
15390
  const hasDirectives = resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
15277
15391
  if (ngDevMode) {
15278
- const hostIsStandalone = isHostComponentStandalone(lView);
15279
- validateElementIsKnown(native, tNode.value, tView.schemas, hasDirectives, hostIsStandalone);
15392
+ validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
15280
15393
  }
15281
15394
  if (tNode.attrs !== null) {
15282
15395
  computeStaticStyling(tNode, tNode.attrs, false);
@@ -15414,12 +15527,12 @@ function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
15414
15527
  * - the element is allowed by one of the schemas
15415
15528
  *
15416
15529
  * @param element Element to validate
15530
+ * @param lView An `LView` that represents a current component that is being rendered.
15417
15531
  * @param tagName Name of the tag to check
15418
15532
  * @param schemas Array of schemas
15419
15533
  * @param hasDirectives Boolean indicating that the element matches any directive
15420
- * @param hostIsStandalone Boolean indicating whether the host is a standalone component
15421
15534
  */
15422
- function validateElementIsKnown(element, tagName, schemas, hasDirectives, hostIsStandalone) {
15535
+ function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
15423
15536
  // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
15424
15537
  // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
15425
15538
  // defined as an array (as an empty array in case `schemas` field is not defined) and we should
@@ -15439,10 +15552,12 @@ function validateElementIsKnown(element, tagName, schemas, hasDirectives, hostIs
15439
15552
  (typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 &&
15440
15553
  !customElements.get(tagName));
15441
15554
  if (isUnknown && !matchingSchemas(schemas, tagName)) {
15442
- const schemas = `'${hostIsStandalone ? '@Component' : '@NgModule'}.schemas'`;
15443
- let message = `'${tagName}' is not a known element:\n`;
15444
- message += `1. If '${tagName}' is an Angular component, then verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' :
15445
- 'a part of this module'}.\n`;
15555
+ const isHostStandalone = isHostComponentStandalone(lView);
15556
+ const templateLocation = getTemplateLocationDetails(lView);
15557
+ const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
15558
+ let message = `'${tagName}' is not a known element${templateLocation}:\n`;
15559
+ message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' :
15560
+ 'a part of an @NgModule where this component is declared'}.\n`;
15446
15561
  if (tagName && tagName.indexOf('-') > -1) {
15447
15562
  message +=
15448
15563
  `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
@@ -21942,7 +22057,7 @@ class Version {
21942
22057
  /**
21943
22058
  * @publicApi
21944
22059
  */
21945
- const VERSION = new Version('14.0.0-rc.2');
22060
+ const VERSION = new Version('14.0.0-rc.3');
21946
22061
 
21947
22062
  /**
21948
22063
  * @license
@@ -26606,7 +26721,10 @@ const TestBed = TestBedRender3;
26606
26721
  */
26607
26722
  const getTestBed = _getTestBedRender3;
26608
26723
  /**
26609
- * Allows injecting dependencies in `beforeEach()` and `it()`.
26724
+ * Allows injecting dependencies in `beforeEach()` and `it()`. Note: this function
26725
+ * (imported from the `@angular/core/testing` package) can **only** be used to inject dependencies
26726
+ * in tests. To inject dependencies in your application code, use the [`inject`](api/core/inject)
26727
+ * function from the `@angular/core` package instead.
26610
26728
  *
26611
26729
  * Example:
26612
26730
  *