UNPKG

@angular/core

Version:

Angular - the core framework

1,485 lines (1,465 loc) 701 kB
/** * @license Angular v19.2.2 * (c) 2010-2025 Google LLC. https://angular.io/ * License: MIT */ import { SIGNAL, SignalNode, ReactiveNode, ValueEqualityFn as ValueEqualityFn$1 } from '@angular/core/primitives/signals'; export { SIGNAL as ɵSIGNAL } from '@angular/core/primitives/signals'; import { Observable, Subject, Subscription, BehaviorSubject, Subscribable } from 'rxjs'; import { EventContract } from '@angular/core/primitives/event-dispatch'; import * as _angular_core from '@angular/core'; export { N as ɵNavigateEvent, a as ɵNavigation, b as ɵNavigationCurrentEntryChangeEvent, l as ɵNavigationDestination, c as ɵNavigationHistoryEntry, k as ɵNavigationInterceptOptions, d as ɵNavigationNavigateOptions, e as ɵNavigationOptions, f as ɵNavigationReloadOptions, g as ɵNavigationResult, h as ɵNavigationTransition, j as ɵNavigationTypeString, i as ɵNavigationUpdateCurrentEntryOptions } from './navigation_types.d-u4EOrrdZ.js'; export { s as ɵsetAlternateWeakRefImpl } from './weak_ref.d-ttyj86RV.js'; export { setCurrentInjector as ɵsetCurrentInjector } from '@angular/core/primitives/di'; /** * A reactive value which notifies consumers of any changes. * * Signals are functions which returns their current value. To access the current value of a signal, * call it. * * Ordinary values can be turned into `Signal`s with the `signal` function. */ type Signal<T> = (() => T) & { [SIGNAL]: unknown; }; /** * Checks if the given `value` is a reactive `Signal`. */ declare function isSignal(value: unknown): value is Signal<unknown>; /** * A comparison function which can determine if two values are equal. */ type ValueEqualityFn<T> = (a: T, b: T) => boolean; /** * Reactive node type for an input signal. An input signal extends a signal. * There are special properties to enable transforms and required inputs. */ interface InputSignalNode<T, TransformT> extends SignalNode<T> { /** * User-configured transform that will run whenever a new value is applied * to the input signal node. */ transformFn: ((value: TransformT) => T) | undefined; /** * Applies a new value to the input signal. Expects transforms to be run * manually before. * * This function is called by the framework runtime code whenever a binding * changes. The value can in practice be anything at runtime, but for typing * purposes we assume it's a valid `T` value. Type-checking will enforce that. */ applyValueToInputSignal<T, TransformT>(node: InputSignalNode<T, TransformT>, value: T): void; /** * A debug name for the input signal. Used in Angular DevTools to identify the signal. */ debugName?: string; } /** * @publicAPI * * Options for signal inputs. */ interface InputOptions<T, TransformT> { /** Optional public name for the input. By default, the class field name is used. */ alias?: string; /** * Optional transform that runs whenever a new value is bound. Can be used to * transform the input value before the input is updated. * * The transform function can widen the type of the input. For example, consider * an input for `disabled`. In practice, as the component author, you want to only * deal with a boolean, but users may want to bind a string if they just use the * attribute form to bind to the input via `<my-dir input>`. A transform can then * handle such string values and convert them to `boolean`. See: {@link booleanAttribute}. */ transform?: (v: TransformT) => T; /** * A debug name for the input signal. Used in Angular DevTools to identify the signal. */ debugName?: string; } /** * Signal input options without the transform option. * * @publicAPI */ type InputOptionsWithoutTransform<T> = Omit<InputOptions<T, T>, 'transform'> & { transform?: undefined; }; /** * Signal input options with the transform option required. * * @publicAPI */ type InputOptionsWithTransform<T, TransformT> = Required<Pick<InputOptions<T, TransformT>, 'transform'>> & InputOptions<T, TransformT>; declare const ɵINPUT_SIGNAL_BRAND_READ_TYPE: unique symbol; declare const ɵINPUT_SIGNAL_BRAND_WRITE_TYPE: unique symbol; /** * `InputSignalWithTransform` represents a special `Signal` for a * directive/component input with a `transform` function. * * Signal inputs with transforms capture an extra generic for their transform write * type. Transforms can expand the accepted bound values for an input while ensuring * value retrievals of the signal input are still matching the generic input type. * * ```ts * class MyDir { * disabled = input(false, { * transform: (v: string|boolean) => convertToBoolean(v), * }); // InputSignalWithTransform<boolean, string|boolean> * * click() { * this.disabled() // always returns a `boolean`. * } * } * ``` * * @see {@link InputSignal} for additional information. * * @publicAPI */ interface InputSignalWithTransform<T, TransformT> extends Signal<T> { [SIGNAL]: InputSignalNode<T, TransformT>; [ɵINPUT_SIGNAL_BRAND_READ_TYPE]: T; [ɵINPUT_SIGNAL_BRAND_WRITE_TYPE]: TransformT; } /** * `InputSignal` represents a special `Signal` for a directive/component input. * * An input signal is similar to a non-writable signal except that it also * carries additional type-information for transforms, and that Angular internally * updates the signal whenever a new value is bound. * * @see {@link InputOptionsWithTransform} for inputs with transforms. * * @publicAPI */ interface InputSignal<T> extends InputSignalWithTransform<T, T> { } /** * The `input` function allows declaration of inputs in directives and * components. * * The function exposes an API for also declaring required inputs via the * `input.required` function. * * @publicAPI * @docsPrivate Ignored because `input` is the canonical API entry. */ interface InputFunction { /** * Initializes an input of type `T` with an initial value of `undefined`. * Angular will implicitly use `undefined` as initial value. */ <T>(): InputSignal<T | undefined>; /** Declares an input of type `T` with an explicit initial value. */ <T>(initialValue: T, opts?: InputOptionsWithoutTransform<T>): InputSignal<T>; /** Declares an input of type `T|undefined` without an initial value, but with input options */ <T>(initialValue: undefined, opts: InputOptionsWithoutTransform<T>): InputSignal<T | undefined>; /** * Declares an input of type `T` with an initial value and a transform * function. * * The input accepts values of type `TransformT` and the given * transform function will transform the value to type `T`. */ <T, TransformT>(initialValue: T, opts: InputOptionsWithTransform<T, TransformT>): InputSignalWithTransform<T, TransformT>; /** * Declares an input of type `T|undefined` without an initial value and with a transform * function. * * The input accepts values of type `TransformT` and the given * transform function will transform the value to type `T|undefined`. */ <T, TransformT>(initialValue: undefined, opts: InputOptionsWithTransform<T | undefined, TransformT>): InputSignalWithTransform<T | undefined, TransformT>; /** * Initializes a required input. * * Consumers of your directive/component need to bind to this * input. If unset, a compile time error will be reported. * * @publicAPI */ required: { /** Declares a required input of type `T`. */ <T>(opts?: InputOptionsWithoutTransform<T>): InputSignal<T>; /** * Declares a required input of type `T` with a transform function. * * The input accepts values of type `TransformT` and the given * transform function will transform the value to type `T`. */ <T, TransformT>(opts: InputOptionsWithTransform<T, TransformT>): InputSignalWithTransform<T, TransformT>; }; } /** * The `input` function allows declaration of Angular inputs in directives * and components. * * There are two variants of inputs that can be declared: * * 1. **Optional inputs** with an initial value. * 2. **Required inputs** that consumers need to set. * * By default, the `input` function will declare optional inputs that * always have an initial value. Required inputs can be declared * using the `input.required()` function. * * Inputs are signals. The values of an input are exposed as a `Signal`. * The signal always holds the latest value of the input that is bound * from the parent. * * @usageNotes * To use signal-based inputs, import `input` from `@angular/core`. * * ```ts * import {input} from '@angular/core`; * ``` * * Inside your component, introduce a new class member and initialize * it with a call to `input` or `input.required`. * * ```ts * @Component({ * ... * }) * export class UserProfileComponent { * firstName = input<string>(); // Signal<string|undefined> * lastName = input.required<string>(); // Signal<string> * age = input(0) // Signal<number> * } * ``` * * Inside your component template, you can display values of the inputs * by calling the signal. * * ```html * <span>{{firstName()}}</span> * ``` * * @publicAPI * @initializerApiFunction */ declare const input: InputFunction; /** Retrieves the write type of an `InputSignal` and `InputSignalWithTransform`. */ type ɵUnwrapInputSignalWriteType<Field> = Field extends InputSignalWithTransform<any, infer WriteT> ? WriteT : never; /** * Unwraps all `InputSignal`/`InputSignalWithTransform` class fields of * the given directive. */ type ɵUnwrapDirectiveSignalInputs<Dir, Fields extends keyof Dir> = { [P in Fields]: ɵUnwrapInputSignalWriteType<Dir[P]>; }; /** Symbol used distinguish `WritableSignal` from other non-writable signals and functions. */ declare const ɵWRITABLE_SIGNAL: unique symbol; /** * A `Signal` with a value that can be mutated via a setter interface. */ interface WritableSignal<T> extends Signal<T> { [ɵWRITABLE_SIGNAL]: T; /** * Directly set the signal to a new value, and notify any dependents. */ set(value: T): void; /** * Update the value of the signal based on its current value, and * notify any dependents. */ update(updateFn: (value: T) => T): void; /** * Returns a readonly version of this signal. Readonly signals can be accessed to read their value * but can't be changed using set or update methods. The readonly signals do _not_ have * any built-in mechanism that would prevent deep-mutation of their value. */ asReadonly(): Signal<T>; } /** * Utility function used during template type checking to extract the value from a `WritableSignal`. * @codeGenApi */ declare function ɵunwrapWritableSignal<T>(value: T | { [ɵWRITABLE_SIGNAL]: T; }): T; /** * Options passed to the `signal` creation function. */ interface CreateSignalOptions<T> { /** * A comparison function which defines equality for signal values. */ equal?: ValueEqualityFn<T>; /** * A debug name for the signal. Used in Angular DevTools to identify the signal. */ debugName?: string; } /** * Create a `Signal` that can be set or updated directly. */ declare function signal<T>(initialValue: T, options?: CreateSignalOptions<T>): WritableSignal<T>; /** * Function that can be used to manually clean up a * programmatic {@link OutputRef#subscribe} subscription. * * Note: Angular will automatically clean up subscriptions * when the directive/component of the output is destroyed. * * @publicAPI */ interface OutputRefSubscription { unsubscribe(): void; } /** * A reference to an Angular output. * * @publicAPI */ interface OutputRef<T> { /** * Registers a callback that is invoked whenever the output * emits a new value of type `T`. * * Angular will automatically clean up the subscription when * the directive/component of the output is destroyed. */ subscribe(callback: (value: T) => void): OutputRefSubscription; } /** * @publicAPI * * Options for model signals. */ interface ModelOptions { /** * Optional public name of the input side of the model. The output side will have the same * name as the input, but suffixed with `Change`. By default, the class field name is used. */ alias?: string; /** * A debug name for the model signal. Used in Angular DevTools to identify the signal. */ debugName?: string; } /** * `ModelSignal` represents a special `Signal` for a directive/component model field. * * A model signal is a writeable signal that can be exposed as an output. * Whenever its value is updated, it emits to the output. * * @publicAPI */ interface ModelSignal<T> extends WritableSignal<T>, InputSignal<T>, OutputRef<T> { [SIGNAL]: InputSignalNode<T, T>; } /** * `model` declares a writeable signal that is exposed as an input/output pair on the containing * directive. The input name is taken either from the class member or from the `alias` option. * The output name is generated by taking the input name and appending `Change`. * * The function exposes an API for also declaring required models via the * `model.required` function. * * @publicAPI * @docsPrivate Ignored because `model` is the canonical API entry. */ interface ModelFunction { /** * Initializes a model of type `T` with an initial value of `undefined`. * Angular will implicitly use `undefined` as initial value. */ <T>(): ModelSignal<T | undefined>; /** Initializes a model of type `T` with the given initial value. */ <T>(initialValue: T, opts?: ModelOptions): ModelSignal<T>; required: { /** * Initializes a required model. * * Users of your directive/component need to bind to the input side of the model. * If unset, a compile time error will be reported. */ <T>(opts?: ModelOptions): ModelSignal<T>; }; } /** * `model` declares a writeable signal that is exposed as an input/output * pair on the containing directive. * * The input name is taken either from the class member or from the `alias` option. * The output name is generated by taking the input name and appending `Change`. * * @usageNotes * * To use `model()`, import the function from `@angular/core`. * * ```ts * import {model} from '@angular/core`; * ``` * * Inside your component, introduce a new class member and initialize * it with a call to `model` or `model.required`. * * ```ts * @Directive({ * ... * }) * export class MyDir { * firstName = model<string>(); // ModelSignal<string|undefined> * lastName = model.required<string>(); // ModelSignal<string> * age = model(0); // ModelSignal<number> * } * ``` * * Inside your component template, you can display the value of a `model` * by calling the signal. * * ```html * <span>{{firstName()}}</span> * ``` * * Updating the `model` is equivalent to updating a writable signal. * * ```ts * updateName(newFirstName: string): void { * this.firstName.set(newFirstName); * } * ``` * * @publicAPI * @initializerApiFunction */ declare const model: ModelFunction; /** * @description * * Represents an abstract class `T`, if applied to a concrete class it would stop being * instantiable. * * @publicApi */ interface AbstractType<T> extends Function { prototype: T; } /** * @description * * Represents a type that a Component or other object is instances of. * * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is represented by * the `MyCustomComponent` constructor function. * * @publicApi */ declare const Type$1: FunctionConstructor; interface Type$1<T> extends Function { new (...args: any[]): T; } /** * Returns a writable type version of type. * * USAGE: * Given: * ```ts * interface Person {readonly name: string} * ``` * * We would like to get a read/write version of `Person`. * ```ts * const WritablePerson = Writable<Person>; * ``` * * The result is that you can do: * * ```ts * const readonlyPerson: Person = {name: 'Marry'}; * readonlyPerson.name = 'John'; // TypeError * (readonlyPerson as WritablePerson).name = 'John'; // OK * * // Error: Correctly detects that `Person` did not have `age` property. * (readonlyPerson as WritablePerson).age = 30; * ``` */ type Writable<T> = { -readonly [K in keyof T]: T[K]; }; /** * 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 * parameterized type. * * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by * the `Injector`. This provides an additional level of type safety. * * <div class="docs-alert docs-alert-helpful"> * * **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the * provider and the injection call. Creating a new instance of `InjectionToken` in different places, * even with the same description, will be treated as different tokens by Angular's DI system, * leading to a `NullInjectorError`. * * </div> * * {@example injection-token/src/main.ts region='InjectionToken'} * * When creating an `InjectionToken`, you can optionally specify a factory function which returns * (possibly by creating) a default value of the parameterized type `T`. This sets up the * `InjectionToken` using this factory as a provider as if it was defined explicitly in the * application's root injector. If the factory function, which takes zero arguments, needs to inject * dependencies, it can do so using the [`inject`](api/core/inject) function. * As you can see in the Tree-shakable InjectionToken example below. * * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which * overrides the above behavior and marks the token as belonging to a particular `@NgModule` (note: * this option is now deprecated). As mentioned above, `'root'` is the default value for * `providedIn`. * * The `providedIn: NgModule` and `providedIn: 'any'` options are deprecated. * * @usageNotes * ### Basic Examples * * ### Plain InjectionToken * * {@example core/di/ts/injector_spec.ts region='InjectionToken'} * * ### Tree-shakable InjectionToken * * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'} * * @publicApi */ declare class InjectionToken<T> { protected _desc: string; readonly ɵprov: unknown; /** * @param _desc Description for the token, * used only for debugging purposes, * it should but does not need to be unique * @param options Options for the token's usage, as described above */ constructor(_desc: string, options?: { providedIn?: Type$1<any> | 'root' | 'platform' | 'any' | null; factory: () => T; }); toString(): string; } declare const enum NotificationSource { MarkAncestorsForTraversal = 0, SetInput = 1, DeferBlockStateUpdate = 2, DebugApplyChanges = 3, MarkForCheck = 4, Listener = 5, CustomElement = 6, RenderHook = 7, ViewAttached = 8, ViewDetachedFromDOM = 9, AsyncAnimationsLoaded = 10, PendingTaskRemoved = 11, RootEffect = 12, ViewEffect = 13 } /** * Injectable that is notified when an `LView` is made aware of changes to application state. */ declare abstract class ChangeDetectionScheduler { abstract notify(source: NotificationSource): void; abstract runningTick: boolean; } /** Token used to indicate if zoneless was enabled via provideZonelessChangeDetection(). */ declare const ZONELESS_ENABLED: InjectionToken<boolean>; /** * Configures the `Injector` to return a value for a token. * Base for `ValueProvider` decorator. * * @publicApi */ interface ValueSansProvider { /** * The value to inject. */ useValue: any; } /** * Configures the `Injector` to return a value for a token. * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @usageNotes * * ### Example * * {@example core/di/ts/provider_spec.ts region='ValueProvider'} * * ### Multi-value example * * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'} * * @publicApi */ interface ValueProvider extends ValueSansProvider { /** * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`. */ provide: any; /** * When true, injector returns an array of instances. This is useful to allow multiple * providers spread across many files to provide configuration information to a common token. */ multi?: boolean; } /** * Configures the `Injector` to return an instance of `useClass` for a token. * Base for `StaticClassProvider` decorator. * * @publicApi */ interface StaticClassSansProvider { /** * An optional class to instantiate for the `token`. By default, the `provide` * class is instantiated. */ useClass: Type$1<any>; /** * A list of `token`s to be resolved by the injector. The list of values is then * used as arguments to the `useClass` constructor. */ deps: any[]; } /** * Configures the `Injector` to return an instance of `useClass` for a token. * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @usageNotes * * {@example core/di/ts/provider_spec.ts region='StaticClassProvider'} * * Note that following two providers are not equal: * * {@example core/di/ts/provider_spec.ts region='StaticClassProviderDifference'} * * ### Multi-value example * * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'} * * @publicApi */ interface StaticClassProvider extends StaticClassSansProvider { /** * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`. */ provide: any; /** * When true, injector returns an array of instances. This is useful to allow multiple * providers spread across many files to provide configuration information to a common token. */ multi?: boolean; } /** * Configures the `Injector` to return an instance of a token. * * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @usageNotes * * ```ts * @Injectable(SomeModule, {deps: []}) * class MyService {} * ``` * * @publicApi */ interface ConstructorSansProvider { /** * A list of `token`s to be resolved by the injector. */ deps?: any[]; } /** * Configures the `Injector` to return an instance of a token. * * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @usageNotes * * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'} * * ### Multi-value example * * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'} * * @publicApi */ interface ConstructorProvider extends ConstructorSansProvider { /** * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`. */ provide: Type$1<any>; /** * When true, injector returns an array of instances. This is useful to allow multiple * providers spread across many files to provide configuration information to a common token. */ multi?: boolean; } /** * Configures the `Injector` to return a value of another `useExisting` token. * * @see {@link ExistingProvider} * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @publicApi */ interface ExistingSansProvider { /** * Existing `token` to return. (Equivalent to `injector.get(useExisting)`) */ useExisting: any; } /** * Configures the `Injector` to return a value of another `useExisting` token. * * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @usageNotes * * {@example core/di/ts/provider_spec.ts region='ExistingProvider'} * * ### Multi-value example * * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'} * * @publicApi */ interface ExistingProvider extends ExistingSansProvider { /** * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`. */ provide: any; /** * When true, injector returns an array of instances. This is useful to allow multiple * providers spread across many files to provide configuration information to a common token. */ multi?: boolean; } /** * Configures the `Injector` to return a value by invoking a `useFactory` function. * * @see {@link FactoryProvider} * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @publicApi */ interface FactorySansProvider { /** * A function to invoke to create a value for this `token`. The function is invoked with * resolved values of `token`s in the `deps` field. */ useFactory: Function; /** * A list of `token`s to be resolved by the injector. The list of values is then * used as arguments to the `useFactory` function. */ deps?: any[]; } /** * Configures the `Injector` to return a value by invoking a `useFactory` function. * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @usageNotes * * {@example core/di/ts/provider_spec.ts region='FactoryProvider'} * * Dependencies can also be marked as optional: * * {@example core/di/ts/provider_spec.ts region='FactoryProviderOptionalDeps'} * * ### Multi-value example * * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'} * * @publicApi */ interface FactoryProvider extends FactorySansProvider { /** * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`). */ provide: any; /** * When true, injector returns an array of instances. This is useful to allow multiple * providers spread across many files to provide configuration information to a common token. */ multi?: boolean; } /** * Describes how an `Injector` should be configured as static (that is, without reflection). * A static provider provides tokens to an injector for various types of dependencies. * * @see {@link Injector.create()} * @see [Dependency Injection Guide](guide/di/dependency-injection-providers). * * @publicApi */ type StaticProvider = ValueProvider | ExistingProvider | StaticClassProvider | ConstructorProvider | FactoryProvider | any[]; /** * Configures the `Injector` to return an instance of `Type` when `Type' is used as the token. * * Create an instance by invoking the `new` operator and supplying additional arguments. * This form is a short form of `TypeProvider`; * * For more details, see the ["Dependency Injection Guide"](guide/di/dependency-injection. * * @usageNotes * * {@example core/di/ts/provider_spec.ts region='TypeProvider'} * * @publicApi */ interface TypeProvider extends Type$1<any> { } /** * Configures the `Injector` to return a value by invoking a `useClass` function. * Base for `ClassProvider` decorator. * * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @publicApi */ interface ClassSansProvider { /** * Class to instantiate for the `token`. */ useClass: Type$1<any>; } /** * Configures the `Injector` to return an instance of `useClass` for a token. * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @usageNotes * * {@example core/di/ts/provider_spec.ts region='ClassProvider'} * * Note that following two providers are not equal: * * {@example core/di/ts/provider_spec.ts region='ClassProviderDifference'} * * ### Multi-value example * * {@example core/di/ts/provider_spec.ts region='MultiProviderAspect'} * * @publicApi */ interface ClassProvider extends ClassSansProvider { /** * An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`). */ provide: any; /** * When true, injector returns an array of instances. This is useful to allow multiple * providers spread across many files to provide configuration information to a common token. */ multi?: boolean; } /** * Describes how the `Injector` should be configured. * @see [Dependency Injection Guide](guide/di/dependency-injection. * * @see {@link StaticProvider} * * @publicApi */ type Provider = TypeProvider | ValueProvider | ClassProvider | ConstructorProvider | ExistingProvider | FactoryProvider | any[]; /** * Encapsulated `Provider`s that are only accepted during creation of an `EnvironmentInjector` (e.g. * in an `NgModule`). * * Using this wrapper type prevents providers which are only designed to work in * application/environment injectors from being accidentally included in * `@Component.providers` and ending up in a component injector. * * This wrapper type prevents access to the `Provider`s inside. * * @see {@link makeEnvironmentProviders} * @see {@link importProvidersFrom} * * @publicApi */ type EnvironmentProviders = { ɵbrand: 'EnvironmentProviders'; }; interface InternalEnvironmentProviders extends EnvironmentProviders { ɵproviders: (Provider | EnvironmentProviders)[]; /** * If present, indicates that the `EnvironmentProviders` were derived from NgModule providers. * * This is used to produce clearer error messages. */ ɵfromNgModule?: true; } declare function isEnvironmentProviders(value: Provider | EnvironmentProviders | InternalEnvironmentProviders): value is InternalEnvironmentProviders; /** * Describes a function that is used to process provider lists (such as provider * overrides). */ type ProcessProvidersFunction = (providers: Provider[]) => Provider[]; /** * A wrapper around an NgModule that associates it with providers * Usage without a generic type is deprecated. * * @publicApi */ interface ModuleWithProviders<T> { ngModule: Type$1<T>; providers?: Array<Provider | EnvironmentProviders>; } /** * Providers that were imported from NgModules via the `importProvidersFrom` function. * * These providers are meant for use in an application injector (or other environment injectors) and * should not be used in component injectors. * * This type cannot be directly implemented. It's returned from the `importProvidersFrom` function * and serves to prevent the extracted NgModule providers from being used in the wrong contexts. * * @see {@link importProvidersFrom} * * @publicApi * @deprecated replaced by `EnvironmentProviders` */ type ImportedNgModuleProviders = EnvironmentProviders; /** * @fileoverview * While Angular only uses Trusted Types internally for the time being, * references to Trusted Types could leak into our core.d.ts, which would force * anyone compiling against @angular/core to provide the @types/trusted-types * package in their compilation unit. * * Until https://github.com/microsoft/TypeScript/issues/30024 is resolved, we * will keep Angular's public API surface free of references to Trusted Types. * For internal and semi-private APIs that need to reference Trusted Types, the * minimal type definitions for the Trusted Types API provided by this module * should be used instead. They are marked as "declare" to prevent them from * being renamed by compiler optimization. * * Adapted from * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/trusted-types/index.d.ts * but restricted to the API surface used within Angular. */ type TrustedHTML = string & { __brand__: 'TrustedHTML'; }; type TrustedScript = string & { __brand__: 'TrustedScript'; }; type TrustedScriptURL = string & { __brand__: 'TrustedScriptURL'; }; /** * Function used to sanitize the value before writing it into the renderer. */ type SanitizerFn = (value: any, tagName?: string, propName?: string) => string | TrustedHTML | TrustedScript | TrustedScriptURL; /** * Stores a list of nodes which need to be removed. * * Numbers are indexes into the `LView` * - index > 0: `removeRNode(lView[0])` * - index < 0: `removeICU(~lView[0])` */ interface I18nRemoveOpCodes extends Array<number> { __brand__: 'I18nRemoveOpCodes'; } /** * Array storing OpCode for dynamically creating `i18n` blocks. * * Example: * ```ts * <I18nCreateOpCode>[ * // For adding text nodes * // --------------------- * // Equivalent to: * // lView[1].appendChild(lView[0] = document.createTextNode('xyz')); * 'xyz', 0, 1 << SHIFT_PARENT | 0 << SHIFT_REF | AppendChild, * * // For adding element nodes * // --------------------- * // Equivalent to: * // lView[1].appendChild(lView[0] = document.createElement('div')); * ELEMENT_MARKER, 'div', 0, 1 << SHIFT_PARENT | 0 << SHIFT_REF | AppendChild, * * // For adding comment nodes * // --------------------- * // Equivalent to: * // lView[1].appendChild(lView[0] = document.createComment('')); * ICU_MARKER, '', 0, 1 << SHIFT_PARENT | 0 << SHIFT_REF | AppendChild, * * // For moving existing nodes to a different location * // -------------------------------------------------- * // Equivalent to: * // const node = lView[1]; * // lView[2].appendChild(node); * 1 << SHIFT_REF | Select, 2 << SHIFT_PARENT | 0 << SHIFT_REF | AppendChild, * * // For removing existing nodes * // -------------------------------------------------- * // const node = lView[1]; * // removeChild(tView.data(1), node, lView); * 1 << SHIFT_REF | Remove, * * // For writing attributes * // -------------------------------------------------- * // const node = lView[1]; * // node.setAttribute('attr', 'value'); * 1 << SHIFT_REF | Attr, 'attr', 'value' * ]; * ``` */ interface IcuCreateOpCodes extends Array<number | string | ELEMENT_MARKER | ICU_MARKER | null>, I18nDebug { __brand__: 'I18nCreateOpCodes'; } /** * Marks that the next string is an element name. * * See `I18nMutateOpCodes` documentation. */ declare const ELEMENT_MARKER: ELEMENT_MARKER; interface ELEMENT_MARKER { marker: 'element'; } /** * Marks that the next string is comment text need for ICU. * * See `I18nMutateOpCodes` documentation. */ declare const ICU_MARKER: ICU_MARKER; interface ICU_MARKER { marker: 'ICU'; } interface I18nDebug { /** * Human readable representation of the OpCode arrays. * * NOTE: This property only exists if `ngDevMode` is set to `true` and it is not present in * production. Its presence is purely to help debug issue in development, and should not be relied * on in production application. */ debug?: string[]; } /** * Array storing OpCode for dynamically creating `i18n` translation DOM elements. * * This array creates a sequence of `Text` and `Comment` (as ICU anchor) DOM elements. It consists * of a pair of `number` and `string` pairs which encode the operations for the creation of the * translated block. * * The number is shifted and encoded according to `I18nCreateOpCode` * * Pseudocode: * ```ts * const i18nCreateOpCodes = [ * 10 << I18nCreateOpCode.SHIFT, "Text Node add to DOM", * 11 << I18nCreateOpCode.SHIFT | I18nCreateOpCode.COMMENT, "Comment Node add to DOM", * 12 << I18nCreateOpCode.SHIFT | I18nCreateOpCode.APPEND_LATER, "Text Node added later" * ]; * * for(var i=0; i<i18nCreateOpCodes.length; i++) { * const opcode = i18NCreateOpCodes[i++]; * const index = opcode >> I18nCreateOpCode.SHIFT; * const text = i18NCreateOpCodes[i]; * let node: Text|Comment; * if (opcode & I18nCreateOpCode.COMMENT === I18nCreateOpCode.COMMENT) { * node = lView[~index] = document.createComment(text); * } else { * node = lView[index] = document.createText(text); * } * if (opcode & I18nCreateOpCode.APPEND_EAGERLY !== I18nCreateOpCode.APPEND_EAGERLY) { * parentNode.appendChild(node); * } * } * ``` */ interface I18nCreateOpCodes extends Array<number | string>, I18nDebug { __brand__: 'I18nCreateOpCodes'; } /** * Stores DOM operations which need to be applied to update DOM render tree due to changes in * expressions. * * The basic idea is that `i18nExp` OpCodes capture expression changes and update a change * mask bit. (Bit 1 for expression 1, bit 2 for expression 2 etc..., bit 32 for expression 32 and * higher.) The OpCodes then compare its own change mask against the expression change mask to * determine if the OpCodes should execute. * * NOTE: 32nd bit is special as it says 32nd or higher. This way if we have more than 32 bindings * the code still works, but with lower efficiency. (it is unlikely that a translation would have * more than 32 bindings.) * * These OpCodes can be used by both the i18n block as well as ICU sub-block. * * ## Example * * Assume * ```ts * if (rf & RenderFlags.Update) { * i18nExp(ctx.exp1); // If changed set mask bit 1 * i18nExp(ctx.exp2); // If changed set mask bit 2 * i18nExp(ctx.exp3); // If changed set mask bit 3 * i18nExp(ctx.exp4); // If changed set mask bit 4 * i18nApply(0); // Apply all changes by executing the OpCodes. * } * ``` * We can assume that each call to `i18nExp` sets an internal `changeMask` bit depending on the * index of `i18nExp`. * * ### OpCodes * ```ts * <I18nUpdateOpCodes>[ * // The following OpCodes represent: `<div i18n-title="pre{{exp1}}in{{exp2}}post">` * // If `changeMask & 0b11` * // has changed then execute update OpCodes. * // has NOT changed then skip `8` values and start processing next OpCodes. * 0b11, 8, * // Concatenate `newValue = 'pre'+lView[bindIndex-4]+'in'+lView[bindIndex-3]+'post';`. * 'pre', -4, 'in', -3, 'post', * // Update attribute: `elementAttribute(1, 'title', sanitizerFn(newValue));` * 1 << SHIFT_REF | Attr, 'title', sanitizerFn, * * // The following OpCodes represent: `<div i18n>Hello {{exp3}}!">` * // If `changeMask & 0b100` * // has changed then execute update OpCodes. * // has NOT changed then skip `4` values and start processing next OpCodes. * 0b100, 4, * // Concatenate `newValue = 'Hello ' + lView[bindIndex -2] + '!';`. * 'Hello ', -2, '!', * // Update text: `lView[1].textContent = newValue;` * 1 << SHIFT_REF | Text, * * // The following OpCodes represent: `<div i18n>{exp4, plural, ... }">` * // If `changeMask & 0b1000` * // has changed then execute update OpCodes. * // has NOT changed then skip `2` values and start processing next OpCodes. * 0b1000, 2, * // Concatenate `newValue = lView[bindIndex -1];`. * -1, * // Switch ICU: `icuSwitchCase(lView[1], 0, newValue);` * 0 << SHIFT_ICU | 1 << SHIFT_REF | IcuSwitch, * * // Note `changeMask & -1` is always true, so the IcuUpdate will always execute. * -1, 1, * // Update ICU: `icuUpdateCase(lView[1], 0);` * 0 << SHIFT_ICU | 1 << SHIFT_REF | IcuUpdate, * * ]; * ``` * */ interface I18nUpdateOpCodes extends Array<string | number | SanitizerFn | null>, I18nDebug { __brand__: 'I18nUpdateOpCodes'; } /** * Store information for the i18n translation block. */ interface TI18n { /** * A set of OpCodes which will create the Text Nodes and ICU anchors for the translation blocks. * * NOTE: The ICU anchors are filled in with ICU Update OpCode. */ create: I18nCreateOpCodes; /** * A set of OpCodes which will be executed on each change detection to determine if any changes to * DOM are required. */ update: I18nUpdateOpCodes; /** * An AST representing the translated message. This is used for hydration (and serialization), * while the Update and Create OpCodes are used at runtime. */ ast: Array<I18nNode>; /** * Index of a parent TNode, which represents a host node for this i18n block. */ parentTNodeIndex: number; } /** * Defines the ICU type of `select` or `plural` */ declare const enum IcuType { select = 0, plural = 1 } interface TIcu { /** * Defines the ICU type of `select` or `plural` */ type: IcuType; /** * Index in `LView` where the anchor node is stored. `<!-- ICU 0:0 -->` */ anchorIdx: number; /** * Currently selected ICU case pointer. * * `lView[currentCaseLViewIndex]` stores the currently selected case. This is needed to know how * to clean up the current case when transitioning no the new case. * * If the value stored is: * `null`: No current case selected. * `<0`: A flag which means that the ICU just switched and that `icuUpdate` must be executed * regardless of the `mask`. (After the execution the flag is cleared) * `>=0` A currently selected case index. */ currentCaseLViewIndex: number; /** * A list of case values which the current ICU will try to match. * * The last value is `other` */ cases: any[]; /** * A set of OpCodes to apply in order to build up the DOM render tree for the ICU */ create: IcuCreateOpCodes[]; /** * A set of OpCodes to apply in order to destroy the DOM render tree for the ICU. */ remove: I18nRemoveOpCodes[]; /** * A set of OpCodes to apply in order to update the DOM render tree for the ICU bindings. */ update: I18nUpdateOpCodes[]; } type I18nNode = I18nTextNode | I18nElementNode | I18nICUNode | I18nPlaceholderNode; /** * Represents a block of text in a translation, such as `Hello, {{ name }}!`. */ interface I18nTextNode { /** The AST node kind */ kind: I18nNodeKind.TEXT; /** The LView index */ index: number; } /** * Represents a simple DOM element in a translation, such as `<div>...</div>` */ interface I18nElementNode { /** The AST node kind */ kind: I18nNodeKind.ELEMENT; /** The LView index */ index: number; /** The child nodes */ children: Array<I18nNode>; } /** * Represents an ICU in a translation. */ interface I18nICUNode { /** The AST node kind */ kind: I18nNodeKind.ICU; /** The LView index */ index: number; /** The branching cases */ cases: Array<Array<I18nNode>>; /** The LView index that stores the active case */ currentCaseLViewIndex: number; } /** * Represents special content that is embedded into the translation. This can * either be a special built-in element, such as <ng-container> and <ng-content>, * or it can be a sub-template, for example, from a structural directive. */ interface I18nPlaceholderNode { /** The AST node kind */ kind: I18nNodeKind.PLACEHOLDER; /** The LView index */ index: number; /** The child nodes */ children: Array<I18nNode>; /** The placeholder type */ type: I18nPlaceholderType; } declare const enum I18nPlaceholderType { ELEMENT = 0, SUBTEMPLATE = 1 } declare const enum I18nNodeKind { TEXT = 0, ELEMENT = 1, PLACEHOLDER = 2, ICU = 3 } /** * The goal here is to make sure that the browser DOM API is the Renderer. * We do this by defining a subset of DOM API to be the renderer and then * use that at runtime for rendering. * * At runtime we can then use the DOM api directly, in server or web-worker * it will be easy to implement such API. */ /** Subset of API needed for appending elements and text nodes. */ interface RNode { /** * Returns the parent Element, Document, or DocumentFragment */ parentNode: RNode | null; /** * Returns the parent Element if there is one */ parentElement: RElement | null; /** * Gets the Node immediately following this one in the parent's childNodes */ nextSibling: RNode | null; /** * Insert a child node. * * Used exclusively for adding View root nodes into ViewAnchor location. */ insertBefore(newChild: RNode, refChild: RNode | null, isViewRoot: boolean): void; /** * Append a child node. * * Used exclusively for building up DOM which are static (ie not View roots) */ appendChild(newChild: RNode): RNode; } /** * Subset of API needed for writing attributes, properties, and setting up * listeners on Element. */ interface RElement extends RNode { firstChild: RNode | null; style: RCssStyleDeclaration; classList: RDomTokenList; className: string; tagName: string; textContent: string | null; hasAttribute(name: string): boolean; getAttribute(name: string): string | null; setAttribute(name: string, value: string | TrustedHTML | TrustedScript | TrustedScriptURL): void; removeAttribute(name: string): void; setAttributeNS(namespaceURI: string, qualifiedName: string, value: string | TrustedHTML | TrustedScript | TrustedScriptURL): void; addEventListener(type: string, listener: EventListener, useCapture?: boolean): void; removeEventListener(type: string, listener?: EventListener, options?: boolean): void; remove(): void; setProperty?(name: string, value: any): void; } interface RCssStyleDeclaration { removeProperty(propertyName: string): string; setProperty(propertyName: string, value: string | null, priority?: string): void; } interface RDomTokenList { add(token: string): void; remove(token: string): void; } interface RText extends RNode { textContent: string | null; } interface RComment extends RNode { textContent: string | null; } /** * Keys within serialized view data structure to represent various * parts. See the `SerializedView` interface below for additional information. */ declare const ELEMENT_CONTAINERS = "e"; declare const TEMPLATES = "t"; declare const CONTAINERS = "c"; declare const MULTIPLIER = "x"; declare const NUM_ROOT_NODES = "r"; declare const TEMPLATE_ID = "i"; declare const NODES = "n"; declare const DISCONNECTED_NODES = "d"; declare const I18N_DATA = "l"; declare const DEFER_BLOCK_ID = "di"; declare const DEFER_BLOCK_STATE = "s"; /** * Represents element containers within this view, stored as key-value pairs * where key is an index of a container in an LView (also used in the * `elementContainerStart` instruction), the value is the number of root nodes * in this container. This information is needed to locate an anchor comment * node that goes after all container nodes. */ interface SerializedElementContainers { [key: number]: number; } /** * Serialized data structure that contains relevant hydration * annotation information that describes a given hydration boundary * (e.g. a component). */ interface SerializedView { /** * Serialized information about <ng-container>s. */ [ELEMENT_CONTAINERS]?: SerializedElementContainers; /** * Serialized information about templates. * Key-value pairs where a key is an index of the corresponding * `template` instruction and the value is a unique id that can * be used during hydration to identify that template. */ [TEMPLATES]?: Record<number, string>; /** * Serialized information about view containers. * Key-value pairs where a key is an index of the corresponding * LContainer entry within an LView, and the value is a list * of serialized information about views within this container. */ [CONTAINERS]?: Record<number, SerializedContainerView[]>; /** * Serialized information about nodes in a template. * Key-value pairs where a key is an index of the corresponding * DOM node in an LView and the value is a path that describes * the location of this node (as a set of navigation instructions). */ [NODES]?: Record<number, string>; /** * A list of ids which represents a set of nodes disconnected * from the DOM tree at the serialization time, but otherwise * present in the internal data structures. * * This information is used to avoid triggering the hydration * logic for such nodes and instead use a regular "creation mode". */ [DISCONNECTED_NODES]?: number[]; /** * Serialized information about i18n blocks in a template. * Key-value pairs where a key is an index of the corresponding * i18n entry within an LView, and the value is a list of * active ICU cases. */ [I18N_DATA]?: Record<number, number[]>; /** * If this view represents a `@defer` block, this field contains * unique id of the block. */ [DEFER_BLOCK_ID]?: string; /** * This field represents a status, based on the `DeferBlockState` enum. */ [DEFER_BLOCK_STATE]?: number; } /** * Serialized data structure that contains relevant hydration * annotation information about a view that is a part of a * ViewContainer collection. */ interface SerializedContainerView extends SerializedView { /** * Unique id that represents a TView that was used to create * a given instance of a view: * - TViewType.Embedded: a unique id generated during serialization on the server * - TViewType.Component: an id generated based on component properties * (see `getComponentId` function for details) */ [TEMPLATE_ID]: string; /** * Number of root nodes that belong to this view. * This information is needed to effectively traverse the DOM tree * and identify segments that belong to different views. */ [NUM_ROOT_NODES]: number; /** * Number of times this view is repeated. * This is used to avoid serializing and sending the same hydration * information about similar views (for example, produced by *ngFor). */ [MULTIPLIER]?: number;