@angular/core
Version:
Angular - the core framework
954 lines (937 loc) • 195 kB
JavaScript
/**
* @license Angular v20.0.3
* (c) 2010-2025 Google LLC. https://angular.io/
* License: MIT
*/
import { RuntimeError, InjectionToken, getCurrentTNode, assertInInjectionContext, signalAsReadonlyFn, assertNgModuleType, Injector, inject, ɵɵdefineInjectable as __defineInjectable, formatRuntimeError, INTERNAL_APPLICATION_ERROR_HANDLER, PROVIDED_ZONELESS, stringify, ChangeDetectionScheduler, errorHandlerEnvironmentInitializer, ɵɵinject as __inject, INJECTOR_SCOPE, makeEnvironmentProviders, runInInjectionContext, provideEnvironmentInitializer, ErrorHandler, _global, isComponentHost, getComponentLViewByIndex, getLView, DECLARATION_COMPONENT_VIEW, ɵɵdefineInjector as __defineInjector, ENVIRONMENT_INITIALIZER, unwrapRNode, CLEANUP, isLContainer, HOST, hasI18n, unwrapLView, RENDERER, assertTNode, isProjectionTNode, getComponentDef, PARENT, isRootView, HEADER_OFFSET, TVIEW, CONTEXT, CONTAINER_HEADER_OFFSET, isLView, getTNode, assertNotInReactiveContext, ViewContext, DestroyRef, getNullInjector } from './root_effect_scheduler-DCy1y1b8.mjs';
export { DOCUMENT, EnvironmentInjector, INJECTOR, PendingTasks, defineInjectable, forwardRef, importProvidersFrom, isSignal, isStandalone, provideBrowserGlobalErrorListeners, resolveForwardRef, signal, EffectScheduler as ɵEffectScheduler, NG_COMP_DEF as ɵNG_COMP_DEF, NG_DIR_DEF as ɵNG_DIR_DEF, NG_ELEMENT_ID as ɵNG_ELEMENT_ID, NG_INJ_DEF as ɵNG_INJ_DEF, NG_MOD_DEF as ɵNG_MOD_DEF, NG_PIPE_DEF as ɵNG_PIPE_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, PendingTasksInternal as ɵPendingTasksInternal, R3Injector as ɵR3Injector, XSS_SECURITY_URL as ɵXSS_SECURITY_URL, ZONELESS_ENABLED as ɵZONELESS_ENABLED, convertToBitFlags as ɵconvertToBitFlags, createInjector as ɵcreateInjector, getInjectableDef as ɵgetInjectableDef, isEnvironmentProviders as ɵisEnvironmentProviders, isInjectable as ɵisInjectable, setInjectorProfilerContext as ɵsetInjectorProfilerContext, store as ɵstore, truncateMiddle as ɵtruncateMiddle, ɵunwrapWritableSignal, ɵɵdisableBindings, ɵɵenableBindings, ɵɵinvalidFactoryDep, ɵɵnamespaceHTML, ɵɵnamespaceMathML, ɵɵnamespaceSVG, ɵɵresetView, ɵɵrestoreView } from './root_effect_scheduler-DCy1y1b8.mjs';
import { SIGNAL_NODE, signalSetFn, SIGNAL, producerAccessed, consumerPollProducersForChange, consumerBeforeComputation, consumerAfterComputation } from './signal-nCiHhWf6.mjs';
import { ɵɵinjectAttribute as __injectAttribute, createMultiResultQuerySignalFn, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, makePropDecorator, NgModuleFactory, COMPILER_OPTIONS, setJitOptions, isComponentResourceResolutionQueueEmpty, getCompilerFacade, resolveComponentResources, IMAGE_CONFIG, getDocument, setClassMetadata, Injectable, NgZone, PROVIDED_NG_ZONE, remove, isPromise, ApplicationInitStatus, LOCALE_ID, DEFAULT_LOCALE_ID, setLocaleId, ApplicationRef, internalProvideZoneChangeDetection, ChangeDetectionSchedulerImpl, createNgModuleRefWithProviders, optionsReducer, getNgZone, getNgZoneOptions, publishDefaultGlobalUtils, PLATFORM_INITIALIZER, publishSignalConfiguration, checkNoChangesInternal, UseExhaustiveCheckNoChanges, getRegisteredNgModuleType, ViewRef as ViewRef$1, isListLikeIterable, iterateListLike, isJsObject, SkipSelf, Optional, ɵɵdefineNgModule as __defineNgModule, NgModule, profiler, assertStandaloneComponentType, EnvironmentNgModuleRefAdapter, JSACTION_BLOCK_ELEMENT_MAP, APP_ID, setStashFn, APP_BOOTSTRAP_LISTENER, JSACTION_EVENT_CONTRACT, removeListeners, isIncrementalHydrationEnabled, DEFER_BLOCK_SSR_ID_ATTRIBUTE, invokeListeners, triggerHydrationFromBlockName, IS_EVENT_REPLAY_ENABLED, EVENT_REPLAY_ENABLED_DEFAULT, performanceMarkFeature, sharedStashFunction, sharedMapFunction, enableStashEventListenerImpl, isI18nHydrationEnabled, TransferState, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, SKIP_HYDRATION_ATTR_NAME, NGH_ATTR_NAME, getLNodeForHydration, isI18nHydrationSupportEnabled, getOrComputeI18nChildren, trySerializeI18nBlock, I18N_DATA, isTNodeShape, isDetachedByI18n, isDisconnectedNode, isInSkipHydrationBlock, unsupportedProjectionOfDomNodes, TEMPLATES, CONTAINERS, isLetDeclaration, ELEMENT_CONTAINERS, processTextNodeBeforeSerialization, setJSActionAttributes, ViewEncapsulation as ViewEncapsulation$1, collectNativeNodes, TEMPLATE_ID, NUM_ROOT_NODES, isDeferBlock, getLDeferBlockDetails, getTDeferBlockDetails, collectNativeNodesInLContainer, validateNodeExists, validateMatchingNode, DEFER_BLOCK_ID, DEFER_BLOCK_STATE, DEFER_BLOCK_STATE$1, MULTIPLIER, NODES, calcPathForNode, DISCONNECTED_NODES, convertHydrateTriggersToJsAction, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, IS_I18N_HYDRATION_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, DEHYDRATED_BLOCK_REGISTRY, DehydratedBlockRegistry, processBlockData, gatherDeferBlocksCommentNodes, processAndInitTriggers, appendDeferBlocksToJSActionMap, verifySsrContentsIntegrity, Console, PRESERVE_HOST_CONTENT, cleanupDehydratedViews, countBlocksSkippedByHydration, enableRetrieveHydrationInfoImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateTextNodeImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableFindMatchingDehydratedViewImpl, enableApplyRootElementTransformImpl, enableLocateOrCreateI18nNodeImpl, enablePrepareI18nBlockForHydrationImpl, setIsI18nHydrationSupportEnabled, enableClaimDehydratedIcuCaseImpl, enableRetrieveDeferBlockDataImpl, readPatchedLView, angularCoreEnv, setClassMetadataAsync, NOOP_AFTER_RENDER_REF, AfterRenderManager, TracingService, AfterRenderImpl, AfterRenderSequence, AFTER_RENDER_PHASES, assertComponentDef, ComponentFactory } from './debug_node-JnOYh9kg.mjs';
export { ANIMATION_MODULE_TYPE, APP_INITIALIZER, Attribute, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory$1 as ComponentFactory, ComponentFactoryResolver, ComponentRef, DEFAULT_CURRENCY_CODE, DebugElement, DebugEventListener, DebugNode, Directive, ElementRef, EventEmitter, Host, HostBinding, HostListener, Inject, Input, MissingTranslationStrategy, ModuleWithComponentFactories, NO_ERRORS_SCHEMA, NgModuleFactory$1 as NgModuleFactory, NgModuleRef$1 as NgModuleRef, NgProbeToken, Output, PACKAGE_ROOT_URL, PLATFORM_ID, Pipe, QueryList, Renderer2, RendererFactory2, RendererStyleFlags2, Sanitizer, SecurityContext, Self, SimpleChange, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, Type, ViewContainerRef, afterEveryRender, afterNextRender, asNativeElements, createEnvironmentInjector, createNgModule, createNgModuleRef, enableProfiling, getDebugNode, inputBinding, makeStateKey, outputBinding, provideAppInitializer, provideNgReflectAttributes, provideZoneChangeDetection, provideZonelessChangeDetection, setTestabilityGetter, twoWayBinding, AcxChangeDetectionStrategy as ɵAcxChangeDetectionStrategy, AcxViewEncapsulation as ɵAcxViewEncapsulation, ComponentFactory$1 as ɵComponentFactory, DEFER_BLOCK_CONFIG as ɵDEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR as ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DeferBlockBehavior as ɵDeferBlockBehavior, DeferBlockState as ɵDeferBlockState, Framework as ɵFramework, HydrationStatus as ɵHydrationStatus, IMAGE_CONFIG_DEFAULTS as ɵIMAGE_CONFIG_DEFAULTS, LContext as ɵLContext, LocaleDataIndex as ɵLocaleDataIndex, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE as ɵNO_CHANGE, NoopNgZone as ɵNoopNgZone, ReflectionCapabilities as ɵReflectionCapabilities, ComponentRef$1 as ɵRender3ComponentRef, NgModuleRef as ɵRender3NgModuleRef, SSR_CONTENT_INTEGRITY_MARKER as ɵSSR_CONTENT_INTEGRITY_MARKER, TESTABILITY as ɵTESTABILITY, TESTABILITY_GETTER as ɵTESTABILITY_GETTER, TimerScheduler as ɵTimerScheduler, TracingAction as ɵTracingAction, _sanitizeHtml as ɵ_sanitizeHtml, _sanitizeUrl as ɵ_sanitizeUrl, allowSanitizationBypassAndThrow as ɵallowSanitizationBypassAndThrow, bypassSanitizationTrustHtml as ɵbypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl as ɵbypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript as ɵbypassSanitizationTrustScript, bypassSanitizationTrustStyle as ɵbypassSanitizationTrustStyle, bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, clearResolutionOfComponentResourcesQueue as ɵclearResolutionOfComponentResourcesQueue, compileComponent as ɵcompileComponent, compileDirective as ɵcompileDirective, compileNgModule as ɵcompileNgModule, compileNgModuleDefs as ɵcompileNgModuleDefs, compilePipe as ɵcompilePipe, depsTracker as ɵdepsTracker, devModeEqual as ɵdevModeEqual, findLocaleData as ɵfindLocaleData, flushModuleScopingQueueAsMuchAsPossible as ɵflushModuleScopingQueueAsMuchAsPossible, generateStandaloneInDeclarationsError as ɵgenerateStandaloneInDeclarationsError, getAsyncClassMetadataFn as ɵgetAsyncClassMetadataFn, getDebugNode as ɵgetDebugNode, getDeferBlocks as ɵgetDeferBlocks, getDirectives as ɵgetDirectives, getHostElement as ɵgetHostElement, getLContext as ɵgetLContext, getLocaleCurrencyCode as ɵgetLocaleCurrencyCode, getLocalePluralCase as ɵgetLocalePluralCase, getSanitizationBypassType as ɵgetSanitizationBypassType, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, isBoundToModule as ɵisBoundToModule, isComponentDefPendingResolution as ɵisComponentDefPendingResolution, isNgModule as ɵisNgModule, isSubscribable as ɵisSubscribable, isViewDirty as ɵisViewDirty, markForRefresh as ɵmarkForRefresh, noSideEffects as ɵnoSideEffects, patchComponentDefWithScope as ɵpatchComponentDefWithScope, publishExternalGlobalUtil as ɵpublishExternalGlobalUtil, readHydrationInfo as ɵreadHydrationInfo, registerLocaleData as ɵregisterLocaleData, renderDeferBlockState as ɵrenderDeferBlockState, resetCompiledComponents as ɵresetCompiledComponents, resetJitOptions as ɵresetJitOptions, restoreComponentResolutionQueue as ɵrestoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest as ɵsetAllowDuplicateNgModuleIdsForTest, ɵsetClassDebugInfo, setDocument as ɵsetDocument, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, transitiveScopesFor as ɵtransitiveScopesFor, triggerResourceLoading as ɵtriggerResourceLoading, unregisterAllLocaleData as ɵunregisterLocaleData, unwrapSafeValue as ɵunwrapSafeValue, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomProperty, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, registerNgModuleType as ɵɵregisterNgModuleType, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal } from './debug_node-JnOYh9kg.mjs';
import { OutputEmitterRef } from './resource-BarKSp_3.mjs';
export { computed, effect, linkedSignal, resource, untracked, ResourceImpl as ɵResourceImpl, encapsulateResourceError as ɵencapsulateResourceError, getOutputDestroyRef as ɵgetOutputDestroyRef } from './resource-BarKSp_3.mjs';
export { setAlternateWeakRefImpl as ɵsetAlternateWeakRefImpl } from './weak_ref-BaIq-pgY.mjs';
export { setCurrentInjector as ɵsetCurrentInjector } from './primitives/di.mjs';
import { clearAppScopedEarlyEventContract, EventContract, EventContractContainer, EventDispatcher, registerDispatcher, EventPhase, getAppScopedQueuedEventInfos, isEarlyEventType, isCaptureEventType } from './primitives/event-dispatch.mjs';
import 'rxjs';
import '@angular/core/primitives/di';
import '@angular/core/primitives/signals';
import 'rxjs/operators';
import './attribute-BWp59EjE.mjs';
import './untracked-DmD_2MlC.mjs';
const REQUIRED_UNSET_VALUE = /* @__PURE__ */ Symbol('InputSignalNode#UNSET');
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const INPUT_SIGNAL_NODE = /* @__PURE__ */ (() => {
return {
...SIGNAL_NODE,
transformFn: undefined,
applyValueToInputSignal(node, value) {
signalSetFn(node, value);
},
};
})();
const ɵINPUT_SIGNAL_BRAND_WRITE_TYPE = /* @__PURE__ */ Symbol();
/**
* Creates an input signal.
*
* @param initialValue The initial value.
* Can be set to {@link REQUIRED_UNSET_VALUE} for required inputs.
* @param options Additional options for the input. e.g. a transform, or an alias.
*/
function createInputSignal(initialValue, options) {
const node = Object.create(INPUT_SIGNAL_NODE);
node.value = initialValue;
// Perf note: Always set `transformFn` here to ensure that `node` always
// has the same v8 class shape, allowing monomorphic reads on input signals.
node.transformFn = options?.transform;
function inputValueFn() {
// Record that someone looked at this signal.
producerAccessed(node);
if (node.value === REQUIRED_UNSET_VALUE) {
let message = null;
if (ngDevMode) {
const name = options?.debugName ?? options?.alias;
message = `Input${name ? ` "${name}"` : ''} is required but no value is available yet.`;
}
throw new RuntimeError(-950 /* RuntimeErrorCode.REQUIRED_INPUT_NO_VALUE */, message);
}
return node.value;
}
inputValueFn[SIGNAL] = node;
if (ngDevMode) {
inputValueFn.toString = () => `[Input Signal: ${inputValueFn()}]`;
node.debugName = options?.debugName;
}
return inputValueFn;
}
var FactoryTarget;
(function (FactoryTarget) {
FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
})(FactoryTarget || (FactoryTarget = {}));
var R3TemplateDependencyKind;
(function (R3TemplateDependencyKind) {
R3TemplateDependencyKind[R3TemplateDependencyKind["Directive"] = 0] = "Directive";
R3TemplateDependencyKind[R3TemplateDependencyKind["Pipe"] = 1] = "Pipe";
R3TemplateDependencyKind[R3TemplateDependencyKind["NgModule"] = 2] = "NgModule";
})(R3TemplateDependencyKind || (R3TemplateDependencyKind = {}));
var ViewEncapsulation;
(function (ViewEncapsulation) {
ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
// Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
})(ViewEncapsulation || (ViewEncapsulation = {}));
/*!
* @license
* Copyright Google LLC 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.dev/license
*/
/**
* Creates a token that can be used to inject static attributes of the host node.
*
* @usageNotes
* ### Injecting an attribute that is known to exist
* ```ts
* @Directive()
* class MyDir {
* attr: string = inject(new HostAttributeToken('some-attr'));
* }
* ```
*
* ### Optionally injecting an attribute
* ```ts
* @Directive()
* class MyDir {
* attr: string | null = inject(new HostAttributeToken('some-attr'), {optional: true});
* }
* ```
* @publicApi
*/
class HostAttributeToken {
attributeName;
constructor(attributeName) {
this.attributeName = attributeName;
}
/** @internal */
__NG_ELEMENT_ID__ = () => __injectAttribute(this.attributeName);
toString() {
return `HostAttributeToken ${this.attributeName}`;
}
}
/**
* A token that can be used to inject the tag name of the host node.
*
* @usageNotes
* ### Injecting a tag name that is known to exist
* ```ts
* @Directive()
* class MyDir {
* tagName: string = inject(HOST_TAG_NAME);
* }
* ```
*
* ### Optionally injecting a tag name
* ```ts
* @Directive()
* class MyDir {
* tagName: string | null = inject(HOST_TAG_NAME, {optional: true});
* }
* ```
* @publicApi
*/
const HOST_TAG_NAME = new InjectionToken(ngDevMode ? 'HOST_TAG_NAME' : '');
// HOST_TAG_NAME should be resolved at the current node, similar to e.g. ElementRef,
// so we manually specify __NG_ELEMENT_ID__ here, instead of using a factory.
// tslint:disable-next-line:no-toplevel-property-access
HOST_TAG_NAME.__NG_ELEMENT_ID__ = (flags) => {
const tNode = getCurrentTNode();
if (tNode === null) {
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, ngDevMode &&
'HOST_TAG_NAME can only be injected in directives and components ' +
'during construction time (in a class constructor or as a class field initializer)');
}
if (tNode.type & 2 /* TNodeType.Element */) {
return tNode.value;
}
if (flags & 8 /* InternalInjectFlags.Optional */) {
return null;
}
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, ngDevMode &&
`HOST_TAG_NAME was used on ${getDevModeNodeName(tNode)} which doesn't have an underlying element in the DOM. ` +
`This is invalid, and so the dependency should be marked as optional.`);
};
function getDevModeNodeName(tNode) {
if (tNode.type & 8 /* TNodeType.ElementContainer */) {
return 'an <ng-container>';
}
else if (tNode.type & 4 /* TNodeType.Container */) {
return 'an <ng-template>';
}
else if (tNode.type & 128 /* TNodeType.LetDeclaration */) {
return 'an @let declaration';
}
else {
return 'a node';
}
}
/**
* The `output` function allows declaration of Angular outputs in
* directives and components.
*
* You can use outputs to emit values to parent directives and component.
* Parents can subscribe to changes via:
*
* - template event bindings. For example, `(myOutput)="doSomething($event)"`
* - programmatic subscription by using `OutputRef#subscribe`.
*
* @usageNotes
*
* To use `output()`, import the function from `@angular/core`.
*
* ```ts
* import {output} from '@angular/core';
* ```
*
* Inside your component, introduce a new class member and initialize
* it with a call to `output`.
*
* ```ts
* @Directive({
* ...
* })
* export class MyDir {
* nameChange = output<string>(); // OutputEmitterRef<string>
* onClick = output(); // OutputEmitterRef<void>
* }
* ```
*
* You can emit values to consumers of your directive, by using
* the `emit` method from `OutputEmitterRef`.
*
* ```ts
* updateName(newName: string): void {
* this.nameChange.emit(newName);
* }
* ```
* @initializerApiFunction {"showTypesInSignaturePreview": true}
* @publicApi 19.0
*/
function output(opts) {
ngDevMode && assertInInjectionContext(output);
return new OutputEmitterRef();
}
function inputFunction(initialValue, opts) {
ngDevMode && assertInInjectionContext(input);
return createInputSignal(initialValue, opts);
}
function inputRequiredFunction(opts) {
ngDevMode && assertInInjectionContext(input);
return createInputSignal(REQUIRED_UNSET_VALUE, opts);
}
/**
* 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
*/
const input = (() => {
// Note: This may be considered a side-effect, but nothing will depend on
// this assignment, unless this `input` constant export is accessed. It's a
// self-contained side effect that is local to the user facing`input` export.
inputFunction.required = inputRequiredFunction;
return inputFunction;
})();
function viewChildFn(locator, opts) {
ngDevMode && assertInInjectionContext(viewChild);
return createSingleResultOptionalQuerySignalFn(opts);
}
function viewChildRequiredFn(locator, opts) {
ngDevMode && assertInInjectionContext(viewChild);
return createSingleResultRequiredQuerySignalFn(opts);
}
/**
* Initializes a view child query.
*
* Consider using `viewChild.required` for queries that should always match.
*
* @usageNotes
* Create a child query in your component by declaring a
* class field and initializing it with the `viewChild()` function.
*
* ```angular-ts
* @Component({template: '<div #el></div><my-component #cmp />'})
* export class TestComponent {
* divEl = viewChild<ElementRef>('el'); // Signal<ElementRef|undefined>
* divElRequired = viewChild.required<ElementRef>('el'); // Signal<ElementRef>
* cmp = viewChild(MyComponent); // Signal<MyComponent|undefined>
* cmpRequired = viewChild.required(MyComponent); // Signal<MyComponent>
* }
* ```
*
* @publicApi 19.0
* @initializerApiFunction
*/
const viewChild = (() => {
// Note: This may be considered a side-effect, but nothing will depend on
// this assignment, unless this `viewChild` constant export is accessed. It's a
// self-contained side effect that is local to the user facing `viewChild` export.
viewChildFn.required = viewChildRequiredFn;
return viewChildFn;
})();
/**
* Initializes a view children query.
*
* Query results are represented as a signal of a read-only collection containing all matched
* elements.
*
* @usageNotes
* Create a children query in your component by declaring a
* class field and initializing it with the `viewChildren()` function.
*
* ```ts
* @Component({...})
* export class TestComponent {
* divEls = viewChildren<ElementRef>('el'); // Signal<ReadonlyArray<ElementRef>>
* }
* ```
*
* @initializerApiFunction
* @publicApi 19.0
*/
function viewChildren(locator, opts) {
ngDevMode && assertInInjectionContext(viewChildren);
return createMultiResultQuerySignalFn(opts);
}
function contentChildFn(locator, opts) {
ngDevMode && assertInInjectionContext(contentChild);
return createSingleResultOptionalQuerySignalFn(opts);
}
function contentChildRequiredFn(locator, opts) {
ngDevMode && assertInInjectionContext(contentChildren);
return createSingleResultRequiredQuerySignalFn(opts);
}
/**
* Initializes a content child query. Consider using `contentChild.required` for queries that should
* always match.
*
* @usageNotes
* Create a child query in your component by declaring a
* class field and initializing it with the `contentChild()` function.
*
* ```ts
* @Component({...})
* export class TestComponent {
* headerEl = contentChild<ElementRef>('h'); // Signal<ElementRef|undefined>
* headerElElRequired = contentChild.required<ElementRef>('h'); // Signal<ElementRef>
* header = contentChild(MyHeader); // Signal<MyHeader|undefined>
* headerRequired = contentChild.required(MyHeader); // Signal<MyHeader>
* }
* ```
*
* Note: By default `descendants` is `true` which means the query will traverse all descendants in the same template.
*
* @initializerApiFunction
* @publicApi 19.0
*/
const contentChild = (() => {
// Note: This may be considered a side-effect, but nothing will depend on
// this assignment, unless this `viewChild` constant export is accessed. It's a
// self-contained side effect that is local to the user facing `viewChild` export.
contentChildFn.required = contentChildRequiredFn;
return contentChildFn;
})();
/**
* Initializes a content children query.
*
* Query results are represented as a signal of a read-only collection containing all matched
* elements.
*
* @usageNotes
* Create a children query in your component by declaring a
* class field and initializing it with the `contentChildren()` function.
*
* ```ts
* @Component({...})
* export class TestComponent {
* headerEl = contentChildren<ElementRef>('h'); // Signal<ReadonlyArray<ElementRef>>
* }
* ```
*
* Note: By default `descendants` is `false` which means the query will not traverse all descendants in the same template.
*
* @initializerApiFunction
* @publicApi 19.0
*/
function contentChildren(locator, opts) {
return createMultiResultQuerySignalFn(opts);
}
/**
* Creates a model signal.
*
* @param initialValue The initial value.
* Can be set to {@link REQUIRED_UNSET_VALUE} for required model signals.
* @param options Additional options for the model.
*/
function createModelSignal(initialValue, opts) {
const node = Object.create(INPUT_SIGNAL_NODE);
const emitterRef = new OutputEmitterRef();
node.value = initialValue;
function getter() {
producerAccessed(node);
assertModelSet(node.value);
return node.value;
}
getter[SIGNAL] = node;
getter.asReadonly = signalAsReadonlyFn.bind(getter);
// TODO: Should we throw an error when updating a destroyed model?
getter.set = (newValue) => {
if (!node.equal(node.value, newValue)) {
signalSetFn(node, newValue);
emitterRef.emit(newValue);
}
};
getter.update = (updateFn) => {
assertModelSet(node.value);
getter.set(updateFn(node.value));
};
getter.subscribe = emitterRef.subscribe.bind(emitterRef);
getter.destroyRef = emitterRef.destroyRef;
if (ngDevMode) {
getter.toString = () => `[Model Signal: ${getter()}]`;
node.debugName = opts?.debugName;
}
return getter;
}
/** Asserts that a model's value is set. */
function assertModelSet(value) {
if (value === REQUIRED_UNSET_VALUE) {
throw new RuntimeError(952 /* RuntimeErrorCode.REQUIRED_MODEL_NO_VALUE */, ngDevMode && 'Model is required but no value is available yet.');
}
}
function modelFunction(initialValue, opts) {
ngDevMode && assertInInjectionContext(model);
return createModelSignal(initialValue, opts);
}
function modelRequiredFunction(opts) {
ngDevMode && assertInInjectionContext(model);
return createModelSignal(REQUIRED_UNSET_VALUE, opts);
}
/**
* `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 19.0
* @initializerApiFunction
*/
const model = (() => {
// Note: This may be considered a side-effect, but nothing will depend on
// this assignment, unless this `model` constant export is accessed. It's a
// self-contained side effect that is local to the user facing `model` export.
modelFunction.required = modelRequiredFunction;
return modelFunction;
})();
// Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not
// explicitly set.
const emitDistinctChangesOnlyDefaultValue = true;
/**
* Base class for query metadata.
*
* @see {@link ContentChildren}
* @see {@link ContentChild}
* @see {@link ViewChildren}
* @see {@link ViewChild}
*
* @publicApi
*/
class Query {
}
/**
* ContentChildren decorator and metadata.
*
*
* @Annotation
* @publicApi
*/
const ContentChildren = makePropDecorator('ContentChildren', (selector, opts = {}) => ({
selector,
first: false,
isViewQuery: false,
descendants: false,
emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue,
...opts,
}), Query);
/**
* ContentChild decorator and metadata.
*
*
* @Annotation
*
* @publicApi
*/
const ContentChild = makePropDecorator('ContentChild', (selector, opts = {}) => ({
selector,
first: true,
isViewQuery: false,
descendants: true,
...opts,
}), Query);
/**
* ViewChildren decorator and metadata.
*
* @Annotation
* @publicApi
*/
const ViewChildren = makePropDecorator('ViewChildren', (selector, opts = {}) => ({
selector,
first: false,
isViewQuery: true,
descendants: true,
emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue,
...opts,
}), Query);
/**
* ViewChild decorator and metadata.
*
* @Annotation
* @publicApi
*/
const ViewChild = makePropDecorator('ViewChild', (selector, opts) => ({
selector,
first: true,
isViewQuery: true,
descendants: true,
...opts,
}), Query);
/**
* @description Represents the version of Angular
*
* @publicApi
*/
class Version {
full;
major;
minor;
patch;
constructor(full) {
this.full = full;
const parts = full.split('.');
this.major = parts[0];
this.minor = parts[1];
this.patch = parts.slice(2).join('.');
}
}
/**
* @publicApi
*/
const VERSION = new Version('20.0.3');
function compileNgModuleFactory(injector, options, moduleType) {
ngDevMode && assertNgModuleType(moduleType);
const moduleFactory = new NgModuleFactory(moduleType);
// All of the logic below is irrelevant for AOT-compiled code.
if (typeof ngJitMode !== 'undefined' && !ngJitMode) {
return Promise.resolve(moduleFactory);
}
const compilerOptions = injector.get(COMPILER_OPTIONS, []).concat(options);
// Configure the compiler to use the provided options. This call may fail when multiple modules
// are bootstrapped with incompatible options, as a component can only be compiled according to
// a single set of options.
setJitOptions({
defaultEncapsulation: _lastDefined(compilerOptions.map((opts) => opts.defaultEncapsulation)),
preserveWhitespaces: _lastDefined(compilerOptions.map((opts) => opts.preserveWhitespaces)),
});
if (isComponentResourceResolutionQueueEmpty()) {
return Promise.resolve(moduleFactory);
}
const compilerProviders = compilerOptions.flatMap((option) => option.providers ?? []);
// In case there are no compiler providers, we just return the module factory as
// there won't be any resource loader. This can happen with Ivy, because AOT compiled
// modules can be still passed through "bootstrapModule". In that case we shouldn't
// unnecessarily require the JIT compiler.
if (compilerProviders.length === 0) {
return Promise.resolve(moduleFactory);
}
const compiler = getCompilerFacade({
usage: 0 /* JitCompilerUsage.Decorator */,
kind: 'NgModule',
type: moduleType,
});
const compilerInjector = Injector.create({ providers: compilerProviders });
const resourceLoader = compilerInjector.get(compiler.ResourceLoader);
// The resource loader can also return a string while the "resolveComponentResources"
// always expects a promise. Therefore we need to wrap the returned value in a promise.
return resolveComponentResources((url) => Promise.resolve(resourceLoader.get(url))).then(() => moduleFactory);
}
function _lastDefined(args) {
for (let i = args.length - 1; i >= 0; i--) {
if (args[i] !== undefined) {
return args[i];
}
}
return undefined;
}
// A delay in milliseconds before the scan is run after onLoad, to avoid any
// potential race conditions with other LCP-related functions. This delay
// happens outside of the main JavaScript execution and will only effect the timing
// on when the warning becomes visible in the console.
const SCAN_DELAY = 200;
const OVERSIZED_IMAGE_TOLERANCE = 1200;
class ImagePerformanceWarning {
// Map of full image URLs -> original `ngSrc` values.
window = null;
observer = null;
options = inject(IMAGE_CONFIG);
lcpImageUrl;
start() {
if ((typeof ngServerMode !== 'undefined' && ngServerMode) ||
typeof PerformanceObserver === 'undefined' ||
(this.options?.disableImageSizeWarning && this.options?.disableImageLazyLoadWarning)) {
return;
}
this.observer = this.initPerformanceObserver();
const doc = getDocument();
const win = doc.defaultView;
if (win) {
this.window = win;
// Wait to avoid race conditions where LCP image triggers
// load event before it's recorded by the performance observer
const waitToScan = () => {
setTimeout(this.scanImages.bind(this), SCAN_DELAY);
};
const setup = () => {
// Consider the case when the application is created and destroyed multiple times.
// Typically, applications are created instantly once the page is loaded, and the
// `window.load` listener is always triggered. However, the `window.load` event will never
// be fired if the page is loaded, and the application is created later. Checking for
// `readyState` is the easiest way to determine whether the page has been loaded or not.
if (doc.readyState === 'complete') {
waitToScan();
}
else {
this.window?.addEventListener('load', waitToScan, { once: true });
}
};
// Angular doesn't have to run change detection whenever any asynchronous tasks are invoked in
// the scope of this functionality.
if (typeof Zone !== 'undefined') {
Zone.root.run(() => setup());
}
else {
setup();
}
}
}
ngOnDestroy() {
this.observer?.disconnect();
}
initPerformanceObserver() {
if (typeof PerformanceObserver === 'undefined') {
return null;
}
const observer = new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
if (entries.length === 0)
return;
// We use the latest entry produced by the `PerformanceObserver` as the best
// signal on which element is actually an LCP one. As an example, the first image to load on
// a page, by virtue of being the only thing on the page so far, is often a LCP candidate
// and gets reported by PerformanceObserver, but isn't necessarily the LCP element.
const lcpElement = entries[entries.length - 1];
// Cast to `any` due to missing `element` on the `LargestContentfulPaint` type of entry.
// See https://developer.mozilla.org/en-US/docs/Web/API/LargestContentfulPaint
const imgSrc = lcpElement.element?.src ?? '';
// Exclude `data:` and `blob:` URLs, since they are fetched resources.
if (imgSrc.startsWith('data:') || imgSrc.startsWith('blob:'))
return;
this.lcpImageUrl = imgSrc;
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });
return observer;
}
scanImages() {
const images = getDocument().querySelectorAll('img');
let lcpElementFound, lcpElementLoadedCorrectly = false;
images.forEach((image) => {
if (!this.options?.disableImageSizeWarning) {
// Image elements using the NgOptimizedImage directive are excluded,
// as that directive has its own version of this check.
if (!image.getAttribute('ng-img') && this.isOversized(image)) {
logOversizedImageWarning(image.src);
}
}
if (!this.options?.disableImageLazyLoadWarning && this.lcpImageUrl) {
if (image.src === this.lcpImageUrl) {
lcpElementFound = true;
if (image.loading !== 'lazy' || image.getAttribute('ng-img')) {
// This variable is set to true and never goes back to false to account
// for the case where multiple images have the same src url, and some
// have lazy loading while others don't.
// Also ignore NgOptimizedImage because there's a different warning for that.
lcpElementLoadedCorrectly = true;
}
}
}
});
if (lcpElementFound &&
!lcpElementLoadedCorrectly &&
this.lcpImageUrl &&
!this.options?.disableImageLazyLoadWarning) {
logLazyLCPWarning(this.lcpImageUrl);
}
}
isOversized(image) {
if (!this.window) {
return false;
}
// The `isOversized` check may not be applicable or may require adjustments
// for several types of image formats or scenarios. Currently, we specify only
// `svg`, but this may also include `gif` since their quality isn’t tied to
// dimensions in the same way as raster images.
const nonOversizedImageExtentions = [
// SVG images are vector-based, which means they can scale
// to any size without losing quality.
'.svg',
];
// Convert it to lowercase because this may have uppercase
// extensions, such as `IMAGE.SVG`.
// We fallback to an empty string because `src` may be `undefined`
// if it is explicitly set to `null` by some third-party code
// (e.g., `image.src = null`).
const imageSource = (image.src || '').toLowerCase();
if (nonOversizedImageExtentions.some((extension) => imageSource.endsWith(extension))) {
return false;
}
const computedStyle = this.window.getComputedStyle(image);
let renderedWidth = parseFloat(computedStyle.getPropertyValue('width'));
let renderedHeight = parseFloat(computedStyle.getPropertyValue('height'));
const boxSizing = computedStyle.getPropertyValue('box-sizing');
const objectFit = computedStyle.getPropertyValue('object-fit');
if (objectFit === `cover`) {
// Object fit cover may indicate a use case such as a sprite sheet where
// this warning does not apply.
return false;
}
if (boxSizing === 'border-box') {
// If the image `box-sizing` is set to `border-box`, we adjust the rendered
// dimensions by subtracting padding values.
const paddingTop = computedStyle.getPropertyValue('padding-top');
const paddingRight = computedStyle.getPropertyValue('padding-right');
const paddingBottom = computedStyle.getPropertyValue('padding-bottom');
const paddingLeft = computedStyle.getPropertyValue('padding-left');
renderedWidth -= parseFloat(paddingRight) + parseFloat(paddingLeft);
renderedHeight -= parseFloat(paddingTop) + parseFloat(paddingBottom);
}
const intrinsicWidth = image.naturalWidth;
const intrinsicHeight = image.naturalHeight;
const recommendedWidth = this.window.devicePixelRatio * renderedWidth;
const recommendedHeight = this.window.devicePixelRatio * renderedHeight;
const oversizedWidth = intrinsicWidth - recommendedWidth >= OVERSIZED_IMAGE_TOLERANCE;
const oversizedHeight = intrinsicHeight - recommendedHeight >= OVERSIZED_IMAGE_TOLERANCE;
return oversizedWidth || oversizedHeight;
}
static ɵfac = function ImagePerformanceWarning_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ImagePerformanceWarning)(); };
static ɵprov = /*@__PURE__*/ __defineInjectable({ token: ImagePerformanceWarning, factory: ImagePerformanceWarning.ɵfac, providedIn: 'root' });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ImagePerformanceWarning, [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], null, null); })();
function logLazyLCPWarning(src) {
console.warn(formatRuntimeError(-913 /* RuntimeErrorCode.IMAGE_PERFORMANCE_WARNING */, `An image with src ${src} is the Largest Contentful Paint (LCP) element ` +
`but was given a "loading" value of "lazy", which can negatively impact ` +
`application loading performance. This warning can be addressed by ` +
`changing the loading value of the LCP image to "eager", or by using the ` +
`NgOptimizedImage directive's prioritization utilities. For more ` +
`information about addressing or disabling this warning, see ` +
`https://angular.dev/errors/NG0913`));
}
function logOversizedImageWarning(src) {
console.warn(formatRuntimeError(-913 /* RuntimeErrorCode.IMAGE_PERFORMANCE_WARNING */, `An image with src ${src} has intrinsic file dimensions much larger than its ` +
`rendered size. This can negatively impact application loading performance. ` +
`For more information about addressing or disabling this warning, see ` +
`https://angular.dev/errors/NG0913`));
}
/**
* Internal token that allows to register extra callbacks that should be invoked during the
* `PlatformRef.destroy` operation. This token is needed to avoid a direct reference to the
* `PlatformRef` class (i.e. register the callback via `PlatformRef.onDestroy`), thus making the
* entire class tree-shakeable.
*/
const PLATFORM_DESTROY_LISTENERS = new InjectionToken(ngDevMode ? 'PlatformDestroyListeners' : '');
/**
* InjectionToken to control root component bootstrap behavior.
*
* This token is primarily used in Angular's server-side rendering (SSR) scenarios,
* particularly by the `@angular/ssr` package, to manage whether the root component
* should be bootstrapped during the application initialization process.
*
* ## Purpose:
* During SSR route extraction, setting this token to `false` prevents Angular from
* bootstrapping the root component. This avoids unnecessary component rendering,
* enabling route extraction without requiring additional APIs or triggering
* component logic.
*
* ## Behavior:
* - **`false`**: Prevents the root component from being bootstrapped.
* - **`true`** (default): Proceeds with the normal root component bootstrap process.
*
* This mechanism ensures SSR can efficiently separate route extraction logic
* from component rendering.
*/
const ENABLE_ROOT_COMPONENT_BOOTSTRAP = new InjectionToken(ngDevMode ? 'ENABLE_ROOT_COMPONENT_BOOTSTRAP' : '');
function isApplicationBootstrapConfig(config) {
return !config.moduleRef;
}
function bootstrap(config) {
const envInjector = isApplicationBootstrapConfig(config)
? config.r3Injector
: config.moduleRef.injector;
const ngZone = envInjector.get(NgZone);
return ngZone.run(() => {
if (isApplicationBootstrapConfig(config)) {
config.r3Injector.resolveInjectorInitializers();
}
else {
config.moduleRef.resolveInjectorInitializers();
}
const exceptionHandler = envInjector.get(INTERNAL_APPLICATION_ERROR_HANDLER);
if (typeof ngDevMode === 'undefined' || ngDevMode) {
if (envInjector.get(PROVIDED_ZONELESS) && envInjector.get(PROVIDED_NG_ZONE)) {
throw new RuntimeError(408 /* RuntimeErrorCode.PROVIDED_BOTH_ZONE_AND_ZONELESS */, 'Invalid change detection configuration: ' +
'provideZoneChangeDetection and provideZonelessChangeDetection cannot be used together.');
}
}
let onErrorSubscription;
ngZone.runOutsideAngular(() => {
onErrorSubscription = ngZone.onError.subscribe({
next: exceptionHandler,
});
});
// If the whole platform is destroyed, invoke the `destroy` method
// for all bootstrapped applications as well.
if (isApplicationBootstrapConfig(config)) {
const destroyListener = () => envInjector.destroy();
const onPlatformDestroyListeners = config.platformInjector.get(PLATFORM_DESTROY_LISTENERS);
onPlatformDestroyListeners.add(destroyListener);
envInjector.onDestroy(() => {
onErrorSubscription.unsubscribe();
onPlatformDestroyListeners.delete(destroyListener);
});
}
else {
const destroyListener = () => config.moduleRef.destroy();
const onPlatformDestroyListeners = config.platformInjector.get(PLATFORM_DESTROY_LISTENERS);
onPlatformDestroyListeners.add(destroyListener);
config.moduleRef.onDestroy(() => {
remove(config.allPlatformModules, config.moduleRef);
onErrorSubscription.unsubscribe();
onPlatformDestroyListeners.delete(destroyListener);
});
}
return _callAndReportToErrorHandler(exceptionHandler, ngZone, () => {
const initStatus = envInjector.get(ApplicationInitStatus);
initStatus.runInitializers();
return initStatus.donePromise.then(() => {
// If the `LOCALE_ID` provider is defined at bootstrap then we set the value for ivy
const localeId = envInjector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
setLocaleId(localeId || DEFAULT_LOCALE_ID);
const enableRootComponentBoostrap = envInjector.get(ENABLE_ROOT_COMPONENT_BOOTSTRAP, true);
if (!enableRootComponentBoostrap) {
if (isApplicationBootstrapConfig(config)) {
return envInjector.get(ApplicationRef);
}
config.allPlatformModules.push(config.moduleRef);
return config.moduleRef;
}
if (typeof ngDevMode === 'undefined' || ngDevMode) {
const imagePerformanceService = envInjector.get(ImagePerformanceWarning);
imagePerformanceService