@angular/core 20.3.21 → 20.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/api.d.d.ts +1 -1
  2. package/chrome_dev_tools_performance.d.d.ts +1 -1
  3. package/discovery.d.d.ts +7 -2
  4. package/effect.d.d.ts +1 -1
  5. package/event_dispatcher.d.d.ts +1 -1
  6. package/fesm2022/attribute.mjs +1 -1
  7. package/fesm2022/core.mjs +1 -1
  8. package/fesm2022/debug_node.mjs +266 -60
  9. package/fesm2022/debug_node.mjs.map +1 -1
  10. package/fesm2022/effect.mjs +1 -1
  11. package/fesm2022/not_found.mjs +1 -1
  12. package/fesm2022/primitives/di.mjs +1 -1
  13. package/fesm2022/primitives/event-dispatch.mjs +1 -1
  14. package/fesm2022/primitives/signals.mjs +1 -1
  15. package/fesm2022/resource.mjs +1 -1
  16. package/fesm2022/root_effect_scheduler.mjs +2 -2
  17. package/fesm2022/root_effect_scheduler.mjs.map +1 -1
  18. package/fesm2022/rxjs-interop.mjs +1 -1
  19. package/fesm2022/signal.mjs +1 -1
  20. package/fesm2022/testing.mjs +1 -1
  21. package/fesm2022/weak_ref.mjs +1 -1
  22. package/formatter.d.d.ts +1 -1
  23. package/index.d.ts +1 -1
  24. package/package.json +2 -2
  25. package/primitives/di/index.d.ts +1 -1
  26. package/primitives/event-dispatch/index.d.ts +1 -1
  27. package/primitives/signals/index.d.ts +1 -1
  28. package/rxjs-interop/index.d.ts +1 -1
  29. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +5 -5
  30. package/schematics/bundles/{apply_import_manager-Clb1Y0Nb.cjs → apply_import_manager-PXAcrMhA.cjs} +3 -3
  31. package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
  32. package/schematics/bundles/{compiler_host-AFZotBLM.cjs → compiler_host-Cko9gxwJ.cjs} +2 -2
  33. package/schematics/bundles/control-flow-migration.cjs +3 -3
  34. package/schematics/bundles/document-core.cjs +5 -5
  35. package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
  36. package/schematics/bundles/{index-CD4aCRVu.cjs → index-Cvub7R-2.cjs} +4 -4
  37. package/schematics/bundles/{index-kR-YjYku.cjs → index-DfqvcK_R.cjs} +12 -12
  38. package/schematics/bundles/inject-flags.cjs +5 -5
  39. package/schematics/bundles/inject-migration.cjs +3 -3
  40. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  41. package/schematics/bundles/{migrate_ts_type_references-BgYfSnnL.cjs → migrate_ts_type_references-TafxKegc.cjs} +5 -5
  42. package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
  43. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  44. package/schematics/bundles/output-migration.cjs +6 -6
  45. package/schematics/bundles/{project_paths-Bq_k0pof.cjs → project_paths-DnFzmfc7.cjs} +3 -3
  46. package/schematics/bundles/{project_tsconfig_paths-D2eb40pS.cjs → project_tsconfig_paths-DkhzVMGt.cjs} +278 -211
  47. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  48. package/schematics/bundles/route-lazy-loading.cjs +3 -3
  49. package/schematics/bundles/router-current-navigation.cjs +4 -4
  50. package/schematics/bundles/self-closing-tags-migration.cjs +4 -4
  51. package/schematics/bundles/signal-input-migration.cjs +7 -7
  52. package/schematics/bundles/signal-queries-migration.cjs +7 -7
  53. package/schematics/bundles/signals.cjs +7 -7
  54. package/schematics/bundles/standalone-migration.cjs +4 -4
  55. package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
  56. package/schematics/bundles/test-bed-get.cjs +4 -4
  57. package/testing/index.d.ts +1 -1
  58. package/weak_ref.d.d.ts +1 -1
