@angular/core
Version:
Angular - the core framework
1,721 lines (1,679 loc) • 547 kB
JavaScript
/**
* @license Angular v5.2.10
* (c) 2010-2018 Google, Inc. https://angular.io/
* License: MIT
*/
import { Observable } from 'rxjs/Observable';
import { merge } from 'rxjs/observable/merge';
import { share } from 'rxjs/operator/share';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Creates a token that can be used in a DI Provider.
*
* Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
* runtime representation) such as when injecting an interface, callable type, array or
* parametrized type.
*
* `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
* the `Injector`. This provides additional level of type safety.
*
* ```
* interface MyInterface {...}
* var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
* // myInterface is inferred to be MyInterface.
* ```
*
* ### Example
*
* {\@example core/di/ts/injector_spec.ts region='InjectionToken'}
*
* \@stable
* @template T
*/
class InjectionToken {
/**
* @param {?} _desc
*/
constructor(_desc) {
this._desc = _desc;
/**
* \@internal
*/
this.ngMetadataName = 'InjectionToken';
}
/**
* @return {?}
*/
toString() { return `InjectionToken ${this._desc}`; }
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* An interface implemented by all Angular type decorators, which allows them to be used as ES7
* decorators as well as
* Angular DSL syntax.
*
* ES7 syntax:
*
* ```
* \@ng.Component({...})
* class MyClass {...}
* ```
* \@stable
* @record
*/
const ANNOTATIONS = '__annotations__';
const PARAMETERS = '__paramaters__';
const PROP_METADATA = '__prop__metadata__';
/**
* @suppress {globalThis}
* @param {?} name
* @param {?=} props
* @param {?=} parentClass
* @param {?=} chainFn
* @return {?}
*/
function makeDecorator(name, props, parentClass, chainFn) {
const /** @type {?} */ metaCtor = makeMetadataCtor(props);
/**
* @param {?} objOrType
* @return {?}
*/
function DecoratorFactory(objOrType) {
if (this instanceof DecoratorFactory) {
metaCtor.call(this, objOrType);
return this;
}
const /** @type {?} */ annotationInstance = new (/** @type {?} */ (DecoratorFactory))(objOrType);
const /** @type {?} */ TypeDecorator = /** @type {?} */ (function TypeDecorator(cls) {
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
const /** @type {?} */ annotations = cls.hasOwnProperty(ANNOTATIONS) ?
(/** @type {?} */ (cls))[ANNOTATIONS] :
Object.defineProperty(cls, ANNOTATIONS, { value: [] })[ANNOTATIONS];
annotations.push(annotationInstance);
return cls;
});
if (chainFn)
chainFn(TypeDecorator);
return TypeDecorator;
}
if (parentClass) {
DecoratorFactory.prototype = Object.create(parentClass.prototype);
}
DecoratorFactory.prototype.ngMetadataName = name;
(/** @type {?} */ (DecoratorFactory)).annotationCls = DecoratorFactory;
return /** @type {?} */ (DecoratorFactory);
}
/**
* @param {?=} props
* @return {?}
*/
function makeMetadataCtor(props) {
return function ctor(...args) {
if (props) {
const /** @type {?} */ values = props(...args);
for (const /** @type {?} */ propName in values) {
this[propName] = values[propName];
}
}
};
}
/**
* @param {?} name
* @param {?=} props
* @param {?=} parentClass
* @return {?}
*/
function makeParamDecorator(name, props, parentClass) {
const /** @type {?} */ metaCtor = makeMetadataCtor(props);
/**
* @param {...?} args
* @return {?}
*/
function ParamDecoratorFactory(...args) {
if (this instanceof ParamDecoratorFactory) {
metaCtor.apply(this, args);
return this;
}
const /** @type {?} */ annotationInstance = new (/** @type {?} */ (ParamDecoratorFactory))(...args);
(/** @type {?} */ (ParamDecorator)).annotation = annotationInstance;
return ParamDecorator;
/**
* @param {?} cls
* @param {?} unusedKey
* @param {?} index
* @return {?}
*/
function ParamDecorator(cls, unusedKey, index) {
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
const /** @type {?} */ parameters = cls.hasOwnProperty(PARAMETERS) ?
(/** @type {?} */ (cls))[PARAMETERS] :
Object.defineProperty(cls, PARAMETERS, { value: [] })[PARAMETERS];
// there might be gaps if some in between parameters do not have annotations.
// we pad with nulls.
while (parameters.length <= index) {
parameters.push(null);
}
(parameters[index] = parameters[index] || []).push(annotationInstance);
return cls;
}
}
if (parentClass) {
ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
}
ParamDecoratorFactory.prototype.ngMetadataName = name;
(/** @type {?} */ (ParamDecoratorFactory)).annotationCls = ParamDecoratorFactory;
return ParamDecoratorFactory;
}
/**
* @param {?} name
* @param {?=} props
* @param {?=} parentClass
* @return {?}
*/
function makePropDecorator(name, props, parentClass) {
const /** @type {?} */ metaCtor = makeMetadataCtor(props);
/**
* @param {...?} args
* @return {?}
*/
function PropDecoratorFactory(...args) {
if (this instanceof PropDecoratorFactory) {
metaCtor.apply(this, args);
return this;
}
const /** @type {?} */ decoratorInstance = new (/** @type {?} */ (PropDecoratorFactory))(...args);
return function PropDecorator(target, name) {
const /** @type {?} */ constructor = target.constructor;
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
const /** @type {?} */ meta = constructor.hasOwnProperty(PROP_METADATA) ?
(/** @type {?} */ (constructor))[PROP_METADATA] :
Object.defineProperty(constructor, PROP_METADATA, { value: {} })[PROP_METADATA];
meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
meta[name].unshift(decoratorInstance);
};
}
if (parentClass) {
PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
}
PropDecoratorFactory.prototype.ngMetadataName = name;
(/** @type {?} */ (PropDecoratorFactory)).annotationCls = PropDecoratorFactory;
return PropDecoratorFactory;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This token can be used to create a virtual provider that will populate the
* `entryComponents` fields of components and ng modules based on its `useValue`.
* All components that are referenced in the `useValue` value (either directly
* or in a nested array or map) will be added to the `entryComponents` property.
*
* ### Example
* The following example shows how the router can populate the `entryComponents`
* field of an NgModule based on the router configuration which refers
* to components.
*
* ```typescript
* // helper function inside the router
* function provideRoutes(routes) {
* return [
* {provide: ROUTES, useValue: routes},
* {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
* ];
* }
*
* // user code
* let routes = [
* {path: '/root', component: RootComp},
* {path: '/teams', component: TeamsComp}
* ];
*
* \@NgModule({
* providers: [provideRoutes(routes)]
* })
* class ModuleWithRoutes {}
* ```
*
* \@experimental
*/
const ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents');
/**
* Type of the Attribute decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Attribute decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Attribute = makeParamDecorator('Attribute', (attributeName) => ({ attributeName }));
/**
* Base class for query metadata.
*
* See {\@link ContentChildren}, {\@link ContentChild}, {\@link ViewChildren}, {\@link ViewChild} for
* more information.
*
* \@stable
* @abstract
*/
class Query {
}
/**
* Type of the ContentChildren decorator / constructor function.
*
* See {\@link ContentChildren}.
*
* \@stable
* @record
*/
/**
* ContentChildren decorator and metadata.
*
* \@stable
* \@Annotation
*/
const ContentChildren = makePropDecorator('ContentChildren', (selector, data = {}) => (Object.assign({ selector, first: false, isViewQuery: false, descendants: false }, data)), Query);
/**
* Type of the ContentChild decorator / constructor function.
*
*
* \@stable
* @record
*/
/**
* ContentChild decorator and metadata.
*
* \@stable
* \@Annotation
*/
const ContentChild = makePropDecorator('ContentChild', (selector, data = {}) => (Object.assign({ selector, first: true, isViewQuery: false, descendants: true }, data)), Query);
/**
* Type of the ViewChildren decorator / constructor function.
*
* See {\@link ViewChildren}.
*
* \@stable
* @record
*/
/**
* ViewChildren decorator and metadata.
*
* \@stable
* \@Annotation
*/
const ViewChildren = makePropDecorator('ViewChildren', (selector, data = {}) => (Object.assign({ selector, first: false, isViewQuery: true, descendants: true }, data)), Query);
/**
* Type of the ViewChild decorator / constructor function.
*
* See {\@link ViewChild}
*
* \@stable
* @record
*/
/**
* ViewChild decorator and metadata.
*
* \@stable
* \@Annotation
*/
const ViewChild = makePropDecorator('ViewChild', (selector, data) => (Object.assign({ selector, first: true, isViewQuery: true, descendants: true }, data)), Query);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** @enum {number} */
const ChangeDetectionStrategy = {
/**
* `OnPush` means that the change detector's mode will be initially set to `CheckOnce`.
*/
OnPush: 0,
/**
* `Default` means that the change detector's mode will be initially set to `CheckAlways`.
*/
Default: 1,
};
ChangeDetectionStrategy[ChangeDetectionStrategy.OnPush] = "OnPush";
ChangeDetectionStrategy[ChangeDetectionStrategy.Default] = "Default";
/** @enum {number} */
const ChangeDetectorStatus = {
/**
* `CheckOnce` means that after calling detectChanges the mode of the change detector
* will become `Checked`.
*/
CheckOnce: 0,
/**
* `Checked` means that the change detector should be skipped until its mode changes to
* `CheckOnce`.
*/
Checked: 1,
/**
* `CheckAlways` means that after calling detectChanges the mode of the change detector
* will remain `CheckAlways`.
*/
CheckAlways: 2,
/**
* `Detached` means that the change detector sub tree is not a part of the main tree and
* should be skipped.
*/
Detached: 3,
/**
* `Errored` means that the change detector encountered an error checking a binding
* or calling a directive lifecycle method and is now in an inconsistent state. Change
* detectors in this state will no longer detect changes.
*/
Errored: 4,
/**
* `Destroyed` means that the change detector is destroyed.
*/
Destroyed: 5,
};
ChangeDetectorStatus[ChangeDetectorStatus.CheckOnce] = "CheckOnce";
ChangeDetectorStatus[ChangeDetectorStatus.Checked] = "Checked";
ChangeDetectorStatus[ChangeDetectorStatus.CheckAlways] = "CheckAlways";
ChangeDetectorStatus[ChangeDetectorStatus.Detached] = "Detached";
ChangeDetectorStatus[ChangeDetectorStatus.Errored] = "Errored";
ChangeDetectorStatus[ChangeDetectorStatus.Destroyed] = "Destroyed";
/**
* @param {?} changeDetectionStrategy
* @return {?}
*/
function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
return changeDetectionStrategy == null ||
changeDetectionStrategy === ChangeDetectionStrategy.Default;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Type of the Directive decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Directive decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Directive = makeDecorator('Directive', (dir = {}) => dir);
/**
* Type of the Component decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Component decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Component = makeDecorator('Component', (c = {}) => (Object.assign({ changeDetection: ChangeDetectionStrategy.Default }, c)), Directive);
/**
* Type of the Pipe decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Pipe decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Pipe = makeDecorator('Pipe', (p) => (Object.assign({ pure: true }, p)));
/**
* Type of the Input decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Input decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Input = makePropDecorator('Input', (bindingPropertyName) => ({ bindingPropertyName }));
/**
* Type of the Output decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Output decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Output = makePropDecorator('Output', (bindingPropertyName) => ({ bindingPropertyName }));
/**
* Type of the HostBinding decorator / constructor function.
*
* \@stable
* @record
*/
/**
* HostBinding decorator and metadata.
*
* \@stable
* \@Annotation
*/
const HostBinding = makePropDecorator('HostBinding', (hostPropertyName) => ({ hostPropertyName }));
/**
* Type of the HostListener decorator / constructor function.
*
* \@stable
* @record
*/
/**
* HostListener decorator and metadata.
*
* \@stable
* \@Annotation
*/
const HostListener = makePropDecorator('HostListener', (eventName, args) => ({ eventName, args }));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A wrapper around a module that also includes the providers.
*
* \@stable
* @record
*/
/**
* Interface for schema definitions in \@NgModules.
*
* \@experimental
* @record
*/
/**
* Defines a schema that will allow:
* - any non-Angular elements with a `-` in their name,
* - any properties on elements with a `-` in their name which is the common rule for custom
* elements.
*
* \@stable
*/
const CUSTOM_ELEMENTS_SCHEMA = {
name: 'custom-elements'
};
/**
* Defines a schema that will allow any property on any element.
*
* \@experimental
*/
const NO_ERRORS_SCHEMA = {
name: 'no-errors-schema'
};
/**
* Type of the NgModule decorator / constructor function.
*
* \@stable
* @record
*/
/**
* NgModule decorator and metadata.
*
* \@stable
* \@Annotation
*/
const NgModule = makeDecorator('NgModule', (ngModule) => ngModule);
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** @enum {number} */
const ViewEncapsulation = {
/**
* Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
* Element and pre-processing the style rules provided via {@link Component#styles styles} or
* {@link Component#styleUrls styleUrls}, and adding the new Host Element attribute to all
* selectors.
*
* This is the default option.
*/
Emulated: 0,
/**
* Use the native encapsulation mechanism of the renderer.
*
* For the DOM this means using [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
* creating a ShadowRoot for Component's Host Element.
*/
Native: 1,
/**
* Don't provide any template or style encapsulation.
*/
None: 2,
};
ViewEncapsulation[ViewEncapsulation.Emulated] = "Emulated";
ViewEncapsulation[ViewEncapsulation.Native] = "Native";
ViewEncapsulation[ViewEncapsulation.None] = "None";
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* \@whatItDoes Represents the version of Angular
*
* \@stable
*/
class Version {
/**
* @param {?} full
*/
constructor(full) {
this.full = full;
this.major = full.split('.')[0];
this.minor = full.split('.')[1];
this.patch = full.split('.').slice(2).join('.');
}
}
/**
* \@stable
*/
const VERSION = new Version('5.2.10');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Type of the Inject decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Inject decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Inject = makeParamDecorator('Inject', (token) => ({ token }));
/**
* Type of the Optional decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Optional decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Optional = makeParamDecorator('Optional');
/**
* Type of the Injectable decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Injectable decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Injectable = makeDecorator('Injectable');
/**
* Type of the Self decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Self decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Self = makeParamDecorator('Self');
/**
* Type of the SkipSelf decorator / constructor function.
*
* \@stable
* @record
*/
/**
* SkipSelf decorator and metadata.
*
* \@stable
* \@Annotation
*/
const SkipSelf = makeParamDecorator('SkipSelf');
/**
* Type of the Host decorator / constructor function.
*
* \@stable
* @record
*/
/**
* Host decorator and metadata.
*
* \@stable
* \@Annotation
*/
const Host = makeParamDecorator('Host');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const __window = typeof window !== 'undefined' && window;
const __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
self instanceof WorkerGlobalScope && self;
const __global = typeof global !== 'undefined' && global;
const _global = __window || __global || __self;
const promise = Promise.resolve(0);
let _symbolIterator = null;
/**
* @return {?}
*/
function getSymbolIterator() {
if (!_symbolIterator) {
const /** @type {?} */ Symbol = _global['Symbol'];
if (Symbol && Symbol.iterator) {
_symbolIterator = Symbol.iterator;
}
else {
// es6-shim specific logic
const /** @type {?} */ keys = Object.getOwnPropertyNames(Map.prototype);
for (let /** @type {?} */ i = 0; i < keys.length; ++i) {
const /** @type {?} */ key = keys[i];
if (key !== 'entries' && key !== 'size' &&
(/** @type {?} */ (Map)).prototype[key] === Map.prototype['entries']) {
_symbolIterator = key;
}
}
}
}
return _symbolIterator;
}
/**
* @param {?} fn
* @return {?}
*/
function scheduleMicroTask(fn) {
if (typeof Zone === 'undefined') {
// use promise to schedule microTask instead of use Zone
promise.then(() => { fn && fn.apply(null, null); });
}
else {
Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
}
}
/**
* @param {?} a
* @param {?} b
* @return {?}
*/
function looseIdentical(a, b) {
return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
}
/**
* @param {?} token
* @return {?}
*/
function stringify(token) {
if (typeof token === 'string') {
return token;
}
if (token instanceof Array) {
return '[' + token.map(stringify).join(', ') + ']';
}
if (token == null) {
return '' + token;
}
if (token.overriddenName) {
return `${token.overriddenName}`;
}
if (token.name) {
return `${token.name}`;
}
const /** @type {?} */ res = token.toString();
if (res == null) {
return '' + res;
}
const /** @type {?} */ newLineIndex = res.indexOf('\n');
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* An interface that a function passed into {\@link forwardRef} has to implement.
*
* ### Example
*
* {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref_fn'}
* \@experimental
* @record
*/
/**
* Allows to refer to references which are not yet defined.
*
* For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
* DI is declared,
* but not yet defined. It is also used when the `token` which we use when creating a query is not
* yet defined.
*
* ### Example
* {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
* \@experimental
* @param {?} forwardRefFn
* @return {?}
*/
function forwardRef(forwardRefFn) {
(/** @type {?} */ (forwardRefFn)).__forward_ref__ = forwardRef;
(/** @type {?} */ (forwardRefFn)).toString = function () { return stringify(this()); };
return (/** @type {?} */ (/** @type {?} */ (forwardRefFn)));
}
/**
* Lazily retrieves the reference value from a forwardRef.
*
* Acts as the identity function when given a non-forward-ref value.
*
* ### Example ([live demo](http://plnkr.co/edit/GU72mJrk1fiodChcmiDR?p=preview))
*
* {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
*
* See: {\@link forwardRef}
* \@experimental
* @param {?} type
* @return {?}
*/
function resolveForwardRef(type) {
if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__') &&
type.__forward_ref__ === forwardRef) {
return (/** @type {?} */ (type))();
}
else {
return type;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const SOURCE = '__source';
const _THROW_IF_NOT_FOUND = new Object();
const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
class _NullInjector {
/**
* @param {?} token
* @param {?=} notFoundValue
* @return {?}
*/
get(token, notFoundValue = _THROW_IF_NOT_FOUND) {
if (notFoundValue === _THROW_IF_NOT_FOUND) {
throw new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
}
return notFoundValue;
}
}
/**
* \@whatItDoes Injector interface
* \@howToUse
* ```
* const injector: Injector = ...;
* injector.get(...);
* ```
*
* \@description
* For more details, see the {\@linkDocs guide/dependency-injection "Dependency Injection Guide"}.
*
* ### Example
*
* {\@example core/di/ts/injector_spec.ts region='Injector'}
*
* `Injector` returns itself when given `Injector` as a token:
* {\@example core/di/ts/injector_spec.ts region='injectInjector'}
*
* \@stable
* @abstract
*/
class Injector {
/**
* Create a new Injector which is configure using `StaticProvider`s.
*
* ### Example
*
* {\@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
* @param {?} options
* @param {?=} parent
* @return {?}
*/
static create(options, parent) {
if (Array.isArray(options)) {
return new StaticInjector(options, parent);
}
else {
return new StaticInjector(options.providers, options.parent, options.name || null);
}
}
}
Injector.THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
Injector.NULL = new _NullInjector();
const IDENT = function (value) {
return value;
};
const EMPTY = /** @type {?} */ ([]);
const CIRCULAR = IDENT;
const MULTI_PROVIDER_FN = function () {
return Array.prototype.slice.call(arguments);
};
const GET_PROPERTY_NAME = /** @type {?} */ ({});
const ɵ2 = GET_PROPERTY_NAME;
const USE_VALUE = getClosureSafeProperty({ provide: String, useValue: ɵ2 });
const NG_TOKEN_PATH = 'ngTokenPath';
const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
const NULL_INJECTOR = Injector.NULL;
const NEW_LINE = /\n/gm;
const NO_NEW_LINE = 'ɵ';
class StaticInjector {
/**
* @param {?} providers
* @param {?=} parent
* @param {?=} source
*/
constructor(providers, parent = NULL_INJECTOR, source = null) {
this.parent = parent;
this.source = source;
const /** @type {?} */ records = this._records = new Map();
records.set(Injector, /** @type {?} */ ({ token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false }));
recursivelyProcessProviders(records, providers);
}
/**
* @param {?} token
* @param {?=} notFoundValue
* @return {?}
*/
get(token, notFoundValue) {
const /** @type {?} */ record = this._records.get(token);
try {
return tryResolveToken(token, record, this._records, this.parent, notFoundValue);
}
catch (/** @type {?} */ e) {
const /** @type {?} */ tokenPath = e[NG_TEMP_TOKEN_PATH];
if (token[SOURCE]) {
tokenPath.unshift(token[SOURCE]);
}
e.message = formatError('\n' + e.message, tokenPath, this.source);
e[NG_TOKEN_PATH] = tokenPath;
e[NG_TEMP_TOKEN_PATH] = null;
throw e;
}
}
/**
* @return {?}
*/
toString() {
const /** @type {?} */ tokens = /** @type {?} */ ([]), /** @type {?} */ records = this._records;
records.forEach((v, token) => tokens.push(stringify(token)));
return `StaticInjector[${tokens.join(', ')}]`;
}
}
/**
* @param {?} provider
* @return {?}
*/
function resolveProvider(provider) {
const /** @type {?} */ deps = computeDeps(provider);
let /** @type {?} */ fn = IDENT;
let /** @type {?} */ value = EMPTY;
let /** @type {?} */ useNew = false;
let /** @type {?} */ provide = resolveForwardRef(provider.provide);
if (USE_VALUE in provider) {
// We need to use USE_VALUE in provider since provider.useValue could be defined as undefined.
value = (/** @type {?} */ (provider)).useValue;
}
else if ((/** @type {?} */ (provider)).useFactory) {
fn = (/** @type {?} */ (provider)).useFactory;
}
else if ((/** @type {?} */ (provider)).useExisting) {
// Just use IDENT
}
else if ((/** @type {?} */ (provider)).useClass) {
useNew = true;
fn = resolveForwardRef((/** @type {?} */ (provider)).useClass);
}
else if (typeof provide == 'function') {
useNew = true;
fn = provide;
}
else {
throw staticError('StaticProvider does not have [useValue|useFactory|useExisting|useClass] or [provide] is not newable', provider);
}
return { deps, fn, useNew, value };
}
/**
* @param {?} token
* @return {?}
*/
function multiProviderMixError(token) {
return staticError('Cannot mix multi providers and regular providers', token);
}
/**
* @param {?} records
* @param {?} provider
* @return {?}
*/
function recursivelyProcessProviders(records, provider) {
if (provider) {
provider = resolveForwardRef(provider);
if (provider instanceof Array) {
// if we have an array recurse into the array
for (let /** @type {?} */ i = 0; i < provider.length; i++) {
recursivelyProcessProviders(records, provider[i]);
}
}
else if (typeof provider === 'function') {
// Functions were supported in ReflectiveInjector, but are not here. For safety give useful
// error messages
throw staticError('Function/Class not supported', provider);
}
else if (provider && typeof provider === 'object' && provider.provide) {
// At this point we have what looks like a provider: {provide: ?, ....}
let /** @type {?} */ token = resolveForwardRef(provider.provide);
const /** @type {?} */ resolvedProvider = resolveProvider(provider);
if (provider.multi === true) {
// This is a multi provider.
let /** @type {?} */ multiProvider = records.get(token);
if (multiProvider) {
if (multiProvider.fn !== MULTI_PROVIDER_FN) {
throw multiProviderMixError(token);
}
}
else {
// Create a placeholder factory which will look up the constituents of the multi provider.
records.set(token, multiProvider = /** @type {?} */ ({
token: provider.provide,
deps: [],
useNew: false,
fn: MULTI_PROVIDER_FN,
value: EMPTY
}));
}
// Treat the provider as the token.
token = provider;
multiProvider.deps.push({ token, options: 6 /* Default */ });
}
const /** @type {?} */ record = records.get(token);
if (record && record.fn == MULTI_PROVIDER_FN) {
throw multiProviderMixError(token);
}
records.set(token, resolvedProvider);
}
else {
throw staticError('Unexpected provider', provider);
}
}
}
/**
* @param {?} token
* @param {?} record
* @param {?} records
* @param {?} parent
* @param {?} notFoundValue
* @return {?}
*/
function tryResolveToken(token, record, records, parent, notFoundValue) {
try {
return resolveToken(token, record, records, parent, notFoundValue);
}
catch (/** @type {?} */ e) {
// ensure that 'e' is of type Error.
if (!(e instanceof Error)) {
e = new Error(e);
}
const /** @type {?} */ path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
path.unshift(token);
if (record && record.value == CIRCULAR) {
// Reset the Circular flag.
record.value = EMPTY;
}
throw e;
}
}
/**
* @param {?} token
* @param {?} record
* @param {?} records
* @param {?} parent
* @param {?} notFoundValue
* @return {?}
*/
function resolveToken(token, record, records, parent, notFoundValue) {
let /** @type {?} */ value;
if (record) {
// If we don't have a record, this implies that we don't own the provider hence don't know how
// to resolve it.
value = record.value;
if (value == CIRCULAR) {
throw Error(NO_NEW_LINE + 'Circular dependency');
}
else if (value === EMPTY) {
record.value = CIRCULAR;
let /** @type {?} */ obj = undefined;
let /** @type {?} */ useNew = record.useNew;
let /** @type {?} */ fn = record.fn;
let /** @type {?} */ depRecords = record.deps;
let /** @type {?} */ deps = EMPTY;
if (depRecords.length) {
deps = [];
for (let /** @type {?} */ i = 0; i < depRecords.length; i++) {
const /** @type {?} */ depRecord = depRecords[i];
const /** @type {?} */ options = depRecord.options;
const /** @type {?} */ childRecord = options & 2 /* CheckSelf */ ? records.get(depRecord.token) : undefined;
deps.push(tryResolveToken(
// Current Token to resolve
depRecord.token, childRecord, records,
// If we don't know how to resolve dependency and we should not check parent for it,
// than pass in Null injector.
!childRecord && !(options & 4 /* CheckParent */) ? NULL_INJECTOR : parent, options & 1 /* Optional */ ? null : Injector.THROW_IF_NOT_FOUND));
}
}
record.value = value = useNew ? new (/** @type {?} */ (fn))(...deps) : fn.apply(obj, deps);
}
}
else {
value = parent.get(token, notFoundValue);
}
return value;
}
/**
* @param {?} provider
* @return {?}
*/
function computeDeps(provider) {
let /** @type {?} */ deps = EMPTY;
const /** @type {?} */ providerDeps = (/** @type {?} */ (provider)).deps;
if (providerDeps && providerDeps.length) {
deps = [];
for (let /** @type {?} */ i = 0; i < providerDeps.length; i++) {
let /** @type {?} */ options = 6;
let /** @type {?} */ token = resolveForwardRef(providerDeps[i]);
if (token instanceof Array) {
for (let /** @type {?} */ j = 0, /** @type {?} */ annotations = token; j < annotations.length; j++) {
const /** @type {?} */ annotation = annotations[j];
if (annotation instanceof Optional || annotation == Optional) {
options = options | 1 /* Optional */;
}
else if (annotation instanceof SkipSelf || annotation == SkipSelf) {
options = options & ~2 /* CheckSelf */;
}
else if (annotation instanceof Self || annotation == Self) {
options = options & ~4 /* CheckParent */;
}
else if (annotation instanceof Inject) {
token = (/** @type {?} */ (annotation)).token;
}
else {
token = resolveForwardRef(annotation);
}
}
}
deps.push({ token, options });
}
}
else if ((/** @type {?} */ (provider)).useExisting) {
const /** @type {?} */ token = resolveForwardRef((/** @type {?} */ (provider)).useExisting);
deps = [{ token, options: 6 /* Default */ }];
}
else if (!providerDeps && !(USE_VALUE in provider)) {
// useValue & useExisting are the only ones which are exempt from deps all others need it.
throw staticError('\'deps\' required', provider);
}
return deps;
}
/**
* @param {?} text
* @param {?} obj
* @param {?=} source
* @return {?}
*/
function formatError(text, obj, source = null) {
text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.substr(2) : text;
let /** @type {?} */ context = stringify(obj);
if (obj instanceof Array) {
context = obj.map(stringify).join(' -> ');
}
else if (typeof obj === 'object') {
let /** @type {?} */ parts = /** @type {?} */ ([]);
for (let /** @type {?} */ key in obj) {
if (obj.hasOwnProperty(key)) {
let /** @type {?} */ value = obj[key];
parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
}
}
context = `{${parts.join(', ')}}`;
}
return `StaticInjectorError${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n ')}`;
}
/**
* @param {?} text
* @param {?} obj
* @return {?}
*/
function staticError(text, obj) {
return new Error(formatError(text, obj));
}
/**
* @template T
* @param {?} objWithPropertyToExtract
* @return {?}
*/
function getClosureSafeProperty(objWithPropertyToExtract) {
for (let /** @type {?} */ key in objWithPropertyToExtract) {
if (objWithPropertyToExtract[key] === GET_PROPERTY_NAME) {
return key;
}
}
throw Error('!prop');
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const ERROR_DEBUG_CONTEXT = 'ngDebugContext';
const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
const ERROR_LOGGER = 'ngErrorLogger';
/**
* @param {?} error
* @return {?}
*/
/**
* @param {?} error
* @return {?}
*/
function getDebugContext(error) {
return (/** @type {?} */ (error))[ERROR_DEBUG_CONTEXT];
}
/**
* @param {?} error
* @return {?}
*/
function getOriginalError(error) {
return (/** @type {?} */ (error))[ERROR_ORIGINAL_ERROR];
}
/**
* @param {?} error
* @return {?}
*/
function getErrorLogger(error) {
return (/** @type {?} */ (error))[ERROR_LOGGER] || defaultErrorLogger;
}
/**
* @param {?} console
* @param {...?} values
* @return {?}
*/
function defaultErrorLogger(console, ...values) {
(/** @type {?} */ (console.error))(...values);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* \@whatItDoes Provides a hook for centralized exception handling.
*
* \@description
*
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
* intercept error handling, write a custom exception handler that replaces this default as
* appropriate for your app.
*
* ### Example
*
* ```
* class MyErrorHandler implements ErrorHandler {
* handleError(error) {
* // do something with the exception
* }
* }
*
* \@NgModule({
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
* })
* class MyModule {}
* ```
*
* \@stable
*/
class ErrorHandler {
constructor() {
/**
* \@internal
*/
this._console = console;
}
/**
* @param {?} error
* @return {?}
*/
handleError(error) {
const /** @type {?} */ originalError = this._findOriginalError(error);
const /** @type {?} */ context = this._findContext(error);
// Note: Browser consoles show the place from where console.error was called.
// We can use this to give users additional information about the error.
const /** @type {?} */ errorLogger = getErrorLogger(error);
errorLogger(this._console, `ERROR`, error);
if (originalError) {
errorLogger(this._console, `ORIGINAL ERROR`, originalError);
}
if (context) {
errorLogger(this._console, 'ERROR CONTEXT', context);
}
}
/**
* \@internal
* @param {?} error
* @return {?}
*/
_findContext(error) {
if (error) {
return getDebugContext(error) ? getDebugContext(error) :
this._findContext(getOriginalError(error));
}
return null;
}
/**
* \@internal
* @param {?} error
* @return {?}
*/
_findOriginalError(error) {
let /** @type {?} */ e = getOriginalError(error);
while (e && getOriginalError(e)) {
e = getOriginalError(e);
}
return e;
}
}
/**
* @param {?} message
* @param {?} originalError
* @return {?}
*/
function wrappedError(message, originalError) {
const /** @type {?} */ msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
const /** @type {?} */ error = Error(msg);
(/** @type {?} */ (error))[ERROR_ORIGINAL_ERROR] = originalError;
return error;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @param {?} keys
* @return {?}
*/
function findFirstClosedCycle(keys) {
const /** @type {?} */ res = [];
for (let /** @type {?} */ i = 0; i < keys.length; ++i) {
if (res.indexOf(keys[i]) > -1) {
res.push(keys[i]);
return res;
}
res.push(keys[i]);
}
return res;
}
/**
* @param {?} keys
* @return {?}
*/
function constructResolvingPath(keys) {
if (keys.length > 1) {
const /** @type {?} */ reversed = findFirstClosedCycle(keys.slice().reverse());
const /** @type {?} */ tokenStrs = reversed.map(k => stringify(k.token));
return ' (' + tokenStrs.join(' -> ') + ')';
}
return '';
}
/**
* @record
*/
/**
* @param {?} injector
* @param {?} key
* @param {?} constructResolvingMessage
* @param {?=} originalError
* @return {?}
*/
function injectionError(injector, key, constructResolvingMessage, originalError) {
const /** @type {?} */ keys = [key];
const /** @type {?} */ errMsg = constructResolvingMessage(keys);
const /** @type {?} */ error = /** @type {?} */ ((originalError ? wrappedError(errMsg, originalError) : Error(errMsg)));
error.addKey = addKey;
error.keys = keys;
error.injectors = [injector];
error.constructResolvingMessage = constructResolvingMessage;
(/** @type {?} */ (error))[ERROR_ORIGINAL_ERROR] = originalError;
return error;
}
/**
* @this {?}
* @param {?} injector
* @param {?} key
* @return {?}
*/
function addKey(injector, key) {
this.injectors.push(injector);
this.keys.push(key);
// Note: This updated message won't be reflected in the `.stack` property
this.message = this.constructResolvingMessage(this.keys);
}
/**
* Thrown when trying to retrieve a dependency by key from {\@link Injector}, but the
* {\@link Injector} does not have a {\@link Provider} for the given key.
*
* ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
*
* ```typescript
* class A {
* constructor(b:B) {}
* }
*
* expect(() => Injector.resolveAndCreate([A])).toThrowError();
* ```
* @param {?} injector
* @param {?} key
* @return {?}
*/
function noProviderError(injector, key) {
return injectionError(injector, key, function (keys) {
const /** @type {?} */ first = stringify(keys[0].token);
return `No provider for ${first}!${constructResolvingPath(keys)}`;
});
}
/**
* Thrown when dependencies form a cycle.
*
* ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
* {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
* ]);
*
* expect(() => injector.get("one")).toThrowError();
* ```
*
* Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
* @param {?} injector
* @param {?} key
* @return {?}
*/
function cyclicDependencyError(injector, key) {
return injectionError(injector, key, function (keys) {
return `Cannot instantiate cyclic dependency!${constructResolvingPath(keys)}`;
});
}
/**
* Thrown when a constructing type returns with an Error.
*
* The `InstantiationError` class contains the original error plus the dependency graph which caused
* this object to be instantiated.
*
* ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
*
* ```typescript
* class A {
* constructor() {
* throw new Error('message');
* }
* }
*
* var injector = Injector.resolveAndCreate([A]);
* try {
* injector.get(A);
* } catch (e) {
* expect(e instanceof InstantiationError).toBe(true);
* expect(e.originalException.message).toEqual("message");
* expect(e.originalStack).toBeDefined();
* }
* ```
* @param {?} injector
* @param {?} originalException
* @param {?} originalStack
* @param {?} key
* @return {?}
*/
function instantiationError(injector, originalException, originalStack, key) {
return injectionError(injector, key, function (keys) {
const /** @type {?} */ first = stringify(keys[0].token);
return `${originalException.message}: Error during instantiation of ${first}!${constructResolvingPath(keys)}.`;
}, originalException);
}
/**
* Thrown when an object other then {\@link Provider} (or `Type`) is passed to {\@link Injector}
* creation.
*
* ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
*
* ```typescript
* expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
* ```
* @param {?} provider
* @return {?}
*/
function invalidProviderError(provider) {
return Error(`Invalid provider - only instances of Provider and Type are allowed, got: ${provider}`);
}
/**
* Thrown when the class has no annotation information.
*
* Lack of annotation information prevents the {\@link Injector} from determining which dependencies
* need to be injected into the constructor.
*
* ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
*
* ```typescript
* class A {
* constructor(b) {}
* }
*
* expect(() => Injector.resolveAndCreate([A])).toThrowError();
* ```
*
* This error is also thrown when the class not marked with {\@link Injectable} has parameter types.
*
* ```typescript
* class B {}
*
* class A {
* constructor(b:B) {} // no information about the parameter types of A is available at runtime.
* }
*
* expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
* ```
* \@stable
* @param {?} typeOrFunc
* @param {?} params
* @return {?}
*/
function noAnnotationError(typeOrFunc, params) {
const /** @type {?} */ signature = [];
for (let /** @type {?} */ i = 0, /** @type {?} */ ii = params.length; i < ii; i++) {
const /** @type {?} */ parameter = params[i];
if (!parameter || parameter.length == 0) {
signature.push('?');
}
else {
signature.push(parameter.map(stringify).join(' '));
}
}
return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' +
signature.join(', ') + '). ' +
'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' +
stringify(typeOrFunc) + '\' is decorated with Injectable.');
}
/**
* Thrown when getting an object by index.
*
* ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
*
* ```typescript
* class A {}
*
* var injector = Injector.resolveAndCreate([A]);
*
* expect(() => injector.getAt(100)).toThrowError();
* ```
* \@stable
* @param {?} index
* @return {?}
*/
function outOfBoundsError(index) {
return Error(`Index ${index} is out-of-bounds.`);
}
/**
* Thrown when a multi provider and a regular provider are bound to the same token.
*
* ### Example
*
* ```typescript
* expect(() => Injector.resolveAndCreate([
* { provide: "Strings", useValue: "string1", multi: true},
*