@angular/core 15.0.0-next.4 → 15.0.0-next.6
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.
- package/esm2020/src/application_ref.mjs +1 -1
- package/esm2020/src/core_private_export.mjs +2 -1
- package/esm2020/src/di/index.mjs +2 -2
- package/esm2020/src/di/injectable.mjs +1 -1
- package/esm2020/src/di/injection_token.mjs +6 -3
- package/esm2020/src/di/interface/defs.mjs +1 -1
- package/esm2020/src/di/interface/provider.mjs +4 -2
- package/esm2020/src/di/provider_collection.mjs +30 -4
- package/esm2020/src/di/r3_injector.mjs +4 -6
- package/esm2020/src/errors.mjs +1 -1
- package/esm2020/src/metadata/directives.mjs +1 -1
- package/esm2020/src/metadata/ng_module.mjs +1 -1
- package/esm2020/src/render3/component_ref.mjs +20 -10
- package/esm2020/src/render3/errors_di.mjs +9 -3
- package/esm2020/src/render3/features/host_directives_feature.mjs +101 -9
- package/esm2020/src/render3/features/ng_onchanges_feature.mjs +4 -2
- package/esm2020/src/render3/instructions/shared.mjs +70 -34
- package/esm2020/src/render3/interfaces/definition.mjs +1 -1
- package/esm2020/src/render3/jit/directive.mjs +2 -6
- package/esm2020/src/render3/jit/module.mjs +2 -2
- package/esm2020/src/render3/ng_module_ref.mjs +1 -1
- package/esm2020/src/version.mjs +1 -1
- package/esm2020/testing/src/logger.mjs +3 -3
- package/esm2020/testing/src/ng_zone_mock.mjs +3 -3
- package/esm2020/testing/src/test_bed_compiler.mjs +29 -11
- package/fesm2015/core.mjs +243 -69
- package/fesm2015/core.mjs.map +1 -1
- package/fesm2015/testing.mjs +269 -73
- package/fesm2015/testing.mjs.map +1 -1
- package/fesm2020/core.mjs +243 -69
- package/fesm2020/core.mjs.map +1 -1
- package/fesm2020/testing.mjs +269 -73
- package/fesm2020/testing.mjs.map +1 -1
- package/index.d.ts +103 -32
- package/package.json +2 -2
- package/schematics/migrations/relative-link-resolution/index.d.ts +10 -0
- package/schematics/migrations/relative-link-resolution/index.js +68 -0
- package/schematics/migrations/relative-link-resolution/util.d.ts +20 -0
- package/schematics/migrations/relative-link-resolution/util.js +82 -0
- package/schematics/migrations/router-link-with-href/index.d.ts +10 -0
- package/schematics/migrations/router-link-with-href/index.js +70 -0
- package/schematics/migrations/router-link-with-href/util.d.ts +19 -0
- package/schematics/migrations/router-link-with-href/util.js +111 -0
- package/schematics/migrations.json +10 -0
- package/schematics/utils/typescript/imports.d.ts +10 -0
- package/schematics/utils/typescript/imports.js +17 -2
- package/testing/index.d.ts +1 -1
package/fesm2015/testing.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v15.0.0-next.
|
|
2
|
+
* @license Angular v15.0.0-next.6
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { getDebugNode as getDebugNode$1, RendererFactory2 as RendererFactory2$1, InjectionToken as InjectionToken$1, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetInjectableDef, resolveForwardRef as resolveForwardRef$1, ɵNG_COMP_DEF, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID as LOCALE_ID$1, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, NgZone, Compiler, COMPILER_OPTIONS, ɵNgModuleFactory, ModuleWithComponentFactories, ɵconvertToBitFlags, Injector as Injector$1, InjectFlags as InjectFlags$1, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode as ɵsetUnknownElementStrictMode$1, ɵsetUnknownPropertyStrictMode as ɵsetUnknownPropertyStrictMode$1, ɵgetUnknownElementStrictMode as ɵgetUnknownElementStrictMode$1, ɵgetUnknownPropertyStrictMode as ɵgetUnknownPropertyStrictMode$1, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
|
|
7
|
+
import { getDebugNode as getDebugNode$1, RendererFactory2 as RendererFactory2$1, InjectionToken as InjectionToken$1, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetInjectableDef, resolveForwardRef as resolveForwardRef$1, ɵNG_COMP_DEF, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID as LOCALE_ID$1, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, NgZone, Compiler, COMPILER_OPTIONS, ɵNgModuleFactory, ɵisEnvironmentProviders, ModuleWithComponentFactories, ɵconvertToBitFlags, Injector as Injector$1, InjectFlags as InjectFlags$1, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode as ɵsetUnknownElementStrictMode$1, ɵsetUnknownPropertyStrictMode as ɵsetUnknownPropertyStrictMode$1, ɵgetUnknownElementStrictMode as ɵgetUnknownElementStrictMode$1, ɵgetUnknownPropertyStrictMode as ɵgetUnknownPropertyStrictMode$1, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
|
|
8
8
|
import { __awaiter } from 'tslib';
|
|
9
9
|
import { ResourceLoader } from '@angular/compiler';
|
|
10
10
|
import { Subject, Subscription } from 'rxjs';
|
|
@@ -1887,6 +1887,17 @@ function initNgDevMode() {
|
|
|
1887
1887
|
return false;
|
|
1888
1888
|
}
|
|
1889
1889
|
|
|
1890
|
+
/**
|
|
1891
|
+
* @license
|
|
1892
|
+
* Copyright Google LLC All Rights Reserved.
|
|
1893
|
+
*
|
|
1894
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
1895
|
+
* found in the LICENSE file at https://angular.io/license
|
|
1896
|
+
*/
|
|
1897
|
+
function isEnvironmentProviders(value) {
|
|
1898
|
+
return value && !!value.ɵproviders;
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1890
1901
|
/**
|
|
1891
1902
|
* @license
|
|
1892
1903
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -1943,8 +1954,13 @@ function throwInvalidProviderError(ngModuleType, providers, provider) {
|
|
|
1943
1954
|
const providerDetail = providers.map(v => v == provider ? '?' + provider + '?' : '...');
|
|
1944
1955
|
throw new Error(`Invalid provider for the NgModule '${stringify(ngModuleType)}' - only instances of Provider and Type are allowed, got: [${providerDetail.join(', ')}]`);
|
|
1945
1956
|
}
|
|
1946
|
-
else if (provider
|
|
1947
|
-
|
|
1957
|
+
else if (isEnvironmentProviders(provider)) {
|
|
1958
|
+
if (provider.ɵfromNgModule) {
|
|
1959
|
+
throw new RuntimeError(207 /* RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT */, `Invalid providers from 'importProvidersFrom' present in a non-environment injector. 'importProvidersFrom' can't be used for component providers.`);
|
|
1960
|
+
}
|
|
1961
|
+
else {
|
|
1962
|
+
throw new RuntimeError(207 /* RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT */, `Invalid providers present in a non-environment injector. 'EnvironmentProviders' can't be used for component providers.`);
|
|
1963
|
+
}
|
|
1948
1964
|
}
|
|
1949
1965
|
else {
|
|
1950
1966
|
throw new Error('Invalid provider');
|
|
@@ -3164,11 +3180,12 @@ function rememberChangeHistoryAndInvokeOnChangesHook() {
|
|
|
3164
3180
|
}
|
|
3165
3181
|
}
|
|
3166
3182
|
function ngOnChangesSetInput(instance, value, publicName, privateName) {
|
|
3183
|
+
const declaredName = this.declaredInputs[publicName];
|
|
3184
|
+
ngDevMode && assertString(declaredName, 'Name of input in ngOnChanges has to be a string');
|
|
3167
3185
|
const simpleChangesStore = getSimpleChangesStore(instance) ||
|
|
3168
3186
|
setSimpleChangesStore(instance, { previous: EMPTY_OBJ, current: null });
|
|
3169
3187
|
const current = simpleChangesStore.current || (simpleChangesStore.current = {});
|
|
3170
3188
|
const previous = simpleChangesStore.previous;
|
|
3171
|
-
const declaredName = this.declaredInputs[publicName];
|
|
3172
3189
|
const previousChange = previous[declaredName];
|
|
3173
3190
|
current[declaredName] = new SimpleChange(previousChange && previousChange.currentValue, value, previous === EMPTY_OBJ);
|
|
3174
3191
|
instance[privateName] = value;
|
|
@@ -6639,8 +6656,11 @@ function getSanitizer() {
|
|
|
6639
6656
|
* As you can see in the Tree-shakable InjectionToken example below.
|
|
6640
6657
|
*
|
|
6641
6658
|
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
|
|
6642
|
-
* overrides the above behavior and marks the token as belonging to a particular `@NgModule
|
|
6643
|
-
* mentioned above, `'root'` is the default value for
|
|
6659
|
+
* overrides the above behavior and marks the token as belonging to a particular `@NgModule` (note:
|
|
6660
|
+
* this option is now deprecated). As mentioned above, `'root'` is the default value for
|
|
6661
|
+
* `providedIn`.
|
|
6662
|
+
*
|
|
6663
|
+
* The `providedIn: NgModule` and `providedIn: 'any'` options are deprecated.
|
|
6644
6664
|
*
|
|
6645
6665
|
* @usageNotes
|
|
6646
6666
|
* ### Basic Examples
|
|
@@ -6771,6 +6791,15 @@ class NullInjector {
|
|
|
6771
6791
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6772
6792
|
* found in the LICENSE file at https://angular.io/license
|
|
6773
6793
|
*/
|
|
6794
|
+
/**
|
|
6795
|
+
* Wrap an array of `Provider`s into `EnvironmentProviders`, preventing them from being accidentally
|
|
6796
|
+
* referenced in `@Component in a component injector.
|
|
6797
|
+
*/
|
|
6798
|
+
function makeEnvironmentProviders(providers) {
|
|
6799
|
+
return {
|
|
6800
|
+
ɵproviders: providers,
|
|
6801
|
+
};
|
|
6802
|
+
}
|
|
6774
6803
|
/**
|
|
6775
6804
|
* Collects providers from all NgModules and standalone components, including transitively imported
|
|
6776
6805
|
* ones.
|
|
@@ -6813,7 +6842,10 @@ class NullInjector {
|
|
|
6813
6842
|
* @developerPreview
|
|
6814
6843
|
*/
|
|
6815
6844
|
function importProvidersFrom(...sources) {
|
|
6816
|
-
return {
|
|
6845
|
+
return {
|
|
6846
|
+
ɵproviders: internalImportProvidersFrom(true, sources),
|
|
6847
|
+
ɵfromNgModule: true,
|
|
6848
|
+
};
|
|
6817
6849
|
}
|
|
6818
6850
|
function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
6819
6851
|
const providersOut = [];
|
|
@@ -6846,7 +6878,7 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
|
6846
6878
|
function processInjectorTypesWithProviders(typesWithProviders, providersOut) {
|
|
6847
6879
|
for (let i = 0; i < typesWithProviders.length; i++) {
|
|
6848
6880
|
const { ngModule, providers } = typesWithProviders[i];
|
|
6849
|
-
|
|
6881
|
+
deepForEachProvider(providers, provider => {
|
|
6850
6882
|
ngDevMode && validateProvider(provider, providers || EMPTY_ARRAY, ngModule);
|
|
6851
6883
|
providersOut.push(provider);
|
|
6852
6884
|
});
|
|
@@ -6963,7 +6995,7 @@ function walkProviderTree(container, providersOut, parents, dedup) {
|
|
|
6963
6995
|
const defProviders = injDef.providers;
|
|
6964
6996
|
if (defProviders != null && !isDuplicate) {
|
|
6965
6997
|
const injectorType = container;
|
|
6966
|
-
|
|
6998
|
+
deepForEachProvider(defProviders, provider => {
|
|
6967
6999
|
ngDevMode && validateProvider(provider, defProviders, injectorType);
|
|
6968
7000
|
providersOut.push(provider);
|
|
6969
7001
|
});
|
|
@@ -6987,6 +7019,19 @@ function validateProvider(provider, providers, containerType) {
|
|
|
6987
7019
|
throwInvalidProviderError(containerType, providers, provider);
|
|
6988
7020
|
}
|
|
6989
7021
|
}
|
|
7022
|
+
function deepForEachProvider(providers, fn) {
|
|
7023
|
+
for (let provider of providers) {
|
|
7024
|
+
if (isEnvironmentProviders(provider)) {
|
|
7025
|
+
provider = provider.ɵproviders;
|
|
7026
|
+
}
|
|
7027
|
+
if (Array.isArray(provider)) {
|
|
7028
|
+
deepForEachProvider(provider, fn);
|
|
7029
|
+
}
|
|
7030
|
+
else {
|
|
7031
|
+
fn(provider);
|
|
7032
|
+
}
|
|
7033
|
+
}
|
|
7034
|
+
}
|
|
6990
7035
|
const USE_VALUE$1 = getClosureSafeProperty({ provide: String, useValue: getClosureSafeProperty });
|
|
6991
7036
|
function isValueProvider(value) {
|
|
6992
7037
|
return value !== null && typeof value == 'object' && USE_VALUE$1 in value;
|
|
@@ -7352,7 +7397,7 @@ function providerToRecord(provider) {
|
|
|
7352
7397
|
*/
|
|
7353
7398
|
function providerToFactory(provider, ngModuleType, providers) {
|
|
7354
7399
|
let factory = undefined;
|
|
7355
|
-
if (ngDevMode &&
|
|
7400
|
+
if (ngDevMode && isEnvironmentProviders(provider)) {
|
|
7356
7401
|
throwInvalidProviderError(undefined, providers, provider);
|
|
7357
7402
|
}
|
|
7358
7403
|
if (isTypeProvider(provider)) {
|
|
@@ -7403,15 +7448,12 @@ function couldBeInjectableType(value) {
|
|
|
7403
7448
|
return (typeof value === 'function') ||
|
|
7404
7449
|
(typeof value === 'object' && value instanceof InjectionToken);
|
|
7405
7450
|
}
|
|
7406
|
-
function isImportedNgModuleProviders(provider) {
|
|
7407
|
-
return !!provider.ɵproviders;
|
|
7408
|
-
}
|
|
7409
7451
|
function forEachSingleProvider(providers, fn) {
|
|
7410
7452
|
for (const provider of providers) {
|
|
7411
7453
|
if (Array.isArray(provider)) {
|
|
7412
7454
|
forEachSingleProvider(provider, fn);
|
|
7413
7455
|
}
|
|
7414
|
-
else if (
|
|
7456
|
+
else if (provider && isEnvironmentProviders(provider)) {
|
|
7415
7457
|
forEachSingleProvider(provider.ɵproviders, fn);
|
|
7416
7458
|
}
|
|
7417
7459
|
else {
|
|
@@ -7642,7 +7684,7 @@ class Version {
|
|
|
7642
7684
|
/**
|
|
7643
7685
|
* @publicApi
|
|
7644
7686
|
*/
|
|
7645
|
-
const VERSION = new Version('15.0.0-next.
|
|
7687
|
+
const VERSION = new Version('15.0.0-next.6');
|
|
7646
7688
|
|
|
7647
7689
|
/**
|
|
7648
7690
|
* @license
|
|
@@ -12612,9 +12654,6 @@ function createViewBlueprint(bindingStartIndex, initialViewLength) {
|
|
|
12612
12654
|
}
|
|
12613
12655
|
return blueprint;
|
|
12614
12656
|
}
|
|
12615
|
-
function createError(text, token) {
|
|
12616
|
-
return new Error(`Renderer: ${text} [${stringifyForError(token)}]`);
|
|
12617
|
-
}
|
|
12618
12657
|
/**
|
|
12619
12658
|
* Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
|
|
12620
12659
|
*
|
|
@@ -12738,26 +12777,49 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
12738
12777
|
}
|
|
12739
12778
|
return tNode;
|
|
12740
12779
|
}
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12780
|
+
/**
|
|
12781
|
+
* Generates the `PropertyAliases` data structure from the provided input/output mapping.
|
|
12782
|
+
* @param aliasMap Input/output mapping from the directive definition.
|
|
12783
|
+
* @param directiveIndex Index of the directive.
|
|
12784
|
+
* @param propertyAliases Object in which to store the results.
|
|
12785
|
+
* @param hostDirectiveAliasMap Object used to alias or filter out properties for host directives.
|
|
12786
|
+
* If the mapping is provided, it'll act as an allowlist, as well as a mapping of what public
|
|
12787
|
+
* name inputs/outputs should be exposed under.
|
|
12788
|
+
*/
|
|
12789
|
+
function generatePropertyAliases(aliasMap, directiveIndex, propertyAliases, hostDirectiveAliasMap) {
|
|
12790
|
+
for (let publicName in aliasMap) {
|
|
12791
|
+
if (aliasMap.hasOwnProperty(publicName)) {
|
|
12792
|
+
propertyAliases = propertyAliases === null ? {} : propertyAliases;
|
|
12793
|
+
const internalName = aliasMap[publicName];
|
|
12794
|
+
// If there are no host directive mappings, we want to remap using the alias map from the
|
|
12795
|
+
// definition itself. If there is an alias map, it has two functions:
|
|
12796
|
+
// 1. It serves as an allowlist of bindings that are exposed by the host directives. Only the
|
|
12797
|
+
// ones inside the host directive map will be exposed on the host.
|
|
12798
|
+
// 2. The public name of the property is aliased using the host directive alias map, rather
|
|
12799
|
+
// than the alias map from the definition.
|
|
12800
|
+
if (hostDirectiveAliasMap === null) {
|
|
12801
|
+
addPropertyAlias(propertyAliases, directiveIndex, publicName, internalName);
|
|
12748
12802
|
}
|
|
12749
|
-
else {
|
|
12750
|
-
(
|
|
12803
|
+
else if (hostDirectiveAliasMap.hasOwnProperty(publicName)) {
|
|
12804
|
+
addPropertyAlias(propertyAliases, directiveIndex, hostDirectiveAliasMap[publicName], internalName);
|
|
12751
12805
|
}
|
|
12752
12806
|
}
|
|
12753
12807
|
}
|
|
12754
|
-
return
|
|
12808
|
+
return propertyAliases;
|
|
12809
|
+
}
|
|
12810
|
+
function addPropertyAlias(propertyAliases, directiveIndex, publicName, internalName) {
|
|
12811
|
+
if (propertyAliases.hasOwnProperty(publicName)) {
|
|
12812
|
+
propertyAliases[publicName].push(directiveIndex, internalName);
|
|
12813
|
+
}
|
|
12814
|
+
else {
|
|
12815
|
+
propertyAliases[publicName] = [directiveIndex, internalName];
|
|
12816
|
+
}
|
|
12755
12817
|
}
|
|
12756
12818
|
/**
|
|
12757
12819
|
* Initializes data structures required to work with directive inputs and outputs.
|
|
12758
12820
|
* Initialization is done for all directives matched on a given TNode.
|
|
12759
12821
|
*/
|
|
12760
|
-
function initializeInputAndOutputAliases(tView, tNode) {
|
|
12822
|
+
function initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefinitionMap) {
|
|
12761
12823
|
ngDevMode && assertFirstCreatePass(tView);
|
|
12762
12824
|
const start = tNode.directiveStart;
|
|
12763
12825
|
const end = tNode.directiveEnd;
|
|
@@ -12766,16 +12828,21 @@ function initializeInputAndOutputAliases(tView, tNode) {
|
|
|
12766
12828
|
const inputsFromAttrs = ngDevMode ? new TNodeInitialInputs() : [];
|
|
12767
12829
|
let inputsStore = null;
|
|
12768
12830
|
let outputsStore = null;
|
|
12769
|
-
for (let
|
|
12770
|
-
const directiveDef = tViewData[
|
|
12771
|
-
|
|
12772
|
-
|
|
12831
|
+
for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
|
|
12832
|
+
const directiveDef = tViewData[directiveIndex];
|
|
12833
|
+
const aliasData = hostDirectiveDefinitionMap ? hostDirectiveDefinitionMap.get(directiveDef) : null;
|
|
12834
|
+
const aliasedInputs = aliasData ? aliasData.inputs : null;
|
|
12835
|
+
const aliasedOutputs = aliasData ? aliasData.outputs : null;
|
|
12836
|
+
inputsStore =
|
|
12837
|
+
generatePropertyAliases(directiveDef.inputs, directiveIndex, inputsStore, aliasedInputs);
|
|
12838
|
+
outputsStore =
|
|
12839
|
+
generatePropertyAliases(directiveDef.outputs, directiveIndex, outputsStore, aliasedOutputs);
|
|
12773
12840
|
// Do not use unbound attributes as inputs to structural directives, since structural
|
|
12774
12841
|
// directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
|
|
12775
12842
|
// TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
|
|
12776
12843
|
// should be set for inline templates.
|
|
12777
12844
|
const initialInputs = (inputsStore !== null && tNodeAttrs !== null && !isInlineTemplate(tNode)) ?
|
|
12778
|
-
generateInitialInputs(inputsStore,
|
|
12845
|
+
generateInitialInputs(inputsStore, directiveIndex, tNodeAttrs) :
|
|
12779
12846
|
null;
|
|
12780
12847
|
inputsFromAttrs.push(initialInputs);
|
|
12781
12848
|
}
|
|
@@ -12900,16 +12967,19 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
|
12900
12967
|
ngDevMode && assertFirstCreatePass(tView);
|
|
12901
12968
|
let hasDirectives = false;
|
|
12902
12969
|
if (getBindingsEnabled()) {
|
|
12903
|
-
const directiveDefs = findDirectiveDefMatches(tView, lView, tNode);
|
|
12904
12970
|
const exportsMap = localRefs === null ? null : { '': -1 };
|
|
12971
|
+
const matchResult = findDirectiveDefMatches(tView, tNode);
|
|
12972
|
+
let directiveDefs;
|
|
12973
|
+
let hostDirectiveDefs;
|
|
12974
|
+
if (matchResult === null) {
|
|
12975
|
+
directiveDefs = hostDirectiveDefs = null;
|
|
12976
|
+
}
|
|
12977
|
+
else {
|
|
12978
|
+
[directiveDefs, hostDirectiveDefs] = matchResult;
|
|
12979
|
+
}
|
|
12905
12980
|
if (directiveDefs !== null) {
|
|
12906
|
-
// Publishes the directive types to DI so they can be injected. Needs to
|
|
12907
|
-
// happen in a separate pass before the TNode flags have been initialized.
|
|
12908
|
-
for (let i = 0; i < directiveDefs.length; i++) {
|
|
12909
|
-
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, directiveDefs[i].type);
|
|
12910
|
-
}
|
|
12911
12981
|
hasDirectives = true;
|
|
12912
|
-
initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap);
|
|
12982
|
+
initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap, hostDirectiveDefs);
|
|
12913
12983
|
}
|
|
12914
12984
|
if (exportsMap)
|
|
12915
12985
|
cacheMatchingLocalNames(tNode, localRefs, exportsMap);
|
|
@@ -12919,8 +12989,13 @@ function resolveDirectives(tView, lView, tNode, localRefs) {
|
|
|
12919
12989
|
return hasDirectives;
|
|
12920
12990
|
}
|
|
12921
12991
|
/** Initializes the data structures necessary for a list of directives to be instantiated. */
|
|
12922
|
-
function initializeDirectives(tView, lView, tNode, directives, exportsMap) {
|
|
12992
|
+
function initializeDirectives(tView, lView, tNode, directives, exportsMap, hostDirectiveDefs) {
|
|
12923
12993
|
ngDevMode && assertFirstCreatePass(tView);
|
|
12994
|
+
// Publishes the directive types to DI so they can be injected. Needs to
|
|
12995
|
+
// happen in a separate pass before the TNode flags have been initialized.
|
|
12996
|
+
for (let i = 0; i < directives.length; i++) {
|
|
12997
|
+
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, directives[i].type);
|
|
12998
|
+
}
|
|
12924
12999
|
initTNodeFlags(tNode, tView.data.length, directives.length);
|
|
12925
13000
|
// When the same token is provided by several directives on the same node, some rules apply in
|
|
12926
13001
|
// the viewEngine:
|
|
@@ -12966,7 +13041,7 @@ function initializeDirectives(tView, lView, tNode, directives, exportsMap) {
|
|
|
12966
13041
|
}
|
|
12967
13042
|
directiveIdx++;
|
|
12968
13043
|
}
|
|
12969
|
-
initializeInputAndOutputAliases(tView, tNode);
|
|
13044
|
+
initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefs);
|
|
12970
13045
|
}
|
|
12971
13046
|
/**
|
|
12972
13047
|
* Add `hostBindings` to the `TView.hostBindingOpCodes`.
|
|
@@ -13078,12 +13153,13 @@ function invokeHostBindingsInCreationMode(def, directive) {
|
|
|
13078
13153
|
* Matches the current node against all available selectors.
|
|
13079
13154
|
* If a component is matched (at most one), it is returned in first position in the array.
|
|
13080
13155
|
*/
|
|
13081
|
-
function findDirectiveDefMatches(tView,
|
|
13156
|
+
function findDirectiveDefMatches(tView, tNode) {
|
|
13082
13157
|
var _a;
|
|
13083
13158
|
ngDevMode && assertFirstCreatePass(tView);
|
|
13084
13159
|
ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */);
|
|
13085
13160
|
const registry = tView.directiveRegistry;
|
|
13086
13161
|
let matches = null;
|
|
13162
|
+
let hostDirectiveDefs = null;
|
|
13087
13163
|
if (registry) {
|
|
13088
13164
|
for (let i = 0; i < registry.length; i++) {
|
|
13089
13165
|
const def = registry[i];
|
|
@@ -13109,7 +13185,8 @@ function findDirectiveDefMatches(tView, lView, tNode) {
|
|
|
13109
13185
|
// 4. Selector-matched directives.
|
|
13110
13186
|
if (def.findHostDirectiveDefs !== null) {
|
|
13111
13187
|
const hostDirectiveMatches = [];
|
|
13112
|
-
|
|
13188
|
+
hostDirectiveDefs = hostDirectiveDefs || new Map();
|
|
13189
|
+
def.findHostDirectiveDefs(def, hostDirectiveMatches, hostDirectiveDefs);
|
|
13113
13190
|
// Add all host directives declared on this component, followed by the component itself.
|
|
13114
13191
|
// Host directives should execute first so the host has a chance to override changes
|
|
13115
13192
|
// to the DOM made by them.
|
|
@@ -13127,13 +13204,14 @@ function findDirectiveDefMatches(tView, lView, tNode) {
|
|
|
13127
13204
|
}
|
|
13128
13205
|
else {
|
|
13129
13206
|
// Append any host directives to the matches first.
|
|
13130
|
-
|
|
13207
|
+
hostDirectiveDefs = hostDirectiveDefs || new Map();
|
|
13208
|
+
(_a = def.findHostDirectiveDefs) === null || _a === void 0 ? void 0 : _a.call(def, def, matches, hostDirectiveDefs);
|
|
13131
13209
|
matches.push(def);
|
|
13132
13210
|
}
|
|
13133
13211
|
}
|
|
13134
13212
|
}
|
|
13135
13213
|
}
|
|
13136
|
-
return matches;
|
|
13214
|
+
return matches === null ? null : [matches, hostDirectiveDefs];
|
|
13137
13215
|
}
|
|
13138
13216
|
/**
|
|
13139
13217
|
* Marks a given TNode as a component's host. This consists of:
|
|
@@ -14214,15 +14292,26 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
14214
14292
|
let component;
|
|
14215
14293
|
let tElementNode;
|
|
14216
14294
|
try {
|
|
14217
|
-
const
|
|
14295
|
+
const rootComponentDef = this.componentDef;
|
|
14296
|
+
let rootDirectives;
|
|
14297
|
+
let hostDirectiveDefs = null;
|
|
14298
|
+
if (rootComponentDef.findHostDirectiveDefs) {
|
|
14299
|
+
rootDirectives = [];
|
|
14300
|
+
hostDirectiveDefs = new Map();
|
|
14301
|
+
rootComponentDef.findHostDirectiveDefs(rootComponentDef, rootDirectives, hostDirectiveDefs);
|
|
14302
|
+
rootDirectives.push(rootComponentDef);
|
|
14303
|
+
}
|
|
14304
|
+
else {
|
|
14305
|
+
rootDirectives = [rootComponentDef];
|
|
14306
|
+
}
|
|
14218
14307
|
const hostTNode = createRootComponentTNode(rootLView, hostRNode);
|
|
14219
|
-
const componentView = createRootComponentView(hostTNode, hostRNode,
|
|
14308
|
+
const componentView = createRootComponentView(hostTNode, hostRNode, rootComponentDef, rootDirectives, rootLView, rendererFactory, hostRenderer);
|
|
14220
14309
|
tElementNode = getTNode(rootTView, HEADER_OFFSET);
|
|
14221
14310
|
// TODO(crisbeto): in practice `hostRNode` should always be defined, but there are some tests
|
|
14222
14311
|
// where the renderer is mocked out and `undefined` is returned. We should update the tests so
|
|
14223
14312
|
// that this check can be removed.
|
|
14224
14313
|
if (hostRNode) {
|
|
14225
|
-
setRootNodeAttributes(hostRenderer,
|
|
14314
|
+
setRootNodeAttributes(hostRenderer, rootComponentDef, hostRNode, rootSelectorOrNode);
|
|
14226
14315
|
}
|
|
14227
14316
|
if (projectableNodes !== undefined) {
|
|
14228
14317
|
projectNodes(tElementNode, this.ngContentSelectors, projectableNodes);
|
|
@@ -14230,7 +14319,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
14230
14319
|
// TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
|
|
14231
14320
|
// executed here?
|
|
14232
14321
|
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
|
|
14233
|
-
component = createRootComponent(componentView,
|
|
14322
|
+
component = createRootComponent(componentView, rootComponentDef, rootDirectives, hostDirectiveDefs, rootLView, [LifecycleHooksFeature]);
|
|
14234
14323
|
renderView(rootTView, rootLView, null);
|
|
14235
14324
|
}
|
|
14236
14325
|
finally {
|
|
@@ -14330,8 +14419,7 @@ function createRootComponentView(tNode, rNode, rootComponentDef, rootDirectives,
|
|
|
14330
14419
|
const viewRenderer = rendererFactory.createRenderer(rNode, rootComponentDef);
|
|
14331
14420
|
const componentView = createLView(rootView, getOrCreateComponentTView(rootComponentDef), null, rootComponentDef.onPush ? 32 /* LViewFlags.Dirty */ : 16 /* LViewFlags.CheckAlways */, rootView[tNode.index], tNode, rendererFactory, viewRenderer, sanitizer || null, null, null);
|
|
14332
14421
|
if (tView.firstCreatePass) {
|
|
14333
|
-
|
|
14334
|
-
markAsComponentHost(tView, tNode, 0);
|
|
14422
|
+
markAsComponentHost(tView, tNode, rootDirectives.length - 1);
|
|
14335
14423
|
}
|
|
14336
14424
|
addToViewTree(rootView, componentView);
|
|
14337
14425
|
// Store component view at node index, with node as the HOST
|
|
@@ -14353,12 +14441,12 @@ function applyRootComponentStyling(rootDirectives, tNode, rNode, hostRenderer) {
|
|
|
14353
14441
|
* Creates a root component and sets it up with features and host bindings.Shared by
|
|
14354
14442
|
* renderComponent() and ViewContainerRef.createComponent().
|
|
14355
14443
|
*/
|
|
14356
|
-
function createRootComponent(componentView, rootComponentDef, rootDirectives, rootLView, hostFeatures) {
|
|
14444
|
+
function createRootComponent(componentView, rootComponentDef, rootDirectives, hostDirectiveDefs, rootLView, hostFeatures) {
|
|
14357
14445
|
const rootTNode = getCurrentTNode();
|
|
14358
14446
|
ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
|
|
14359
14447
|
const tView = rootLView[TVIEW];
|
|
14360
14448
|
const native = getNativeByTNode(rootTNode, rootLView);
|
|
14361
|
-
initializeDirectives(tView, rootLView, rootTNode, rootDirectives, null);
|
|
14449
|
+
initializeDirectives(tView, rootLView, rootTNode, rootDirectives, null, hostDirectiveDefs);
|
|
14362
14450
|
for (let i = 0; i < rootDirectives.length; i++) {
|
|
14363
14451
|
const directiveIndex = rootTNode.directiveStart + i;
|
|
14364
14452
|
const directiveInstance = getNodeInjectable(rootLView, tView, directiveIndex, rootTNode);
|
|
@@ -14679,7 +14767,7 @@ function ɵɵCopyDefinitionFeature(definition) {
|
|
|
14679
14767
|
* found in the LICENSE file at https://angular.io/license
|
|
14680
14768
|
*/
|
|
14681
14769
|
/**
|
|
14682
|
-
* This feature
|
|
14770
|
+
* This feature adds the host directives behavior to a directive definition by patching a
|
|
14683
14771
|
* function onto it. The expectation is that the runtime will invoke the function during
|
|
14684
14772
|
* directive matching.
|
|
14685
14773
|
*
|
|
@@ -14713,14 +14801,20 @@ function ɵɵHostDirectivesFeature(rawHostDirectives) {
|
|
|
14713
14801
|
});
|
|
14714
14802
|
};
|
|
14715
14803
|
}
|
|
14716
|
-
function findHostDirectiveDefs(
|
|
14717
|
-
if (
|
|
14718
|
-
for (const hostDirectiveConfig of
|
|
14804
|
+
function findHostDirectiveDefs(currentDef, matchedDefs, hostDirectiveDefs) {
|
|
14805
|
+
if (currentDef.hostDirectives !== null) {
|
|
14806
|
+
for (const hostDirectiveConfig of currentDef.hostDirectives) {
|
|
14719
14807
|
const hostDirectiveDef = getDirectiveDef(hostDirectiveConfig.directive);
|
|
14720
|
-
|
|
14808
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
14809
|
+
validateHostDirective(hostDirectiveConfig, hostDirectiveDef, matchedDefs);
|
|
14810
|
+
}
|
|
14811
|
+
// We need to patch the `declaredInputs` so that
|
|
14812
|
+
// `ngOnChanges` can map the properties correctly.
|
|
14813
|
+
patchDeclaredInputs(hostDirectiveDef.declaredInputs, hostDirectiveConfig.inputs);
|
|
14721
14814
|
// Host directives execute before the host so that its host bindings can be overwritten.
|
|
14722
|
-
findHostDirectiveDefs(
|
|
14723
|
-
|
|
14815
|
+
findHostDirectiveDefs(hostDirectiveDef, matchedDefs, hostDirectiveDefs);
|
|
14816
|
+
hostDirectiveDefs.set(hostDirectiveDef, hostDirectiveConfig);
|
|
14817
|
+
matchedDefs.push(hostDirectiveDef);
|
|
14724
14818
|
}
|
|
14725
14819
|
}
|
|
14726
14820
|
}
|
|
@@ -14738,6 +14832,90 @@ function bindingArrayToMap(bindings) {
|
|
|
14738
14832
|
}
|
|
14739
14833
|
return result;
|
|
14740
14834
|
}
|
|
14835
|
+
/**
|
|
14836
|
+
* `ngOnChanges` has some leftover legacy ViewEngine behavior where the keys inside the
|
|
14837
|
+
* `SimpleChanges` event refer to the *declared* name of the input, not its public name or its
|
|
14838
|
+
* minified name. E.g. in `@Input('alias') foo: string`, the name in the `SimpleChanges` object
|
|
14839
|
+
* will always be `foo`, and not `alias` or the minified name of `foo` in apps using property
|
|
14840
|
+
* minification.
|
|
14841
|
+
*
|
|
14842
|
+
* This is achieved through the `DirectiveDef.declaredInputs` map that is constructed when the
|
|
14843
|
+
* definition is declared. When a property is written to the directive instance, the
|
|
14844
|
+
* `NgOnChangesFeature` will try to remap the property name being written to using the
|
|
14845
|
+
* `declaredInputs`.
|
|
14846
|
+
*
|
|
14847
|
+
* Since the host directive input remapping happens during directive matching, `declaredInputs`
|
|
14848
|
+
* won't contain the new alias that the input is available under. This function addresses the
|
|
14849
|
+
* issue by patching the host directive aliases to the `declaredInputs`. There is *not* a risk of
|
|
14850
|
+
* this patching accidentally introducing new inputs to the host directive, because `declaredInputs`
|
|
14851
|
+
* is used *only* by the `NgOnChangesFeature` when determining what name is used in the
|
|
14852
|
+
* `SimpleChanges` object which won't be reached if an input doesn't exist.
|
|
14853
|
+
*/
|
|
14854
|
+
function patchDeclaredInputs(declaredInputs, exposedInputs) {
|
|
14855
|
+
for (const publicName in exposedInputs) {
|
|
14856
|
+
if (exposedInputs.hasOwnProperty(publicName)) {
|
|
14857
|
+
const remappedPublicName = exposedInputs[publicName];
|
|
14858
|
+
const privateName = declaredInputs[publicName];
|
|
14859
|
+
// We *technically* shouldn't be able to hit this case because we can't have multiple
|
|
14860
|
+
// inputs on the same property and we have validations against conflicting aliases in
|
|
14861
|
+
// `validateMappings`. If we somehow did, it would lead to `ngOnChanges` being invoked
|
|
14862
|
+
// with the wrong name so we have a non-user-friendly assertion here just in case.
|
|
14863
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
14864
|
+
declaredInputs.hasOwnProperty(remappedPublicName)) {
|
|
14865
|
+
assertEqual(declaredInputs[remappedPublicName], declaredInputs[publicName], `Conflicting host directive input alias ${publicName}.`);
|
|
14866
|
+
}
|
|
14867
|
+
declaredInputs[remappedPublicName] = privateName;
|
|
14868
|
+
}
|
|
14869
|
+
}
|
|
14870
|
+
}
|
|
14871
|
+
/**
|
|
14872
|
+
* Verifies that the host directive has been configured correctly.
|
|
14873
|
+
* @param hostDirectiveConfig Host directive configuration object.
|
|
14874
|
+
* @param directiveDef Directive definition of the host directive.
|
|
14875
|
+
* @param matchedDefs Directives that have been matched so far.
|
|
14876
|
+
*/
|
|
14877
|
+
function validateHostDirective(hostDirectiveConfig, directiveDef, matchedDefs) {
|
|
14878
|
+
// TODO(crisbeto): implement more of these checks in the compiler.
|
|
14879
|
+
const type = hostDirectiveConfig.directive;
|
|
14880
|
+
if (directiveDef === null) {
|
|
14881
|
+
if (getComponentDef$1(type) !== null) {
|
|
14882
|
+
throw new RuntimeError(310 /* RuntimeErrorCode.HOST_DIRECTIVE_COMPONENT */, `Host directive ${type.name} cannot be a component.`);
|
|
14883
|
+
}
|
|
14884
|
+
throw new RuntimeError(307 /* RuntimeErrorCode.HOST_DIRECTIVE_UNRESOLVABLE */, `Could not resolve metadata for host directive ${type.name}. ` +
|
|
14885
|
+
`Make sure that the ${type.name} class is annotated with an @Directive decorator.`);
|
|
14886
|
+
}
|
|
14887
|
+
if (!directiveDef.standalone) {
|
|
14888
|
+
throw new RuntimeError(308 /* RuntimeErrorCode.HOST_DIRECTIVE_NOT_STANDALONE */, `Host directive ${directiveDef.type.name} must be standalone.`);
|
|
14889
|
+
}
|
|
14890
|
+
if (matchedDefs.indexOf(directiveDef) > -1) {
|
|
14891
|
+
throw new RuntimeError(309 /* RuntimeErrorCode.DUPLICATE_DIRECTITVE */, `Directive ${directiveDef.type.name} matches multiple times on the same element. ` +
|
|
14892
|
+
`Directives can only match an element once.`);
|
|
14893
|
+
}
|
|
14894
|
+
validateMappings('input', directiveDef, hostDirectiveConfig.inputs);
|
|
14895
|
+
validateMappings('output', directiveDef, hostDirectiveConfig.outputs);
|
|
14896
|
+
}
|
|
14897
|
+
/**
|
|
14898
|
+
* Checks that the host directive inputs/outputs configuration is valid.
|
|
14899
|
+
* @param bindingType Kind of binding that is being validated. Used in the error message.
|
|
14900
|
+
* @param def Definition of the host directive that is being validated against.
|
|
14901
|
+
* @param hostDirectiveDefs Host directive mapping object that shold be validated.
|
|
14902
|
+
*/
|
|
14903
|
+
function validateMappings(bindingType, def, hostDirectiveDefs) {
|
|
14904
|
+
const className = def.type.name;
|
|
14905
|
+
const bindings = bindingType === 'input' ? def.inputs : def.outputs;
|
|
14906
|
+
for (const publicName in hostDirectiveDefs) {
|
|
14907
|
+
if (hostDirectiveDefs.hasOwnProperty(publicName)) {
|
|
14908
|
+
if (!bindings.hasOwnProperty(publicName)) {
|
|
14909
|
+
throw new RuntimeError(311 /* RuntimeErrorCode.HOST_DIRECTIVE_UNDEFINED_BINDING */, `Directive ${className} does not have an ${bindingType} with a public name of ${publicName}.`);
|
|
14910
|
+
}
|
|
14911
|
+
const remappedPublicName = hostDirectiveDefs[publicName];
|
|
14912
|
+
if (bindings.hasOwnProperty(remappedPublicName) &&
|
|
14913
|
+
bindings[remappedPublicName] !== publicName) {
|
|
14914
|
+
throw new RuntimeError(312 /* RuntimeErrorCode.HOST_DIRECTIVE_CONFLICTING_ALIAS */, `Cannot alias ${bindingType} ${publicName} of host directive ${className} to ${remappedPublicName}, because it already has a different ${bindingType} with the same public name.`);
|
|
14915
|
+
}
|
|
14916
|
+
}
|
|
14917
|
+
}
|
|
14918
|
+
}
|
|
14741
14919
|
|
|
14742
14920
|
/**
|
|
14743
14921
|
* @license
|
|
@@ -24641,7 +24819,7 @@ function generateStandaloneInDeclarationsError(type, location) {
|
|
|
24641
24819
|
function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot, importingModule) {
|
|
24642
24820
|
if (verifiedNgModule.get(moduleType))
|
|
24643
24821
|
return;
|
|
24644
|
-
// skip verifications of standalone components, directives and pipes
|
|
24822
|
+
// skip verifications of standalone components, directives, and pipes
|
|
24645
24823
|
if (isStandalone(moduleType))
|
|
24646
24824
|
return;
|
|
24647
24825
|
verifiedNgModule.set(moduleType, true);
|
|
@@ -25903,17 +26081,17 @@ class TestBedCompiler {
|
|
|
25903
26081
|
getProviderOverrides(providers) {
|
|
25904
26082
|
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
|
|
25905
26083
|
return [];
|
|
25906
|
-
// There are two flattening operations here. The inner
|
|
25907
|
-
// providers and applies a mapping function which retrieves overrides for each
|
|
25908
|
-
// provider. The outer flatten() then flattens the produced overrides array. If this is
|
|
25909
|
-
// done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
|
|
26084
|
+
// There are two flattening operations here. The inner flattenProviders() operates on the
|
|
26085
|
+
// metadata's providers and applies a mapping function which retrieves overrides for each
|
|
26086
|
+
// incoming provider. The outer flatten() then flattens the produced overrides array. If this is
|
|
26087
|
+
// not done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
|
|
25910
26088
|
// providers array and contaminate any error messages that might be generated.
|
|
25911
|
-
return flatten(
|
|
26089
|
+
return flatten(flattenProviders(providers, (provider) => this.getSingleProviderOverrides(provider) || []));
|
|
25912
26090
|
}
|
|
25913
26091
|
getOverriddenProviders(providers) {
|
|
25914
26092
|
if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
|
|
25915
26093
|
return [];
|
|
25916
|
-
const flattenedProviders =
|
|
26094
|
+
const flattenedProviders = flattenProviders(providers);
|
|
25917
26095
|
const overrides = this.getProviderOverrides(flattenedProviders);
|
|
25918
26096
|
const overriddenProviders = [...flattenedProviders, ...overrides];
|
|
25919
26097
|
const final = [];
|
|
@@ -25978,18 +26156,36 @@ function isNgModule(value) {
|
|
|
25978
26156
|
function maybeUnwrapFn(maybeFn) {
|
|
25979
26157
|
return maybeFn instanceof Function ? maybeFn() : maybeFn;
|
|
25980
26158
|
}
|
|
25981
|
-
function flatten(values
|
|
26159
|
+
function flatten(values) {
|
|
25982
26160
|
const out = [];
|
|
25983
26161
|
values.forEach(value => {
|
|
25984
26162
|
if (Array.isArray(value)) {
|
|
25985
|
-
out.push(...flatten(value
|
|
26163
|
+
out.push(...flatten(value));
|
|
25986
26164
|
}
|
|
25987
26165
|
else {
|
|
25988
|
-
out.push(
|
|
26166
|
+
out.push(value);
|
|
25989
26167
|
}
|
|
25990
26168
|
});
|
|
25991
26169
|
return out;
|
|
25992
26170
|
}
|
|
26171
|
+
function identityFn(value) {
|
|
26172
|
+
return value;
|
|
26173
|
+
}
|
|
26174
|
+
function flattenProviders(providers, mapFn = identityFn) {
|
|
26175
|
+
const out = [];
|
|
26176
|
+
for (let provider of providers) {
|
|
26177
|
+
if (ɵisEnvironmentProviders(provider)) {
|
|
26178
|
+
provider = provider.ɵproviders;
|
|
26179
|
+
}
|
|
26180
|
+
if (Array.isArray(provider)) {
|
|
26181
|
+
out.push(...flattenProviders(provider, mapFn));
|
|
26182
|
+
}
|
|
26183
|
+
else {
|
|
26184
|
+
out.push(mapFn(provider));
|
|
26185
|
+
}
|
|
26186
|
+
}
|
|
26187
|
+
return out;
|
|
26188
|
+
}
|
|
25993
26189
|
function getProviderField(provider, field) {
|
|
25994
26190
|
return provider && typeof provider === 'object' && provider[field];
|
|
25995
26191
|
}
|