package/api.d.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
package/discovery.d.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -1350,6 +1350,10 @@ interface TNode {
1350
1350
  * `TNodeType.ICUContainer`: `TIcu`
1351
1351
  */
1352
1352
  value: any;
1353
+ /**
1354
+ * The namespace associated with this node.
1355
+ */
1356
+ namespace: string | null;
1353
1357
  /**
1354
1358
  * Attributes associated with an element. We need to store attributes to support various
1355
1359
  * use-cases (attribute injection, content projection with selectors, directives matching).
@@ -2927,7 +2931,8 @@ declare enum SecurityContext {
2927
2931
  STYLE = 2,
2928
2932
  SCRIPT = 3,
2929
2933
  URL = 4,
2930
- RESOURCE_URL = 5
2934
+ RESOURCE_URL = 5,
2935
+ ATTRIBUTE_NO_BINDING = 6
2931
2936
  }
2932
2937
 
2933
2938
  /**
package/effect.d.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
package/fesm2022/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @license Angular v20.3.21
2
+ * @license Angular v20.3.22
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, inject, formatRuntimeError, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, isDirectiveHost, XSS_SECURITY_URL, RENDERER, renderStringify, getSelectedTNode, ENVIRONMENT, makeEnvironmentProviders, resetPreOrderHookFlags, PARENT, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, isInInjectionContext, DestroyRef, PendingTasksInternal, noop, ChangeDetectionScheduler, ErrorHandler, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, assertNotInReactiveContext, assertInInjectionContext, ViewContext, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, ANIMATIONS, assertParentView, CONTAINER_HEADER_OFFSET, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, ENVIRONMENT_INITIALIZER, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, ZONELESS_SCHEDULER_DISABLED, SCHEDULE_IN_ROOT_ZONE, PROVIDED_ZONELESS, getNativeByTNodeOrNull } from './root_effect_scheduler.mjs';
7
+ import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, inject, formatRuntimeError, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, isDirectiveHost, XSS_SECURITY_URL, RENDERER, renderStringify, getSelectedTNode, ENVIRONMENT, getSelectedIndex, makeEnvironmentProviders, resetPreOrderHookFlags, PARENT, CHILD_TAIL, assertSame, assertFirstUpdatePass, getTView, assertIndexInDeclRange, setSelectedIndex, isInInjectionContext, DestroyRef, PendingTasksInternal, noop, ChangeDetectionScheduler, ErrorHandler, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, assertNotInReactiveContext, assertInInjectionContext, ViewContext, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, ANIMATIONS, assertParentView, CONTAINER_HEADER_OFFSET, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getNamespace, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, EnvironmentInjector, SVG_NAMESPACE as SVG_NAMESPACE$1, MATH_ML_NAMESPACE as MATH_ML_NAMESPACE$1, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, ENVIRONMENT_INITIALIZER, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, ZONELESS_SCHEDULER_DISABLED, SCHEDULE_IN_ROOT_ZONE, PROVIDED_ZONELESS, getNativeByTNodeOrNull } from './root_effect_scheduler.mjs';
8
8
  import { setActiveConsumer, SIGNAL, consumerDestroy, REACTIVE_NODE, consumerPollProducersForChange, consumerBeforeComputation, getActiveConsumer, consumerAfterComputation, createComputed, setThrowInvalidWriteToSignalError } from './signal.mjs';
9
9
  import { Subject, Subscription } from 'rxjs';
10
10
  import { setActiveConsumer as setActiveConsumer$1 } from '@angular/core/primitives/signals';
@@ -5622,13 +5622,6 @@ const VALID_ATTRS = merge(URI_ATTRS, HTML_ATTRS, ARIA_ATTRS);
5622
5622
  // `Some content`, but strip `invalid-element` opening/closing tags. For some elements, though, we
5623
5623
  // don't want to preserve the content, if the elements themselves are going to be removed.
5624
5624
  const SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS = tagSet('script,style,template');
5625
- /**
5626
- * Attributes that are potential attach vectors and may need to be sanitized.
5627
- */
5628
- const SENSITIVE_ATTRS = merge(URI_ATTRS,
5629
- // Note: we don't include these attributes in `URI_ATTRS`, because `URI_ATTRS` also
5630
- // determines whether an attribute should be dropped when sanitizing an HTML string.
5631
- tagSet('action,formaction,data,codebase'));
5632
5625
  /**
5633
5626
  * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
5634
5627
  * attributes.
@@ -6032,7 +6025,132 @@ var SecurityContext;
6032
6025
  SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
6033
6026
  SecurityContext[SecurityContext["URL"] = 4] = "URL";
6034
6027
  SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
6028
+ SecurityContext[SecurityContext["ATTRIBUTE_NO_BINDING"] = 6] = "ATTRIBUTE_NO_BINDING";
6035
6029
  })(SecurityContext || (SecurityContext = {}));
6030
+ // =================================================================================================
6031
+ // =================================================================================================
6032
+ // =========== S T O P - S T O P - S T O P - S T O P - S T O P - S T O P ===========
6033
+ // =================================================================================================
6034
+ // =================================================================================================
6035
+ //
6036
+ // DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW!
6037
+ //
6038
+ // =================================================================================================
6039
+ /**
6040
+ * Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'.
6041
+ */
6042
+ let _SECURITY_SCHEMA;
6043
+ const SVG_NAMESPACE = 'svg';
6044
+ const MATH_ML_NAMESPACE = 'math';
6045
+ /**
6046
+ * @remarks Keep is a copy of DOM Security Schema.
6047
+ * @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
6048
+ */
6049
+ function SECURITY_SCHEMA() {
6050
+ if (!_SECURITY_SCHEMA) {
6051
+ _SECURITY_SCHEMA = {};
6052
+ // Case is insignificant below, all element and attribute names are lower-cased for lookup.
6053
+ registerContext(SecurityContext.HTML, /** Namespace */ undefined, [
6054
+ ['iframe', ['srcdoc']],
6055
+ ['*', ['innerHTML', 'outerHTML']],
6056
+ ]);
6057
+ registerContext(SecurityContext.STYLE, /** Namespace */ undefined, [['*', ['style']]]);
6058
+ // NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.
6059
+ registerContext(SecurityContext.URL, /** Namespace */ undefined, [
6060
+ ['*', ['formAction']],
6061
+ ['area', ['href']],
6062
+ ['a', ['href', 'xlink:href']],
6063
+ ['form', ['action']],
6064
+ // The below two items are safe and should be removed but they require a G3 clean-up as a small number of tests fail.
6065
+ ['img', ['src']],
6066
+ ['video', ['src']],
6067
+ ]);
6068
+ registerContext(SecurityContext.URL, MATH_ML_NAMESPACE, [
6069
+ // MathML namespace
6070
+ // https://crsrc.org/c/third_party/blink/renderer/core/sanitizer/sanitizer.cc;l=753-768;drc=b3eb16372dcd3317d65e9e0265015e322494edcd;bpv=1;bpt=1
6071
+ ['annotation', ['href', 'xlink:href']],
6072
+ ['annotation-xml', ['href', 'xlink:href']],
6073
+ ['maction', ['href', 'xlink:href']],
6074
+ ['malignmark', ['href', 'xlink:href']],
6075
+ ['math', ['href', 'xlink:href']],
6076
+ ['mroot', ['href', 'xlink:href']],
6077
+ ['msqrt', ['href', 'xlink:href']],
6078
+ ['merror', ['href', 'xlink:href']],
6079
+ ['mfrac', ['href', 'xlink:href']],
6080
+ ['mglyph', ['href', 'xlink:href']],
6081
+ ['msub', ['href', 'xlink:href']],
6082
+ ['msup', ['href', 'xlink:href']],
6083
+ ['msubsup', ['href', 'xlink:href']],
6084
+ ['mmultiscripts', ['href', 'xlink:href']],
6085
+ ['mprescripts', ['href', 'xlink:href']],
6086
+ ['mi', ['href', 'xlink:href']],
6087
+ ['mn', ['href', 'xlink:href']],
6088
+ ['mo', ['href', 'xlink:href']],
6089
+ ['mpadded', ['href', 'xlink:href']],
6090
+ ['mphantom', ['href', 'xlink:href']],
6091
+ ['mrow', ['href', 'xlink:href']],
6092
+ ['ms', ['href', 'xlink:href']],
6093
+ ['mspace', ['href', 'xlink:href']],
6094
+ ['mstyle', ['href', 'xlink:href']],
6095
+ ['mtable', ['href', 'xlink:href']],
6096
+ ['mtd', ['href', 'xlink:href']],
6097
+ ['mtr', ['href', 'xlink:href']],
6098
+ ['mtext', ['href', 'xlink:href']],
6099
+ ['mover', ['href', 'xlink:href']],
6100
+ ['munder', ['href', 'xlink:href']],
6101
+ ['munderover', ['href', 'xlink:href']],
6102
+ ['semantics', ['href', 'xlink:href']],
6103
+ ['none', ['href', 'xlink:href']],
6104
+ ]);
6105
+ registerContext(SecurityContext.RESOURCE_URL, /** Namespace */ undefined, [
6106
+ ['base', ['href']],
6107
+ ['embed', ['src']],
6108
+ ['frame', ['src']],
6109
+ ['iframe', ['src']],
6110
+ ['link', ['href']],
6111
+ ['object', ['codebase', 'data']],
6112
+ ]);
6113
+ registerContext(SecurityContext.URL, SVG_NAMESPACE, [['a', ['href', 'xlink:href']]]);
6114
+ // Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts
6115
+ // Unknown is the internal tag name for unknown elements example used for host-bindings.
6116
+ // These are unsafe as `attributeName` can be `href` or `xlink:href`
6117
+ // See: http://b/463880509#comment7
6118
+ registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, SVG_NAMESPACE, [
6119
+ ['animate', ['attributeName', 'values', 'to', 'from']],
6120
+ ['set', ['to', 'attributeName']],
6121
+ ['animateMotion', ['attributeName']],
6122
+ ['animateTransform', ['attributeName']],
6123
+ ]);
6124
+ registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, /** Namespace */ undefined, [
6125
+ [
6126
+ 'unknown',
6127
+ [
6128
+ 'attributeName',
6129
+ 'values',
6130
+ 'to',
6131
+ 'from',
6132
+ 'sandbox',
6133
+ 'allow',
6134
+ 'allowFullscreen',
6135
+ 'referrerPolicy',
6136
+ 'csp',
6137
+ 'fetchPriority',
6138
+ ],
6139
+ ],
6140
+ ['iframe', ['sandbox', 'allow', 'allowFullscreen', 'referrerPolicy', 'csp', 'fetchPriority']],
6141
+ ]);
6142
+ }
6143
+ return _SECURITY_SCHEMA;
6144
+ }
6145
+ function registerContext(ctx, namespace, specs) {
6146
+ for (const [element, attributeNames] of specs) {
6147
+ let tagName = namespace && element !== '*' && element !== 'unknown' ? `:${namespace}:${element}` : element;
6148
+ tagName = tagName.toLowerCase();
6149
+ for (const attr of attributeNames) {
6150
+ _SECURITY_SCHEMA[`${tagName}|${attr.toLowerCase()}`] = ctx;
6151
+ }
6152
+ }
6153
+ }
6036
6154
 
