@angular/core 19.2.21 → 19.2.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/event_dispatcher.d-K56StcHr.d.ts +1 -1
- package/fesm2022/core.mjs +279 -50
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/fesm2022/untracked-BKcld_ew.mjs +1 -1
- package/index.d.ts +8 -3
- package/navigation_types.d-fAxd92YV.d.ts +1 -1
- package/package.json +1 -1
- package/primitives/di/index.d.ts +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +2 -2
- package/schematics/bundles/{apply_import_manager-QEWElZT-.cjs → apply_import_manager-D8er9283.cjs} +3 -3
- package/schematics/bundles/{change_tracker-BPk3UwXG.cjs → change_tracker-BMoOL0o6.cjs} +2 -2
- package/schematics/bundles/{checker-DLkGMJj-.cjs → checker-C9K-IOAk.cjs} +287 -213
- package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
- package/schematics/bundles/compiler_host-CAfDJO3W.cjs +1 -1
- package/schematics/bundles/control-flow-migration.cjs +3 -3
- package/schematics/bundles/explicit-standalone-flag.cjs +3 -3
- package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
- package/schematics/bundles/{index-BPwBW8Gv.cjs → index-C0sKgTb6.cjs} +4 -4
- package/schematics/bundles/{index-iQYWEThN.cjs → index-C55Aq2GC.cjs} +12 -12
- package/schematics/bundles/inject-migration.cjs +3 -3
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-BhOqwhYA.cjs → migrate_ts_type_references-CjUloDnc.cjs} +5 -5
- package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +6 -6
- package/schematics/bundles/pending-tasks.cjs +3 -3
- package/schematics/bundles/{project_paths-DePtMwan.cjs → project_paths-D8qIpJ6r.cjs} +3 -3
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +1 -1
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/provide-initializer.cjs +3 -3
- package/schematics/bundles/route-lazy-loading.cjs +3 -3
- package/schematics/bundles/self-closing-tags-migration.cjs +4 -4
- package/schematics/bundles/signal-input-migration.cjs +7 -7
- package/schematics/bundles/signal-queries-migration.cjs +7 -7
- package/schematics/bundles/signals.cjs +7 -7
- package/schematics/bundles/standalone-migration.cjs +4 -4
- package/testing/index.d.ts +1 -1
- package/weak_ref.d-DWHPG08n.d.ts +1 -1
package/fesm2022/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v19.2.
|
|
2
|
+
* @license Angular v19.2.23
|
|
3
3
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -3195,8 +3195,8 @@ const profiler = function (event, instance = null, hookOrListener) {
|
|
|
3195
3195
|
}
|
|
3196
3196
|
};
|
|
3197
3197
|
|
|
3198
|
-
const SVG_NAMESPACE = 'svg';
|
|
3199
|
-
const MATH_ML_NAMESPACE = 'math';
|
|
3198
|
+
const SVG_NAMESPACE$1 = 'svg';
|
|
3199
|
+
const MATH_ML_NAMESPACE$1 = 'math';
|
|
3200
3200
|
|
|
3201
3201
|
/**
|
|
3202
3202
|
* For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`)
|
|
@@ -3981,7 +3981,7 @@ function getSelectedTNode() {
|
|
|
3981
3981
|
* @codeGenApi
|
|
3982
3982
|
*/
|
|
3983
3983
|
function ɵɵnamespaceSVG() {
|
|
3984
|
-
instructionState.lFrame.currentNamespace = SVG_NAMESPACE;
|
|
3984
|
+
instructionState.lFrame.currentNamespace = SVG_NAMESPACE$1;
|
|
3985
3985
|
}
|
|
3986
3986
|
/**
|
|
3987
3987
|
* Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.
|
|
@@ -3989,7 +3989,7 @@ function ɵɵnamespaceSVG() {
|
|
|
3989
3989
|
* @codeGenApi
|
|
3990
3990
|
*/
|
|
3991
3991
|
function ɵɵnamespaceMathML() {
|
|
3992
|
-
instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE;
|
|
3992
|
+
instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE$1;
|
|
3993
3993
|
}
|
|
3994
3994
|
/**
|
|
3995
3995
|
* Sets the namespace used to create elements to `null`, which forces element creation to use
|
|
@@ -10880,13 +10880,6 @@ const VALID_ATTRS = merge(URI_ATTRS, HTML_ATTRS, ARIA_ATTRS);
|
|
|
10880
10880
|
// `Some content`, but strip `invalid-element` opening/closing tags. For some elements, though, we
|
|
10881
10881
|
// don't want to preserve the content, if the elements themselves are going to be removed.
|
|
10882
10882
|
const SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS = tagSet('script,style,template');
|
|
10883
|
-
/**
|
|
10884
|
-
* Attributes that are potential attach vectors and may need to be sanitized.
|
|
10885
|
-
*/
|
|
10886
|
-
const SENSITIVE_ATTRS = merge(URI_ATTRS,
|
|
10887
|
-
// Note: we don't include these attributes in `URI_ATTRS`, because `URI_ATTRS` also
|
|
10888
|
-
// determines whether an attribute should be dropped when sanitizing an HTML string.
|
|
10889
|
-
tagSet('action,formaction,data,codebase'));
|
|
10890
10883
|
/**
|
|
10891
10884
|
* SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
|
|
10892
10885
|
* attributes.
|
|
@@ -11298,7 +11291,132 @@ var SecurityContext;
|
|
|
11298
11291
|
SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
|
|
11299
11292
|
SecurityContext[SecurityContext["URL"] = 4] = "URL";
|
|
11300
11293
|
SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
|
|
11294
|
+
SecurityContext[SecurityContext["ATTRIBUTE_NO_BINDING"] = 6] = "ATTRIBUTE_NO_BINDING";
|
|
11301
11295
|
})(SecurityContext || (SecurityContext = {}));
|
|
11296
|
+
// =================================================================================================
|
|
11297
|
+
// =================================================================================================
|
|
11298
|
+
// =========== S T O P - S T O P - S T O P - S T O P - S T O P - S T O P ===========
|
|
11299
|
+
// =================================================================================================
|
|
11300
|
+
// =================================================================================================
|
|
11301
|
+
//
|
|
11302
|
+
// DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW!
|
|
11303
|
+
//
|
|
11304
|
+
// =================================================================================================
|
|
11305
|
+
/**
|
|
11306
|
+
* Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'.
|
|
11307
|
+
*/
|
|
11308
|
+
let _SECURITY_SCHEMA;
|
|
11309
|
+
const SVG_NAMESPACE = 'svg';
|
|
11310
|
+
const MATH_ML_NAMESPACE = 'math';
|
|
11311
|
+
/**
|
|
11312
|
+
* @remarks Keep is a copy of DOM Security Schema.
|
|
11313
|
+
* @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
|
|
11314
|
+
*/
|
|
11315
|
+
function SECURITY_SCHEMA() {
|
|
11316
|
+
if (!_SECURITY_SCHEMA) {
|
|
11317
|
+
_SECURITY_SCHEMA = {};
|
|
11318
|
+
// Case is insignificant below, all element and attribute names are lower-cased for lookup.
|
|
11319
|
+
registerContext(SecurityContext.HTML, /** Namespace */ undefined, [
|
|
11320
|
+
['iframe', ['srcdoc']],
|
|
11321
|
+
['*', ['innerHTML', 'outerHTML']],
|
|
11322
|
+
]);
|
|
11323
|
+
registerContext(SecurityContext.STYLE, /** Namespace */ undefined, [['*', ['style']]]);
|
|
11324
|
+
// NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.
|
|
11325
|
+
registerContext(SecurityContext.URL, /** Namespace */ undefined, [
|
|
11326
|
+
['*', ['formAction']],
|
|
11327
|
+
['area', ['href']],
|
|
11328
|
+
['a', ['href', 'xlink:href']],
|
|
11329
|
+
['form', ['action']],
|
|
11330
|
+
// The below two items are safe and should be removed but they require a G3 clean-up as a small number of tests fail.
|
|
11331
|
+
['img', ['src']],
|
|
11332
|
+
['video', ['src']],
|
|
11333
|
+
]);
|
|
11334
|
+
registerContext(SecurityContext.URL, MATH_ML_NAMESPACE, [
|
|
11335
|
+
// MathML namespace
|
|
11336
|
+
// https://crsrc.org/c/third_party/blink/renderer/core/sanitizer/sanitizer.cc;l=753-768;drc=b3eb16372dcd3317d65e9e0265015e322494edcd;bpv=1;bpt=1
|
|
11337
|
+
['annotation', ['href', 'xlink:href']],
|
|
11338
|
+
['annotation-xml', ['href', 'xlink:href']],
|
|
11339
|
+
['maction', ['href', 'xlink:href']],
|
|
11340
|
+
['malignmark', ['href', 'xlink:href']],
|
|
11341
|
+
['math', ['href', 'xlink:href']],
|
|
11342
|
+
['mroot', ['href', 'xlink:href']],
|
|
11343
|
+
['msqrt', ['href', 'xlink:href']],
|
|
11344
|
+
['merror', ['href', 'xlink:href']],
|
|
11345
|
+
['mfrac', ['href', 'xlink:href']],
|
|
11346
|
+
['mglyph', ['href', 'xlink:href']],
|
|
11347
|
+
['msub', ['href', 'xlink:href']],
|
|
11348
|
+
['msup', ['href', 'xlink:href']],
|
|
11349
|
+
['msubsup', ['href', 'xlink:href']],
|
|
11350
|
+
['mmultiscripts', ['href', 'xlink:href']],
|
|
11351
|
+
['mprescripts', ['href', 'xlink:href']],
|
|
11352
|
+
['mi', ['href', 'xlink:href']],
|
|
11353
|
+
['mn', ['href', 'xlink:href']],
|
|
11354
|
+
['mo', ['href', 'xlink:href']],
|
|
11355
|
+
['mpadded', ['href', 'xlink:href']],
|
|
11356
|
+
['mphantom', ['href', 'xlink:href']],
|
|
11357
|
+
['mrow', ['href', 'xlink:href']],
|
|
11358
|
+
['ms', ['href', 'xlink:href']],
|
|
11359
|
+
['mspace', ['href', 'xlink:href']],
|
|
11360
|
+
['mstyle', ['href', 'xlink:href']],
|
|
11361
|
+
['mtable', ['href', 'xlink:href']],
|
|
11362
|
+
['mtd', ['href', 'xlink:href']],
|
|
11363
|
+
['mtr', ['href', 'xlink:href']],
|
|
11364
|
+
['mtext', ['href', 'xlink:href']],
|
|
11365
|
+
['mover', ['href', 'xlink:href']],
|
|
11366
|
+
['munder', ['href', 'xlink:href']],
|
|
11367
|
+
['munderover', ['href', 'xlink:href']],
|
|
11368
|
+
['semantics', ['href', 'xlink:href']],
|
|
11369
|
+
['none', ['href', 'xlink:href']],
|
|
11370
|
+
]);
|
|
11371
|
+
registerContext(SecurityContext.RESOURCE_URL, /** Namespace */ undefined, [
|
|
11372
|
+
['base', ['href']],
|
|
11373
|
+
['embed', ['src']],
|
|
11374
|
+
['frame', ['src']],
|
|
11375
|
+
['iframe', ['src']],
|
|
11376
|
+
['link', ['href']],
|
|
11377
|
+
['object', ['codebase', 'data']],
|
|
11378
|
+
]);
|
|
11379
|
+
registerContext(SecurityContext.URL, SVG_NAMESPACE, [['a', ['href', 'xlink:href']]]);
|
|
11380
|
+
// Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts
|
|
11381
|
+
// Unknown is the internal tag name for unknown elements example used for host-bindings.
|
|
11382
|
+
// These are unsafe as `attributeName` can be `href` or `xlink:href`
|
|
11383
|
+
// See: http://b/463880509#comment7
|
|
11384
|
+
registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, SVG_NAMESPACE, [
|
|
11385
|
+
['animate', ['attributeName', 'values', 'to', 'from']],
|
|
11386
|
+
['set', ['to', 'attributeName']],
|
|
11387
|
+
['animateMotion', ['attributeName']],
|
|
11388
|
+
['animateTransform', ['attributeName']],
|
|
11389
|
+
]);
|
|
11390
|
+
registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, /** Namespace */ undefined, [
|
|
11391
|
+
[
|
|
11392
|
+
'unknown',
|
|
11393
|
+
[
|
|
11394
|
+
'attributeName',
|
|
11395
|
+
'values',
|
|
11396
|
+
'to',
|
|
11397
|
+
'from',
|
|
11398
|
+
'sandbox',
|
|
11399
|
+
'allow',
|
|
11400
|
+
'allowFullscreen',
|
|
11401
|
+
'referrerPolicy',
|
|
11402
|
+
'csp',
|
|
11403
|
+
'fetchPriority',
|
|
11404
|
+
],
|
|
11405
|
+
],
|
|
11406
|
+
['iframe', ['sandbox', 'allow', 'allowFullscreen', 'referrerPolicy', 'csp', 'fetchPriority']],
|
|
11407
|
+
]);
|
|
11408
|
+
}
|
|
11409
|
+
return _SECURITY_SCHEMA;
|
|
11410
|
+
}
|
|
11411
|
+
function registerContext(ctx, namespace, specs) {
|
|
11412
|
+
for (const [element, attributeNames] of specs) {
|
|
11413
|
+
let tagName = namespace && element !== '*' && element !== 'unknown' ? `:${namespace}:${element}` : element;
|
|
11414
|
+
tagName = tagName.toLowerCase();
|
|
11415
|
+
for (const attr of attributeNames) {
|
|
11416
|
+
_SECURITY_SCHEMA[`${tagName}|${attr.toLowerCase()}`] = ctx;
|
|
11417
|
+
}
|
|
11418
|
+
}
|
|
11419
|
+
}
|
|
11302
11420
|
|
|
11303
11421
|
/**
|
|
11304
11422
|
* An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
|
|
@@ -11466,8 +11584,15 @@ function ɵɵtrustConstantResourceUrl(url) {
|
|
|
11466
11584
|
return trustedScriptURLFromString(url[0]);
|
|
11467
11585
|
}
|
|
11468
11586
|
// Define sets outside the function for O(1) lookups and memory efficiency
|
|
11469
|
-
const
|
|
11470
|
-
|
|
11587
|
+
const RESOURCE_MAP = {
|
|
11588
|
+
'embed': { 'src': true },
|
|
11589
|
+
'frame': { 'src': true },
|
|
11590
|
+
'iframe': { 'src': true },
|
|
11591
|
+
'media': { 'src': true },
|
|
11592
|
+
'base': { 'href': true },
|
|
11593
|
+
'link': { 'href': true },
|
|
11594
|
+
'object': { 'data': true, 'codebase': true },
|
|
11595
|
+
};
|
|
11471
11596
|
/**
|
|
11472
11597
|
* Detects which sanitizer to use for URL property, based on tag name and prop name.
|
|
11473
11598
|
*
|
|
@@ -11476,9 +11601,7 @@ const HREF_RESOURCE_TAGS = new Set(['base', 'link', 'script']);
|
|
|
11476
11601
|
* If tag and prop names don't match Resource URL schema, use URL sanitizer.
|
|
11477
11602
|
*/
|
|
11478
11603
|
function getUrlSanitizer(tag, prop) {
|
|
11479
|
-
const isResource = (prop
|
|
11480
|
-
(prop === 'href' && HREF_RESOURCE_TAGS.has(tag)) ||
|
|
11481
|
-
(prop === 'xlink:href' && tag === 'script');
|
|
11604
|
+
const isResource = RESOURCE_MAP[tag.toLowerCase()]?.[prop.toLowerCase()] === true;
|
|
11482
11605
|
return isResource ? ɵɵsanitizeResourceUrl : ɵɵsanitizeUrl;
|
|
11483
11606
|
}
|
|
11484
11607
|
/**
|
|
@@ -11510,33 +11633,41 @@ function validateAgainstEventProperties(name) {
|
|
|
11510
11633
|
}
|
|
11511
11634
|
function validateAgainstEventAttributes(name) {
|
|
11512
11635
|
if (name.toLowerCase().startsWith('on')) {
|
|
11513
|
-
|
|
11514
|
-
`
|
|
11515
|
-
|
|
11636
|
+
throw new RuntimeError(306 /* RuntimeErrorCode.INVALID_EVENT_BINDING */, ngDevMode &&
|
|
11637
|
+
`Binding to event attribute '${name}' is disallowed for security reasons, ` +
|
|
11638
|
+
`please use (${name.slice(2)})=...`);
|
|
11516
11639
|
}
|
|
11517
11640
|
}
|
|
11518
11641
|
function getSanitizer() {
|
|
11519
11642
|
const lView = getLView();
|
|
11520
11643
|
return lView && lView[ENVIRONMENT].sanitizer;
|
|
11521
11644
|
}
|
|
11522
|
-
const attributeName = new Set(['attributename']);
|
|
11523
11645
|
/**
|
|
11524
11646
|
* @remarks Keep this in sync with DOM Security Schema.
|
|
11525
11647
|
* @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
|
|
11526
11648
|
*/
|
|
11649
|
+
/**
|
|
11650
|
+
* Set of attributes that are sensitive and should be sanitized.
|
|
11651
|
+
*/
|
|
11652
|
+
const SECURITY_SENSITIVE_ATTRIBUTE_NAMES = new Set(['href', 'xlink:href']);
|
|
11527
11653
|
const SECURITY_SENSITIVE_ELEMENTS = {
|
|
11528
|
-
'iframe':
|
|
11529
|
-
'sandbox',
|
|
11530
|
-
'allow',
|
|
11531
|
-
'allowfullscreen',
|
|
11532
|
-
'referrerpolicy',
|
|
11533
|
-
'csp',
|
|
11534
|
-
'fetchpriority',
|
|
11535
|
-
|
|
11536
|
-
'animate':
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11654
|
+
'iframe': {
|
|
11655
|
+
'sandbox': true,
|
|
11656
|
+
'allow': true,
|
|
11657
|
+
'allowfullscreen': true,
|
|
11658
|
+
'referrerpolicy': true,
|
|
11659
|
+
'csp': true,
|
|
11660
|
+
'fetchpriority': true,
|
|
11661
|
+
},
|
|
11662
|
+
':svg:animate': {
|
|
11663
|
+
'attributename': true,
|
|
11664
|
+
'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
|
|
11665
|
+
'values': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
|
|
11666
|
+
'from': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
|
|
11667
|
+
},
|
|
11668
|
+
':svg:set': { 'attributename': true, 'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES },
|
|
11669
|
+
':svg:animatemotion': { 'attributename': true },
|
|
11670
|
+
':svg:animatetransform': { 'attributename': true },
|
|
11540
11671
|
};
|
|
11541
11672
|
/**
|
|
11542
11673
|
* Validates that the attribute binding is safe to use.
|
|
@@ -11548,22 +11679,54 @@ const SECURITY_SENSITIVE_ELEMENTS = {
|
|
|
11548
11679
|
function ɵɵvalidateAttribute(value, tagName, attributeName) {
|
|
11549
11680
|
const lowerCaseTagName = tagName.toLowerCase();
|
|
11550
11681
|
const lowerCaseAttrName = attributeName.toLowerCase();
|
|
11551
|
-
|
|
11682
|
+
const index = getSelectedIndex();
|
|
11683
|
+
const tNode = index === -1 ? null : getSelectedTNode();
|
|
11684
|
+
if (tNode && tNode.type !== 2 /* TNodeType.Element */) {
|
|
11552
11685
|
return value;
|
|
11553
11686
|
}
|
|
11554
|
-
|
|
11555
|
-
|
|
11687
|
+
// Leverage tNode.namespace if active, otherwise check both namespaced and base variants.
|
|
11688
|
+
const fullTagName = lowerCaseTagName[0] !== ':' && tNode?.namespace
|
|
11689
|
+
? `:${tNode.namespace}:${lowerCaseTagName}`
|
|
11690
|
+
: lowerCaseTagName;
|
|
11691
|
+
const validationConfig = SECURITY_SENSITIVE_ELEMENTS[fullTagName]?.[lowerCaseAttrName];
|
|
11692
|
+
if (!validationConfig) {
|
|
11556
11693
|
return value;
|
|
11557
11694
|
}
|
|
11558
11695
|
const lView = getLView();
|
|
11559
|
-
if (lowerCaseTagName === 'iframe') {
|
|
11696
|
+
if (tNode && lowerCaseTagName === 'iframe') {
|
|
11560
11697
|
const element = getNativeByTNode(tNode, lView);
|
|
11561
11698
|
enforceIframeSecurity(element);
|
|
11562
11699
|
}
|
|
11700
|
+
const displayTagName = tagName[0] === ':' ? tagName.split(':').pop() : tagName;
|
|
11701
|
+
if (typeof validationConfig !== 'boolean') {
|
|
11702
|
+
if (!tNode) {
|
|
11703
|
+
const errorMessage = ngDevMode &&
|
|
11704
|
+
`Angular has detected that the \`${attributeName}\` was applied ` +
|
|
11705
|
+
`as a binding to the <${tagName}> element. ` +
|
|
11706
|
+
`For security reasons, the \`${attributeName}\` can be set on the <${tagName}> element ` +
|
|
11707
|
+
`as a static attribute only. \n` +
|
|
11708
|
+
`To fix this, switch the \`${attributeName}\` binding to a static attribute ` +
|
|
11709
|
+
`in a template or in host bindings section.`;
|
|
11710
|
+
throw new RuntimeError(-910 /* RuntimeErrorCode.UNSAFE_ATTRIBUTE_BINDING */, errorMessage);
|
|
11711
|
+
}
|
|
11712
|
+
const element = getNativeByTNode(tNode, lView);
|
|
11713
|
+
const attributeNameValue = element.getAttribute('attributeName');
|
|
11714
|
+
if (attributeNameValue && validationConfig.has(attributeNameValue.toLowerCase())) {
|
|
11715
|
+
const errorMessage = ngDevMode &&
|
|
11716
|
+
`Angular has detected that the \`${attributeName}\` was applied ` +
|
|
11717
|
+
`as a binding to the <${displayTagName}> element${getTemplateLocationDetails(lView)}. ` +
|
|
11718
|
+
`For security reasons, the \`${attributeName}\` can be set on the <${displayTagName}> element ` +
|
|
11719
|
+
`as a static attribute only when the "attributeName" is set to \'${attributeNameValue}\'. \n` +
|
|
11720
|
+
`To fix this, switch the \`${attributeNameValue}\` binding to a static attribute ` +
|
|
11721
|
+
`in a template or in host bindings section.`;
|
|
11722
|
+
throw new RuntimeError(-910 /* RuntimeErrorCode.UNSAFE_ATTRIBUTE_BINDING */, errorMessage);
|
|
11723
|
+
}
|
|
11724
|
+
return value;
|
|
11725
|
+
}
|
|
11563
11726
|
const errorMessage = ngDevMode &&
|
|
11564
11727
|
`Angular has detected that the \`${attributeName}\` was applied ` +
|
|
11565
|
-
`as a binding to the <${
|
|
11566
|
-
`For security reasons, the \`${attributeName}\` can be set on the <${
|
|
11728
|
+
`as a binding to the <${displayTagName}> element${tNode ? getTemplateLocationDetails(lView) : ''}. ` +
|
|
11729
|
+
`For security reasons, the \`${attributeName}\` can be set on the <${displayTagName}> element ` +
|
|
11567
11730
|
`as a static attribute only. \n` +
|
|
11568
11731
|
`To fix this, switch the \`${attributeName}\` binding to a static attribute ` +
|
|
11569
11732
|
`in a template or in host bindings section.`;
|
|
@@ -12558,6 +12721,9 @@ function locateHostElement(renderer, elementOrSelector, encapsulation, injector)
|
|
|
12558
12721
|
// projection.
|
|
12559
12722
|
const preserveContent = preserveHostContent || encapsulation === ViewEncapsulation.ShadowDom;
|
|
12560
12723
|
const rootElement = renderer.selectRootElement(elementOrSelector, preserveContent);
|
|
12724
|
+
if (rootElement?.tagName?.toLowerCase() === 'script') {
|
|
12725
|
+
throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, ngDevMode && `"<script>" tag is not allowed as a component host element.`);
|
|
12726
|
+
}
|
|
12561
12727
|
applyRootElementTransform(rootElement);
|
|
12562
12728
|
return rootElement;
|
|
12563
12729
|
}
|
|
@@ -12804,10 +12970,12 @@ function findDirectiveDefMatches(tView, tNode) {
|
|
|
12804
12970
|
function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace) {
|
|
12805
12971
|
if (ngDevMode) {
|
|
12806
12972
|
assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
|
|
12807
|
-
validateAgainstEventAttributes(name);
|
|
12808
12973
|
assertTNodeType(tNode, 2 /* TNodeType.Element */, `Attempted to set attribute \`${name}\` on a container node. ` +
|
|
12809
12974
|
`Host bindings are not valid on ng-container or ng-template.`);
|
|
12810
12975
|
}
|
|
12976
|
+
if (lView[TVIEW].firstUpdatePass) {
|
|
12977
|
+
validateAgainstEventAttributes(name);
|
|
12978
|
+
}
|
|
12811
12979
|
const element = getNativeByTNode(tNode, lView);
|
|
12812
12980
|
setElementAttribute(lView[RENDERER], element, namespace, tNode.value, name, value, sanitizer);
|
|
12813
12981
|
}
|
|
@@ -15588,6 +15756,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
15588
15756
|
flags,
|
|
15589
15757
|
providerIndexes: 0,
|
|
15590
15758
|
value: value,
|
|
15759
|
+
namespace: getNamespace(),
|
|
15591
15760
|
attrs: attrs,
|
|
15592
15761
|
mergedAttrs: null,
|
|
15593
15762
|
localNames: null,
|
|
@@ -18043,7 +18212,7 @@ function createHostElement(componentDef, render) {
|
|
|
18043
18212
|
// dynamically. Default to 'div' if this component did not specify any tag name in its
|
|
18044
18213
|
// selector.
|
|
18045
18214
|
const tagName = (componentDef.selectors[0][0] || 'div').toLowerCase();
|
|
18046
|
-
const namespace = tagName === 'svg' ? SVG_NAMESPACE : tagName === 'math' ? MATH_ML_NAMESPACE : null;
|
|
18215
|
+
const namespace = tagName === 'svg' ? SVG_NAMESPACE$1 : tagName === 'math' ? MATH_ML_NAMESPACE$1 : null;
|
|
18047
18216
|
return createElementNode(render, tagName, namespace);
|
|
18048
18217
|
}
|
|
18049
18218
|
/**
|
|
@@ -18086,7 +18255,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
18086
18255
|
const cmpDef = this.componentDef;
|
|
18087
18256
|
ngDevMode && verifyNotAnOrphanComponent(cmpDef);
|
|
18088
18257
|
const tAttributes = rootSelectorOrNode
|
|
18089
|
-
? ['ng-version', '19.2.
|
|
18258
|
+
? ['ng-version', '19.2.23']
|
|
18090
18259
|
: // Extract attributes and classes from the first selector only to match VE behavior.
|
|
18091
18260
|
extractAttrsAndClassesFromSelector(this.componentDef.selectors[0]);
|
|
18092
18261
|
// Create the root view. Uses empty TView and ContentTemplate.
|
|
@@ -28896,7 +29065,14 @@ function applyUpdateOpCodes(tView, lView, updateOpCodes, bindingsStartIndex, cha
|
|
|
28896
29065
|
setElementAttribute(lView[RENDERER], lView[nodeIndex], null, tNodeOrTagName, propName, value, sanitizeFn);
|
|
28897
29066
|
}
|
|
28898
29067
|
else {
|
|
28899
|
-
|
|
29068
|
+
const prevSelectedIndex = getSelectedIndex();
|
|
29069
|
+
setSelectedIndex(nodeIndex);
|
|
29070
|
+
try {
|
|
29071
|
+
elementPropertyInternal(tView, tNodeOrTagName, lView, propName, value, lView[RENDERER], sanitizeFn, false);
|
|
29072
|
+
}
|
|
29073
|
+
finally {
|
|
29074
|
+
setSelectedIndex(prevSelectedIndex);
|
|
29075
|
+
}
|
|
28900
29076
|
}
|
|
28901
29077
|
break;
|
|
28902
29078
|
case 0 /* I18nUpdateOpCode.Text */:
|
|
@@ -29476,7 +29652,10 @@ function i18nAttributesFirstPass(tView, index, values) {
|
|
|
29476
29652
|
// the compiler treats static i18n attributes as regular attribute bindings.
|
|
29477
29653
|
// Since this may not be the first i18n attribute on this element we need to pass in how
|
|
29478
29654
|
// many previous bindings there have already been.
|
|
29479
|
-
|
|
29655
|
+
const tagName = previousElement.namespace
|
|
29656
|
+
? `:${previousElement.namespace}:${previousElement.value}`
|
|
29657
|
+
: previousElement.value;
|
|
29658
|
+
generateBindingUpdateOpCodes(updateOpCodes, message, previousElementIndex, attrName, countBindings(updateOpCodes), i18nResolveSanitizer(attrName, tagName));
|
|
29480
29659
|
}
|
|
29481
29660
|
}
|
|
29482
29661
|
tView.data[index] = updateOpCodes;
|
|
@@ -29802,9 +29981,15 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
|
|
|
29802
29981
|
const attr = elAttrs.item(i);
|
|
29803
29982
|
const lowerAttrName = attr.name.toLowerCase();
|
|
29804
29983
|
const hasBinding = !!attr.value.match(BINDING_REGEXP);
|
|
29984
|
+
const elementNS = element.namespaceURI;
|
|
29985
|
+
const tagNameWithNamespace = elementNS === 'http://www.w3.org/2000/svg'
|
|
29986
|
+
? `:svg:${tagName}`
|
|
29987
|
+
: elementNS === 'http://www.w3.org/1998/Math/MathML'
|
|
29988
|
+
? `:math:${tagName}`
|
|
29989
|
+
: tagName;
|
|
29805
29990
|
if (hasBinding) {
|
|
29806
29991
|
if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
|
|
29807
|
-
generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0,
|
|
29992
|
+
generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace));
|
|
29808
29993
|
}
|
|
29809
29994
|
else {
|
|
29810
29995
|
ngDevMode &&
|
|
@@ -29814,9 +29999,9 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
|
|
|
29814
29999
|
}
|
|
29815
30000
|
}
|
|
29816
30001
|
else if (VALID_ATTRS[lowerAttrName]) {
|
|
29817
|
-
|
|
29818
|
-
|
|
29819
|
-
|
|
30002
|
+
let val = attr.value;
|
|
30003
|
+
const sanitizer = i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace);
|
|
30004
|
+
if (sanitizer) {
|
|
29820
30005
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
29821
30006
|
console.warn(`WARNING: ignoring unsafe attribute ` +
|
|
29822
30007
|
`${lowerAttrName} on element ${tagName} ` +
|
|
@@ -29825,7 +30010,7 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
|
|
|
29825
30010
|
addCreateAttribute(create, newIndex, attr.name, 'unsafe:blocked');
|
|
29826
30011
|
}
|
|
29827
30012
|
else {
|
|
29828
|
-
addCreateAttribute(create, newIndex, attr.name,
|
|
30013
|
+
addCreateAttribute(create, newIndex, attr.name, val);
|
|
29829
30014
|
}
|
|
29830
30015
|
}
|
|
29831
30016
|
else {
|
|
@@ -29905,6 +30090,50 @@ function addCreateNodeAndAppend(create, marker, text, appendToParentIdx, createA
|
|
|
29905
30090
|
function addCreateAttribute(create, newIndex, attrName, attrValue) {
|
|
29906
30091
|
create.push((newIndex << 1 /* IcuCreateOpCode.SHIFT_REF */) | 1 /* IcuCreateOpCode.Attr */, attrName, attrValue);
|
|
29907
30092
|
}
|
|
30093
|
+
function splitNsName(elementName, fatal = true) {
|
|
30094
|
+
if (elementName[0] != ':') {
|
|
30095
|
+
return [null, elementName];
|
|
30096
|
+
}
|
|
30097
|
+
const colonIndex = elementName.indexOf(':', 1);
|
|
30098
|
+
if (colonIndex === -1) {
|
|
30099
|
+
if (fatal) {
|
|
30100
|
+
throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
|
|
30101
|
+
}
|
|
30102
|
+
else {
|
|
30103
|
+
return [null, elementName];
|
|
30104
|
+
}
|
|
30105
|
+
}
|
|
30106
|
+
return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
|
|
30107
|
+
}
|
|
30108
|
+
function normalizeTagName(tagName) {
|
|
30109
|
+
const tagNameLower = tagName.toLowerCase();
|
|
30110
|
+
const [ns, name] = splitNsName(tagNameLower, false);
|
|
30111
|
+
return ns === SVG_NAMESPACE$1 || ns === MATH_ML_NAMESPACE$1 ? `:${ns}:${name}` : name;
|
|
30112
|
+
}
|
|
30113
|
+
function i18nResolveSanitizer(attrName, tagName) {
|
|
30114
|
+
const lowerAttrName = attrName.toLowerCase();
|
|
30115
|
+
const lowerTagName = tagName ? normalizeTagName(tagName) : '*';
|
|
30116
|
+
const schema = SECURITY_SCHEMA();
|
|
30117
|
+
const schemaContext = schema[`${lowerTagName}|${lowerAttrName}`] ||
|
|
30118
|
+
schema[`*|${lowerAttrName}`] ||
|
|
30119
|
+
SecurityContext.NONE;
|
|
30120
|
+
switch (schemaContext) {
|
|
30121
|
+
case SecurityContext.HTML:
|
|
30122
|
+
return ɵɵsanitizeHtml;
|
|
30123
|
+
case SecurityContext.STYLE:
|
|
30124
|
+
return ɵɵsanitizeStyle;
|
|
30125
|
+
case SecurityContext.SCRIPT:
|
|
30126
|
+
return ɵɵsanitizeScript;
|
|
30127
|
+
case SecurityContext.URL:
|
|
30128
|
+
return _sanitizeUrl;
|
|
30129
|
+
case SecurityContext.RESOURCE_URL:
|
|
30130
|
+
return ɵɵsanitizeResourceUrl;
|
|
30131
|
+
case SecurityContext.ATTRIBUTE_NO_BINDING:
|
|
30132
|
+
return ɵɵvalidateAttribute;
|
|
30133
|
+
default:
|
|
30134
|
+
return null;
|
|
30135
|
+
}
|
|
30136
|
+
}
|
|
29908
30137
|
|
|
29909
30138
|
// i18nPostprocess consts
|
|
29910
30139
|
const ROOT_TEMPLATE_ID = 0;
|
|
@@ -34806,7 +35035,7 @@ class Version {
|
|
|
34806
35035
|
/**
|
|
34807
35036
|
* @publicApi
|
|
34808
35037
|
*/
|
|
34809
|
-
const VERSION = new Version('19.2.
|
|
35038
|
+
const VERSION = new Version('19.2.23');
|
|
34810
35039
|
|
|
34811
35040
|
/**
|
|
34812
35041
|
* Combination of NgModuleFactory and ComponentFactories.
|