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