6037
6155
  /**
6038
6156
  * An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
@@ -6200,8 +6318,15 @@ function ɵɵtrustConstantResourceUrl(url) {
6200
6318
  return trustedScriptURLFromString(url[0]);
6201
6319
  }
6202
6320
  // Define sets outside the function for O(1) lookups and memory efficiency
6203
- const SRC_RESOURCE_TAGS = new Set(['embed', 'frame', 'iframe', 'media', 'script']);
6204
- const HREF_RESOURCE_TAGS = new Set(['base', 'link', 'script']);
6321
+ const RESOURCE_MAP = {
6322
+ 'embed': { 'src': true },
6323
+ 'frame': { 'src': true },
6324
+ 'iframe': { 'src': true },
6325
+ 'media': { 'src': true },
6326
+ 'base': { 'href': true },
6327
+ 'link': { 'href': true },
6328
+ 'object': { 'data': true, 'codebase': true },
6329
+ };
6205
6330
  /**
6206
6331
  * Detects which sanitizer to use for URL property, based on tag name and prop name.
6207
6332
  *
@@ -6210,9 +6335,7 @@ const HREF_RESOURCE_TAGS = new Set(['base', 'link', 'script']);
6210
6335
  * If tag and prop names don't match Resource URL schema, use URL sanitizer.
6211
6336
  */
6212
6337
  function getUrlSanitizer(tag, prop) {
6213
- const isResource = (prop === 'src' && SRC_RESOURCE_TAGS.has(tag)) ||
6214
- (prop === 'href' && HREF_RESOURCE_TAGS.has(tag)) ||
6215
- (prop === 'xlink:href' && tag === 'script');
6338
+ const isResource = RESOURCE_MAP[tag.toLowerCase()]?.[prop.toLowerCase()] === true;
6216
6339
  return isResource ? ɵɵsanitizeResourceUrl : ɵɵsanitizeUrl;
6217
6340
  }
6218
6341
  /**
@@ -6246,24 +6369,32 @@ function getSanitizer() {
6246
6369
  const lView = getLView();
6247
6370
  return lView && lView[ENVIRONMENT].sanitizer;
6248
6371
  }
6249
- const attributeName = new Set(['attributename']);
6250
6372
  /**
6251
6373
  * @remarks Keep this in sync with DOM Security Schema.
6252
6374
  * @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
6253
6375
  */
6376
+ /**
6377
+ * Set of attributes that are sensitive and should be sanitized.
6378
+ */
6379
+ const SECURITY_SENSITIVE_ATTRIBUTE_NAMES = new Set(['href', 'xlink:href']);
6254
6380
  const SECURITY_SENSITIVE_ELEMENTS = {
6255
- 'iframe': new Set([
6256
- 'sandbox',
6257
- 'allow',
6258
- 'allowfullscreen',
6259
- 'referrerpolicy',
6260
- 'csp',
6261
- 'fetchpriority',
6262
- ]),
6263
- 'animate': attributeName,
6264
- 'set': attributeName,
6265
- 'animatemotion': attributeName,
6266
- 'animatetransform': attributeName,
6381
+ 'iframe': {
6382
+ 'sandbox': true,
6383
+ 'allow': true,
6384
+ 'allowfullscreen': true,
6385
+ 'referrerpolicy': true,
6386
+ 'csp': true,
6387
+ 'fetchpriority': true,
6388
+ },
6389
+ ':svg:animate': {
6390
+ 'attributename': true,
6391
+ 'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
6392
+ 'values': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
6393
+ 'from': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
6394
+ },
6395
+ ':svg:set': { 'attributename': true, 'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES },
6396
+ ':svg:animatemotion': { 'attributename': true },
6397
+ ':svg:animatetransform': { 'attributename': true },
6267
6398
  };
6268
6399
  /**
6269
6400
  * Validates that the attribute binding is safe to use.
@@ -6275,22 +6406,54 @@ const SECURITY_SENSITIVE_ELEMENTS = {
6275
6406
  function ɵɵvalidateAttribute(value, tagName, attributeName) {
6276
6407
  const lowerCaseTagName = tagName.toLowerCase();
6277
6408
  const lowerCaseAttrName = attributeName.toLowerCase();
6278
- if (!SECURITY_SENSITIVE_ELEMENTS[lowerCaseTagName]?.has(lowerCaseAttrName)) {
6409
+ const index = getSelectedIndex();
6410
+ const tNode = index === -1 ? null : getSelectedTNode();
6411
+ if (tNode && tNode.type !== 2 /* TNodeType.Element */) {
6279
6412
  return value;
6280
6413
  }
6281
- const tNode = getSelectedTNode();
6282
- if (tNode.type !== 2 /* TNodeType.Element */) {
6414
+ // Leverage tNode.namespace if active, otherwise check both namespaced and base variants.
6415
+ const fullTagName = lowerCaseTagName[0] !== ':' && tNode?.namespace
6416
+ ? `:${tNode.namespace}:${lowerCaseTagName}`
6417
+ : lowerCaseTagName;
6418
+ const validationConfig = SECURITY_SENSITIVE_ELEMENTS[fullTagName]?.[lowerCaseAttrName];
6419
+ if (!validationConfig) {
6283
6420
  return value;
6284
6421
  }
6285
6422
  const lView = getLView();
6286
- if (lowerCaseTagName === 'iframe') {
6423
+ if (tNode && lowerCaseTagName === 'iframe') {
6287
6424
  const element = getNativeByTNode(tNode, lView);
6288
6425
  enforceIframeSecurity(element);
6289
6426
  }
6427
+ const displayTagName = tagName[0] === ':' ? tagName.split(':').pop() : tagName;
6428
+ if (typeof validationConfig !== 'boolean') {
6429
+ if (!tNode) {
6430
+ const errorMessage = ngDevMode &&
6431
+ `Angular has detected that the \`${attributeName}\` was applied ` +
6432
+ `as a binding to the <${tagName}> element. ` +
6433
+ `For security reasons, the \`${attributeName}\` can be set on the <${tagName}> element ` +
6434
+ `as a static attribute only. \n` +
6435
+ `To fix this, switch the \`${attributeName}\` binding to a static attribute ` +
6436
+ `in a template or in host bindings section.`;
6437
+ throw new RuntimeError(-910 /* RuntimeErrorCode.UNSAFE_ATTRIBUTE_BINDING */, errorMessage);
6438
+ }
6439
+ const element = getNativeByTNode(tNode, lView);
6440
+ const attributeNameValue = element.getAttribute('attributeName');
6441
+ if (attributeNameValue && validationConfig.has(attributeNameValue.toLowerCase())) {
6442
+ const errorMessage = ngDevMode &&
6443
+ `Angular has detected that the \`${attributeName}\` was applied ` +
6444
+ `as a binding to the <${displayTagName}> element${getTemplateLocationDetails(lView)}. ` +
6445
+ `For security reasons, the \`${attributeName}\` can be set on the <${displayTagName}> element ` +
6446
+ `as a static attribute only when the "attributeName" is set to \'${attributeNameValue}\'. \n` +
6447
+ `To fix this, switch the \`${attributeNameValue}\` binding to a static attribute ` +
6448
+ `in a template or in host bindings section.`;
6449
+ throw new RuntimeError(-910 /* RuntimeErrorCode.UNSAFE_ATTRIBUTE_BINDING */, errorMessage);
6450
+ }
6451
+ return value;
6452
+ }
6290
6453
  const errorMessage = ngDevMode &&
6291
6454
  `Angular has detected that the \`${attributeName}\` was applied ` +
6292
- `as a binding to the <${tagName}> element${getTemplateLocationDetails(lView)}. ` +
6293
- `For security reasons, the \`${attributeName}\` can be set on the <${tagName}> element ` +
6455
+ `as a binding to the <${displayTagName}> element${tNode ? getTemplateLocationDetails(lView) : ''}. ` +
6456
+ `For security reasons, the \`${attributeName}\` can be set on the <${displayTagName}> element ` +
6294
6457
  `as a static attribute only. \n` +
6295
6458
  `To fix this, switch the \`${attributeName}\` binding to a static attribute ` +
6296
6459
  `in a template or in host bindings section.`;
@@ -9178,6 +9341,9 @@ function locateHostElement(renderer, elementOrSelector, encapsulation, injector)
9178
9341
  // projection.
9179
9342
  const preserveContent = preserveHostContent || encapsulation === ViewEncapsulation.ShadowDom;
9180
9343
  const rootElement = renderer.selectRootElement(elementOrSelector, preserveContent);
9344
+ if (rootElement.tagName.toLowerCase() === 'script') {
9345
+ throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, ngDevMode && `"<script>" tag is not allowed as a component host element.`);
9346
+ }
9181
9347
  applyRootElementTransform(rootElement);
9182
9348
  return rootElement;
9183
9349
  }
@@ -11598,6 +11764,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
11598
11764
  flags,
11599
11765
  providerIndexes: 0,
11600
11766
  value: value,
11767
+ namespace: getNamespace(),
11601
11768
  attrs: attrs,
11602
11769
  mergedAttrs: null,
11603
11770
  localNames: null,
@@ -14613,7 +14780,7 @@ function createHostElement(componentDef, renderer) {
14613
14780
  // dynamically. Default to 'div' if this component did not specify any tag name in its
14614
14781
  // selector.
14615
14782
  const tagName = inferTagNameFromDefinition(componentDef);
14616
- const namespace = tagName === 'svg' ? SVG_NAMESPACE : tagName === 'math' ? MATH_ML_NAMESPACE : null;
14783
+ const namespace = tagName === 'svg' ? SVG_NAMESPACE$1 : tagName === 'math' ? MATH_ML_NAMESPACE$1 : null;
14617
14784
  return createElementNode(renderer, tagName, namespace);
14618
14785
  }
14619
14786
  /**
@@ -14721,7 +14888,7 @@ class ComponentFactory extends ComponentFactory$1 {
14721
14888
  }
14722
14889
  function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
14723
14890
  const tAttributes = rootSelectorOrNode
14724
- ? ['ng-version', '20.3.21']
14891
+ ? ['ng-version', '20.3.22']
14725
14892
  : // Extract attributes and classes from the first selector only to match VE behavior.
14726
14893
  extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
14727
14894
  let creationBindings = null;
@@ -24338,7 +24505,14 @@ function applyUpdateOpCodes(tView, lView, updateOpCodes, bindingsStartIndex, cha
24338
24505
  setElementAttribute(lView[RENDERER], lView[nodeIndex], null, tNodeOrTagName, propName, value, sanitizeFn);
24339
24506
  }
24340
24507
  else {
24341
- setPropertyAndInputs(tNodeOrTagName, lView, propName, value, lView[RENDERER], sanitizeFn);
24508
+ const prevSelectedIndex = getSelectedIndex();
24509
+ setSelectedIndex(nodeIndex);
24510
+ try {
24511
+ setPropertyAndInputs(tNodeOrTagName, lView, propName, value, lView[RENDERER], sanitizeFn);
24512
+ }
24513
+ finally {
24514
+ setSelectedIndex(prevSelectedIndex);
24515
+ }
24342
24516
  }
24343
24517
  break;
24344
24518
  case 0 /* I18nUpdateOpCode.Text */:
@@ -24918,7 +25092,10 @@ function i18nAttributesFirstPass(tView, index, values) {
24918
25092
  // the compiler treats static i18n attributes as regular attribute bindings.
24919
25093
  // Since this may not be the first i18n attribute on this element we need to pass in how
24920
25094
  // many previous bindings there have already been.
24921
- generateBindingUpdateOpCodes(updateOpCodes, message, previousElementIndex, attrName, countBindings(updateOpCodes), i18nSanitizeAttribute(attrName));
25095
+ const tagName = previousElement.namespace
25096
+ ? `:${previousElement.namespace}:${previousElement.value}`
25097
+ : previousElement.value;
25098
+ generateBindingUpdateOpCodes(updateOpCodes, message, previousElementIndex, attrName, countBindings(updateOpCodes), i18nResolveSanitizer(attrName, tagName));
24922
25099
  }
24923
25100
  }
24924
25101
  tView.data[index] = updateOpCodes;
@@ -25244,9 +25421,15 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
25244
25421
  const attr = elAttrs.item(i);
25245
25422
  const lowerAttrName = attr.name.toLowerCase();
25246
25423
  const hasBinding = !!attr.value.match(BINDING_REGEXP);
25424
+ const elementNS = element.namespaceURI;
25425
+ const tagNameWithNamespace = elementNS === 'http://www.w3.org/2000/svg'
25426
+ ? `:svg:${tagName}`
25427
+ : elementNS === 'http://www.w3.org/1998/Math/MathML'
25428
+ ? `:math:${tagName}`
25429
+ : tagName;
25247
25430
  if (hasBinding) {
25248
25431
  if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
25249
- generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, i18nSanitizeAttribute(lowerAttrName));
25432
+ generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace));
25250
25433
  }
25251
25434
  else {
25252
25435
  ngDevMode &&
@@ -25256,9 +25439,9 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
25256
25439
  }
25257
25440
  }
25258
25441
  else if (VALID_ATTRS[lowerAttrName]) {
25259
- if (SENSITIVE_ATTRS[lowerAttrName]) {
25260
- // Don't sanitize, because no value is acceptable in sensitive attributes.
25261
- // Translators are not allowed to create URIs.
25442
+ let val = attr.value;
25443
+ const sanitizer = i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace);
25444
+ if (sanitizer) {
25262
25445
  if (typeof ngDevMode !== 'undefined' && ngDevMode) {
25263
25446
  console.warn(`WARNING: ignoring unsafe attribute ` +
25264
25447
  `${lowerAttrName} on element ${tagName} ` +
@@ -25267,7 +25450,7 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
25267
25450
  addCreateAttribute(create, newIndex, attr.name, 'unsafe:blocked');
25268
25451
  }
25269
25452
  else {
25270
- addCreateAttribute(create, newIndex, attr.name, attr.value);
25453
+ addCreateAttribute(create, newIndex, attr.name, val);
25271
25454
  }
25272
25455
  }
25273
25456
  else {
@@ -25347,26 +25530,49 @@ function addCreateNodeAndAppend(create, marker, text, appendToParentIdx, createA
25347
25530
  function addCreateAttribute(create, newIndex, attrName, attrValue) {
25348
25531
  create.push((newIndex << 1 /* IcuCreateOpCode.SHIFT_REF */) | 1 /* IcuCreateOpCode.Attr */, attrName, attrValue);
25349
25532
  }
25350
- /**
25351
- * Caches all keys of `SECURITY_SENSITIVE_ELEMENTS` in a Set to avoid recomputing
25352
- * or scanning them on every invocation.
25353
- */
25354
- const SECURITY_SENSITIVE_ATTRS = /* @__PURE__ */ (() => new Set(Object.values(SECURITY_SENSITIVE_ELEMENTS).flatMap((attrs) => (attrs ? [...attrs.keys()] : []))))();
25355
- /**
25356
- * Returns a sanitizer for the given attribute name or null if the attribute is not security sensitive.
25357
- *
25358
- * @param attrName The name of the attribute to sanitize.
25359
- * @returns The sanitizer for the given attribute name.
25360
- */
25361
- function i18nSanitizeAttribute(attrName) {
25362
- const lowerAttrName = attrName.toLowerCase();
25363
- if (SENSITIVE_ATTRS[lowerAttrName]) {
25364
- return _sanitizeUrl;
25533
+ function splitNsName(elementName, fatal = true) {
25534
+ if (elementName[0] != ':') {
25535
+ return [null, elementName];
25365
25536
  }
25366
- if (SECURITY_SENSITIVE_ATTRS.has(lowerAttrName)) {
25367
- return ɵɵvalidateAttribute;
25537
+ const colonIndex = elementName.indexOf(':', 1);
25538
+ if (colonIndex === -1) {
25539
+ if (fatal) {
25540
+ throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
25541
+ }
25542
+ else {
25543
+ return [null, elementName];
25544
+ }
25545
+ }
25546
+ return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
25547
+ }
25548
+ function normalizeTagName(tagName) {
25549
+ const tagNameLower = tagName.toLowerCase();
25550
+ const [ns, name] = splitNsName(tagNameLower, false);
25551
+ return ns === SVG_NAMESPACE$1 || ns === MATH_ML_NAMESPACE$1 ? `:${ns}:${name}` : name;
25552
+ }
25553
+ function i18nResolveSanitizer(attrName, tagName) {
25554
+ const lowerAttrName = attrName.toLowerCase();
25555
+ const lowerTagName = tagName ? normalizeTagName(tagName) : '*';
25556
+ const schema = SECURITY_SCHEMA();
25557
+ const schemaContext = schema[`${lowerTagName}|${lowerAttrName}`] ||
25558
+ schema[`*|${lowerAttrName}`] ||
25559
+ SecurityContext.NONE;
25560
+ switch (schemaContext) {
25561
+ case SecurityContext.HTML:
25562
+ return ɵɵsanitizeHtml;
25563
+ case SecurityContext.STYLE:
25564
+ return ɵɵsanitizeStyle;
25565
+ case SecurityContext.SCRIPT:
25566
+ return ɵɵsanitizeScript;
25567
+ case SecurityContext.URL:
25568
+ return _sanitizeUrl;
25569
+ case SecurityContext.RESOURCE_URL:
25570
+ return ɵɵsanitizeResourceUrl;
25571
+ case SecurityContext.ATTRIBUTE_NO_BINDING:
25572
+ return ɵɵvalidateAttribute;
25573
+ default:
25574
+ return null;
25368
25575
  }
25369
- return null;
25370
25576
  }
25371
25577
 
25372
25578
  // i18nPostprocess consts