@wavemaker-ai/angular-codegen 1.0.0-rc.332 → 1.0.0-rc.334
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/angular-app/dependency-report.html +1 -1
- package/angular-app/npm-shrinkwrap.json +4155 -4123
- package/angular-app/package-lock.json +4155 -4123
- package/angular-app/package.json +21 -15
- package/angular-app/src/assets/styles/css/wm-style.css +1 -1
- package/dependencies/expression-parser.cjs.js +1918 -1778
- package/dependencies/pipe-provider.cjs.js +3172 -1972
- package/dependencies/transpilation-web.cjs.js +1874 -1290
- package/npm-shrinkwrap.json +51 -51
- package/package-lock.json +51 -51
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @license Angular v20.3.
|
|
4
|
+
* @license Angular v20.3.28
|
|
5
5
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
6
6
|
* License: MIT
|
|
7
7
|
*/
|
|
@@ -408,6 +408,151 @@ class SelectorlessMatcher {
|
|
|
408
408
|
return this.registry.has(name) ? this.registry.get(name) : [];
|
|
409
409
|
}
|
|
410
410
|
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* A SecurityContext marks a location that has dangerous security implications, e.g. a DOM property
|
|
414
|
+
* like `innerHTML` that could cause Cross Site Scripting (XSS) security bugs when improperly
|
|
415
|
+
* handled.
|
|
416
|
+
*
|
|
417
|
+
* See DomSanitizer for more details on security in Angular applications.
|
|
418
|
+
*
|
|
419
|
+
* @publicApi
|
|
420
|
+
*/
|
|
421
|
+
var SecurityContext$1;
|
|
422
|
+
(function (SecurityContext) {
|
|
423
|
+
SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
|
|
424
|
+
SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
|
|
425
|
+
SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
|
|
426
|
+
SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
|
|
427
|
+
SecurityContext[SecurityContext["URL"] = 4] = "URL";
|
|
428
|
+
SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
|
|
429
|
+
SecurityContext[SecurityContext["ATTRIBUTE_NO_BINDING"] = 6] = "ATTRIBUTE_NO_BINDING";
|
|
430
|
+
})(SecurityContext$1 || (SecurityContext$1 = {}));
|
|
431
|
+
// =================================================================================================
|
|
432
|
+
// =================================================================================================
|
|
433
|
+
// =========== S T O P - S T O P - S T O P - S T O P - S T O P - S T O P ===========
|
|
434
|
+
// =================================================================================================
|
|
435
|
+
// =================================================================================================
|
|
436
|
+
//
|
|
437
|
+
// DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW!
|
|
438
|
+
//
|
|
439
|
+
// =================================================================================================
|
|
440
|
+
/**
|
|
441
|
+
* Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'.
|
|
442
|
+
*/
|
|
443
|
+
let _SECURITY_SCHEMA$1;
|
|
444
|
+
const SVG_NAMESPACE$1$1 = 'svg';
|
|
445
|
+
const MATH_ML_NAMESPACE$1$1 = 'math';
|
|
446
|
+
/**
|
|
447
|
+
* @remarks Keep is a copy of DOM Security Schema.
|
|
448
|
+
* @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
|
|
449
|
+
*/
|
|
450
|
+
function SECURITY_SCHEMA$1() {
|
|
451
|
+
if (!_SECURITY_SCHEMA$1) {
|
|
452
|
+
_SECURITY_SCHEMA$1 = {};
|
|
453
|
+
// Case is insignificant below, all element and attribute names are lower-cased for lookup.
|
|
454
|
+
registerContext$1(SecurityContext$1.HTML, /** Namespace */ undefined, [
|
|
455
|
+
['iframe', ['srcdoc']],
|
|
456
|
+
['*', ['innerHTML', 'outerHTML']],
|
|
457
|
+
]);
|
|
458
|
+
registerContext$1(SecurityContext$1.STYLE, /** Namespace */ undefined, [['*', ['style']]]);
|
|
459
|
+
// NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.
|
|
460
|
+
registerContext$1(SecurityContext$1.URL, /** Namespace */ undefined, [
|
|
461
|
+
['*', ['formAction']],
|
|
462
|
+
['area', ['href']],
|
|
463
|
+
['a', ['href', 'xlink:href']],
|
|
464
|
+
['form', ['action']],
|
|
465
|
+
// The below two items are safe and should be removed but they require a G3 clean-up as a small number of tests fail.
|
|
466
|
+
['img', ['src']],
|
|
467
|
+
['video', ['src']],
|
|
468
|
+
]);
|
|
469
|
+
registerContext$1(SecurityContext$1.URL, MATH_ML_NAMESPACE$1$1, [
|
|
470
|
+
// MathML namespace
|
|
471
|
+
// https://crsrc.org/c/third_party/blink/renderer/core/sanitizer/sanitizer.cc;l=753-768;drc=b3eb16372dcd3317d65e9e0265015e322494edcd;bpv=1;bpt=1
|
|
472
|
+
['*', ['href', 'xlink:href']],
|
|
473
|
+
['annotation', ['href', 'xlink:href']],
|
|
474
|
+
['annotation-xml', ['href', 'xlink:href']],
|
|
475
|
+
['maction', ['href', 'xlink:href']],
|
|
476
|
+
['malignmark', ['href', 'xlink:href']],
|
|
477
|
+
['math', ['href', 'xlink:href']],
|
|
478
|
+
['mroot', ['href', 'xlink:href']],
|
|
479
|
+
['msqrt', ['href', 'xlink:href']],
|
|
480
|
+
['merror', ['href', 'xlink:href']],
|
|
481
|
+
['mfrac', ['href', 'xlink:href']],
|
|
482
|
+
['mglyph', ['href', 'xlink:href']],
|
|
483
|
+
['msub', ['href', 'xlink:href']],
|
|
484
|
+
['msup', ['href', 'xlink:href']],
|
|
485
|
+
['msubsup', ['href', 'xlink:href']],
|
|
486
|
+
['mmultiscripts', ['href', 'xlink:href']],
|
|
487
|
+
['mprescripts', ['href', 'xlink:href']],
|
|
488
|
+
['mi', ['href', 'xlink:href']],
|
|
489
|
+
['mn', ['href', 'xlink:href']],
|
|
490
|
+
['mo', ['href', 'xlink:href']],
|
|
491
|
+
['mpadded', ['href', 'xlink:href']],
|
|
492
|
+
['mphantom', ['href', 'xlink:href']],
|
|
493
|
+
['mrow', ['href', 'xlink:href']],
|
|
494
|
+
['ms', ['href', 'xlink:href']],
|
|
495
|
+
['mspace', ['href', 'xlink:href']],
|
|
496
|
+
['mstyle', ['href', 'xlink:href']],
|
|
497
|
+
['mtable', ['href', 'xlink:href']],
|
|
498
|
+
['mtd', ['href', 'xlink:href']],
|
|
499
|
+
['mtr', ['href', 'xlink:href']],
|
|
500
|
+
['mtext', ['href', 'xlink:href']],
|
|
501
|
+
['mover', ['href', 'xlink:href']],
|
|
502
|
+
['munder', ['href', 'xlink:href']],
|
|
503
|
+
['munderover', ['href', 'xlink:href']],
|
|
504
|
+
['semantics', ['href', 'xlink:href']],
|
|
505
|
+
['none', ['href', 'xlink:href']],
|
|
506
|
+
]);
|
|
507
|
+
registerContext$1(SecurityContext$1.RESOURCE_URL, /** Namespace */ undefined, [
|
|
508
|
+
['base', ['href']],
|
|
509
|
+
['embed', ['src']],
|
|
510
|
+
['frame', ['src']],
|
|
511
|
+
['iframe', ['src']],
|
|
512
|
+
['link', ['href']],
|
|
513
|
+
['object', ['codebase', 'data']],
|
|
514
|
+
]);
|
|
515
|
+
registerContext$1(SecurityContext$1.URL, SVG_NAMESPACE$1$1, [['a', ['href', 'xlink:href']]]);
|
|
516
|
+
// Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts
|
|
517
|
+
// Unknown is the internal tag name for unknown elements example used for host-bindings.
|
|
518
|
+
// These are unsafe as `attributeName` can be `href` or `xlink:href`
|
|
519
|
+
// See: http://b/463880509#comment7
|
|
520
|
+
registerContext$1(SecurityContext$1.ATTRIBUTE_NO_BINDING, SVG_NAMESPACE$1$1, [
|
|
521
|
+
['animate', ['attributeName', 'values', 'to', 'from']],
|
|
522
|
+
['set', ['to', 'attributeName']],
|
|
523
|
+
['animateMotion', ['attributeName']],
|
|
524
|
+
['animateTransform', ['attributeName']],
|
|
525
|
+
]);
|
|
526
|
+
registerContext$1(SecurityContext$1.ATTRIBUTE_NO_BINDING, /** Namespace */ undefined, [
|
|
527
|
+
[
|
|
528
|
+
'unknown',
|
|
529
|
+
[
|
|
530
|
+
'attributeName',
|
|
531
|
+
'values',
|
|
532
|
+
'to',
|
|
533
|
+
'from',
|
|
534
|
+
'sandbox',
|
|
535
|
+
'allow',
|
|
536
|
+
'allowFullscreen',
|
|
537
|
+
'referrerPolicy',
|
|
538
|
+
'csp',
|
|
539
|
+
'fetchPriority',
|
|
540
|
+
],
|
|
541
|
+
],
|
|
542
|
+
['iframe', ['sandbox', 'allow', 'allowFullscreen', 'referrerPolicy', 'csp', 'fetchPriority']],
|
|
543
|
+
]);
|
|
544
|
+
}
|
|
545
|
+
return _SECURITY_SCHEMA$1;
|
|
546
|
+
}
|
|
547
|
+
function registerContext$1(ctx, namespace, specs) {
|
|
548
|
+
for (const [element, attributeNames] of specs) {
|
|
549
|
+
let tagName = namespace && element !== 'unknown' ? `:${namespace}:${element}` : element;
|
|
550
|
+
tagName = tagName.toLowerCase();
|
|
551
|
+
for (const attr of attributeNames) {
|
|
552
|
+
_SECURITY_SCHEMA$1[`${tagName}|${attr.toLowerCase()}`] = ctx;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
411
556
|
var ViewEncapsulation$1$1;
|
|
412
557
|
(function (ViewEncapsulation) {
|
|
413
558
|
ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
|
|
@@ -433,16 +578,6 @@ const CUSTOM_ELEMENTS_SCHEMA$1 = {
|
|
|
433
578
|
const NO_ERRORS_SCHEMA$1 = {
|
|
434
579
|
name: 'no-errors-schema',
|
|
435
580
|
};
|
|
436
|
-
var SecurityContext$1;
|
|
437
|
-
(function (SecurityContext) {
|
|
438
|
-
SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
|
|
439
|
-
SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
|
|
440
|
-
SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
|
|
441
|
-
SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
|
|
442
|
-
SecurityContext[SecurityContext["URL"] = 4] = "URL";
|
|
443
|
-
SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
|
|
444
|
-
SecurityContext[SecurityContext["ATTRIBUTE_NO_BINDING"] = 6] = "ATTRIBUTE_NO_BINDING";
|
|
445
|
-
})(SecurityContext$1 || (SecurityContext$1 = {}));
|
|
446
581
|
var MissingTranslationStrategy$1;
|
|
447
582
|
(function (MissingTranslationStrategy) {
|
|
448
583
|
MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error";
|
|
@@ -4277,7 +4412,7 @@ var TagContentType;
|
|
|
4277
4412
|
TagContentType[TagContentType["ESCAPABLE_RAW_TEXT"] = 1] = "ESCAPABLE_RAW_TEXT";
|
|
4278
4413
|
TagContentType[TagContentType["PARSABLE_DATA"] = 2] = "PARSABLE_DATA";
|
|
4279
4414
|
})(TagContentType || (TagContentType = {}));
|
|
4280
|
-
function splitNsName(elementName, fatal = true) {
|
|
4415
|
+
function splitNsName$1(elementName, fatal = true) {
|
|
4281
4416
|
if (elementName[0] != ':') {
|
|
4282
4417
|
return [null, elementName];
|
|
4283
4418
|
}
|
|
@@ -4294,18 +4429,18 @@ function splitNsName(elementName, fatal = true) {
|
|
|
4294
4429
|
}
|
|
4295
4430
|
// `<ng-container>` tags work the same regardless the namespace
|
|
4296
4431
|
function isNgContainer(tagName) {
|
|
4297
|
-
return splitNsName(tagName)[1] === 'ng-container';
|
|
4432
|
+
return splitNsName$1(tagName)[1] === 'ng-container';
|
|
4298
4433
|
}
|
|
4299
4434
|
// `<ng-content>` tags work the same regardless the namespace
|
|
4300
4435
|
function isNgContent(tagName) {
|
|
4301
|
-
return splitNsName(tagName)[1] === 'ng-content';
|
|
4436
|
+
return splitNsName$1(tagName)[1] === 'ng-content';
|
|
4302
4437
|
}
|
|
4303
4438
|
// `<ng-template>` tags work the same regardless the namespace
|
|
4304
4439
|
function isNgTemplate(tagName) {
|
|
4305
|
-
return splitNsName(tagName)[1] === 'ng-template';
|
|
4440
|
+
return splitNsName$1(tagName)[1] === 'ng-template';
|
|
4306
4441
|
}
|
|
4307
4442
|
function getNsPrefix(fullName) {
|
|
4308
|
-
return fullName === null ? null : splitNsName(fullName)[0];
|
|
4443
|
+
return fullName === null ? null : splitNsName$1(fullName)[0];
|
|
4309
4444
|
}
|
|
4310
4445
|
function mergeNsAndName(prefix, localName) {
|
|
4311
4446
|
return prefix ? `:${prefix}:${localName}` : localName;
|
|
@@ -5363,10 +5498,10 @@ function createCssSelectorFromNode(node) {
|
|
|
5363
5498
|
const elementName = node instanceof Element$1 ? node.name : 'ng-template';
|
|
5364
5499
|
const attributes = getAttrsForDirectiveMatching(node);
|
|
5365
5500
|
const cssSelector = new CssSelector();
|
|
5366
|
-
const elementNameNoNs = splitNsName(elementName)[1];
|
|
5501
|
+
const elementNameNoNs = splitNsName$1(elementName)[1];
|
|
5367
5502
|
cssSelector.setElement(elementNameNoNs);
|
|
5368
5503
|
Object.getOwnPropertyNames(attributes).forEach((name) => {
|
|
5369
|
-
const nameNoNs = splitNsName(name)[1];
|
|
5504
|
+
const nameNoNs = splitNsName$1(name)[1];
|
|
5370
5505
|
const value = attributes[name];
|
|
5371
5506
|
cssSelector.addAttribute(nameNoNs, value);
|
|
5372
5507
|
if (name.toLowerCase() === 'class') {
|
|
@@ -11013,7 +11148,7 @@ function specializeBindings(job) {
|
|
|
11013
11148
|
OpList.replace(op, createAnimationBindingOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, op.expression, op.securityContext, op.sourceSpan, 0 /* ir.AnimationBindingKind.STRING */));
|
|
11014
11149
|
}
|
|
11015
11150
|
else {
|
|
11016
|
-
const [namespace, name] = splitNsName(op.name);
|
|
11151
|
+
const [namespace, name] = splitNsName$1(op.name);
|
|
11017
11152
|
OpList.replace(op, createAttributeOp(op.target, namespace, name, op.expression, op.securityContext, op.isTextAttribute, op.isStructuralTemplateAttribute, op.templateKind, op.i18nMessage, op.sourceSpan));
|
|
11018
11153
|
}
|
|
11019
11154
|
break;
|
|
@@ -11451,10 +11586,7 @@ class ElementAttributes {
|
|
|
11451
11586
|
if (value === null) {
|
|
11452
11587
|
throw Error('Attribute, i18n attribute, & style element attributes must have a value');
|
|
11453
11588
|
}
|
|
11454
|
-
if (trustedValueFn !== null) {
|
|
11455
|
-
if (!isStringLiteral(value)) {
|
|
11456
|
-
throw Error('AssertionError: extracted attribute value should be string literal');
|
|
11457
|
-
}
|
|
11589
|
+
if (trustedValueFn !== null && isStringLiteral(value)) {
|
|
11458
11590
|
array.push(taggedTemplate(trustedValueFn, new TemplateLiteralExpr([new TemplateLiteralElementExpr(value.value)], []), undefined, value.sourceSpan));
|
|
11459
11591
|
}
|
|
11460
11592
|
else {
|
|
@@ -17116,7 +17248,7 @@ class _TreeBuilder {
|
|
|
17116
17248
|
if (!prefix && parent) {
|
|
17117
17249
|
const parentName = parent instanceof Element$2 ? parent.name : parent.tagName;
|
|
17118
17250
|
if (parentName !== null) {
|
|
17119
|
-
const parentTagName = splitNsName(parentName)[1];
|
|
17251
|
+
const parentTagName = splitNsName$1(parentName)[1];
|
|
17120
17252
|
const parentTagDefinition = this._getTagDefinition(parentTagName);
|
|
17121
17253
|
if (parentTagDefinition !== null && !parentTagDefinition.preventNamespaceInheritance) {
|
|
17122
17254
|
prefix = getNsPrefix(parentName);
|
|
@@ -19409,162 +19541,8 @@ function interleave(left, right) {
|
|
|
19409
19541
|
return result;
|
|
19410
19542
|
}
|
|
19411
19543
|
|
|
19412
|
-
|
|
19413
|
-
|
|
19414
|
-
// =========== S T O P - S T O P - S T O P - S T O P - S T O P - S T O P ===========
|
|
19415
|
-
// =================================================================================================
|
|
19416
|
-
// =================================================================================================
|
|
19417
|
-
//
|
|
19418
|
-
// DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW!
|
|
19419
|
-
//
|
|
19420
|
-
// =================================================================================================
|
|
19421
|
-
/** Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'. */
|
|
19422
|
-
let _SECURITY_SCHEMA;
|
|
19423
|
-
function SECURITY_SCHEMA() {
|
|
19424
|
-
if (!_SECURITY_SCHEMA) {
|
|
19425
|
-
_SECURITY_SCHEMA = {};
|
|
19426
|
-
// Case is insignificant below, all element and attribute names are lower-cased for lookup.
|
|
19427
|
-
registerContext(SecurityContext$1.HTML, ['iframe|srcdoc', '*|innerHTML', '*|outerHTML']);
|
|
19428
|
-
registerContext(SecurityContext$1.STYLE, ['*|style']);
|
|
19429
|
-
// NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.
|
|
19430
|
-
registerContext(SecurityContext$1.URL, [
|
|
19431
|
-
'*|formAction',
|
|
19432
|
-
'area|href',
|
|
19433
|
-
'area|ping',
|
|
19434
|
-
'audio|src',
|
|
19435
|
-
'a|href',
|
|
19436
|
-
'a|xlink:href',
|
|
19437
|
-
'a|ping',
|
|
19438
|
-
'blockquote|cite',
|
|
19439
|
-
'body|background',
|
|
19440
|
-
'del|cite',
|
|
19441
|
-
'form|action',
|
|
19442
|
-
'img|src',
|
|
19443
|
-
'input|src',
|
|
19444
|
-
'ins|cite',
|
|
19445
|
-
'q|cite',
|
|
19446
|
-
'source|src',
|
|
19447
|
-
'track|src',
|
|
19448
|
-
'video|poster',
|
|
19449
|
-
'video|src',
|
|
19450
|
-
// MathML namespace
|
|
19451
|
-
// https://crsrc.org/c/third_party/blink/renderer/core/sanitizer/sanitizer.cc;l=753-768;drc=b3eb16372dcd3317d65e9e0265015e322494edcd;bpv=1;bpt=1
|
|
19452
|
-
'annotation|href',
|
|
19453
|
-
'annotation|xlink:href',
|
|
19454
|
-
'annotation-xml|href',
|
|
19455
|
-
'annotation-xml|xlink:href',
|
|
19456
|
-
'maction|href',
|
|
19457
|
-
'maction|xlink:href',
|
|
19458
|
-
'malignmark|href',
|
|
19459
|
-
'malignmark|xlink:href',
|
|
19460
|
-
'math|href',
|
|
19461
|
-
'math|xlink:href',
|
|
19462
|
-
'mroot|href',
|
|
19463
|
-
'mroot|xlink:href',
|
|
19464
|
-
'msqrt|href',
|
|
19465
|
-
'msqrt|xlink:href',
|
|
19466
|
-
'merror|href',
|
|
19467
|
-
'merror|xlink:href',
|
|
19468
|
-
'mfrac|href',
|
|
19469
|
-
'mfrac|xlink:href',
|
|
19470
|
-
'mglyph|href',
|
|
19471
|
-
'mglyph|xlink:href',
|
|
19472
|
-
'msub|href',
|
|
19473
|
-
'msub|xlink:href',
|
|
19474
|
-
'msup|href',
|
|
19475
|
-
'msup|xlink:href',
|
|
19476
|
-
'msubsup|href',
|
|
19477
|
-
'msubsup|xlink:href',
|
|
19478
|
-
'mmultiscripts|href',
|
|
19479
|
-
'mmultiscripts|xlink:href',
|
|
19480
|
-
'mprescripts|href',
|
|
19481
|
-
'mprescripts|xlink:href',
|
|
19482
|
-
'mi|href',
|
|
19483
|
-
'mi|xlink:href',
|
|
19484
|
-
'mn|href',
|
|
19485
|
-
'mn|xlink:href',
|
|
19486
|
-
'mo|href',
|
|
19487
|
-
'mo|xlink:href',
|
|
19488
|
-
'mpadded|href',
|
|
19489
|
-
'mpadded|xlink:href',
|
|
19490
|
-
'mphantom|href',
|
|
19491
|
-
'mphantom|xlink:href',
|
|
19492
|
-
'mrow|href',
|
|
19493
|
-
'mrow|xlink:href',
|
|
19494
|
-
'ms|href',
|
|
19495
|
-
'ms|xlink:href',
|
|
19496
|
-
'mspace|href',
|
|
19497
|
-
'mspace|xlink:href',
|
|
19498
|
-
'mstyle|href',
|
|
19499
|
-
'mstyle|xlink:href',
|
|
19500
|
-
'mtable|href',
|
|
19501
|
-
'mtable|xlink:href',
|
|
19502
|
-
'mtd|href',
|
|
19503
|
-
'mtd|xlink:href',
|
|
19504
|
-
'mtr|href',
|
|
19505
|
-
'mtr|xlink:href',
|
|
19506
|
-
'mtext|href',
|
|
19507
|
-
'mtext|xlink:href',
|
|
19508
|
-
'mover|href',
|
|
19509
|
-
'mover|xlink:href',
|
|
19510
|
-
'munder|href',
|
|
19511
|
-
'munder|xlink:href',
|
|
19512
|
-
'munderover|href',
|
|
19513
|
-
'munderover|xlink:href',
|
|
19514
|
-
'semantics|href',
|
|
19515
|
-
'semantics|xlink:href',
|
|
19516
|
-
'none|href',
|
|
19517
|
-
'none|xlink:href',
|
|
19518
|
-
]);
|
|
19519
|
-
registerContext(SecurityContext$1.RESOURCE_URL, [
|
|
19520
|
-
'applet|code',
|
|
19521
|
-
'applet|codebase',
|
|
19522
|
-
'base|href',
|
|
19523
|
-
'embed|src',
|
|
19524
|
-
'frame|src',
|
|
19525
|
-
'head|profile',
|
|
19526
|
-
'html|manifest',
|
|
19527
|
-
'iframe|src',
|
|
19528
|
-
'link|href',
|
|
19529
|
-
'media|src',
|
|
19530
|
-
'object|codebase',
|
|
19531
|
-
'object|data',
|
|
19532
|
-
'script|src',
|
|
19533
|
-
// The below two are for Script SVG
|
|
19534
|
-
// See: https://developer.mozilla.org/en-US/docs/Web/API/SVGScriptElement/href
|
|
19535
|
-
'script|href',
|
|
19536
|
-
'script|xlink:href',
|
|
19537
|
-
]);
|
|
19538
|
-
// Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts
|
|
19539
|
-
// Unknown is the internal tag name for unknown elements example used for host-bindings.
|
|
19540
|
-
// These are unsafe as `attributeName` can be `href` or `xlink:href`
|
|
19541
|
-
// See: http://b/463880509#comment7
|
|
19542
|
-
registerContext(SecurityContext$1.ATTRIBUTE_NO_BINDING, [
|
|
19543
|
-
'animate|attributeName',
|
|
19544
|
-
'set|attributeName',
|
|
19545
|
-
'animateMotion|attributeName',
|
|
19546
|
-
'animateTransform|attributeName',
|
|
19547
|
-
'unknown|attributeName',
|
|
19548
|
-
'iframe|sandbox',
|
|
19549
|
-
'iframe|allow',
|
|
19550
|
-
'iframe|allowFullscreen',
|
|
19551
|
-
'iframe|referrerPolicy',
|
|
19552
|
-
'iframe|csp',
|
|
19553
|
-
'iframe|fetchPriority',
|
|
19554
|
-
'unknown|sandbox',
|
|
19555
|
-
'unknown|allow',
|
|
19556
|
-
'unknown|allowFullscreen',
|
|
19557
|
-
'unknown|referrerPolicy',
|
|
19558
|
-
'unknown|csp',
|
|
19559
|
-
'unknown|fetchPriority',
|
|
19560
|
-
]);
|
|
19561
|
-
}
|
|
19562
|
-
return _SECURITY_SCHEMA;
|
|
19563
|
-
}
|
|
19564
|
-
function registerContext(ctx, specs) {
|
|
19565
|
-
for (const spec of specs)
|
|
19566
|
-
_SECURITY_SCHEMA[spec.toLowerCase()] = ctx;
|
|
19567
|
-
}
|
|
19544
|
+
const SVG_NAMESPACE$2 = 'svg';
|
|
19545
|
+
const MATH_ML_NAMESPACE$2 = 'math';
|
|
19568
19546
|
|
|
19569
19547
|
class ElementSchemaRegistry {
|
|
19570
19548
|
}
|
|
@@ -19573,6 +19551,11 @@ const BOOLEAN = 'boolean';
|
|
|
19573
19551
|
const NUMBER = 'number';
|
|
19574
19552
|
const STRING = 'string';
|
|
19575
19553
|
const OBJECT = 'object';
|
|
19554
|
+
function normalizeTagName$1(tagName) {
|
|
19555
|
+
const tagNameLower = tagName.toLowerCase();
|
|
19556
|
+
const [ns, name] = splitNsName$1(tagNameLower, false);
|
|
19557
|
+
return ns === SVG_NAMESPACE$2 || ns === MATH_ML_NAMESPACE$2 ? `:${ns}:${name}` : name;
|
|
19558
|
+
}
|
|
19576
19559
|
/**
|
|
19577
19560
|
* This array represents the DOM schema. It encodes inheritance, properties, and events.
|
|
19578
19561
|
*
|
|
@@ -19918,8 +19901,9 @@ class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
|
|
19918
19901
|
if (schemaMetas.some((schema) => schema.name === NO_ERRORS_SCHEMA$1.name)) {
|
|
19919
19902
|
return true;
|
|
19920
19903
|
}
|
|
19921
|
-
|
|
19922
|
-
|
|
19904
|
+
const normalizedTag = normalizeTagName$1(tagName);
|
|
19905
|
+
if (normalizedTag.includes('-')) {
|
|
19906
|
+
if (isNgContainer(normalizedTag) || isNgContent(normalizedTag)) {
|
|
19923
19907
|
return false;
|
|
19924
19908
|
}
|
|
19925
19909
|
if (schemaMetas.some((schema) => schema.name === CUSTOM_ELEMENTS_SCHEMA$1.name)) {
|
|
@@ -19928,15 +19912,16 @@ class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
|
|
19928
19912
|
return true;
|
|
19929
19913
|
}
|
|
19930
19914
|
}
|
|
19931
|
-
const elementProperties = this._schema.get(
|
|
19915
|
+
const elementProperties = this._schema.get(normalizedTag) || this._schema.get('unknown');
|
|
19932
19916
|
return elementProperties.has(propName);
|
|
19933
19917
|
}
|
|
19934
19918
|
hasElement(tagName, schemaMetas) {
|
|
19935
19919
|
if (schemaMetas.some((schema) => schema.name === NO_ERRORS_SCHEMA$1.name)) {
|
|
19936
19920
|
return true;
|
|
19937
19921
|
}
|
|
19938
|
-
|
|
19939
|
-
|
|
19922
|
+
const normalizedTag = normalizeTagName$1(tagName);
|
|
19923
|
+
if (normalizedTag.includes('-')) {
|
|
19924
|
+
if (isNgContainer(normalizedTag) || isNgContent(normalizedTag)) {
|
|
19940
19925
|
return true;
|
|
19941
19926
|
}
|
|
19942
19927
|
if (schemaMetas.some((schema) => schema.name === CUSTOM_ELEMENTS_SCHEMA$1.name)) {
|
|
@@ -19944,7 +19929,7 @@ class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
|
|
19944
19929
|
return true;
|
|
19945
19930
|
}
|
|
19946
19931
|
}
|
|
19947
|
-
return this._schema.has(
|
|
19932
|
+
return this._schema.has(normalizedTag);
|
|
19948
19933
|
}
|
|
19949
19934
|
/**
|
|
19950
19935
|
* securityContext returns the security context for the given property on the given DOM tag.
|
|
@@ -19961,16 +19946,15 @@ class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
|
|
19961
19946
|
// NB: For security purposes, use the mapped property name, not the attribute name.
|
|
19962
19947
|
propName = this.getMappedPropName(propName);
|
|
19963
19948
|
}
|
|
19964
|
-
|
|
19965
|
-
// property names do not have a security impact.
|
|
19966
|
-
tagName = tagName.toLowerCase();
|
|
19949
|
+
const normalizedTag = normalizeTagName$1(tagName);
|
|
19967
19950
|
propName = propName.toLowerCase();
|
|
19968
|
-
|
|
19969
|
-
|
|
19970
|
-
|
|
19971
|
-
|
|
19972
|
-
|
|
19973
|
-
|
|
19951
|
+
const [namespace] = splitNsName$1(normalizedTag, false);
|
|
19952
|
+
const securitySchema = SECURITY_SCHEMA$1();
|
|
19953
|
+
const ctx = securitySchema[normalizedTag + '|' + propName] ??
|
|
19954
|
+
(namespace ? securitySchema[`:${namespace}:*|${propName}`] : undefined) ??
|
|
19955
|
+
securitySchema['*|' + propName] ??
|
|
19956
|
+
SecurityContext$1.NONE;
|
|
19957
|
+
return ctx;
|
|
19974
19958
|
}
|
|
19975
19959
|
getMappedPropName(propName) {
|
|
19976
19960
|
return _ATTR_TO_PROP.get(propName) ?? propName;
|
|
@@ -20004,12 +19988,14 @@ class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
|
|
20004
19988
|
return Array.from(this._schema.keys());
|
|
20005
19989
|
}
|
|
20006
19990
|
allKnownAttributesOfElement(tagName) {
|
|
20007
|
-
const
|
|
19991
|
+
const normalizedTag = normalizeTagName$1(tagName);
|
|
19992
|
+
const elementProperties = this._schema.get(normalizedTag) || this._schema.get('unknown');
|
|
20008
19993
|
// Convert properties to attributes.
|
|
20009
19994
|
return Array.from(elementProperties.keys()).map((prop) => _PROP_TO_ATTR.get(prop) ?? prop);
|
|
20010
19995
|
}
|
|
20011
19996
|
allKnownEventsOfElement(tagName) {
|
|
20012
|
-
|
|
19997
|
+
const normalizedTag = normalizeTagName$1(tagName);
|
|
19998
|
+
return Array.from(this._eventSchema.get(normalizedTag) ?? []);
|
|
20013
19999
|
}
|
|
20014
20000
|
normalizeAnimationStyleProperty(propName) {
|
|
20015
20001
|
return dashCaseToCamelCase(propName);
|
|
@@ -20858,7 +20844,7 @@ class I18nMetaVisitor {
|
|
|
20858
20844
|
else {
|
|
20859
20845
|
isTrustedType = isTrustedTypesSink(node.name, name);
|
|
20860
20846
|
}
|
|
20861
|
-
if (isTrustedType) {
|
|
20847
|
+
if (isTrustedType || isPossibleEventHandler(name)) {
|
|
20862
20848
|
this._reportError(attr, `Translating attribute '${name}' is disallowed for security reasons.`);
|
|
20863
20849
|
}
|
|
20864
20850
|
else {
|
|
@@ -20989,6 +20975,16 @@ function i18nMetaToJSDoc(meta) {
|
|
|
20989
20975
|
}
|
|
20990
20976
|
return jsDocComment(tags);
|
|
20991
20977
|
}
|
|
20978
|
+
/**
|
|
20979
|
+
* Check if the propertyName is a potential event handler.
|
|
20980
|
+
* We consider a property to be a potential event handler if its name is longer than 2 characters and starts with 'on' (e.g. 'onclick', 'onload', etc.).
|
|
20981
|
+
* @param propertyName The name of the property to check.
|
|
20982
|
+
* @returns True if the property is a potential event handler, false otherwise.
|
|
20983
|
+
*/
|
|
20984
|
+
function isPossibleEventHandler(propertyName) {
|
|
20985
|
+
const name = propertyName.toLowerCase();
|
|
20986
|
+
return name.length > 2 && name !== 'only' && name.startsWith('on');
|
|
20987
|
+
}
|
|
20992
20988
|
|
|
20993
20989
|
/** Closure uses `goog.getMsg(message)` to lookup translations */
|
|
20994
20990
|
const GOOG_GET_MSG = 'goog.getMsg';
|
|
@@ -24214,6 +24210,61 @@ function updatePlaceholder(op, value, i18nContexts, icuPlaceholders) {
|
|
|
24214
24210
|
}
|
|
24215
24211
|
}
|
|
24216
24212
|
|
|
24213
|
+
/**
|
|
24214
|
+
* Wraps static i18n extracted attributes in their corresponding sanitizers/validators.
|
|
24215
|
+
*/
|
|
24216
|
+
function resolveI18nAttrSanitizers(job) {
|
|
24217
|
+
const tagNamesByElement = new Map();
|
|
24218
|
+
for (const unit of job.units) {
|
|
24219
|
+
for (const op of unit.ops()) {
|
|
24220
|
+
if (op.kind === OpKind.ElementStart || op.kind === OpKind.Template) {
|
|
24221
|
+
let tag = op.tag ?? '';
|
|
24222
|
+
switch (op.namespace) {
|
|
24223
|
+
case Namespace.SVG:
|
|
24224
|
+
tag = `:${SVG_NAMESPACE$2}:${tag}`;
|
|
24225
|
+
break;
|
|
24226
|
+
case Namespace.Math:
|
|
24227
|
+
tag = `:${MATH_ML_NAMESPACE$2}:${tag}`;
|
|
24228
|
+
break;
|
|
24229
|
+
}
|
|
24230
|
+
tagNamesByElement.set(op.xref, tag);
|
|
24231
|
+
}
|
|
24232
|
+
}
|
|
24233
|
+
}
|
|
24234
|
+
for (const unit of job.units) {
|
|
24235
|
+
for (const op of unit.create) {
|
|
24236
|
+
if (op.kind === OpKind.ExtractedAttribute &&
|
|
24237
|
+
op.i18nContext !== null &&
|
|
24238
|
+
op.expression !== null) {
|
|
24239
|
+
const tagName = tagNamesByElement.get(op.target) ?? '';
|
|
24240
|
+
let expr = op.expression;
|
|
24241
|
+
switch (op.securityContext) {
|
|
24242
|
+
case SecurityContext$1.HTML:
|
|
24243
|
+
expr = importExpr(Identifiers.sanitizeHtml).callFn([expr]);
|
|
24244
|
+
break;
|
|
24245
|
+
case SecurityContext$1.STYLE:
|
|
24246
|
+
expr = importExpr(Identifiers.sanitizeStyle).callFn([expr]);
|
|
24247
|
+
break;
|
|
24248
|
+
case SecurityContext$1.SCRIPT:
|
|
24249
|
+
expr = importExpr(Identifiers.sanitizeScript).callFn([expr]);
|
|
24250
|
+
break;
|
|
24251
|
+
case SecurityContext$1.URL:
|
|
24252
|
+
expr = importExpr(Identifiers.sanitizeUrl).callFn([expr]);
|
|
24253
|
+
break;
|
|
24254
|
+
case SecurityContext$1.RESOURCE_URL:
|
|
24255
|
+
expr = importExpr(Identifiers.sanitizeResourceUrl).callFn([expr]);
|
|
24256
|
+
break;
|
|
24257
|
+
case SecurityContext$1.ATTRIBUTE_NO_BINDING:
|
|
24258
|
+
expr = importExpr(Identifiers.validateAttribute)
|
|
24259
|
+
.callFn([expr, literal(tagName), literal(op.name)]);
|
|
24260
|
+
break;
|
|
24261
|
+
}
|
|
24262
|
+
op.expression = expr;
|
|
24263
|
+
}
|
|
24264
|
+
}
|
|
24265
|
+
}
|
|
24266
|
+
}
|
|
24267
|
+
|
|
24217
24268
|
/**
|
|
24218
24269
|
* Resolves lexical references in views (`ir.LexicalReadExpr`) to either a target variable or to
|
|
24219
24270
|
* property reads on the top-level component context.
|
|
@@ -24379,15 +24430,14 @@ function resolveSanitizers(job) {
|
|
|
24379
24430
|
case OpKind.Property:
|
|
24380
24431
|
case OpKind.Attribute:
|
|
24381
24432
|
case OpKind.DomProperty:
|
|
24433
|
+
case OpKind.TwoWayProperty:
|
|
24382
24434
|
let sanitizerFn = null;
|
|
24383
24435
|
if (Array.isArray(op.securityContext) &&
|
|
24384
|
-
op.securityContext
|
|
24385
|
-
|
|
24386
|
-
|
|
24387
|
-
//
|
|
24388
|
-
//
|
|
24389
|
-
// sanitization function and select the actual sanitizer at runtime based on a tag name
|
|
24390
|
-
// that is provided while invoking sanitization function.
|
|
24436
|
+
hasCompositeUrlSecurityContext(op.securityContext)) {
|
|
24437
|
+
// When the host element isn't known, attributes such as `href`, `src`, `data`,
|
|
24438
|
+
// `action`, and `codebase` may be part of multiple security contexts. In this case we
|
|
24439
|
+
// use a special sanitization function and select the actual behavior at runtime based
|
|
24440
|
+
// on the concrete host element.
|
|
24391
24441
|
sanitizerFn = Identifiers.sanitizeUrlOrResourceUrl;
|
|
24392
24442
|
}
|
|
24393
24443
|
else {
|
|
@@ -24399,21 +24449,47 @@ function resolveSanitizers(job) {
|
|
|
24399
24449
|
}
|
|
24400
24450
|
}
|
|
24401
24451
|
}
|
|
24452
|
+
function hasCompositeUrlSecurityContext(securityContext) {
|
|
24453
|
+
let hasUrlContext = false;
|
|
24454
|
+
let hasResourceUrlContext = false;
|
|
24455
|
+
let hasNoneContext = false;
|
|
24456
|
+
for (const context of securityContext) {
|
|
24457
|
+
switch (context) {
|
|
24458
|
+
case SecurityContext$1.URL:
|
|
24459
|
+
hasUrlContext = true;
|
|
24460
|
+
break;
|
|
24461
|
+
case SecurityContext$1.RESOURCE_URL:
|
|
24462
|
+
hasResourceUrlContext = true;
|
|
24463
|
+
break;
|
|
24464
|
+
case SecurityContext$1.NONE:
|
|
24465
|
+
hasNoneContext = true;
|
|
24466
|
+
break;
|
|
24467
|
+
default:
|
|
24468
|
+
return false;
|
|
24469
|
+
}
|
|
24470
|
+
}
|
|
24471
|
+
return (((hasUrlContext || hasResourceUrlContext) && hasNoneContext) ||
|
|
24472
|
+
(hasUrlContext && hasResourceUrlContext));
|
|
24473
|
+
}
|
|
24402
24474
|
/**
|
|
24403
|
-
* Asserts that there is only a single security context and returns it.
|
|
24475
|
+
* Asserts that there is only a single non-NONE security context and returns it.
|
|
24404
24476
|
*/
|
|
24405
24477
|
function getOnlySecurityContext(securityContext) {
|
|
24406
|
-
if (Array.isArray(securityContext)) {
|
|
24407
|
-
|
|
24408
|
-
|
|
24409
|
-
|
|
24410
|
-
|
|
24411
|
-
// do turn out to be other cases, throwing an error until we can address it feels safer.
|
|
24412
|
-
throw Error(`AssertionError: Ambiguous security context`);
|
|
24413
|
-
}
|
|
24414
|
-
return securityContext[0] || SecurityContext$1.NONE;
|
|
24478
|
+
if (!Array.isArray(securityContext)) {
|
|
24479
|
+
return securityContext;
|
|
24480
|
+
}
|
|
24481
|
+
if (securityContext.length < 2) {
|
|
24482
|
+
return securityContext[0] ?? SecurityContext$1.NONE;
|
|
24415
24483
|
}
|
|
24416
|
-
|
|
24484
|
+
const nonNoneSecurityContexts = securityContext.filter((context) => context !== SecurityContext$1.NONE);
|
|
24485
|
+
if (nonNoneSecurityContexts.length > 1) {
|
|
24486
|
+
// TODO: What should we do here? TDB just took the first one, but this feels like something we
|
|
24487
|
+
// would want to know about and create a special case for like we did for Url/ResourceUrl. My
|
|
24488
|
+
// guess is that, outside of the Url/ResourceUrl case, this never actually happens. If there
|
|
24489
|
+
// do turn out to be other cases, throwing an error until we can address it feels safer.
|
|
24490
|
+
throw Error(`AssertionError: Ambiguous security context`);
|
|
24491
|
+
}
|
|
24492
|
+
return nonNoneSecurityContexts[0] ?? SecurityContext$1.NONE;
|
|
24417
24493
|
}
|
|
24418
24494
|
|
|
24419
24495
|
/**
|
|
@@ -25613,6 +25689,7 @@ const phases = [
|
|
|
25613
25689
|
{ kind: CompilationJobKind.Tmpl, fn: resolveI18nExpressionPlaceholders },
|
|
25614
25690
|
{ kind: CompilationJobKind.Tmpl, fn: extractI18nMessages },
|
|
25615
25691
|
{ kind: CompilationJobKind.Tmpl, fn: collectI18nConsts },
|
|
25692
|
+
{ kind: CompilationJobKind.Tmpl, fn: resolveI18nAttrSanitizers },
|
|
25616
25693
|
{ kind: CompilationJobKind.Tmpl, fn: collectConstExpressions },
|
|
25617
25694
|
{ kind: CompilationJobKind.Both, fn: collectElementConsts },
|
|
25618
25695
|
{ kind: CompilationJobKind.Tmpl, fn: removeI18nContexts },
|
|
@@ -25726,200 +25803,714 @@ function emitHostBindingFunction(job) {
|
|
|
25726
25803
|
/* sourceSpan */ undefined, job.root.fnName);
|
|
25727
25804
|
}
|
|
25728
25805
|
|
|
25729
|
-
const
|
|
25730
|
-
|
|
25731
|
-
const
|
|
25732
|
-
|
|
25733
|
-
const
|
|
25734
|
-
|
|
25735
|
-
const
|
|
25736
|
-
function isI18nRootNode(meta) {
|
|
25737
|
-
return meta instanceof Message;
|
|
25738
|
-
}
|
|
25739
|
-
function isSingleI18nIcu(meta) {
|
|
25740
|
-
return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
|
|
25741
|
-
}
|
|
25742
|
-
/**
|
|
25743
|
-
* Process a template AST and convert it into a `ComponentCompilation` in the intermediate
|
|
25744
|
-
* representation.
|
|
25745
|
-
* TODO: Refactor more of the ingestion code into phases.
|
|
25746
|
-
*/
|
|
25747
|
-
function ingestComponent(componentName, template, constantPool, compilationMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations) {
|
|
25748
|
-
const job = new ComponentCompilationJob(componentName, constantPool, compatibilityMode, compilationMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations);
|
|
25749
|
-
ingestNodes(job.root, template);
|
|
25750
|
-
return job;
|
|
25751
|
-
}
|
|
25806
|
+
const PROPERTY_PARTS_SEPARATOR = '.';
|
|
25807
|
+
const ATTRIBUTE_PREFIX = 'attr';
|
|
25808
|
+
const ANIMATE_PREFIX$1 = 'animate';
|
|
25809
|
+
const CLASS_PREFIX = 'class';
|
|
25810
|
+
const STYLE_PREFIX = 'style';
|
|
25811
|
+
const TEMPLATE_ATTR_PREFIX$1 = '*';
|
|
25812
|
+
const LEGACY_ANIMATE_PROP_PREFIX = 'animate-';
|
|
25752
25813
|
/**
|
|
25753
|
-
*
|
|
25754
|
-
* representation.
|
|
25814
|
+
* Parses bindings in templates and in the directive host area.
|
|
25755
25815
|
*/
|
|
25756
|
-
|
|
25757
|
-
|
|
25758
|
-
|
|
25759
|
-
|
|
25760
|
-
|
|
25761
|
-
|
|
25762
|
-
|
|
25763
|
-
|
|
25764
|
-
|
|
25765
|
-
|
|
25766
|
-
bindingKind = BindingKind.LegacyAnimation;
|
|
25767
|
-
}
|
|
25768
|
-
if (property.isAnimation) {
|
|
25769
|
-
bindingKind = BindingKind.Animation;
|
|
25770
|
-
}
|
|
25771
|
-
const securityContexts = bindingParser
|
|
25772
|
-
.calcPossibleSecurityContexts(input.componentSelector, property.name, bindingKind === BindingKind.Attribute)
|
|
25773
|
-
.filter((context) => context !== SecurityContext$1.NONE);
|
|
25774
|
-
ingestDomProperty(job, property, bindingKind, securityContexts);
|
|
25775
|
-
}
|
|
25776
|
-
for (const [name, expr] of Object.entries(input.attributes) ?? []) {
|
|
25777
|
-
const securityContexts = bindingParser
|
|
25778
|
-
.calcPossibleSecurityContexts(input.componentSelector, name, true)
|
|
25779
|
-
.filter((context) => context !== SecurityContext$1.NONE);
|
|
25780
|
-
ingestHostAttribute(job, name, expr, securityContexts);
|
|
25781
|
-
}
|
|
25782
|
-
for (const event of input.events ?? []) {
|
|
25783
|
-
ingestHostEvent(job, event);
|
|
25816
|
+
class BindingParser {
|
|
25817
|
+
_exprParser;
|
|
25818
|
+
_interpolationConfig;
|
|
25819
|
+
_schemaRegistry;
|
|
25820
|
+
errors;
|
|
25821
|
+
constructor(_exprParser, _interpolationConfig, _schemaRegistry, errors) {
|
|
25822
|
+
this._exprParser = _exprParser;
|
|
25823
|
+
this._interpolationConfig = _interpolationConfig;
|
|
25824
|
+
this._schemaRegistry = _schemaRegistry;
|
|
25825
|
+
this.errors = errors;
|
|
25784
25826
|
}
|
|
25785
|
-
|
|
25786
|
-
|
|
25787
|
-
// TODO: We should refactor the parser to use the same types and structures for host bindings as
|
|
25788
|
-
// with ordinary components. This would allow us to share a lot more ingestion code.
|
|
25789
|
-
function ingestDomProperty(job, property, bindingKind, securityContexts) {
|
|
25790
|
-
let expression;
|
|
25791
|
-
const ast = property.expression.ast;
|
|
25792
|
-
if (ast instanceof Interpolation$1) {
|
|
25793
|
-
expression = new Interpolation(ast.strings, ast.expressions.map((expr) => convertAst(expr, job, property.sourceSpan)), []);
|
|
25827
|
+
get interpolationConfig() {
|
|
25828
|
+
return this._interpolationConfig;
|
|
25794
25829
|
}
|
|
25795
|
-
|
|
25796
|
-
|
|
25830
|
+
createBoundHostProperties(properties, sourceSpan) {
|
|
25831
|
+
const boundProps = [];
|
|
25832
|
+
for (const propName of Object.keys(properties)) {
|
|
25833
|
+
const expression = properties[propName];
|
|
25834
|
+
if (typeof expression === 'string') {
|
|
25835
|
+
this.parsePropertyBinding(propName, expression, true, false, sourceSpan, sourceSpan.start.offset, undefined, [],
|
|
25836
|
+
// Use the `sourceSpan` for `keySpan`. This isn't really accurate, but neither is the
|
|
25837
|
+
// sourceSpan, as it represents the sourceSpan of the host itself rather than the
|
|
25838
|
+
// source of the host binding (which doesn't exist in the template). Regardless,
|
|
25839
|
+
// neither of these values are used in Ivy but are only here to satisfy the function
|
|
25840
|
+
// signature. This should likely be refactored in the future so that `sourceSpan`
|
|
25841
|
+
// isn't being used inaccurately.
|
|
25842
|
+
boundProps, sourceSpan);
|
|
25843
|
+
}
|
|
25844
|
+
else {
|
|
25845
|
+
this._reportError(`Value of the host property binding "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, sourceSpan);
|
|
25846
|
+
}
|
|
25847
|
+
}
|
|
25848
|
+
return boundProps;
|
|
25797
25849
|
}
|
|
25798
|
-
|
|
25799
|
-
|
|
25800
|
-
|
|
25801
|
-
|
|
25802
|
-
|
|
25803
|
-
|
|
25804
|
-
|
|
25805
|
-
|
|
25806
|
-
|
|
25807
|
-
|
|
25808
|
-
|
|
25809
|
-
|
|
25810
|
-
|
|
25811
|
-
|
|
25812
|
-
|
|
25813
|
-
|
|
25850
|
+
createDirectiveHostEventAsts(hostListeners, sourceSpan) {
|
|
25851
|
+
const targetEvents = [];
|
|
25852
|
+
for (const propName of Object.keys(hostListeners)) {
|
|
25853
|
+
const expression = hostListeners[propName];
|
|
25854
|
+
if (typeof expression === 'string') {
|
|
25855
|
+
// Use the `sourceSpan` for `keySpan` and `handlerSpan`. This isn't really accurate, but
|
|
25856
|
+
// neither is the `sourceSpan`, as it represents the `sourceSpan` of the host itself
|
|
25857
|
+
// rather than the source of the host binding (which doesn't exist in the template).
|
|
25858
|
+
// Regardless, neither of these values are used in Ivy but are only here to satisfy the
|
|
25859
|
+
// function signature. This should likely be refactored in the future so that `sourceSpan`
|
|
25860
|
+
// isn't being used inaccurately.
|
|
25861
|
+
this.parseEvent(propName, expression,
|
|
25862
|
+
/* isAssignmentEvent */ false, sourceSpan, sourceSpan, [], targetEvents, sourceSpan);
|
|
25863
|
+
}
|
|
25864
|
+
else {
|
|
25865
|
+
this._reportError(`Value of the host listener "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, sourceSpan);
|
|
25866
|
+
}
|
|
25867
|
+
}
|
|
25868
|
+
return targetEvents;
|
|
25814
25869
|
}
|
|
25815
|
-
|
|
25816
|
-
const
|
|
25817
|
-
|
|
25818
|
-
|
|
25819
|
-
|
|
25870
|
+
parseInterpolation(value, sourceSpan, interpolatedTokens) {
|
|
25871
|
+
const absoluteOffset = sourceSpan.fullStart.offset;
|
|
25872
|
+
try {
|
|
25873
|
+
const ast = this._exprParser.parseInterpolation(value, sourceSpan, absoluteOffset, interpolatedTokens, this._interpolationConfig);
|
|
25874
|
+
if (ast) {
|
|
25875
|
+
this.errors.push(...ast.errors);
|
|
25876
|
+
}
|
|
25877
|
+
return ast;
|
|
25878
|
+
}
|
|
25879
|
+
catch (e) {
|
|
25880
|
+
this._reportError(`${e}`, sourceSpan);
|
|
25881
|
+
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
25882
|
+
}
|
|
25820
25883
|
}
|
|
25821
|
-
|
|
25822
|
-
|
|
25823
|
-
|
|
25824
|
-
|
|
25825
|
-
|
|
25826
|
-
|
|
25827
|
-
|
|
25828
|
-
|
|
25829
|
-
|
|
25884
|
+
/**
|
|
25885
|
+
* Similar to `parseInterpolation`, but treats the provided string as a single expression
|
|
25886
|
+
* element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
|
|
25887
|
+
* This is used for parsing the switch expression in ICUs.
|
|
25888
|
+
*/
|
|
25889
|
+
parseInterpolationExpression(expression, sourceSpan) {
|
|
25890
|
+
const absoluteOffset = sourceSpan.start.offset;
|
|
25891
|
+
try {
|
|
25892
|
+
const ast = this._exprParser.parseInterpolationExpression(expression, sourceSpan, absoluteOffset);
|
|
25893
|
+
if (ast) {
|
|
25894
|
+
this.errors.push(...ast.errors);
|
|
25895
|
+
}
|
|
25896
|
+
return ast;
|
|
25830
25897
|
}
|
|
25831
|
-
|
|
25832
|
-
|
|
25898
|
+
catch (e) {
|
|
25899
|
+
this._reportError(`${e}`, sourceSpan);
|
|
25900
|
+
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
25833
25901
|
}
|
|
25834
|
-
|
|
25835
|
-
|
|
25902
|
+
}
|
|
25903
|
+
/**
|
|
25904
|
+
* Parses the bindings in a microsyntax expression, and converts them to
|
|
25905
|
+
* `ParsedProperty` or `ParsedVariable`.
|
|
25906
|
+
*
|
|
25907
|
+
* @param tplKey template binding name
|
|
25908
|
+
* @param tplValue template binding value
|
|
25909
|
+
* @param sourceSpan span of template binding relative to entire the template
|
|
25910
|
+
* @param absoluteValueOffset start of the tplValue relative to the entire template
|
|
25911
|
+
* @param targetMatchableAttrs potential attributes to match in the template
|
|
25912
|
+
* @param targetProps target property bindings in the template
|
|
25913
|
+
* @param targetVars target variables in the template
|
|
25914
|
+
*/
|
|
25915
|
+
parseInlineTemplateBinding(tplKey, tplValue, sourceSpan, absoluteValueOffset, targetMatchableAttrs, targetProps, targetVars, isIvyAst) {
|
|
25916
|
+
const absoluteKeyOffset = sourceSpan.start.offset + TEMPLATE_ATTR_PREFIX$1.length;
|
|
25917
|
+
const bindings = this._parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset);
|
|
25918
|
+
for (const binding of bindings) {
|
|
25919
|
+
// sourceSpan is for the entire HTML attribute. bindingSpan is for a particular
|
|
25920
|
+
// binding within the microsyntax expression so it's more narrow than sourceSpan.
|
|
25921
|
+
const bindingSpan = moveParseSourceSpan(sourceSpan, binding.sourceSpan);
|
|
25922
|
+
const key = binding.key.source;
|
|
25923
|
+
const keySpan = moveParseSourceSpan(sourceSpan, binding.key.span);
|
|
25924
|
+
if (binding instanceof VariableBinding) {
|
|
25925
|
+
const value = binding.value ? binding.value.source : '$implicit';
|
|
25926
|
+
const valueSpan = binding.value
|
|
25927
|
+
? moveParseSourceSpan(sourceSpan, binding.value.span)
|
|
25928
|
+
: undefined;
|
|
25929
|
+
targetVars.push(new ParsedVariable(key, value, bindingSpan, keySpan, valueSpan));
|
|
25930
|
+
}
|
|
25931
|
+
else if (binding.value) {
|
|
25932
|
+
const srcSpan = isIvyAst ? bindingSpan : sourceSpan;
|
|
25933
|
+
const valueSpan = moveParseSourceSpan(sourceSpan, binding.value.ast.sourceSpan);
|
|
25934
|
+
this._parsePropertyAst(key, binding.value, false, srcSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25935
|
+
}
|
|
25936
|
+
else {
|
|
25937
|
+
targetMatchableAttrs.push([key, '' /* value */]);
|
|
25938
|
+
// Since this is a literal attribute with no RHS, source span should be
|
|
25939
|
+
// just the key span.
|
|
25940
|
+
this.parseLiteralAttr(key, null /* value */, keySpan, absoluteValueOffset, undefined /* valueSpan */, targetMatchableAttrs, targetProps, keySpan);
|
|
25941
|
+
}
|
|
25836
25942
|
}
|
|
25837
|
-
|
|
25838
|
-
|
|
25943
|
+
}
|
|
25944
|
+
/**
|
|
25945
|
+
* Parses the bindings in a microsyntax expression, e.g.
|
|
25946
|
+
* ```html
|
|
25947
|
+
* <tag *tplKey="let value1 = prop; let value2 = localVar">
|
|
25948
|
+
* ```
|
|
25949
|
+
*
|
|
25950
|
+
* @param tplKey template binding name
|
|
25951
|
+
* @param tplValue template binding value
|
|
25952
|
+
* @param sourceSpan span of template binding relative to entire the template
|
|
25953
|
+
* @param absoluteKeyOffset start of the `tplKey`
|
|
25954
|
+
* @param absoluteValueOffset start of the `tplValue`
|
|
25955
|
+
*/
|
|
25956
|
+
_parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset) {
|
|
25957
|
+
try {
|
|
25958
|
+
const bindingsResult = this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset);
|
|
25959
|
+
bindingsResult.errors.forEach((e) => this.errors.push(e));
|
|
25960
|
+
bindingsResult.warnings.forEach((warning) => {
|
|
25961
|
+
this._reportError(warning, sourceSpan, ParseErrorLevel.WARNING);
|
|
25962
|
+
});
|
|
25963
|
+
return bindingsResult.templateBindings;
|
|
25839
25964
|
}
|
|
25840
|
-
|
|
25841
|
-
|
|
25965
|
+
catch (e) {
|
|
25966
|
+
this._reportError(`${e}`, sourceSpan);
|
|
25967
|
+
return [];
|
|
25842
25968
|
}
|
|
25843
|
-
|
|
25844
|
-
|
|
25969
|
+
}
|
|
25970
|
+
parseLiteralAttr(name, value, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
|
|
25971
|
+
if (isLegacyAnimationLabel(name)) {
|
|
25972
|
+
name = name.substring(1);
|
|
25973
|
+
if (keySpan !== undefined) {
|
|
25974
|
+
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
|
25975
|
+
}
|
|
25976
|
+
if (value) {
|
|
25977
|
+
this._reportError(`Assigning animation triggers via @prop="exp" attributes with an expression is invalid.` +
|
|
25978
|
+
` Use property bindings (e.g. [@prop]="exp") or use an attribute without a value (e.g. @prop) instead.`, sourceSpan, ParseErrorLevel.ERROR);
|
|
25979
|
+
}
|
|
25980
|
+
this._parseLegacyAnimation(name, value, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25845
25981
|
}
|
|
25846
|
-
else
|
|
25847
|
-
|
|
25982
|
+
else {
|
|
25983
|
+
targetProps.push(new ParsedProperty(name, this._exprParser.wrapLiteralPrimitive(value, '', absoluteOffset), ParsedPropertyType.LITERAL_ATTR, sourceSpan, keySpan, valueSpan));
|
|
25848
25984
|
}
|
|
25849
|
-
|
|
25850
|
-
|
|
25985
|
+
}
|
|
25986
|
+
parsePropertyBinding(name, expression, isHost, isPartOfAssignmentBinding, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
|
|
25987
|
+
if (name.length === 0) {
|
|
25988
|
+
this._reportError(`Property name is missing in binding`, sourceSpan);
|
|
25851
25989
|
}
|
|
25852
|
-
|
|
25853
|
-
|
|
25990
|
+
let isLegacyAnimationProp = false;
|
|
25991
|
+
if (name.startsWith(LEGACY_ANIMATE_PROP_PREFIX)) {
|
|
25992
|
+
isLegacyAnimationProp = true;
|
|
25993
|
+
name = name.substring(LEGACY_ANIMATE_PROP_PREFIX.length);
|
|
25994
|
+
if (keySpan !== undefined) {
|
|
25995
|
+
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + LEGACY_ANIMATE_PROP_PREFIX.length, keySpan.end.offset));
|
|
25996
|
+
}
|
|
25854
25997
|
}
|
|
25855
|
-
else if (
|
|
25856
|
-
|
|
25998
|
+
else if (isLegacyAnimationLabel(name)) {
|
|
25999
|
+
isLegacyAnimationProp = true;
|
|
26000
|
+
name = name.substring(1);
|
|
26001
|
+
if (keySpan !== undefined) {
|
|
26002
|
+
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
|
26003
|
+
}
|
|
25857
26004
|
}
|
|
25858
|
-
|
|
25859
|
-
|
|
26005
|
+
if (isLegacyAnimationProp) {
|
|
26006
|
+
this._parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
26007
|
+
}
|
|
26008
|
+
else if (name.startsWith(`${ANIMATE_PREFIX$1}${PROPERTY_PARTS_SEPARATOR}`)) {
|
|
26009
|
+
this._parseAnimation(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25860
26010
|
}
|
|
25861
|
-
else if (node instanceof Component$1) ;
|
|
25862
26011
|
else {
|
|
25863
|
-
|
|
26012
|
+
this._parsePropertyAst(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25864
26013
|
}
|
|
25865
26014
|
}
|
|
25866
|
-
|
|
25867
|
-
|
|
25868
|
-
|
|
25869
|
-
|
|
25870
|
-
|
|
25871
|
-
|
|
25872
|
-
|
|
25873
|
-
throw Error(`Unhandled i18n metadata type for element: ${element.i18n.constructor.name}`);
|
|
25874
|
-
}
|
|
25875
|
-
const id = unit.job.allocateXrefId();
|
|
25876
|
-
const [namespaceKey, elementName] = splitNsName(element.name);
|
|
25877
|
-
const startOp = createElementStartOp(elementName, id, namespaceForKey(namespaceKey), element.i18n instanceof TagPlaceholder ? element.i18n : undefined, element.startSourceSpan, element.sourceSpan);
|
|
25878
|
-
unit.create.push(startOp);
|
|
25879
|
-
ingestElementBindings(unit, startOp, element);
|
|
25880
|
-
ingestReferences(startOp, element);
|
|
25881
|
-
// Start i18n, if needed, goes after the element create and bindings, but before the nodes
|
|
25882
|
-
let i18nBlockId = null;
|
|
25883
|
-
if (element.i18n instanceof Message) {
|
|
25884
|
-
i18nBlockId = unit.job.allocateXrefId();
|
|
25885
|
-
unit.create.push(createI18nStartOp(i18nBlockId, element.i18n, undefined, element.startSourceSpan));
|
|
26015
|
+
parsePropertyInterpolation(name, value, sourceSpan, valueSpan, targetMatchableAttrs, targetProps, keySpan, interpolatedTokens) {
|
|
26016
|
+
const expr = this.parseInterpolation(value, valueSpan || sourceSpan, interpolatedTokens);
|
|
26017
|
+
if (expr) {
|
|
26018
|
+
this._parsePropertyAst(name, expr, false, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
26019
|
+
return true;
|
|
26020
|
+
}
|
|
26021
|
+
return false;
|
|
25886
26022
|
}
|
|
25887
|
-
|
|
25888
|
-
|
|
25889
|
-
|
|
25890
|
-
// instructions will be collapsed into one `element` instruction, negating the purpose of this
|
|
25891
|
-
// fallback, but in cases when it is not collapsed (such as an input with a binding), we still
|
|
25892
|
-
// want to map the end instruction to the main element.
|
|
25893
|
-
const endOp = createElementEndOp(id, element.endSourceSpan ?? element.startSourceSpan);
|
|
25894
|
-
unit.create.push(endOp);
|
|
25895
|
-
// If there is an i18n message associated with this element, insert i18n start and end ops.
|
|
25896
|
-
if (i18nBlockId !== null) {
|
|
25897
|
-
OpList.insertBefore(createI18nEndOp(i18nBlockId, element.endSourceSpan ?? element.startSourceSpan), endOp);
|
|
26023
|
+
_parsePropertyAst(name, ast, isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
26024
|
+
targetMatchableAttrs.push([name, ast.source]);
|
|
26025
|
+
targetProps.push(new ParsedProperty(name, ast, isPartOfAssignmentBinding ? ParsedPropertyType.TWO_WAY : ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
|
|
25898
26026
|
}
|
|
25899
|
-
|
|
25900
|
-
|
|
25901
|
-
|
|
25902
|
-
*/
|
|
25903
|
-
function ingestTemplate(unit, tmpl) {
|
|
25904
|
-
if (tmpl.i18n !== undefined &&
|
|
25905
|
-
!(tmpl.i18n instanceof Message || tmpl.i18n instanceof TagPlaceholder)) {
|
|
25906
|
-
throw Error(`Unhandled i18n metadata type for template: ${tmpl.i18n.constructor.name}`);
|
|
26027
|
+
_parseAnimation(name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
26028
|
+
targetMatchableAttrs.push([name, ast.source]);
|
|
26029
|
+
targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan));
|
|
25907
26030
|
}
|
|
25908
|
-
|
|
25909
|
-
|
|
25910
|
-
|
|
25911
|
-
|
|
25912
|
-
|
|
26031
|
+
_parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
26032
|
+
if (name.length === 0) {
|
|
26033
|
+
this._reportError('Animation trigger is missing', sourceSpan);
|
|
26034
|
+
}
|
|
26035
|
+
// This will occur when a @trigger is not paired with an expression.
|
|
26036
|
+
// For animations it is valid to not have an expression since */void
|
|
26037
|
+
// states will be applied by angular when the element is attached/detached
|
|
26038
|
+
const ast = this.parseBinding(expression || 'undefined', false, valueSpan || sourceSpan, absoluteOffset);
|
|
26039
|
+
targetMatchableAttrs.push([name, ast.source]);
|
|
26040
|
+
targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.LEGACY_ANIMATION, sourceSpan, keySpan, valueSpan));
|
|
25913
26041
|
}
|
|
25914
|
-
|
|
25915
|
-
|
|
25916
|
-
|
|
25917
|
-
|
|
25918
|
-
|
|
25919
|
-
|
|
25920
|
-
|
|
25921
|
-
|
|
25922
|
-
|
|
26042
|
+
parseBinding(value, isHostBinding, sourceSpan, absoluteOffset) {
|
|
26043
|
+
try {
|
|
26044
|
+
const ast = isHostBinding
|
|
26045
|
+
? this._exprParser.parseSimpleBinding(value, sourceSpan, absoluteOffset, this._interpolationConfig)
|
|
26046
|
+
: this._exprParser.parseBinding(value, sourceSpan, absoluteOffset, this._interpolationConfig);
|
|
26047
|
+
if (ast) {
|
|
26048
|
+
this.errors.push(...ast.errors);
|
|
26049
|
+
}
|
|
26050
|
+
return ast;
|
|
26051
|
+
}
|
|
26052
|
+
catch (e) {
|
|
26053
|
+
this._reportError(`${e}`, sourceSpan);
|
|
26054
|
+
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
26055
|
+
}
|
|
26056
|
+
}
|
|
26057
|
+
createBoundElementProperty(elementSelector, boundProp, skipValidation = false, mapPropertyName = true) {
|
|
26058
|
+
if (boundProp.isLegacyAnimation) {
|
|
26059
|
+
return new BoundElementProperty(boundProp.name, BindingType.LegacyAnimation, SecurityContext$1.NONE, boundProp.expression, null, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
|
|
26060
|
+
}
|
|
26061
|
+
let unit = null;
|
|
26062
|
+
let bindingType = undefined;
|
|
26063
|
+
let boundPropertyName = null;
|
|
26064
|
+
const parts = boundProp.name.split(PROPERTY_PARTS_SEPARATOR);
|
|
26065
|
+
let securityContexts = undefined;
|
|
26066
|
+
// Check for special cases (prefix style, attr, class)
|
|
26067
|
+
if (parts.length > 1) {
|
|
26068
|
+
if (parts[0] == ATTRIBUTE_PREFIX) {
|
|
26069
|
+
boundPropertyName = parts.slice(1).join(PROPERTY_PARTS_SEPARATOR);
|
|
26070
|
+
if (!skipValidation) {
|
|
26071
|
+
this._validatePropertyOrAttributeName(boundPropertyName, boundProp.sourceSpan, true);
|
|
26072
|
+
}
|
|
26073
|
+
securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, boundPropertyName, true);
|
|
26074
|
+
const nsSeparatorIdx = boundPropertyName.indexOf(':');
|
|
26075
|
+
if (nsSeparatorIdx > -1) {
|
|
26076
|
+
const ns = boundPropertyName.substring(0, nsSeparatorIdx);
|
|
26077
|
+
const name = boundPropertyName.substring(nsSeparatorIdx + 1);
|
|
26078
|
+
boundPropertyName = mergeNsAndName(ns, name);
|
|
26079
|
+
}
|
|
26080
|
+
bindingType = BindingType.Attribute;
|
|
26081
|
+
}
|
|
26082
|
+
else if (parts[0] == CLASS_PREFIX) {
|
|
26083
|
+
boundPropertyName = parts[1];
|
|
26084
|
+
bindingType = BindingType.Class;
|
|
26085
|
+
securityContexts = [SecurityContext$1.NONE];
|
|
26086
|
+
}
|
|
26087
|
+
else if (parts[0] == STYLE_PREFIX) {
|
|
26088
|
+
unit = parts.length > 2 ? parts[2] : null;
|
|
26089
|
+
boundPropertyName = parts[1];
|
|
26090
|
+
bindingType = BindingType.Style;
|
|
26091
|
+
securityContexts = [SecurityContext$1.STYLE];
|
|
26092
|
+
}
|
|
26093
|
+
else if (parts[0] == ANIMATE_PREFIX$1) {
|
|
26094
|
+
boundPropertyName = boundProp.name;
|
|
26095
|
+
bindingType = BindingType.Animation;
|
|
26096
|
+
securityContexts = [SecurityContext$1.NONE];
|
|
26097
|
+
}
|
|
26098
|
+
}
|
|
26099
|
+
// If not a special case, use the full property name
|
|
26100
|
+
if (boundPropertyName === null) {
|
|
26101
|
+
const mappedPropName = this._schemaRegistry.getMappedPropName(boundProp.name);
|
|
26102
|
+
boundPropertyName = mapPropertyName ? mappedPropName : boundProp.name;
|
|
26103
|
+
securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, mappedPropName, false);
|
|
26104
|
+
bindingType =
|
|
26105
|
+
boundProp.type === ParsedPropertyType.TWO_WAY ? BindingType.TwoWay : BindingType.Property;
|
|
26106
|
+
if (!skipValidation) {
|
|
26107
|
+
this._validatePropertyOrAttributeName(mappedPropName, boundProp.sourceSpan, false);
|
|
26108
|
+
}
|
|
26109
|
+
}
|
|
26110
|
+
return new BoundElementProperty(boundPropertyName, bindingType, securityContexts[0], boundProp.expression, unit, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
|
|
26111
|
+
}
|
|
26112
|
+
parseEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
|
|
26113
|
+
if (name.length === 0) {
|
|
26114
|
+
this._reportError(`Event name is missing in binding`, sourceSpan);
|
|
26115
|
+
}
|
|
26116
|
+
if (isLegacyAnimationLabel(name)) {
|
|
26117
|
+
name = name.slice(1);
|
|
26118
|
+
if (keySpan !== undefined) {
|
|
26119
|
+
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
|
26120
|
+
}
|
|
26121
|
+
this._parseLegacyAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan);
|
|
26122
|
+
}
|
|
26123
|
+
else {
|
|
26124
|
+
this._parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan);
|
|
26125
|
+
}
|
|
26126
|
+
}
|
|
26127
|
+
calcPossibleSecurityContexts(selector, propName, isAttribute) {
|
|
26128
|
+
const prop = this._schemaRegistry.getMappedPropName(propName);
|
|
26129
|
+
return calcPossibleSecurityContexts(this._schemaRegistry, selector, prop, isAttribute);
|
|
26130
|
+
}
|
|
26131
|
+
parseEventListenerName(rawName) {
|
|
26132
|
+
const [target, eventName] = splitAtColon(rawName, [null, rawName]);
|
|
26133
|
+
return { eventName: eventName, target };
|
|
26134
|
+
}
|
|
26135
|
+
parseLegacyAnimationEventName(rawName) {
|
|
26136
|
+
const matches = splitAtPeriod(rawName, [rawName, null]);
|
|
26137
|
+
return { eventName: matches[0], phase: matches[1] === null ? null : matches[1].toLowerCase() };
|
|
26138
|
+
}
|
|
26139
|
+
_parseLegacyAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan) {
|
|
26140
|
+
const { eventName, phase } = this.parseLegacyAnimationEventName(name);
|
|
26141
|
+
const ast = this._parseAction(expression, handlerSpan);
|
|
26142
|
+
targetEvents.push(new ParsedEvent(eventName, phase, ParsedEventType.LegacyAnimation, ast, sourceSpan, handlerSpan, keySpan));
|
|
26143
|
+
if (eventName.length === 0) {
|
|
26144
|
+
this._reportError(`Animation event name is missing in binding`, sourceSpan);
|
|
26145
|
+
}
|
|
26146
|
+
if (phase) {
|
|
26147
|
+
if (phase !== 'start' && phase !== 'done') {
|
|
26148
|
+
this._reportError(`The provided animation output phase value "${phase}" for "@${eventName}" is not supported (use start or done)`, sourceSpan);
|
|
26149
|
+
}
|
|
26150
|
+
}
|
|
26151
|
+
else {
|
|
26152
|
+
this._reportError(`The animation trigger output event (@${eventName}) is missing its phase value name (start or done are currently supported)`, sourceSpan);
|
|
26153
|
+
}
|
|
26154
|
+
}
|
|
26155
|
+
_parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
|
|
26156
|
+
// long format: 'target: eventName'
|
|
26157
|
+
const { eventName, target } = this.parseEventListenerName(name);
|
|
26158
|
+
const prevErrorCount = this.errors.length;
|
|
26159
|
+
const ast = this._parseAction(expression, handlerSpan);
|
|
26160
|
+
const isValid = this.errors.length === prevErrorCount;
|
|
26161
|
+
targetMatchableAttrs.push([name, ast.source]);
|
|
26162
|
+
// Don't try to validate assignment events if there were other
|
|
26163
|
+
// parsing errors to avoid adding more noise to the error logs.
|
|
26164
|
+
if (isAssignmentEvent && isValid && !this._isAllowedAssignmentEvent(ast)) {
|
|
26165
|
+
this._reportError('Unsupported expression in a two-way binding', sourceSpan);
|
|
26166
|
+
}
|
|
26167
|
+
let eventType = ParsedEventType.Regular;
|
|
26168
|
+
if (isAssignmentEvent) {
|
|
26169
|
+
eventType = ParsedEventType.TwoWay;
|
|
26170
|
+
}
|
|
26171
|
+
if (name.startsWith(`${ANIMATE_PREFIX$1}${PROPERTY_PARTS_SEPARATOR}`)) {
|
|
26172
|
+
eventType = ParsedEventType.Animation;
|
|
26173
|
+
}
|
|
26174
|
+
targetEvents.push(new ParsedEvent(eventName, target, eventType, ast, sourceSpan, handlerSpan, keySpan));
|
|
26175
|
+
// Don't detect directives for event names for now,
|
|
26176
|
+
// so don't add the event name to the matchableAttrs
|
|
26177
|
+
}
|
|
26178
|
+
_parseAction(value, sourceSpan) {
|
|
26179
|
+
const absoluteOffset = sourceSpan && sourceSpan.start ? sourceSpan.start.offset : 0;
|
|
26180
|
+
try {
|
|
26181
|
+
const ast = this._exprParser.parseAction(value, sourceSpan, absoluteOffset, this._interpolationConfig);
|
|
26182
|
+
if (ast) {
|
|
26183
|
+
this.errors.push(...ast.errors);
|
|
26184
|
+
}
|
|
26185
|
+
if (!ast || ast.ast instanceof EmptyExpr$1) {
|
|
26186
|
+
this._reportError(`Empty expressions are not allowed`, sourceSpan);
|
|
26187
|
+
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
26188
|
+
}
|
|
26189
|
+
return ast;
|
|
26190
|
+
}
|
|
26191
|
+
catch (e) {
|
|
26192
|
+
this._reportError(`${e}`, sourceSpan);
|
|
26193
|
+
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
26194
|
+
}
|
|
26195
|
+
}
|
|
26196
|
+
_reportError(message, sourceSpan, level = ParseErrorLevel.ERROR) {
|
|
26197
|
+
this.errors.push(new ParseError(sourceSpan, message, level));
|
|
26198
|
+
}
|
|
26199
|
+
/**
|
|
26200
|
+
* @param propName the name of the property / attribute
|
|
26201
|
+
* @param sourceSpan
|
|
26202
|
+
* @param isAttr true when binding to an attribute
|
|
26203
|
+
*/
|
|
26204
|
+
_validatePropertyOrAttributeName(propName, sourceSpan, isAttr) {
|
|
26205
|
+
const report = isAttr
|
|
26206
|
+
? this._schemaRegistry.validateAttribute(propName)
|
|
26207
|
+
: this._schemaRegistry.validateProperty(propName);
|
|
26208
|
+
if (report.error) {
|
|
26209
|
+
this._reportError(report.msg, sourceSpan, ParseErrorLevel.ERROR);
|
|
26210
|
+
}
|
|
26211
|
+
}
|
|
26212
|
+
/**
|
|
26213
|
+
* Returns whether a parsed AST is allowed to be used within the event side of a two-way binding.
|
|
26214
|
+
* @param ast Parsed AST to be checked.
|
|
26215
|
+
*/
|
|
26216
|
+
_isAllowedAssignmentEvent(ast) {
|
|
26217
|
+
if (ast instanceof ASTWithSource) {
|
|
26218
|
+
return this._isAllowedAssignmentEvent(ast.ast);
|
|
26219
|
+
}
|
|
26220
|
+
if (ast instanceof NonNullAssert) {
|
|
26221
|
+
return this._isAllowedAssignmentEvent(ast.expression);
|
|
26222
|
+
}
|
|
26223
|
+
if (ast instanceof Call &&
|
|
26224
|
+
ast.args.length === 1 &&
|
|
26225
|
+
ast.receiver instanceof PropertyRead &&
|
|
26226
|
+
ast.receiver.name === '$any' &&
|
|
26227
|
+
ast.receiver.receiver instanceof ImplicitReceiver &&
|
|
26228
|
+
!(ast.receiver.receiver instanceof ThisReceiver)) {
|
|
26229
|
+
return this._isAllowedAssignmentEvent(ast.args[0]);
|
|
26230
|
+
}
|
|
26231
|
+
if (ast instanceof PropertyRead || ast instanceof KeyedRead) {
|
|
26232
|
+
if (!hasRecursiveSafeReceiver(ast)) {
|
|
26233
|
+
return true;
|
|
26234
|
+
}
|
|
26235
|
+
}
|
|
26236
|
+
return false;
|
|
26237
|
+
}
|
|
26238
|
+
}
|
|
26239
|
+
function hasRecursiveSafeReceiver(ast) {
|
|
26240
|
+
if (ast instanceof SafePropertyRead || ast instanceof SafeKeyedRead) {
|
|
26241
|
+
return true;
|
|
26242
|
+
}
|
|
26243
|
+
if (ast instanceof ParenthesizedExpression) {
|
|
26244
|
+
return hasRecursiveSafeReceiver(ast.expression);
|
|
26245
|
+
}
|
|
26246
|
+
if (ast instanceof PropertyRead || ast instanceof KeyedRead || ast instanceof Call) {
|
|
26247
|
+
return hasRecursiveSafeReceiver(ast.receiver);
|
|
26248
|
+
}
|
|
26249
|
+
return false;
|
|
26250
|
+
}
|
|
26251
|
+
function isLegacyAnimationLabel(name) {
|
|
26252
|
+
return name[0] == '@';
|
|
26253
|
+
}
|
|
26254
|
+
function calcPossibleSecurityContexts(registry, selector, propName, isAttribute) {
|
|
26255
|
+
let ctxs;
|
|
26256
|
+
const [namespaceKey, baseSelector] = selector ? splitNsName$1(selector, false) : [null, selector];
|
|
26257
|
+
const nameToContext = (elName) => {
|
|
26258
|
+
const [nsStr, name] = splitNsName$1(elName, false);
|
|
26259
|
+
const ns = nsStr ?? namespaceKey;
|
|
26260
|
+
const fullName = ns ? `:${ns}:${name}` : name;
|
|
26261
|
+
return registry.securityContext(fullName, propName, isAttribute);
|
|
26262
|
+
};
|
|
26263
|
+
const allKnownElements = registry.allKnownElementNames();
|
|
26264
|
+
if (baseSelector === null) {
|
|
26265
|
+
ctxs = allKnownElements.map(nameToContext);
|
|
26266
|
+
}
|
|
26267
|
+
else {
|
|
26268
|
+
ctxs = [];
|
|
26269
|
+
CssSelector.parse(baseSelector).forEach((selector) => {
|
|
26270
|
+
let elementNames = selector.element ? [selector.element] : allKnownElements;
|
|
26271
|
+
if (selector.element && !registry.hasElement(selector.element, [])) {
|
|
26272
|
+
const svgElement = `:${SVG_NAMESPACE$2}:${selector.element}`;
|
|
26273
|
+
const mathElement = `:${MATH_ML_NAMESPACE$2}:${selector.element}`;
|
|
26274
|
+
if (registry.hasElement(svgElement, [])) {
|
|
26275
|
+
elementNames = [svgElement];
|
|
26276
|
+
}
|
|
26277
|
+
else if (registry.hasElement(mathElement, [])) {
|
|
26278
|
+
elementNames = [mathElement];
|
|
26279
|
+
}
|
|
26280
|
+
}
|
|
26281
|
+
const notElementNames = new Set(selector.notSelectors
|
|
26282
|
+
.filter((selector) => selector.isElementSelector())
|
|
26283
|
+
.map((selector) => selector.element?.toLowerCase()));
|
|
26284
|
+
const possibleElementNames = elementNames.filter((elName) => {
|
|
26285
|
+
const elNameLowerCase = elName.toLowerCase();
|
|
26286
|
+
return (!notElementNames.has(elNameLowerCase) &&
|
|
26287
|
+
!notElementNames.has(splitNsName$1(elNameLowerCase)[1]));
|
|
26288
|
+
});
|
|
26289
|
+
ctxs.push(...possibleElementNames.map(nameToContext));
|
|
26290
|
+
});
|
|
26291
|
+
}
|
|
26292
|
+
return ctxs.length === 0 ? [SecurityContext$1.NONE] : Array.from(new Set(ctxs)).sort();
|
|
26293
|
+
}
|
|
26294
|
+
/**
|
|
26295
|
+
* Compute a new ParseSourceSpan based off an original `sourceSpan` by using
|
|
26296
|
+
* absolute offsets from the specified `absoluteSpan`.
|
|
26297
|
+
*
|
|
26298
|
+
* @param sourceSpan original source span
|
|
26299
|
+
* @param absoluteSpan absolute source span to move to
|
|
26300
|
+
*/
|
|
26301
|
+
function moveParseSourceSpan(sourceSpan, absoluteSpan) {
|
|
26302
|
+
// The difference of two absolute offsets provide the relative offset
|
|
26303
|
+
const startDiff = absoluteSpan.start - sourceSpan.start.offset;
|
|
26304
|
+
const endDiff = absoluteSpan.end - sourceSpan.end.offset;
|
|
26305
|
+
return new ParseSourceSpan(sourceSpan.start.moveBy(startDiff), sourceSpan.end.moveBy(endDiff), sourceSpan.fullStart.moveBy(startDiff), sourceSpan.details);
|
|
26306
|
+
}
|
|
26307
|
+
|
|
26308
|
+
const compatibilityMode = CompatibilityMode.TemplateDefinitionBuilder;
|
|
26309
|
+
// Schema containing DOM elements and their properties.
|
|
26310
|
+
const domSchema = new DomElementSchemaRegistry();
|
|
26311
|
+
// Tag name of the `ng-template` element.
|
|
26312
|
+
const NG_TEMPLATE_TAG_NAME = 'ng-template';
|
|
26313
|
+
// prefix for any animation binding
|
|
26314
|
+
const ANIMATE_PREFIX = 'animate.';
|
|
26315
|
+
function isI18nRootNode(meta) {
|
|
26316
|
+
return meta instanceof Message;
|
|
26317
|
+
}
|
|
26318
|
+
function isSingleI18nIcu(meta) {
|
|
26319
|
+
return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
|
|
26320
|
+
}
|
|
26321
|
+
/**
|
|
26322
|
+
* Process a template AST and convert it into a `ComponentCompilation` in the intermediate
|
|
26323
|
+
* representation.
|
|
26324
|
+
* TODO: Refactor more of the ingestion code into phases.
|
|
26325
|
+
*/
|
|
26326
|
+
function ingestComponent(componentName, template, constantPool, compilationMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations) {
|
|
26327
|
+
const job = new ComponentCompilationJob(componentName, constantPool, compatibilityMode, compilationMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations);
|
|
26328
|
+
ingestNodes(job.root, template);
|
|
26329
|
+
return job;
|
|
26330
|
+
}
|
|
26331
|
+
/**
|
|
26332
|
+
* Process a host binding AST and convert it into a `HostBindingCompilationJob` in the intermediate
|
|
26333
|
+
* representation.
|
|
26334
|
+
*/
|
|
26335
|
+
function ingestHostBinding(input, bindingParser, constantPool) {
|
|
26336
|
+
const job = new HostBindingCompilationJob(input.componentName, constantPool, compatibilityMode, TemplateCompilationMode.DomOnly);
|
|
26337
|
+
for (const property of input.properties ?? []) {
|
|
26338
|
+
let bindingKind = BindingKind.Property;
|
|
26339
|
+
// TODO: this should really be handled in the parser.
|
|
26340
|
+
if (property.name.startsWith('attr.')) {
|
|
26341
|
+
property.name = property.name.substring('attr.'.length);
|
|
26342
|
+
bindingKind = BindingKind.Attribute;
|
|
26343
|
+
}
|
|
26344
|
+
if (property.isLegacyAnimation) {
|
|
26345
|
+
bindingKind = BindingKind.LegacyAnimation;
|
|
26346
|
+
}
|
|
26347
|
+
if (property.isAnimation) {
|
|
26348
|
+
bindingKind = BindingKind.Animation;
|
|
26349
|
+
}
|
|
26350
|
+
const securityContexts = calcHostBindingSecurityContexts(bindingParser, input.componentSelector, property.name, bindingKind === BindingKind.Attribute);
|
|
26351
|
+
ingestDomProperty(job, property, bindingKind, securityContexts);
|
|
26352
|
+
}
|
|
26353
|
+
for (const [name, expr] of Object.entries(input.attributes) ?? []) {
|
|
26354
|
+
const securityContexts = calcHostBindingSecurityContexts(bindingParser, input.componentSelector, name, true);
|
|
26355
|
+
ingestHostAttribute(job, name, expr, securityContexts);
|
|
26356
|
+
}
|
|
26357
|
+
for (const event of input.events ?? []) {
|
|
26358
|
+
ingestHostEvent(job, event);
|
|
26359
|
+
}
|
|
26360
|
+
return job;
|
|
26361
|
+
}
|
|
26362
|
+
function calcHostBindingSecurityContexts(bindingParser, selector, name, isAttribute) {
|
|
26363
|
+
const declaringSelectorContexts = bindingParser.calcPossibleSecurityContexts(selector, name, isAttribute);
|
|
26364
|
+
const concreteHostContexts = calcPossibleSecurityContexts(domSchema, null, domSchema.getMappedPropName(name), isAttribute);
|
|
26365
|
+
const concreteHostNonNoneContexts = concreteHostContexts.filter((context) => context !== SecurityContext$1.NONE);
|
|
26366
|
+
const concreteHostNonNoneCount = concreteHostNonNoneContexts.length;
|
|
26367
|
+
const hasConcreteHostNoneContext = concreteHostNonNoneCount !== concreteHostContexts.length;
|
|
26368
|
+
// Host bindings can run against a concrete host whose element name differs from the declaring
|
|
26369
|
+
// selector, including dynamic root components whose TNode name is `#host`.
|
|
26370
|
+
if (hasConcreteHostNoneContext && concreteHostNonNoneCount > 0) {
|
|
26371
|
+
return concreteHostContexts;
|
|
26372
|
+
}
|
|
26373
|
+
if (concreteHostNonNoneContexts.some((context) => !declaringSelectorContexts.includes(context))) {
|
|
26374
|
+
return concreteHostContexts;
|
|
26375
|
+
}
|
|
26376
|
+
return declaringSelectorContexts.filter((context) => context !== SecurityContext$1.NONE);
|
|
26377
|
+
}
|
|
26378
|
+
// TODO: We should refactor the parser to use the same types and structures for host bindings as
|
|
26379
|
+
// with ordinary components. This would allow us to share a lot more ingestion code.
|
|
26380
|
+
function ingestDomProperty(job, property, bindingKind, securityContexts) {
|
|
26381
|
+
let expression;
|
|
26382
|
+
const ast = property.expression.ast;
|
|
26383
|
+
if (ast instanceof Interpolation$1) {
|
|
26384
|
+
expression = new Interpolation(ast.strings, ast.expressions.map((expr) => convertAst(expr, job, property.sourceSpan)), []);
|
|
26385
|
+
}
|
|
26386
|
+
else {
|
|
26387
|
+
expression = convertAst(ast, job, property.sourceSpan);
|
|
26388
|
+
}
|
|
26389
|
+
job.root.update.push(createBindingOp(job.root.xref, bindingKind, property.name, expression, null, securityContexts, false, false, null,
|
|
26390
|
+
/* TODO: How do Host bindings handle i18n attrs? */ null, property.sourceSpan));
|
|
26391
|
+
}
|
|
26392
|
+
function ingestHostAttribute(job, name, value, securityContexts) {
|
|
26393
|
+
const attrBinding = createBindingOp(job.root.xref, BindingKind.Attribute, name, value, null, securityContexts,
|
|
26394
|
+
/* Host attributes should always be extracted to const hostAttrs, even if they are not
|
|
26395
|
+
*strictly* text literals */
|
|
26396
|
+
true, false, null,
|
|
26397
|
+
/* TODO */ null,
|
|
26398
|
+
/** TODO: May be null? */ value.sourceSpan);
|
|
26399
|
+
job.root.update.push(attrBinding);
|
|
26400
|
+
}
|
|
26401
|
+
function ingestHostEvent(job, event) {
|
|
26402
|
+
let eventBinding;
|
|
26403
|
+
if (event.type === ParsedEventType.Animation) {
|
|
26404
|
+
eventBinding = createAnimationListenerOp(job.root.xref, new SlotHandle(), event.name, null, makeListenerHandlerOps(job.root, event.handler, event.handlerSpan), event.name.endsWith('enter') ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, event.targetOrPhase, true, event.sourceSpan);
|
|
26405
|
+
}
|
|
26406
|
+
else {
|
|
26407
|
+
const [phase, target] = event.type !== ParsedEventType.LegacyAnimation
|
|
26408
|
+
? [null, event.targetOrPhase]
|
|
26409
|
+
: [event.targetOrPhase, null];
|
|
26410
|
+
eventBinding = createListenerOp(job.root.xref, new SlotHandle(), event.name, null, makeListenerHandlerOps(job.root, event.handler, event.handlerSpan), phase, target, true, event.sourceSpan);
|
|
26411
|
+
}
|
|
26412
|
+
job.root.create.push(eventBinding);
|
|
26413
|
+
}
|
|
26414
|
+
/**
|
|
26415
|
+
* Ingest the nodes of a template AST into the given `ViewCompilation`.
|
|
26416
|
+
*/
|
|
26417
|
+
function ingestNodes(unit, template) {
|
|
26418
|
+
for (const node of template) {
|
|
26419
|
+
if (node instanceof Element$1) {
|
|
26420
|
+
ingestElement(unit, node);
|
|
26421
|
+
}
|
|
26422
|
+
else if (node instanceof Template) {
|
|
26423
|
+
ingestTemplate(unit, node);
|
|
26424
|
+
}
|
|
26425
|
+
else if (node instanceof Content) {
|
|
26426
|
+
ingestContent(unit, node);
|
|
26427
|
+
}
|
|
26428
|
+
else if (node instanceof Text$3) {
|
|
26429
|
+
ingestText(unit, node, null);
|
|
26430
|
+
}
|
|
26431
|
+
else if (node instanceof BoundText) {
|
|
26432
|
+
ingestBoundText(unit, node, null);
|
|
26433
|
+
}
|
|
26434
|
+
else if (node instanceof IfBlock) {
|
|
26435
|
+
ingestIfBlock(unit, node);
|
|
26436
|
+
}
|
|
26437
|
+
else if (node instanceof SwitchBlock) {
|
|
26438
|
+
ingestSwitchBlock(unit, node);
|
|
26439
|
+
}
|
|
26440
|
+
else if (node instanceof DeferredBlock) {
|
|
26441
|
+
ingestDeferBlock(unit, node);
|
|
26442
|
+
}
|
|
26443
|
+
else if (node instanceof Icu$1) {
|
|
26444
|
+
ingestIcu(unit, node);
|
|
26445
|
+
}
|
|
26446
|
+
else if (node instanceof ForLoopBlock) {
|
|
26447
|
+
ingestForBlock(unit, node);
|
|
26448
|
+
}
|
|
26449
|
+
else if (node instanceof LetDeclaration$1) {
|
|
26450
|
+
ingestLetDeclaration(unit, node);
|
|
26451
|
+
}
|
|
26452
|
+
else if (node instanceof Component$1) ;
|
|
26453
|
+
else {
|
|
26454
|
+
throw new Error(`Unsupported template node: ${node.constructor.name}`);
|
|
26455
|
+
}
|
|
26456
|
+
}
|
|
26457
|
+
}
|
|
26458
|
+
/**
|
|
26459
|
+
* Ingest an element AST from the template into the given `ViewCompilation`.
|
|
26460
|
+
*/
|
|
26461
|
+
function ingestElement(unit, element) {
|
|
26462
|
+
if (element.i18n !== undefined &&
|
|
26463
|
+
!(element.i18n instanceof Message || element.i18n instanceof TagPlaceholder)) {
|
|
26464
|
+
throw Error(`Unhandled i18n metadata type for element: ${element.i18n.constructor.name}`);
|
|
26465
|
+
}
|
|
26466
|
+
const id = unit.job.allocateXrefId();
|
|
26467
|
+
const [namespaceKey, elementName] = splitNsName$1(element.name);
|
|
26468
|
+
const startOp = createElementStartOp(elementName, id, namespaceForKey(namespaceKey), element.i18n instanceof TagPlaceholder ? element.i18n : undefined, element.startSourceSpan, element.sourceSpan);
|
|
26469
|
+
unit.create.push(startOp);
|
|
26470
|
+
ingestElementBindings(unit, startOp, element);
|
|
26471
|
+
ingestReferences(startOp, element);
|
|
26472
|
+
// Start i18n, if needed, goes after the element create and bindings, but before the nodes
|
|
26473
|
+
let i18nBlockId = null;
|
|
26474
|
+
if (element.i18n instanceof Message) {
|
|
26475
|
+
i18nBlockId = unit.job.allocateXrefId();
|
|
26476
|
+
unit.create.push(createI18nStartOp(i18nBlockId, element.i18n, undefined, element.startSourceSpan));
|
|
26477
|
+
}
|
|
26478
|
+
ingestNodes(unit, element.children);
|
|
26479
|
+
// The source span for the end op is typically the element closing tag. However, if no closing tag
|
|
26480
|
+
// exists, such as in `<input>`, we use the start source span instead. Usually the start and end
|
|
26481
|
+
// instructions will be collapsed into one `element` instruction, negating the purpose of this
|
|
26482
|
+
// fallback, but in cases when it is not collapsed (such as an input with a binding), we still
|
|
26483
|
+
// want to map the end instruction to the main element.
|
|
26484
|
+
const endOp = createElementEndOp(id, element.endSourceSpan ?? element.startSourceSpan);
|
|
26485
|
+
unit.create.push(endOp);
|
|
26486
|
+
// If there is an i18n message associated with this element, insert i18n start and end ops.
|
|
26487
|
+
if (i18nBlockId !== null) {
|
|
26488
|
+
OpList.insertBefore(createI18nEndOp(i18nBlockId, element.endSourceSpan ?? element.startSourceSpan), endOp);
|
|
26489
|
+
}
|
|
26490
|
+
}
|
|
26491
|
+
/**
|
|
26492
|
+
* Ingest an `ng-template` node from the AST into the given `ViewCompilation`.
|
|
26493
|
+
*/
|
|
26494
|
+
function ingestTemplate(unit, tmpl) {
|
|
26495
|
+
if (tmpl.i18n !== undefined &&
|
|
26496
|
+
!(tmpl.i18n instanceof Message || tmpl.i18n instanceof TagPlaceholder)) {
|
|
26497
|
+
throw Error(`Unhandled i18n metadata type for template: ${tmpl.i18n.constructor.name}`);
|
|
26498
|
+
}
|
|
26499
|
+
const childView = unit.job.allocateView(unit.xref);
|
|
26500
|
+
let tagNameWithoutNamespace = tmpl.tagName;
|
|
26501
|
+
let namespacePrefix = '';
|
|
26502
|
+
if (tmpl.tagName) {
|
|
26503
|
+
[namespacePrefix, tagNameWithoutNamespace] = splitNsName$1(tmpl.tagName);
|
|
26504
|
+
}
|
|
26505
|
+
const i18nPlaceholder = tmpl.i18n instanceof TagPlaceholder ? tmpl.i18n : undefined;
|
|
26506
|
+
const namespace = namespaceForKey(namespacePrefix);
|
|
26507
|
+
const functionNameSuffix = tagNameWithoutNamespace === null ? '' : prefixWithNamespace(tagNameWithoutNamespace, namespace);
|
|
26508
|
+
const templateKind = isPlainTemplate(tmpl)
|
|
26509
|
+
? TemplateKind.NgTemplate
|
|
26510
|
+
: TemplateKind.Structural;
|
|
26511
|
+
const templateOp = createTemplateOp(childView.xref, templateKind, tagNameWithoutNamespace, functionNameSuffix, namespace, i18nPlaceholder, tmpl.startSourceSpan, tmpl.sourceSpan);
|
|
26512
|
+
unit.create.push(templateOp);
|
|
26513
|
+
ingestTemplateBindings(unit, templateOp, tmpl, templateKind);
|
|
25923
26514
|
ingestReferences(templateOp, tmpl);
|
|
25924
26515
|
ingestNodes(childView, tmpl.children);
|
|
25925
26516
|
for (const { name, value } of tmpl.variables) {
|
|
@@ -26460,7 +27051,7 @@ const BINDING_KINDS = new Map([
|
|
|
26460
27051
|
* | `<ng-template *ngIf>` (structural) | null |
|
|
26461
27052
|
*/
|
|
26462
27053
|
function isPlainTemplate(tmpl) {
|
|
26463
|
-
return splitNsName(tmpl.tagName ?? '')[1] === NG_TEMPLATE_TAG_NAME;
|
|
27054
|
+
return splitNsName$1(tmpl.tagName ?? '')[1] === NG_TEMPLATE_TAG_NAME;
|
|
26464
27055
|
}
|
|
26465
27056
|
/**
|
|
26466
27057
|
* Ensures that the i18nMeta, if provided, is an i18n.Message.
|
|
@@ -26483,7 +27074,19 @@ function ingestElementBindings(unit, op, element) {
|
|
|
26483
27074
|
let i18nAttributeBindingNames = new Set();
|
|
26484
27075
|
for (const attr of element.attributes) {
|
|
26485
27076
|
// Attribute literal bindings, such as `attr.foo="bar"`.
|
|
26486
|
-
const
|
|
27077
|
+
const [ns, elementName] = splitNsName$1(element.name);
|
|
27078
|
+
let namespace = ns;
|
|
27079
|
+
if (!ns) {
|
|
27080
|
+
switch (op.namespace) {
|
|
27081
|
+
case Namespace.SVG:
|
|
27082
|
+
namespace = SVG_NAMESPACE$2;
|
|
27083
|
+
break;
|
|
27084
|
+
case Namespace.Math:
|
|
27085
|
+
namespace = MATH_ML_NAMESPACE$2;
|
|
27086
|
+
break;
|
|
27087
|
+
}
|
|
27088
|
+
}
|
|
27089
|
+
const securityContext = domSchema.securityContext(namespace ? `:${namespace}:${elementName}` : elementName, attr.name, true);
|
|
26487
27090
|
bindings.push(createBindingOp(op.xref, BindingKind.Attribute, attr.name, convertAstWithInterpolation(unit.job, attr.value, attr.i18n), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
|
|
26488
27091
|
if (attr.i18n) {
|
|
26489
27092
|
i18nAttributeBindingNames.add(attr.name);
|
|
@@ -26767,715 +27370,234 @@ function ingestControlFlowInsertionPoint(unit, xref, node) {
|
|
|
26767
27370
|
if (child instanceof Element$1 || (child instanceof Template && child.tagName !== null)) {
|
|
26768
27371
|
root = child;
|
|
26769
27372
|
}
|
|
26770
|
-
else {
|
|
26771
|
-
return null;
|
|
26772
|
-
}
|
|
26773
|
-
}
|
|
26774
|
-
// If we've found a single root node, its tag name and attributes can be
|
|
26775
|
-
// copied to the surrounding template to be used for content projection.
|
|
26776
|
-
if (root !== null) {
|
|
26777
|
-
// Collect the static attributes for content projection purposes.
|
|
26778
|
-
for (const attr of root.attributes) {
|
|
26779
|
-
if (!attr.name.startsWith(ANIMATE_PREFIX$1)) {
|
|
26780
|
-
const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
|
|
26781
|
-
unit.update.push(createBindingOp(xref, BindingKind.Attribute, attr.name, literal(attr.value), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
|
|
26782
|
-
}
|
|
26783
|
-
}
|
|
26784
|
-
// Also collect the inputs since they participate in content projection as well.
|
|
26785
|
-
// Note that TDB used to collect the outputs as well, but it wasn't passing them into
|
|
26786
|
-
// the template instruction. Here we just don't collect them.
|
|
26787
|
-
for (const attr of root.inputs) {
|
|
26788
|
-
if (attr.type !== BindingType.LegacyAnimation &&
|
|
26789
|
-
attr.type !== BindingType.Animation &&
|
|
26790
|
-
attr.type !== BindingType.Attribute) {
|
|
26791
|
-
const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
|
|
26792
|
-
unit.create.push(createExtractedAttributeOp(xref, BindingKind.Property, null, attr.name, null, null, null, securityContext));
|
|
26793
|
-
}
|
|
26794
|
-
}
|
|
26795
|
-
const tagName = root instanceof Element$1 ? root.name : root.tagName;
|
|
26796
|
-
// Don't pass along `ng-template` tag name since it enables directive matching.
|
|
26797
|
-
return tagName === NG_TEMPLATE_TAG_NAME ? null : tagName;
|
|
26798
|
-
}
|
|
26799
|
-
return null;
|
|
26800
|
-
}
|
|
26801
|
-
|
|
26802
|
-
/*!
|
|
26803
|
-
* @license
|
|
26804
|
-
* Copyright Google LLC All Rights Reserved.
|
|
26805
|
-
*
|
|
26806
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
26807
|
-
* found in the LICENSE file at https://angular.dev/license
|
|
26808
|
-
*/
|
|
26809
|
-
/**
|
|
26810
|
-
* Whether to produce instructions that will attach the source location to each DOM node.
|
|
26811
|
-
*
|
|
26812
|
-
* !!!Important!!! at the time of writing this flag isn't exposed externally, but internal debug
|
|
26813
|
-
* tools enable it via a local change. Any modifications to this flag need to update the
|
|
26814
|
-
* internal tooling as well.
|
|
26815
|
-
*/
|
|
26816
|
-
let ENABLE_TEMPLATE_SOURCE_LOCATIONS = false;
|
|
26817
|
-
/** Gets whether template source locations are enabled. */
|
|
26818
|
-
function getTemplateSourceLocationsEnabled() {
|
|
26819
|
-
return ENABLE_TEMPLATE_SOURCE_LOCATIONS;
|
|
26820
|
-
}
|
|
26821
|
-
|
|
26822
|
-
// if (rf & flags) { .. }
|
|
26823
|
-
function renderFlagCheckIfStmt(flags, statements) {
|
|
26824
|
-
return ifStmt(variable(RENDER_FLAGS).bitwiseAnd(literal(flags), null), statements);
|
|
26825
|
-
}
|
|
26826
|
-
/**
|
|
26827
|
-
* Translates query flags into `TQueryFlags` type in
|
|
26828
|
-
* packages/core/src/render3/interfaces/query.ts
|
|
26829
|
-
* @param query
|
|
26830
|
-
*/
|
|
26831
|
-
function toQueryFlags(query) {
|
|
26832
|
-
return ((query.descendants ? 1 /* QueryFlags.descendants */ : 0 /* QueryFlags.none */) |
|
|
26833
|
-
(query.static ? 2 /* QueryFlags.isStatic */ : 0 /* QueryFlags.none */) |
|
|
26834
|
-
(query.emitDistinctChangesOnly ? 4 /* QueryFlags.emitDistinctChangesOnly */ : 0 /* QueryFlags.none */));
|
|
26835
|
-
}
|
|
26836
|
-
function getQueryPredicate(query, constantPool) {
|
|
26837
|
-
if (Array.isArray(query.predicate)) {
|
|
26838
|
-
let predicate = [];
|
|
26839
|
-
query.predicate.forEach((selector) => {
|
|
26840
|
-
// Each item in predicates array may contain strings with comma-separated refs
|
|
26841
|
-
// (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
|
|
26842
|
-
// as separate array entities
|
|
26843
|
-
const selectors = selector.split(',').map((token) => literal(token.trim()));
|
|
26844
|
-
predicate.push(...selectors);
|
|
26845
|
-
});
|
|
26846
|
-
return constantPool.getConstLiteral(literalArr(predicate), true);
|
|
26847
|
-
}
|
|
26848
|
-
else {
|
|
26849
|
-
// The original predicate may have been wrapped in a `forwardRef()` call.
|
|
26850
|
-
switch (query.predicate.forwardRef) {
|
|
26851
|
-
case 0 /* ForwardRefHandling.None */:
|
|
26852
|
-
case 2 /* ForwardRefHandling.Unwrapped */:
|
|
26853
|
-
return query.predicate.expression;
|
|
26854
|
-
case 1 /* ForwardRefHandling.Wrapped */:
|
|
26855
|
-
return importExpr(Identifiers.resolveForwardRef).callFn([query.predicate.expression]);
|
|
26856
|
-
}
|
|
26857
|
-
}
|
|
26858
|
-
}
|
|
26859
|
-
function createQueryCreateCall(query, constantPool, queryTypeFns, prependParams) {
|
|
26860
|
-
const parameters = [];
|
|
26861
|
-
if (prependParams !== undefined) {
|
|
26862
|
-
parameters.push(...prependParams);
|
|
26863
|
-
}
|
|
26864
|
-
if (query.isSignal) {
|
|
26865
|
-
parameters.push(new ReadPropExpr(variable(CONTEXT_NAME), query.propertyName));
|
|
26866
|
-
}
|
|
26867
|
-
parameters.push(getQueryPredicate(query, constantPool), literal(toQueryFlags(query)));
|
|
26868
|
-
if (query.read) {
|
|
26869
|
-
parameters.push(query.read);
|
|
26870
|
-
}
|
|
26871
|
-
const queryCreateFn = query.isSignal ? queryTypeFns.signalBased : queryTypeFns.nonSignal;
|
|
26872
|
-
return importExpr(queryCreateFn).callFn(parameters);
|
|
26873
|
-
}
|
|
26874
|
-
const queryAdvancePlaceholder = Symbol('queryAdvancePlaceholder');
|
|
26875
|
-
/**
|
|
26876
|
-
* Collapses query advance placeholders in a list of statements.
|
|
26877
|
-
*
|
|
26878
|
-
* This allows for less generated code because multiple sibling query advance
|
|
26879
|
-
* statements can be collapsed into a single call with the count as argument.
|
|
26880
|
-
*
|
|
26881
|
-
* e.g.
|
|
26882
|
-
*
|
|
26883
|
-
* ```ts
|
|
26884
|
-
* bla();
|
|
26885
|
-
* queryAdvance();
|
|
26886
|
-
* queryAdvance();
|
|
26887
|
-
* bla();
|
|
26888
|
-
* ```
|
|
26889
|
-
*
|
|
26890
|
-
* --> will turn into
|
|
26891
|
-
*
|
|
26892
|
-
* ```ts
|
|
26893
|
-
* bla();
|
|
26894
|
-
* queryAdvance(2);
|
|
26895
|
-
* bla();
|
|
26896
|
-
* ```
|
|
26897
|
-
*/
|
|
26898
|
-
function collapseAdvanceStatements(statements) {
|
|
26899
|
-
const result = [];
|
|
26900
|
-
let advanceCollapseCount = 0;
|
|
26901
|
-
const flushAdvanceCount = () => {
|
|
26902
|
-
if (advanceCollapseCount > 0) {
|
|
26903
|
-
result.unshift(importExpr(Identifiers.queryAdvance)
|
|
26904
|
-
.callFn(advanceCollapseCount === 1 ? [] : [literal(advanceCollapseCount)])
|
|
26905
|
-
.toStmt());
|
|
26906
|
-
advanceCollapseCount = 0;
|
|
26907
|
-
}
|
|
26908
|
-
};
|
|
26909
|
-
// Iterate through statements in reverse and collapse advance placeholders.
|
|
26910
|
-
for (let i = statements.length - 1; i >= 0; i--) {
|
|
26911
|
-
const st = statements[i];
|
|
26912
|
-
if (st === queryAdvancePlaceholder) {
|
|
26913
|
-
advanceCollapseCount++;
|
|
26914
|
-
}
|
|
26915
|
-
else {
|
|
26916
|
-
flushAdvanceCount();
|
|
26917
|
-
result.unshift(st);
|
|
26918
|
-
}
|
|
26919
|
-
}
|
|
26920
|
-
flushAdvanceCount();
|
|
26921
|
-
return result;
|
|
26922
|
-
}
|
|
26923
|
-
// Define and update any view queries
|
|
26924
|
-
function createViewQueriesFunction(viewQueries, constantPool, name) {
|
|
26925
|
-
const createStatements = [];
|
|
26926
|
-
const updateStatements = [];
|
|
26927
|
-
const tempAllocator = temporaryAllocator((st) => updateStatements.push(st), TEMPORARY_NAME);
|
|
26928
|
-
viewQueries.forEach((query) => {
|
|
26929
|
-
// creation call, e.g. r3.viewQuery(somePredicate, true) or
|
|
26930
|
-
// r3.viewQuerySignal(ctx.prop, somePredicate, true);
|
|
26931
|
-
const queryDefinitionCall = createQueryCreateCall(query, constantPool, {
|
|
26932
|
-
signalBased: Identifiers.viewQuerySignal,
|
|
26933
|
-
nonSignal: Identifiers.viewQuery,
|
|
26934
|
-
});
|
|
26935
|
-
createStatements.push(queryDefinitionCall.toStmt());
|
|
26936
|
-
// Signal queries update lazily and we just advance the index.
|
|
26937
|
-
if (query.isSignal) {
|
|
26938
|
-
updateStatements.push(queryAdvancePlaceholder);
|
|
26939
|
-
return;
|
|
26940
|
-
}
|
|
26941
|
-
// update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
|
|
26942
|
-
const temporary = tempAllocator();
|
|
26943
|
-
const getQueryList = importExpr(Identifiers.loadQuery).callFn([]);
|
|
26944
|
-
const refresh = importExpr(Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
|
|
26945
|
-
const updateDirective = variable(CONTEXT_NAME)
|
|
26946
|
-
.prop(query.propertyName)
|
|
26947
|
-
.set(query.first ? temporary.prop('first') : temporary);
|
|
26948
|
-
updateStatements.push(refresh.and(updateDirective).toStmt());
|
|
26949
|
-
});
|
|
26950
|
-
const viewQueryFnName = name ? `${name}_Query` : null;
|
|
26951
|
-
return fn([new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], [
|
|
26952
|
-
renderFlagCheckIfStmt(1 /* core.RenderFlags.Create */, createStatements),
|
|
26953
|
-
renderFlagCheckIfStmt(2 /* core.RenderFlags.Update */, collapseAdvanceStatements(updateStatements)),
|
|
26954
|
-
], INFERRED_TYPE, null, viewQueryFnName);
|
|
26955
|
-
}
|
|
26956
|
-
// Define and update any content queries
|
|
26957
|
-
function createContentQueriesFunction(queries, constantPool, name) {
|
|
26958
|
-
const createStatements = [];
|
|
26959
|
-
const updateStatements = [];
|
|
26960
|
-
const tempAllocator = temporaryAllocator((st) => updateStatements.push(st), TEMPORARY_NAME);
|
|
26961
|
-
for (const query of queries) {
|
|
26962
|
-
// creation, e.g. r3.contentQuery(dirIndex, somePredicate, true, null) or
|
|
26963
|
-
// r3.contentQuerySignal(dirIndex, propName, somePredicate, <flags>, <read>).
|
|
26964
|
-
createStatements.push(createQueryCreateCall(query, constantPool, { nonSignal: Identifiers.contentQuery, signalBased: Identifiers.contentQuerySignal },
|
|
26965
|
-
/* prependParams */ [variable('dirIndex')]).toStmt());
|
|
26966
|
-
// Signal queries update lazily and we just advance the index.
|
|
26967
|
-
if (query.isSignal) {
|
|
26968
|
-
updateStatements.push(queryAdvancePlaceholder);
|
|
26969
|
-
continue;
|
|
26970
|
-
}
|
|
26971
|
-
// update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
|
|
26972
|
-
const temporary = tempAllocator();
|
|
26973
|
-
const getQueryList = importExpr(Identifiers.loadQuery).callFn([]);
|
|
26974
|
-
const refresh = importExpr(Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
|
|
26975
|
-
const updateDirective = variable(CONTEXT_NAME)
|
|
26976
|
-
.prop(query.propertyName)
|
|
26977
|
-
.set(query.first ? temporary.prop('first') : temporary);
|
|
26978
|
-
updateStatements.push(refresh.and(updateDirective).toStmt());
|
|
26979
|
-
}
|
|
26980
|
-
const contentQueriesFnName = name ? `${name}_ContentQueries` : null;
|
|
26981
|
-
return fn([
|
|
26982
|
-
new FnParam(RENDER_FLAGS, NUMBER_TYPE),
|
|
26983
|
-
new FnParam(CONTEXT_NAME, null),
|
|
26984
|
-
new FnParam('dirIndex', null),
|
|
26985
|
-
], [
|
|
26986
|
-
renderFlagCheckIfStmt(1 /* core.RenderFlags.Create */, createStatements),
|
|
26987
|
-
renderFlagCheckIfStmt(2 /* core.RenderFlags.Update */, collapseAdvanceStatements(updateStatements)),
|
|
26988
|
-
], INFERRED_TYPE, null, contentQueriesFnName);
|
|
26989
|
-
}
|
|
26990
|
-
|
|
26991
|
-
class HtmlParser extends Parser$1 {
|
|
26992
|
-
constructor() {
|
|
26993
|
-
super(getHtmlTagDefinition);
|
|
26994
|
-
}
|
|
26995
|
-
parse(source, url, options) {
|
|
26996
|
-
return super.parse(source, url, options);
|
|
26997
|
-
}
|
|
26998
|
-
}
|
|
26999
|
-
|
|
27000
|
-
const PROPERTY_PARTS_SEPARATOR = '.';
|
|
27001
|
-
const ATTRIBUTE_PREFIX = 'attr';
|
|
27002
|
-
const ANIMATE_PREFIX = 'animate';
|
|
27003
|
-
const CLASS_PREFIX = 'class';
|
|
27004
|
-
const STYLE_PREFIX = 'style';
|
|
27005
|
-
const TEMPLATE_ATTR_PREFIX$1 = '*';
|
|
27006
|
-
const LEGACY_ANIMATE_PROP_PREFIX = 'animate-';
|
|
27007
|
-
/**
|
|
27008
|
-
* Parses bindings in templates and in the directive host area.
|
|
27009
|
-
*/
|
|
27010
|
-
class BindingParser {
|
|
27011
|
-
_exprParser;
|
|
27012
|
-
_interpolationConfig;
|
|
27013
|
-
_schemaRegistry;
|
|
27014
|
-
errors;
|
|
27015
|
-
constructor(_exprParser, _interpolationConfig, _schemaRegistry, errors) {
|
|
27016
|
-
this._exprParser = _exprParser;
|
|
27017
|
-
this._interpolationConfig = _interpolationConfig;
|
|
27018
|
-
this._schemaRegistry = _schemaRegistry;
|
|
27019
|
-
this.errors = errors;
|
|
27020
|
-
}
|
|
27021
|
-
get interpolationConfig() {
|
|
27022
|
-
return this._interpolationConfig;
|
|
27023
|
-
}
|
|
27024
|
-
createBoundHostProperties(properties, sourceSpan) {
|
|
27025
|
-
const boundProps = [];
|
|
27026
|
-
for (const propName of Object.keys(properties)) {
|
|
27027
|
-
const expression = properties[propName];
|
|
27028
|
-
if (typeof expression === 'string') {
|
|
27029
|
-
this.parsePropertyBinding(propName, expression, true, false, sourceSpan, sourceSpan.start.offset, undefined, [],
|
|
27030
|
-
// Use the `sourceSpan` for `keySpan`. This isn't really accurate, but neither is the
|
|
27031
|
-
// sourceSpan, as it represents the sourceSpan of the host itself rather than the
|
|
27032
|
-
// source of the host binding (which doesn't exist in the template). Regardless,
|
|
27033
|
-
// neither of these values are used in Ivy but are only here to satisfy the function
|
|
27034
|
-
// signature. This should likely be refactored in the future so that `sourceSpan`
|
|
27035
|
-
// isn't being used inaccurately.
|
|
27036
|
-
boundProps, sourceSpan);
|
|
27037
|
-
}
|
|
27038
|
-
else {
|
|
27039
|
-
this._reportError(`Value of the host property binding "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, sourceSpan);
|
|
27040
|
-
}
|
|
27041
|
-
}
|
|
27042
|
-
return boundProps;
|
|
27043
|
-
}
|
|
27044
|
-
createDirectiveHostEventAsts(hostListeners, sourceSpan) {
|
|
27045
|
-
const targetEvents = [];
|
|
27046
|
-
for (const propName of Object.keys(hostListeners)) {
|
|
27047
|
-
const expression = hostListeners[propName];
|
|
27048
|
-
if (typeof expression === 'string') {
|
|
27049
|
-
// Use the `sourceSpan` for `keySpan` and `handlerSpan`. This isn't really accurate, but
|
|
27050
|
-
// neither is the `sourceSpan`, as it represents the `sourceSpan` of the host itself
|
|
27051
|
-
// rather than the source of the host binding (which doesn't exist in the template).
|
|
27052
|
-
// Regardless, neither of these values are used in Ivy but are only here to satisfy the
|
|
27053
|
-
// function signature. This should likely be refactored in the future so that `sourceSpan`
|
|
27054
|
-
// isn't being used inaccurately.
|
|
27055
|
-
this.parseEvent(propName, expression,
|
|
27056
|
-
/* isAssignmentEvent */ false, sourceSpan, sourceSpan, [], targetEvents, sourceSpan);
|
|
27057
|
-
}
|
|
27058
|
-
else {
|
|
27059
|
-
this._reportError(`Value of the host listener "${propName}" needs to be a string representing an expression but got "${expression}" (${typeof expression})`, sourceSpan);
|
|
27060
|
-
}
|
|
27061
|
-
}
|
|
27062
|
-
return targetEvents;
|
|
27063
|
-
}
|
|
27064
|
-
parseInterpolation(value, sourceSpan, interpolatedTokens) {
|
|
27065
|
-
const absoluteOffset = sourceSpan.fullStart.offset;
|
|
27066
|
-
try {
|
|
27067
|
-
const ast = this._exprParser.parseInterpolation(value, sourceSpan, absoluteOffset, interpolatedTokens, this._interpolationConfig);
|
|
27068
|
-
if (ast) {
|
|
27069
|
-
this.errors.push(...ast.errors);
|
|
27070
|
-
}
|
|
27071
|
-
return ast;
|
|
27072
|
-
}
|
|
27073
|
-
catch (e) {
|
|
27074
|
-
this._reportError(`${e}`, sourceSpan);
|
|
27075
|
-
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
27076
|
-
}
|
|
27077
|
-
}
|
|
27078
|
-
/**
|
|
27079
|
-
* Similar to `parseInterpolation`, but treats the provided string as a single expression
|
|
27080
|
-
* element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
|
|
27081
|
-
* This is used for parsing the switch expression in ICUs.
|
|
27082
|
-
*/
|
|
27083
|
-
parseInterpolationExpression(expression, sourceSpan) {
|
|
27084
|
-
const absoluteOffset = sourceSpan.start.offset;
|
|
27085
|
-
try {
|
|
27086
|
-
const ast = this._exprParser.parseInterpolationExpression(expression, sourceSpan, absoluteOffset);
|
|
27087
|
-
if (ast) {
|
|
27088
|
-
this.errors.push(...ast.errors);
|
|
27089
|
-
}
|
|
27090
|
-
return ast;
|
|
27091
|
-
}
|
|
27092
|
-
catch (e) {
|
|
27093
|
-
this._reportError(`${e}`, sourceSpan);
|
|
27094
|
-
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
27095
|
-
}
|
|
27096
|
-
}
|
|
27097
|
-
/**
|
|
27098
|
-
* Parses the bindings in a microsyntax expression, and converts them to
|
|
27099
|
-
* `ParsedProperty` or `ParsedVariable`.
|
|
27100
|
-
*
|
|
27101
|
-
* @param tplKey template binding name
|
|
27102
|
-
* @param tplValue template binding value
|
|
27103
|
-
* @param sourceSpan span of template binding relative to entire the template
|
|
27104
|
-
* @param absoluteValueOffset start of the tplValue relative to the entire template
|
|
27105
|
-
* @param targetMatchableAttrs potential attributes to match in the template
|
|
27106
|
-
* @param targetProps target property bindings in the template
|
|
27107
|
-
* @param targetVars target variables in the template
|
|
27108
|
-
*/
|
|
27109
|
-
parseInlineTemplateBinding(tplKey, tplValue, sourceSpan, absoluteValueOffset, targetMatchableAttrs, targetProps, targetVars, isIvyAst) {
|
|
27110
|
-
const absoluteKeyOffset = sourceSpan.start.offset + TEMPLATE_ATTR_PREFIX$1.length;
|
|
27111
|
-
const bindings = this._parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset);
|
|
27112
|
-
for (const binding of bindings) {
|
|
27113
|
-
// sourceSpan is for the entire HTML attribute. bindingSpan is for a particular
|
|
27114
|
-
// binding within the microsyntax expression so it's more narrow than sourceSpan.
|
|
27115
|
-
const bindingSpan = moveParseSourceSpan(sourceSpan, binding.sourceSpan);
|
|
27116
|
-
const key = binding.key.source;
|
|
27117
|
-
const keySpan = moveParseSourceSpan(sourceSpan, binding.key.span);
|
|
27118
|
-
if (binding instanceof VariableBinding) {
|
|
27119
|
-
const value = binding.value ? binding.value.source : '$implicit';
|
|
27120
|
-
const valueSpan = binding.value
|
|
27121
|
-
? moveParseSourceSpan(sourceSpan, binding.value.span)
|
|
27122
|
-
: undefined;
|
|
27123
|
-
targetVars.push(new ParsedVariable(key, value, bindingSpan, keySpan, valueSpan));
|
|
27124
|
-
}
|
|
27125
|
-
else if (binding.value) {
|
|
27126
|
-
const srcSpan = isIvyAst ? bindingSpan : sourceSpan;
|
|
27127
|
-
const valueSpan = moveParseSourceSpan(sourceSpan, binding.value.ast.sourceSpan);
|
|
27128
|
-
this._parsePropertyAst(key, binding.value, false, srcSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27129
|
-
}
|
|
27130
|
-
else {
|
|
27131
|
-
targetMatchableAttrs.push([key, '' /* value */]);
|
|
27132
|
-
// Since this is a literal attribute with no RHS, source span should be
|
|
27133
|
-
// just the key span.
|
|
27134
|
-
this.parseLiteralAttr(key, null /* value */, keySpan, absoluteValueOffset, undefined /* valueSpan */, targetMatchableAttrs, targetProps, keySpan);
|
|
27135
|
-
}
|
|
27136
|
-
}
|
|
27137
|
-
}
|
|
27138
|
-
/**
|
|
27139
|
-
* Parses the bindings in a microsyntax expression, e.g.
|
|
27140
|
-
* ```html
|
|
27141
|
-
* <tag *tplKey="let value1 = prop; let value2 = localVar">
|
|
27142
|
-
* ```
|
|
27143
|
-
*
|
|
27144
|
-
* @param tplKey template binding name
|
|
27145
|
-
* @param tplValue template binding value
|
|
27146
|
-
* @param sourceSpan span of template binding relative to entire the template
|
|
27147
|
-
* @param absoluteKeyOffset start of the `tplKey`
|
|
27148
|
-
* @param absoluteValueOffset start of the `tplValue`
|
|
27149
|
-
*/
|
|
27150
|
-
_parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset) {
|
|
27151
|
-
try {
|
|
27152
|
-
const bindingsResult = this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset);
|
|
27153
|
-
bindingsResult.errors.forEach((e) => this.errors.push(e));
|
|
27154
|
-
bindingsResult.warnings.forEach((warning) => {
|
|
27155
|
-
this._reportError(warning, sourceSpan, ParseErrorLevel.WARNING);
|
|
27156
|
-
});
|
|
27157
|
-
return bindingsResult.templateBindings;
|
|
27158
|
-
}
|
|
27159
|
-
catch (e) {
|
|
27160
|
-
this._reportError(`${e}`, sourceSpan);
|
|
27161
|
-
return [];
|
|
27162
|
-
}
|
|
27163
|
-
}
|
|
27164
|
-
parseLiteralAttr(name, value, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
|
|
27165
|
-
if (isLegacyAnimationLabel(name)) {
|
|
27166
|
-
name = name.substring(1);
|
|
27167
|
-
if (keySpan !== undefined) {
|
|
27168
|
-
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
|
27169
|
-
}
|
|
27170
|
-
if (value) {
|
|
27171
|
-
this._reportError(`Assigning animation triggers via @prop="exp" attributes with an expression is invalid.` +
|
|
27172
|
-
` Use property bindings (e.g. [@prop]="exp") or use an attribute without a value (e.g. @prop) instead.`, sourceSpan, ParseErrorLevel.ERROR);
|
|
27173
|
-
}
|
|
27174
|
-
this._parseLegacyAnimation(name, value, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27175
|
-
}
|
|
27176
|
-
else {
|
|
27177
|
-
targetProps.push(new ParsedProperty(name, this._exprParser.wrapLiteralPrimitive(value, '', absoluteOffset), ParsedPropertyType.LITERAL_ATTR, sourceSpan, keySpan, valueSpan));
|
|
27178
|
-
}
|
|
27179
|
-
}
|
|
27180
|
-
parsePropertyBinding(name, expression, isHost, isPartOfAssignmentBinding, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
|
|
27181
|
-
if (name.length === 0) {
|
|
27182
|
-
this._reportError(`Property name is missing in binding`, sourceSpan);
|
|
27183
|
-
}
|
|
27184
|
-
let isLegacyAnimationProp = false;
|
|
27185
|
-
if (name.startsWith(LEGACY_ANIMATE_PROP_PREFIX)) {
|
|
27186
|
-
isLegacyAnimationProp = true;
|
|
27187
|
-
name = name.substring(LEGACY_ANIMATE_PROP_PREFIX.length);
|
|
27188
|
-
if (keySpan !== undefined) {
|
|
27189
|
-
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + LEGACY_ANIMATE_PROP_PREFIX.length, keySpan.end.offset));
|
|
27190
|
-
}
|
|
27191
|
-
}
|
|
27192
|
-
else if (isLegacyAnimationLabel(name)) {
|
|
27193
|
-
isLegacyAnimationProp = true;
|
|
27194
|
-
name = name.substring(1);
|
|
27195
|
-
if (keySpan !== undefined) {
|
|
27196
|
-
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
|
27197
|
-
}
|
|
27198
|
-
}
|
|
27199
|
-
if (isLegacyAnimationProp) {
|
|
27200
|
-
this._parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27201
|
-
}
|
|
27202
|
-
else if (name.startsWith(`${ANIMATE_PREFIX}${PROPERTY_PARTS_SEPARATOR}`)) {
|
|
27203
|
-
this._parseAnimation(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27204
|
-
}
|
|
27205
|
-
else {
|
|
27206
|
-
this._parsePropertyAst(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27207
|
-
}
|
|
27208
|
-
}
|
|
27209
|
-
parsePropertyInterpolation(name, value, sourceSpan, valueSpan, targetMatchableAttrs, targetProps, keySpan, interpolatedTokens) {
|
|
27210
|
-
const expr = this.parseInterpolation(value, valueSpan || sourceSpan, interpolatedTokens);
|
|
27211
|
-
if (expr) {
|
|
27212
|
-
this._parsePropertyAst(name, expr, false, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27213
|
-
return true;
|
|
27214
|
-
}
|
|
27215
|
-
return false;
|
|
27216
|
-
}
|
|
27217
|
-
_parsePropertyAst(name, ast, isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
27218
|
-
targetMatchableAttrs.push([name, ast.source]);
|
|
27219
|
-
targetProps.push(new ParsedProperty(name, ast, isPartOfAssignmentBinding ? ParsedPropertyType.TWO_WAY : ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
|
|
27220
|
-
}
|
|
27221
|
-
_parseAnimation(name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
27222
|
-
targetMatchableAttrs.push([name, ast.source]);
|
|
27223
|
-
targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan));
|
|
27224
|
-
}
|
|
27225
|
-
_parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
27226
|
-
if (name.length === 0) {
|
|
27227
|
-
this._reportError('Animation trigger is missing', sourceSpan);
|
|
27228
|
-
}
|
|
27229
|
-
// This will occur when a @trigger is not paired with an expression.
|
|
27230
|
-
// For animations it is valid to not have an expression since */void
|
|
27231
|
-
// states will be applied by angular when the element is attached/detached
|
|
27232
|
-
const ast = this.parseBinding(expression || 'undefined', false, valueSpan || sourceSpan, absoluteOffset);
|
|
27233
|
-
targetMatchableAttrs.push([name, ast.source]);
|
|
27234
|
-
targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.LEGACY_ANIMATION, sourceSpan, keySpan, valueSpan));
|
|
27235
|
-
}
|
|
27236
|
-
parseBinding(value, isHostBinding, sourceSpan, absoluteOffset) {
|
|
27237
|
-
try {
|
|
27238
|
-
const ast = isHostBinding
|
|
27239
|
-
? this._exprParser.parseSimpleBinding(value, sourceSpan, absoluteOffset, this._interpolationConfig)
|
|
27240
|
-
: this._exprParser.parseBinding(value, sourceSpan, absoluteOffset, this._interpolationConfig);
|
|
27241
|
-
if (ast) {
|
|
27242
|
-
this.errors.push(...ast.errors);
|
|
27243
|
-
}
|
|
27244
|
-
return ast;
|
|
27245
|
-
}
|
|
27246
|
-
catch (e) {
|
|
27247
|
-
this._reportError(`${e}`, sourceSpan);
|
|
27248
|
-
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
27249
|
-
}
|
|
27250
|
-
}
|
|
27251
|
-
createBoundElementProperty(elementSelector, boundProp, skipValidation = false, mapPropertyName = true) {
|
|
27252
|
-
if (boundProp.isLegacyAnimation) {
|
|
27253
|
-
return new BoundElementProperty(boundProp.name, BindingType.LegacyAnimation, SecurityContext$1.NONE, boundProp.expression, null, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
|
|
27254
|
-
}
|
|
27255
|
-
let unit = null;
|
|
27256
|
-
let bindingType = undefined;
|
|
27257
|
-
let boundPropertyName = null;
|
|
27258
|
-
const parts = boundProp.name.split(PROPERTY_PARTS_SEPARATOR);
|
|
27259
|
-
let securityContexts = undefined;
|
|
27260
|
-
// Check for special cases (prefix style, attr, class)
|
|
27261
|
-
if (parts.length > 1) {
|
|
27262
|
-
if (parts[0] == ATTRIBUTE_PREFIX) {
|
|
27263
|
-
boundPropertyName = parts.slice(1).join(PROPERTY_PARTS_SEPARATOR);
|
|
27264
|
-
if (!skipValidation) {
|
|
27265
|
-
this._validatePropertyOrAttributeName(boundPropertyName, boundProp.sourceSpan, true);
|
|
27266
|
-
}
|
|
27267
|
-
securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, boundPropertyName, true);
|
|
27268
|
-
const nsSeparatorIdx = boundPropertyName.indexOf(':');
|
|
27269
|
-
if (nsSeparatorIdx > -1) {
|
|
27270
|
-
const ns = boundPropertyName.substring(0, nsSeparatorIdx);
|
|
27271
|
-
const name = boundPropertyName.substring(nsSeparatorIdx + 1);
|
|
27272
|
-
boundPropertyName = mergeNsAndName(ns, name);
|
|
27273
|
-
}
|
|
27274
|
-
bindingType = BindingType.Attribute;
|
|
27275
|
-
}
|
|
27276
|
-
else if (parts[0] == CLASS_PREFIX) {
|
|
27277
|
-
boundPropertyName = parts[1];
|
|
27278
|
-
bindingType = BindingType.Class;
|
|
27279
|
-
securityContexts = [SecurityContext$1.NONE];
|
|
27280
|
-
}
|
|
27281
|
-
else if (parts[0] == STYLE_PREFIX) {
|
|
27282
|
-
unit = parts.length > 2 ? parts[2] : null;
|
|
27283
|
-
boundPropertyName = parts[1];
|
|
27284
|
-
bindingType = BindingType.Style;
|
|
27285
|
-
securityContexts = [SecurityContext$1.STYLE];
|
|
27286
|
-
}
|
|
27287
|
-
else if (parts[0] == ANIMATE_PREFIX) {
|
|
27288
|
-
boundPropertyName = boundProp.name;
|
|
27289
|
-
bindingType = BindingType.Animation;
|
|
27290
|
-
securityContexts = [SecurityContext$1.NONE];
|
|
27291
|
-
}
|
|
27292
|
-
}
|
|
27293
|
-
// If not a special case, use the full property name
|
|
27294
|
-
if (boundPropertyName === null) {
|
|
27295
|
-
const mappedPropName = this._schemaRegistry.getMappedPropName(boundProp.name);
|
|
27296
|
-
boundPropertyName = mapPropertyName ? mappedPropName : boundProp.name;
|
|
27297
|
-
securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, mappedPropName, false);
|
|
27298
|
-
bindingType =
|
|
27299
|
-
boundProp.type === ParsedPropertyType.TWO_WAY ? BindingType.TwoWay : BindingType.Property;
|
|
27300
|
-
if (!skipValidation) {
|
|
27301
|
-
this._validatePropertyOrAttributeName(mappedPropName, boundProp.sourceSpan, false);
|
|
27302
|
-
}
|
|
27303
|
-
}
|
|
27304
|
-
return new BoundElementProperty(boundPropertyName, bindingType, securityContexts[0], boundProp.expression, unit, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
|
|
27305
|
-
}
|
|
27306
|
-
parseEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
|
|
27307
|
-
if (name.length === 0) {
|
|
27308
|
-
this._reportError(`Event name is missing in binding`, sourceSpan);
|
|
27309
|
-
}
|
|
27310
|
-
if (isLegacyAnimationLabel(name)) {
|
|
27311
|
-
name = name.slice(1);
|
|
27312
|
-
if (keySpan !== undefined) {
|
|
27313
|
-
keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
|
27314
|
-
}
|
|
27315
|
-
this._parseLegacyAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan);
|
|
27316
|
-
}
|
|
27317
|
-
else {
|
|
27318
|
-
this._parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan);
|
|
27319
|
-
}
|
|
27320
|
-
}
|
|
27321
|
-
calcPossibleSecurityContexts(selector, propName, isAttribute) {
|
|
27322
|
-
const prop = this._schemaRegistry.getMappedPropName(propName);
|
|
27323
|
-
return calcPossibleSecurityContexts(this._schemaRegistry, selector, prop, isAttribute);
|
|
27324
|
-
}
|
|
27325
|
-
parseEventListenerName(rawName) {
|
|
27326
|
-
const [target, eventName] = splitAtColon(rawName, [null, rawName]);
|
|
27327
|
-
return { eventName: eventName, target };
|
|
27328
|
-
}
|
|
27329
|
-
parseLegacyAnimationEventName(rawName) {
|
|
27330
|
-
const matches = splitAtPeriod(rawName, [rawName, null]);
|
|
27331
|
-
return { eventName: matches[0], phase: matches[1] === null ? null : matches[1].toLowerCase() };
|
|
27332
|
-
}
|
|
27333
|
-
_parseLegacyAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan) {
|
|
27334
|
-
const { eventName, phase } = this.parseLegacyAnimationEventName(name);
|
|
27335
|
-
const ast = this._parseAction(expression, handlerSpan);
|
|
27336
|
-
targetEvents.push(new ParsedEvent(eventName, phase, ParsedEventType.LegacyAnimation, ast, sourceSpan, handlerSpan, keySpan));
|
|
27337
|
-
if (eventName.length === 0) {
|
|
27338
|
-
this._reportError(`Animation event name is missing in binding`, sourceSpan);
|
|
27339
|
-
}
|
|
27340
|
-
if (phase) {
|
|
27341
|
-
if (phase !== 'start' && phase !== 'done') {
|
|
27342
|
-
this._reportError(`The provided animation output phase value "${phase}" for "@${eventName}" is not supported (use start or done)`, sourceSpan);
|
|
27343
|
-
}
|
|
27344
|
-
}
|
|
27345
|
-
else {
|
|
27346
|
-
this._reportError(`The animation trigger output event (@${eventName}) is missing its phase value name (start or done are currently supported)`, sourceSpan);
|
|
27347
|
-
}
|
|
27348
|
-
}
|
|
27349
|
-
_parseRegularEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
|
|
27350
|
-
// long format: 'target: eventName'
|
|
27351
|
-
const { eventName, target } = this.parseEventListenerName(name);
|
|
27352
|
-
const prevErrorCount = this.errors.length;
|
|
27353
|
-
const ast = this._parseAction(expression, handlerSpan);
|
|
27354
|
-
const isValid = this.errors.length === prevErrorCount;
|
|
27355
|
-
targetMatchableAttrs.push([name, ast.source]);
|
|
27356
|
-
// Don't try to validate assignment events if there were other
|
|
27357
|
-
// parsing errors to avoid adding more noise to the error logs.
|
|
27358
|
-
if (isAssignmentEvent && isValid && !this._isAllowedAssignmentEvent(ast)) {
|
|
27359
|
-
this._reportError('Unsupported expression in a two-way binding', sourceSpan);
|
|
27360
|
-
}
|
|
27361
|
-
let eventType = ParsedEventType.Regular;
|
|
27362
|
-
if (isAssignmentEvent) {
|
|
27363
|
-
eventType = ParsedEventType.TwoWay;
|
|
27364
|
-
}
|
|
27365
|
-
if (name.startsWith(`${ANIMATE_PREFIX}${PROPERTY_PARTS_SEPARATOR}`)) {
|
|
27366
|
-
eventType = ParsedEventType.Animation;
|
|
27373
|
+
else {
|
|
27374
|
+
return null;
|
|
27367
27375
|
}
|
|
27368
|
-
targetEvents.push(new ParsedEvent(eventName, target, eventType, ast, sourceSpan, handlerSpan, keySpan));
|
|
27369
|
-
// Don't detect directives for event names for now,
|
|
27370
|
-
// so don't add the event name to the matchableAttrs
|
|
27371
27376
|
}
|
|
27372
|
-
|
|
27373
|
-
|
|
27374
|
-
|
|
27375
|
-
|
|
27376
|
-
|
|
27377
|
-
|
|
27378
|
-
|
|
27379
|
-
|
|
27380
|
-
this._reportError(`Empty expressions are not allowed`, sourceSpan);
|
|
27381
|
-
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
|
|
27377
|
+
// If we've found a single root node, its tag name and attributes can be
|
|
27378
|
+
// copied to the surrounding template to be used for content projection.
|
|
27379
|
+
if (root !== null) {
|
|
27380
|
+
// Collect the static attributes for content projection purposes.
|
|
27381
|
+
for (const attr of root.attributes) {
|
|
27382
|
+
if (!attr.name.startsWith(ANIMATE_PREFIX)) {
|
|
27383
|
+
const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
|
|
27384
|
+
unit.update.push(createBindingOp(xref, BindingKind.Attribute, attr.name, literal(attr.value), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
|
|
27382
27385
|
}
|
|
27383
|
-
return ast;
|
|
27384
27386
|
}
|
|
27385
|
-
|
|
27386
|
-
|
|
27387
|
-
|
|
27387
|
+
// Also collect the inputs since they participate in content projection as well.
|
|
27388
|
+
// Note that TDB used to collect the outputs as well, but it wasn't passing them into
|
|
27389
|
+
// the template instruction. Here we just don't collect them.
|
|
27390
|
+
for (const attr of root.inputs) {
|
|
27391
|
+
if (attr.type !== BindingType.LegacyAnimation &&
|
|
27392
|
+
attr.type !== BindingType.Animation &&
|
|
27393
|
+
attr.type !== BindingType.Attribute) {
|
|
27394
|
+
const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
|
|
27395
|
+
unit.create.push(createExtractedAttributeOp(xref, BindingKind.Property, null, attr.name, null, null, null, securityContext));
|
|
27396
|
+
}
|
|
27388
27397
|
}
|
|
27398
|
+
const tagName = root instanceof Element$1 ? root.name : root.tagName;
|
|
27399
|
+
// Don't pass along `ng-template` tag name since it enables directive matching.
|
|
27400
|
+
return tagName === NG_TEMPLATE_TAG_NAME ? null : tagName;
|
|
27389
27401
|
}
|
|
27390
|
-
|
|
27391
|
-
|
|
27392
|
-
|
|
27393
|
-
|
|
27394
|
-
|
|
27395
|
-
|
|
27396
|
-
|
|
27397
|
-
|
|
27398
|
-
|
|
27399
|
-
|
|
27400
|
-
|
|
27401
|
-
|
|
27402
|
-
|
|
27403
|
-
|
|
27404
|
-
|
|
27402
|
+
return null;
|
|
27403
|
+
}
|
|
27404
|
+
|
|
27405
|
+
/*!
|
|
27406
|
+
* @license
|
|
27407
|
+
* Copyright Google LLC All Rights Reserved.
|
|
27408
|
+
*
|
|
27409
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
27410
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
27411
|
+
*/
|
|
27412
|
+
/**
|
|
27413
|
+
* Whether to produce instructions that will attach the source location to each DOM node.
|
|
27414
|
+
*
|
|
27415
|
+
* !!!Important!!! at the time of writing this flag isn't exposed externally, but internal debug
|
|
27416
|
+
* tools enable it via a local change. Any modifications to this flag need to update the
|
|
27417
|
+
* internal tooling as well.
|
|
27418
|
+
*/
|
|
27419
|
+
let ENABLE_TEMPLATE_SOURCE_LOCATIONS = false;
|
|
27420
|
+
/** Gets whether template source locations are enabled. */
|
|
27421
|
+
function getTemplateSourceLocationsEnabled() {
|
|
27422
|
+
return ENABLE_TEMPLATE_SOURCE_LOCATIONS;
|
|
27423
|
+
}
|
|
27424
|
+
|
|
27425
|
+
// if (rf & flags) { .. }
|
|
27426
|
+
function renderFlagCheckIfStmt(flags, statements) {
|
|
27427
|
+
return ifStmt(variable(RENDER_FLAGS).bitwiseAnd(literal(flags), null), statements);
|
|
27428
|
+
}
|
|
27429
|
+
/**
|
|
27430
|
+
* Translates query flags into `TQueryFlags` type in
|
|
27431
|
+
* packages/core/src/render3/interfaces/query.ts
|
|
27432
|
+
* @param query
|
|
27433
|
+
*/
|
|
27434
|
+
function toQueryFlags(query) {
|
|
27435
|
+
return ((query.descendants ? 1 /* QueryFlags.descendants */ : 0 /* QueryFlags.none */) |
|
|
27436
|
+
(query.static ? 2 /* QueryFlags.isStatic */ : 0 /* QueryFlags.none */) |
|
|
27437
|
+
(query.emitDistinctChangesOnly ? 4 /* QueryFlags.emitDistinctChangesOnly */ : 0 /* QueryFlags.none */));
|
|
27438
|
+
}
|
|
27439
|
+
function getQueryPredicate(query, constantPool) {
|
|
27440
|
+
if (Array.isArray(query.predicate)) {
|
|
27441
|
+
let predicate = [];
|
|
27442
|
+
query.predicate.forEach((selector) => {
|
|
27443
|
+
// Each item in predicates array may contain strings with comma-separated refs
|
|
27444
|
+
// (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
|
|
27445
|
+
// as separate array entities
|
|
27446
|
+
const selectors = selector.split(',').map((token) => literal(token.trim()));
|
|
27447
|
+
predicate.push(...selectors);
|
|
27448
|
+
});
|
|
27449
|
+
return constantPool.getConstLiteral(literalArr(predicate), true);
|
|
27405
27450
|
}
|
|
27406
|
-
|
|
27407
|
-
|
|
27408
|
-
|
|
27409
|
-
|
|
27410
|
-
|
|
27411
|
-
|
|
27412
|
-
|
|
27413
|
-
|
|
27414
|
-
if (ast instanceof NonNullAssert) {
|
|
27415
|
-
return this._isAllowedAssignmentEvent(ast.expression);
|
|
27416
|
-
}
|
|
27417
|
-
if (ast instanceof Call &&
|
|
27418
|
-
ast.args.length === 1 &&
|
|
27419
|
-
ast.receiver instanceof PropertyRead &&
|
|
27420
|
-
ast.receiver.name === '$any' &&
|
|
27421
|
-
ast.receiver.receiver instanceof ImplicitReceiver &&
|
|
27422
|
-
!(ast.receiver.receiver instanceof ThisReceiver)) {
|
|
27423
|
-
return this._isAllowedAssignmentEvent(ast.args[0]);
|
|
27424
|
-
}
|
|
27425
|
-
if (ast instanceof PropertyRead || ast instanceof KeyedRead) {
|
|
27426
|
-
if (!hasRecursiveSafeReceiver(ast)) {
|
|
27427
|
-
return true;
|
|
27428
|
-
}
|
|
27451
|
+
else {
|
|
27452
|
+
// The original predicate may have been wrapped in a `forwardRef()` call.
|
|
27453
|
+
switch (query.predicate.forwardRef) {
|
|
27454
|
+
case 0 /* ForwardRefHandling.None */:
|
|
27455
|
+
case 2 /* ForwardRefHandling.Unwrapped */:
|
|
27456
|
+
return query.predicate.expression;
|
|
27457
|
+
case 1 /* ForwardRefHandling.Wrapped */:
|
|
27458
|
+
return importExpr(Identifiers.resolveForwardRef).callFn([query.predicate.expression]);
|
|
27429
27459
|
}
|
|
27430
|
-
return false;
|
|
27431
27460
|
}
|
|
27432
27461
|
}
|
|
27433
|
-
function
|
|
27434
|
-
|
|
27435
|
-
|
|
27462
|
+
function createQueryCreateCall(query, constantPool, queryTypeFns, prependParams) {
|
|
27463
|
+
const parameters = [];
|
|
27464
|
+
if (prependParams !== undefined) {
|
|
27465
|
+
parameters.push(...prependParams);
|
|
27436
27466
|
}
|
|
27437
|
-
if (
|
|
27438
|
-
|
|
27467
|
+
if (query.isSignal) {
|
|
27468
|
+
parameters.push(new ReadPropExpr(variable(CONTEXT_NAME), query.propertyName));
|
|
27439
27469
|
}
|
|
27440
|
-
|
|
27441
|
-
|
|
27470
|
+
parameters.push(getQueryPredicate(query, constantPool), literal(toQueryFlags(query)));
|
|
27471
|
+
if (query.read) {
|
|
27472
|
+
parameters.push(query.read);
|
|
27442
27473
|
}
|
|
27443
|
-
|
|
27444
|
-
|
|
27445
|
-
function isLegacyAnimationLabel(name) {
|
|
27446
|
-
return name[0] == '@';
|
|
27474
|
+
const queryCreateFn = query.isSignal ? queryTypeFns.signalBased : queryTypeFns.nonSignal;
|
|
27475
|
+
return importExpr(queryCreateFn).callFn(parameters);
|
|
27447
27476
|
}
|
|
27448
|
-
|
|
27449
|
-
|
|
27450
|
-
|
|
27451
|
-
|
|
27452
|
-
|
|
27477
|
+
const queryAdvancePlaceholder = Symbol('queryAdvancePlaceholder');
|
|
27478
|
+
/**
|
|
27479
|
+
* Collapses query advance placeholders in a list of statements.
|
|
27480
|
+
*
|
|
27481
|
+
* This allows for less generated code because multiple sibling query advance
|
|
27482
|
+
* statements can be collapsed into a single call with the count as argument.
|
|
27483
|
+
*
|
|
27484
|
+
* e.g.
|
|
27485
|
+
*
|
|
27486
|
+
* ```ts
|
|
27487
|
+
* bla();
|
|
27488
|
+
* queryAdvance();
|
|
27489
|
+
* queryAdvance();
|
|
27490
|
+
* bla();
|
|
27491
|
+
* ```
|
|
27492
|
+
*
|
|
27493
|
+
* --> will turn into
|
|
27494
|
+
*
|
|
27495
|
+
* ```ts
|
|
27496
|
+
* bla();
|
|
27497
|
+
* queryAdvance(2);
|
|
27498
|
+
* bla();
|
|
27499
|
+
* ```
|
|
27500
|
+
*/
|
|
27501
|
+
function collapseAdvanceStatements(statements) {
|
|
27502
|
+
const result = [];
|
|
27503
|
+
let advanceCollapseCount = 0;
|
|
27504
|
+
const flushAdvanceCount = () => {
|
|
27505
|
+
if (advanceCollapseCount > 0) {
|
|
27506
|
+
result.unshift(importExpr(Identifiers.queryAdvance)
|
|
27507
|
+
.callFn(advanceCollapseCount === 1 ? [] : [literal(advanceCollapseCount)])
|
|
27508
|
+
.toStmt());
|
|
27509
|
+
advanceCollapseCount = 0;
|
|
27510
|
+
}
|
|
27511
|
+
};
|
|
27512
|
+
// Iterate through statements in reverse and collapse advance placeholders.
|
|
27513
|
+
for (let i = statements.length - 1; i >= 0; i--) {
|
|
27514
|
+
const st = statements[i];
|
|
27515
|
+
if (st === queryAdvancePlaceholder) {
|
|
27516
|
+
advanceCollapseCount++;
|
|
27517
|
+
}
|
|
27518
|
+
else {
|
|
27519
|
+
flushAdvanceCount();
|
|
27520
|
+
result.unshift(st);
|
|
27521
|
+
}
|
|
27453
27522
|
}
|
|
27454
|
-
|
|
27455
|
-
|
|
27456
|
-
|
|
27457
|
-
|
|
27458
|
-
|
|
27459
|
-
|
|
27460
|
-
|
|
27461
|
-
|
|
27462
|
-
|
|
27523
|
+
flushAdvanceCount();
|
|
27524
|
+
return result;
|
|
27525
|
+
}
|
|
27526
|
+
// Define and update any view queries
|
|
27527
|
+
function createViewQueriesFunction(viewQueries, constantPool, name) {
|
|
27528
|
+
const createStatements = [];
|
|
27529
|
+
const updateStatements = [];
|
|
27530
|
+
const tempAllocator = temporaryAllocator((st) => updateStatements.push(st), TEMPORARY_NAME);
|
|
27531
|
+
viewQueries.forEach((query) => {
|
|
27532
|
+
// creation call, e.g. r3.viewQuery(somePredicate, true) or
|
|
27533
|
+
// r3.viewQuerySignal(ctx.prop, somePredicate, true);
|
|
27534
|
+
const queryDefinitionCall = createQueryCreateCall(query, constantPool, {
|
|
27535
|
+
signalBased: Identifiers.viewQuerySignal,
|
|
27536
|
+
nonSignal: Identifiers.viewQuery,
|
|
27463
27537
|
});
|
|
27538
|
+
createStatements.push(queryDefinitionCall.toStmt());
|
|
27539
|
+
// Signal queries update lazily and we just advance the index.
|
|
27540
|
+
if (query.isSignal) {
|
|
27541
|
+
updateStatements.push(queryAdvancePlaceholder);
|
|
27542
|
+
return;
|
|
27543
|
+
}
|
|
27544
|
+
// update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
|
|
27545
|
+
const temporary = tempAllocator();
|
|
27546
|
+
const getQueryList = importExpr(Identifiers.loadQuery).callFn([]);
|
|
27547
|
+
const refresh = importExpr(Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
|
|
27548
|
+
const updateDirective = variable(CONTEXT_NAME)
|
|
27549
|
+
.prop(query.propertyName)
|
|
27550
|
+
.set(query.first ? temporary.prop('first') : temporary);
|
|
27551
|
+
updateStatements.push(refresh.and(updateDirective).toStmt());
|
|
27552
|
+
});
|
|
27553
|
+
const viewQueryFnName = name ? `${name}_Query` : null;
|
|
27554
|
+
return fn([new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], [
|
|
27555
|
+
renderFlagCheckIfStmt(1 /* core.RenderFlags.Create */, createStatements),
|
|
27556
|
+
renderFlagCheckIfStmt(2 /* core.RenderFlags.Update */, collapseAdvanceStatements(updateStatements)),
|
|
27557
|
+
], INFERRED_TYPE, null, viewQueryFnName);
|
|
27558
|
+
}
|
|
27559
|
+
// Define and update any content queries
|
|
27560
|
+
function createContentQueriesFunction(queries, constantPool, name) {
|
|
27561
|
+
const createStatements = [];
|
|
27562
|
+
const updateStatements = [];
|
|
27563
|
+
const tempAllocator = temporaryAllocator((st) => updateStatements.push(st), TEMPORARY_NAME);
|
|
27564
|
+
for (const query of queries) {
|
|
27565
|
+
// creation, e.g. r3.contentQuery(dirIndex, somePredicate, true, null) or
|
|
27566
|
+
// r3.contentQuerySignal(dirIndex, propName, somePredicate, <flags>, <read>).
|
|
27567
|
+
createStatements.push(createQueryCreateCall(query, constantPool, { nonSignal: Identifiers.contentQuery, signalBased: Identifiers.contentQuerySignal },
|
|
27568
|
+
/* prependParams */ [variable('dirIndex')]).toStmt());
|
|
27569
|
+
// Signal queries update lazily and we just advance the index.
|
|
27570
|
+
if (query.isSignal) {
|
|
27571
|
+
updateStatements.push(queryAdvancePlaceholder);
|
|
27572
|
+
continue;
|
|
27573
|
+
}
|
|
27574
|
+
// update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
|
|
27575
|
+
const temporary = tempAllocator();
|
|
27576
|
+
const getQueryList = importExpr(Identifiers.loadQuery).callFn([]);
|
|
27577
|
+
const refresh = importExpr(Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
|
|
27578
|
+
const updateDirective = variable(CONTEXT_NAME)
|
|
27579
|
+
.prop(query.propertyName)
|
|
27580
|
+
.set(query.first ? temporary.prop('first') : temporary);
|
|
27581
|
+
updateStatements.push(refresh.and(updateDirective).toStmt());
|
|
27464
27582
|
}
|
|
27465
|
-
|
|
27583
|
+
const contentQueriesFnName = name ? `${name}_ContentQueries` : null;
|
|
27584
|
+
return fn([
|
|
27585
|
+
new FnParam(RENDER_FLAGS, NUMBER_TYPE),
|
|
27586
|
+
new FnParam(CONTEXT_NAME, null),
|
|
27587
|
+
new FnParam('dirIndex', null),
|
|
27588
|
+
], [
|
|
27589
|
+
renderFlagCheckIfStmt(1 /* core.RenderFlags.Create */, createStatements),
|
|
27590
|
+
renderFlagCheckIfStmt(2 /* core.RenderFlags.Update */, collapseAdvanceStatements(updateStatements)),
|
|
27591
|
+
], INFERRED_TYPE, null, contentQueriesFnName);
|
|
27466
27592
|
}
|
|
27467
|
-
|
|
27468
|
-
|
|
27469
|
-
|
|
27470
|
-
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
// The difference of two absolute offsets provide the relative offset
|
|
27476
|
-
const startDiff = absoluteSpan.start - sourceSpan.start.offset;
|
|
27477
|
-
const endDiff = absoluteSpan.end - sourceSpan.end.offset;
|
|
27478
|
-
return new ParseSourceSpan(sourceSpan.start.moveBy(startDiff), sourceSpan.end.moveBy(endDiff), sourceSpan.fullStart.moveBy(startDiff), sourceSpan.details);
|
|
27593
|
+
|
|
27594
|
+
class HtmlParser extends Parser$1 {
|
|
27595
|
+
constructor() {
|
|
27596
|
+
super(getHtmlTagDefinition);
|
|
27597
|
+
}
|
|
27598
|
+
parse(source, url, options) {
|
|
27599
|
+
return super.parse(source, url, options);
|
|
27600
|
+
}
|
|
27479
27601
|
}
|
|
27480
27602
|
|
|
27481
27603
|
// Some of the code comes from WebComponents.JS
|
|
@@ -27494,7 +27616,7 @@ const LINK_STYLE_REL_ATTR = 'rel';
|
|
|
27494
27616
|
const LINK_STYLE_HREF_ATTR = 'href';
|
|
27495
27617
|
const LINK_STYLE_REL_VALUE = 'stylesheet';
|
|
27496
27618
|
const STYLE_ELEMENT = 'style';
|
|
27497
|
-
const
|
|
27619
|
+
const SCRIPT_ELEMENTS = new Set([':svg:script', 'script']);
|
|
27498
27620
|
const NG_NON_BINDABLE_ATTR = 'ngNonBindable';
|
|
27499
27621
|
const NG_PROJECT_AS = 'ngProjectAs';
|
|
27500
27622
|
function preparseElement(ast) {
|
|
@@ -27503,7 +27625,7 @@ function preparseElement(ast) {
|
|
|
27503
27625
|
let relAttr = null;
|
|
27504
27626
|
let nonBindable = false;
|
|
27505
27627
|
let projectAs = '';
|
|
27506
|
-
ast.attrs
|
|
27628
|
+
for (const attr of ast.attrs) {
|
|
27507
27629
|
const lcAttrName = attr.name.toLowerCase();
|
|
27508
27630
|
if (lcAttrName == NG_CONTENT_SELECT_ATTR) {
|
|
27509
27631
|
selectAttr = attr.value;
|
|
@@ -27522,17 +27644,18 @@ function preparseElement(ast) {
|
|
|
27522
27644
|
projectAs = attr.value;
|
|
27523
27645
|
}
|
|
27524
27646
|
}
|
|
27525
|
-
}
|
|
27526
|
-
|
|
27647
|
+
}
|
|
27648
|
+
// Normalize selector to '*' if empty
|
|
27649
|
+
selectAttr ||= '*';
|
|
27527
27650
|
const nodeName = ast.name.toLowerCase();
|
|
27528
27651
|
let type = PreparsedElementType.OTHER;
|
|
27529
27652
|
if (isNgContent(nodeName)) {
|
|
27530
27653
|
type = PreparsedElementType.NG_CONTENT;
|
|
27531
27654
|
}
|
|
27532
|
-
else if (
|
|
27655
|
+
else if (STYLE_ELEMENT === nodeName) {
|
|
27533
27656
|
type = PreparsedElementType.STYLE;
|
|
27534
27657
|
}
|
|
27535
|
-
else if (nodeName
|
|
27658
|
+
else if (SCRIPT_ELEMENTS.has(nodeName)) {
|
|
27536
27659
|
type = PreparsedElementType.SCRIPT;
|
|
27537
27660
|
}
|
|
27538
27661
|
else if (nodeName == LINK_ELEMENT && relAttr == LINK_STYLE_REL_VALUE) {
|
|
@@ -27562,12 +27685,6 @@ class PreparsedElement {
|
|
|
27562
27685
|
this.projectAs = projectAs;
|
|
27563
27686
|
}
|
|
27564
27687
|
}
|
|
27565
|
-
function normalizeNgContentSelect(selectAttr) {
|
|
27566
|
-
if (selectAttr === null || selectAttr.length === 0) {
|
|
27567
|
-
return '*';
|
|
27568
|
-
}
|
|
27569
|
-
return selectAttr;
|
|
27570
|
-
}
|
|
27571
27688
|
|
|
27572
27689
|
/** Pattern for the expression in a for loop block. */
|
|
27573
27690
|
const FOR_LOOP_EXPRESSION_PATTERN = /^\s*([0-9A-Za-z_$]*)\s+of\s+([\S\s]*)/;
|
|
@@ -28855,8 +28972,9 @@ class HtmlAstToIvyAst {
|
|
|
28855
28972
|
// Note that validation is skipped and property mapping is disabled
|
|
28856
28973
|
// due to the fact that we need to make sure a given prop is not an
|
|
28857
28974
|
// input of a directive and directive matching happens at runtime.
|
|
28975
|
+
const isAttrOn = prop.name.toLowerCase().startsWith('attr.on');
|
|
28858
28976
|
const bep = this.bindingParser.createBoundElementProperty(elementName, prop,
|
|
28859
|
-
/* skipValidation */
|
|
28977
|
+
/* skipValidation */ !isAttrOn,
|
|
28860
28978
|
/* mapPropertyName */ false);
|
|
28861
28979
|
bound.push(BoundAttribute.fromBoundElementProperty(bep, i18n));
|
|
28862
28980
|
}
|
|
@@ -29752,8 +29870,30 @@ function verifyHostBindings(bindings, sourceSpan) {
|
|
|
29752
29870
|
const bindingParser = makeBindingParser();
|
|
29753
29871
|
bindingParser.createDirectiveHostEventAsts(bindings.listeners, sourceSpan);
|
|
29754
29872
|
bindingParser.createBoundHostProperties(bindings.properties, sourceSpan);
|
|
29873
|
+
validateNoEventBindings(bindings, bindingParser, sourceSpan);
|
|
29755
29874
|
return bindingParser.errors;
|
|
29756
29875
|
}
|
|
29876
|
+
/**
|
|
29877
|
+
* Validates that there are no event attribute bindings in the host bindings.
|
|
29878
|
+
* @param bindings - Map of host bindings for the component.
|
|
29879
|
+
* @param bindingParser - Binding parser used to create the binding expression.
|
|
29880
|
+
* @param sourceSpan - Source span where the host bindings were defined.
|
|
29881
|
+
*/
|
|
29882
|
+
function validateNoEventBindings(bindings, bindingParser, sourceSpan) {
|
|
29883
|
+
for (const prop in bindings.properties) {
|
|
29884
|
+
const isAttr = prop.startsWith('attr.');
|
|
29885
|
+
const boundName = isAttr ? prop.slice(5) : prop;
|
|
29886
|
+
if (boundName.toLowerCase().startsWith('on')) {
|
|
29887
|
+
const errorType = isAttr ? 'attribute' : 'property';
|
|
29888
|
+
const suggestion = `(${boundName.slice(2)})=...`;
|
|
29889
|
+
let msg = `Binding to event ${errorType} '${boundName}' is disallowed for security reasons, please use ${suggestion}`;
|
|
29890
|
+
if (!isAttr) {
|
|
29891
|
+
msg += `\nIf '${prop}' is a directive input, make sure the directive is imported by the current module.`;
|
|
29892
|
+
}
|
|
29893
|
+
bindingParser.errors.push(new ParseError(sourceSpan, msg));
|
|
29894
|
+
}
|
|
29895
|
+
}
|
|
29896
|
+
}
|
|
29757
29897
|
function compileStyles(styles, selector, hostSelector) {
|
|
29758
29898
|
const shadowCss = new ShadowCss();
|
|
29759
29899
|
return styles.map((style) => {
|
|
@@ -31357,11 +31497,6 @@ function createR3ComponentDeferMetadata(boundTarget, deferBlockDependencies) {
|
|
|
31357
31497
|
function extractHostBindings(propMetadata, sourceSpan, host) {
|
|
31358
31498
|
// First parse the declarations from the metadata.
|
|
31359
31499
|
const bindings = parseHostBindings(host || {});
|
|
31360
|
-
// After that check host bindings for errors
|
|
31361
|
-
const errors = verifyHostBindings(bindings, sourceSpan);
|
|
31362
|
-
if (errors.length) {
|
|
31363
|
-
throw new Error(errors.map((error) => error.msg).join('\n'));
|
|
31364
|
-
}
|
|
31365
31500
|
// Next, loop over the properties of the object, looking for @HostBinding and @HostListener.
|
|
31366
31501
|
for (const field in propMetadata) {
|
|
31367
31502
|
if (propMetadata.hasOwnProperty(field)) {
|
|
@@ -31378,6 +31513,11 @@ function extractHostBindings(propMetadata, sourceSpan, host) {
|
|
|
31378
31513
|
});
|
|
31379
31514
|
}
|
|
31380
31515
|
}
|
|
31516
|
+
// After that check host bindings for errors
|
|
31517
|
+
const errors = verifyHostBindings(bindings, sourceSpan);
|
|
31518
|
+
if (errors.length) {
|
|
31519
|
+
throw new Error(errors.map((error) => error.msg).join('\n'));
|
|
31520
|
+
}
|
|
31381
31521
|
return bindings;
|
|
31382
31522
|
}
|
|
31383
31523
|
function isHostBinding(value) {
|
|
@@ -31512,7 +31652,7 @@ var _VisitorMode;
|
|
|
31512
31652
|
* @description
|
|
31513
31653
|
* Entry point for all public APIs of the compiler package.
|
|
31514
31654
|
*/
|
|
31515
|
-
new Version$1('20.3.
|
|
31655
|
+
new Version$1('20.3.28');
|
|
31516
31656
|
|
|
31517
31657
|
//////////////////////////////////////
|
|
31518
31658
|
// THIS FILE HAS GLOBAL SIDE EFFECT //
|
|
@@ -40750,11 +40890,22 @@ function requireConventions () {
|
|
|
40750
40890
|
XMLNS: 'http://www.w3.org/2000/xmlns/',
|
|
40751
40891
|
});
|
|
40752
40892
|
|
|
40893
|
+
//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
|
40894
|
+
//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
|
|
40895
|
+
//[5] Name ::= NameStartChar (NameChar)*
|
|
40896
|
+
var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;//\u10000-\uEFFFF
|
|
40897
|
+
var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
|
|
40898
|
+
var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
|
|
40899
|
+
//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
|
|
40900
|
+
|
|
40753
40901
|
conventions.assign = assign;
|
|
40754
40902
|
conventions.find = find;
|
|
40755
40903
|
conventions.freeze = freeze;
|
|
40756
40904
|
conventions.MIME_TYPE = MIME_TYPE;
|
|
40757
40905
|
conventions.NAMESPACE = NAMESPACE;
|
|
40906
|
+
conventions.nameStartChar = nameStartChar;
|
|
40907
|
+
conventions.nameChar = nameChar;
|
|
40908
|
+
conventions.tagNamePattern = tagNamePattern;
|
|
40758
40909
|
return conventions;
|
|
40759
40910
|
}
|
|
40760
40911
|
|
|
@@ -40767,6 +40918,7 @@ function requireDom () {
|
|
|
40767
40918
|
|
|
40768
40919
|
var find = conventions.find;
|
|
40769
40920
|
var NAMESPACE = conventions.NAMESPACE;
|
|
40921
|
+
var tagNamePattern = conventions.tagNamePattern;
|
|
40770
40922
|
|
|
40771
40923
|
/**
|
|
40772
40924
|
* A prerequisite for `[].filter`, to drop elements that are empty
|
|
@@ -40998,6 +41150,13 @@ function requireDom () {
|
|
|
40998
41150
|
* used for attributes or DocumentType entities
|
|
40999
41151
|
*/
|
|
41000
41152
|
function NamedNodeMap() {
|
|
41153
|
+
// nodeName -> Attr membership index; lets the parse-time de-duplication in
|
|
41154
|
+
// setNamedItem resolve an existing attribute in O(1) instead of scanning the
|
|
41155
|
+
// list, so building an element with M attributes costs O(M) rather than O(M^2).
|
|
41156
|
+
// The numbered entries and length remain the sole authority for attribute order.
|
|
41157
|
+
// Object.create(null) so an attribute named __proto__ or constructor is an
|
|
41158
|
+
// ordinary key.
|
|
41159
|
+
this._nameIndex = Object.create(null);
|
|
41001
41160
|
}
|
|
41002
41161
|
function _findNodeIndex(list,node){
|
|
41003
41162
|
var i = list.length;
|
|
@@ -41006,12 +41165,27 @@ function requireDom () {
|
|
|
41006
41165
|
}
|
|
41007
41166
|
}
|
|
41008
41167
|
|
|
41168
|
+
function _nnmIndexAdd(list, attr) {
|
|
41169
|
+
list._nameIndex[attr.nodeName] = attr;
|
|
41170
|
+
}
|
|
41171
|
+
function _nnmIndexRemove(list, attr) {
|
|
41172
|
+
// Only drop the entry if it still points at this attribute; a replacement with
|
|
41173
|
+
// a different nodeName may already have re-keyed it.
|
|
41174
|
+
if (list._nameIndex[attr.nodeName] === attr) {
|
|
41175
|
+
delete list._nameIndex[attr.nodeName];
|
|
41176
|
+
}
|
|
41177
|
+
}
|
|
41178
|
+
|
|
41009
41179
|
function _addNamedNode(el,list,newAttr,oldAttr){
|
|
41010
41180
|
if(oldAttr){
|
|
41011
41181
|
list[_findNodeIndex(list,oldAttr)] = newAttr;
|
|
41182
|
+
// oldAttr leaves the list; drop its index entry (its nodeName may differ
|
|
41183
|
+
// from newAttr's when the replacement came via setNamedItemNS).
|
|
41184
|
+
_nnmIndexRemove(list, oldAttr);
|
|
41012
41185
|
}else {
|
|
41013
41186
|
list[list.length++] = newAttr;
|
|
41014
41187
|
}
|
|
41188
|
+
_nnmIndexAdd(list, newAttr);
|
|
41015
41189
|
if(el){
|
|
41016
41190
|
newAttr.ownerElement = el;
|
|
41017
41191
|
var doc = el.ownerDocument;
|
|
@@ -41030,6 +41204,7 @@ function requireDom () {
|
|
|
41030
41204
|
list[i] = list[++i];
|
|
41031
41205
|
}
|
|
41032
41206
|
list.length = lastIndex;
|
|
41207
|
+
_nnmIndexRemove(list, attr);
|
|
41033
41208
|
if(el){
|
|
41034
41209
|
var doc = el.ownerDocument;
|
|
41035
41210
|
if(doc){
|
|
@@ -41063,7 +41238,11 @@ function requireDom () {
|
|
|
41063
41238
|
if(el && el!=this._ownerElement){
|
|
41064
41239
|
throw new DOMException(INUSE_ATTRIBUTE_ERR);
|
|
41065
41240
|
}
|
|
41066
|
-
|
|
41241
|
+
// Resolve any existing attribute with the same nodeName through the O(1)
|
|
41242
|
+
// membership index rather than an O(M) scan — this is the parse-dedup hot
|
|
41243
|
+
// path (setAttributeNode per attribute during parse). Absent -> undefined,
|
|
41244
|
+
// matching getNamedItem's contract.
|
|
41245
|
+
var oldAttr = this._nameIndex[attr.nodeName];
|
|
41067
41246
|
_addNamedNode(this._ownerElement,this,attr,oldAttr);
|
|
41068
41247
|
return oldAttr;
|
|
41069
41248
|
},
|
|
@@ -41296,9 +41475,38 @@ function requireDom () {
|
|
|
41296
41475
|
while (child) {
|
|
41297
41476
|
var next = child.nextSibling;
|
|
41298
41477
|
if (next !== null && next.nodeType === TEXT_NODE && child.nodeType === TEXT_NODE) {
|
|
41299
|
-
|
|
41300
|
-
|
|
41301
|
-
//
|
|
41478
|
+
// Merge the whole run of adjacent text nodes at once: gather the
|
|
41479
|
+
// following text siblings' data, unlink them in a single pass, and
|
|
41480
|
+
// re-index the child list a single time. Per-sibling `removeChild`
|
|
41481
|
+
// (each an O(K) re-index) plus per-sibling `appendData` (each an O(K)
|
|
41482
|
+
// string rebuild) is O(K^2) over a long run of single-character text
|
|
41483
|
+
// nodes; this keeps it O(K). The first text node of the run survives
|
|
41484
|
+
// and carries the concatenated data, preserving node identity and
|
|
41485
|
+
// locator semantics.
|
|
41486
|
+
var tail = [];
|
|
41487
|
+
var sibling = next;
|
|
41488
|
+
while (sibling !== null && sibling.nodeType === TEXT_NODE) {
|
|
41489
|
+
tail.push(sibling.data);
|
|
41490
|
+
sibling = sibling.nextSibling;
|
|
41491
|
+
}
|
|
41492
|
+
// `sibling` is now the first non-text node after the run, or null.
|
|
41493
|
+
var removed = child.nextSibling;
|
|
41494
|
+
while (removed !== sibling) {
|
|
41495
|
+
var following = removed.nextSibling;
|
|
41496
|
+
removed.parentNode = null;
|
|
41497
|
+
removed.previousSibling = null;
|
|
41498
|
+
removed.nextSibling = null;
|
|
41499
|
+
removed = following;
|
|
41500
|
+
}
|
|
41501
|
+
child.nextSibling = sibling;
|
|
41502
|
+
if (sibling !== null) {
|
|
41503
|
+
sibling.previousSibling = child;
|
|
41504
|
+
} else {
|
|
41505
|
+
node.lastChild = child;
|
|
41506
|
+
}
|
|
41507
|
+
child.appendData(tail.join('')); // single O(K) string rebuild
|
|
41508
|
+
_onUpdateChild(node.ownerDocument, node); // single O(K) re-index
|
|
41509
|
+
child = sibling;
|
|
41302
41510
|
} else {
|
|
41303
41511
|
child = next;
|
|
41304
41512
|
}
|
|
@@ -42109,8 +42317,10 @@ function requireDom () {
|
|
|
42109
42317
|
* - it does not do any input validation on the arguments and doesn't throw "InvalidCharacterError".
|
|
42110
42318
|
*
|
|
42111
42319
|
* Note: When the resulting document is serialized with `requireWellFormed: true`, the
|
|
42112
|
-
* serializer throws with code `INVALID_STATE_ERR` if `.
|
|
42113
|
-
*
|
|
42320
|
+
* serializer throws with code `INVALID_STATE_ERR` if `.target` is not a valid XML `NCName`
|
|
42321
|
+
* (a `Name` with no colon) or is an ASCII case-insensitive match for `"xml"`, or if `.data`
|
|
42322
|
+
* contains `?>` (W3C DOM Parsing §3.2.1.7). Without that option the target and data are
|
|
42323
|
+
* emitted verbatim.
|
|
42114
42324
|
*
|
|
42115
42325
|
* @param {string} target
|
|
42116
42326
|
* @param {string} data
|
|
@@ -42135,7 +42345,27 @@ function requireDom () {
|
|
|
42135
42345
|
node.specified = true;
|
|
42136
42346
|
return node;
|
|
42137
42347
|
},
|
|
42348
|
+
/**
|
|
42349
|
+
* Creates an EntityReference object, serialized as `&name;`.
|
|
42350
|
+
*
|
|
42351
|
+
* The `name` is validated against the XML `Name` production at creation time; an invalid name
|
|
42352
|
+
* throws a `DOMException` with code `INVALID_CHARACTER_ERR`. When the resulting node is
|
|
42353
|
+
* serialized with `requireWellFormed: true`, the serializer re-validates `nodeName` and throws
|
|
42354
|
+
* a `DOMException` with code `INVALID_STATE_ERR` if a later `nodeName` mutation made it invalid;
|
|
42355
|
+
* without that option the name is emitted verbatim.
|
|
42356
|
+
*
|
|
42357
|
+
* Note: xmldom does not expand entities — the parser resolves entity references inline and never
|
|
42358
|
+
* constructs `EntityReference` nodes, so this method is the only producer.
|
|
42359
|
+
*
|
|
42360
|
+
* @param {string} name The name of the entity to reference.
|
|
42361
|
+
* @returns {EntityReference}
|
|
42362
|
+
* @throws {DOMException} With code `INVALID_CHARACTER_ERR` when `name` is not a valid XML `Name`.
|
|
42363
|
+
* @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE
|
|
42364
|
+
*/
|
|
42138
42365
|
createEntityReference : function(name){
|
|
42366
|
+
if (!tagNamePattern.test(name)) {
|
|
42367
|
+
throw new DOMException(INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
|
|
42368
|
+
}
|
|
42139
42369
|
var node = new EntityReference();
|
|
42140
42370
|
node.ownerDocument = this;
|
|
42141
42371
|
node.nodeName = name;
|
|
@@ -42347,15 +42577,16 @@ function requireDom () {
|
|
|
42347
42577
|
/**
|
|
42348
42578
|
* Represents a DocumentType node (the `<!DOCTYPE ...>` declaration).
|
|
42349
42579
|
*
|
|
42350
|
-
* `publicId`, `systemId`, and `internalSubset` are plain own-property assignments.
|
|
42580
|
+
* `name`, `publicId`, `systemId`, and `internalSubset` are plain own-property assignments.
|
|
42351
42581
|
* xmldom does not enforce the `readonly` constraint declared by the WHATWG DOM spec —
|
|
42352
42582
|
* direct property writes succeed silently. Values are serialized verbatim when
|
|
42353
42583
|
* `requireWellFormed` is false (the default). When the serializer is invoked with
|
|
42354
42584
|
* `requireWellFormed: true` (via the 4th-parameter options object), it validates each
|
|
42355
|
-
* field
|
|
42585
|
+
* field — including `name`, which is checked against the XML `Name` production — and throws
|
|
42586
|
+
* `DOMException` with code `INVALID_STATE_ERR` on invalid values.
|
|
42356
42587
|
*
|
|
42357
42588
|
* @class
|
|
42358
|
-
* @see https://developer.mozilla.org/
|
|
42589
|
+
* @see https://developer.mozilla.org/docs/Web/API/DocumentType MDN
|
|
42359
42590
|
*/
|
|
42360
42591
|
function DocumentType() {
|
|
42361
42592
|
} DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
|
|
@@ -42369,6 +42600,20 @@ function requireDom () {
|
|
|
42369
42600
|
} Entity.prototype.nodeType = ENTITY_NODE;
|
|
42370
42601
|
_extends(Entity,Node);
|
|
42371
42602
|
|
|
42603
|
+
/**
|
|
42604
|
+
* Represents an EntityReference node, serialized as `&nodeName;`.
|
|
42605
|
+
*
|
|
42606
|
+
* `nodeName` is the referenced entity's name, stored verbatim. When serialized with
|
|
42607
|
+
* `requireWellFormed: true`, the serializer validates `nodeName` against the XML `Name` production
|
|
42608
|
+
* and throws a `DOMException` with code `INVALID_STATE_ERR` if it does not match; without that
|
|
42609
|
+
* option the name is emitted verbatim between `&` and `;`.
|
|
42610
|
+
*
|
|
42611
|
+
* Note: xmldom does not expand entities — the parser resolves entity references inline and never
|
|
42612
|
+
* constructs `EntityReference` nodes, so the only producer is `Document.createEntityReference`.
|
|
42613
|
+
*
|
|
42614
|
+
* @class
|
|
42615
|
+
* @see https://www.w3.org/TR/xml/#NT-Name
|
|
42616
|
+
*/
|
|
42372
42617
|
function EntityReference() {
|
|
42373
42618
|
} EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
|
|
42374
42619
|
_extends(EntityReference,Node);
|
|
@@ -42406,14 +42651,20 @@ function requireDom () {
|
|
|
42406
42651
|
* @returns {string}
|
|
42407
42652
|
* @throws {DOMException}
|
|
42408
42653
|
* With code `INVALID_STATE_ERR` when `requireWellFormed` is `true` and:
|
|
42654
|
+
* - an Element's qualified name (including any namespace prefix) is not a valid XML QName,
|
|
42655
|
+
* - an attribute's qualified name (including a synthesized `xmlns:` namespace declaration) is
|
|
42656
|
+
* not a valid XML QName,
|
|
42409
42657
|
* - a CDATASection node's data contains `"]]>"`,
|
|
42410
42658
|
* - a Comment node's data contains `"-->"` (bare `"--"` does not throw on this branch),
|
|
42411
|
-
* - a ProcessingInstruction's
|
|
42659
|
+
* - a ProcessingInstruction's target is not a valid XML `NCName` (a `Name` with no colon) or is
|
|
42660
|
+
* an ASCII case-insensitive match for `"xml"`, or its data contains `"?>"`,
|
|
42661
|
+
* - a DocumentType's `name` is not a valid XML `Name` (XML 1.0 production [5]),
|
|
42412
42662
|
* - a DocumentType's `publicId` is non-empty and does not match the XML `PubidLiteral`
|
|
42413
42663
|
* production,
|
|
42414
42664
|
* - a DocumentType's `systemId` is non-empty and does not match the XML `SystemLiteral`
|
|
42415
|
-
* production,
|
|
42416
|
-
* - a DocumentType's `internalSubset` contains `"]>"
|
|
42665
|
+
* production,
|
|
42666
|
+
* - a DocumentType's `internalSubset` contains `"]>"`, or
|
|
42667
|
+
* - an EntityReference's `nodeName` is not a valid XML `Name` (XML 1.0 production [5]).
|
|
42417
42668
|
* Note: xmldom does not enforce `readonly` on DocumentType fields — direct property
|
|
42418
42669
|
* writes succeed and are covered by the serializer-level checks above.
|
|
42419
42670
|
* @see https://html.spec.whatwg.org/#dom-xmlserializer-serializetostring
|
|
@@ -42487,7 +42738,10 @@ function requireDom () {
|
|
|
42487
42738
|
* @see https://www.w3.org/TR/xml11/#AVNormalize
|
|
42488
42739
|
* @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes
|
|
42489
42740
|
*/
|
|
42490
|
-
function addSerializedAttribute(buf, qualifiedName, value) {
|
|
42741
|
+
function addSerializedAttribute(buf, qualifiedName, value, requireWellFormed) {
|
|
42742
|
+
if (requireWellFormed && !tagNamePattern.test(qualifiedName)) {
|
|
42743
|
+
throw new DOMException(INVALID_STATE_ERR, 'The attribute name "' + qualifiedName + '" is not a valid XML QName');
|
|
42744
|
+
}
|
|
42491
42745
|
buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
|
|
42492
42746
|
}
|
|
42493
42747
|
|
|
@@ -42553,6 +42807,9 @@ function requireDom () {
|
|
|
42553
42807
|
}
|
|
42554
42808
|
}
|
|
42555
42809
|
|
|
42810
|
+
if (requireWellFormed && !tagNamePattern.test(prefixedNodeName)) {
|
|
42811
|
+
throw new DOMException(INVALID_STATE_ERR, 'The element name "' + prefixedNodeName + '" is not a valid XML QName');
|
|
42812
|
+
}
|
|
42556
42813
|
buf.push('<', prefixedNodeName);
|
|
42557
42814
|
|
|
42558
42815
|
// Build a fresh namespace snapshot for this element's children.
|
|
@@ -42572,7 +42829,7 @@ function requireDom () {
|
|
|
42572
42829
|
if (needNamespaceDefine(attr, html, childNs)) {
|
|
42573
42830
|
var attrPrefix = attr.prefix || '';
|
|
42574
42831
|
var uri = attr.namespaceURI;
|
|
42575
|
-
addSerializedAttribute(buf, attrPrefix ? 'xmlns:' + attrPrefix : 'xmlns', uri);
|
|
42832
|
+
addSerializedAttribute(buf, attrPrefix ? 'xmlns:' + attrPrefix : 'xmlns', uri, requireWellFormed);
|
|
42576
42833
|
childNs.push({ prefix: attrPrefix, namespace: uri });
|
|
42577
42834
|
}
|
|
42578
42835
|
// Apply nodeFilter and serialize the attribute.
|
|
@@ -42581,7 +42838,7 @@ function requireDom () {
|
|
|
42581
42838
|
if (typeof filteredAttr === 'string') {
|
|
42582
42839
|
buf.push(filteredAttr);
|
|
42583
42840
|
} else {
|
|
42584
|
-
addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value);
|
|
42841
|
+
addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value, requireWellFormed);
|
|
42585
42842
|
}
|
|
42586
42843
|
}
|
|
42587
42844
|
}
|
|
@@ -42590,7 +42847,7 @@ function requireDom () {
|
|
|
42590
42847
|
if (nodeName === prefixedNodeName && needNamespaceDefine(n, html, childNs)) {
|
|
42591
42848
|
var nodePrefix = n.prefix || '';
|
|
42592
42849
|
var uri = n.namespaceURI;
|
|
42593
|
-
addSerializedAttribute(buf, nodePrefix ? 'xmlns:' + nodePrefix : 'xmlns', uri);
|
|
42850
|
+
addSerializedAttribute(buf, nodePrefix ? 'xmlns:' + nodePrefix : 'xmlns', uri, requireWellFormed);
|
|
42594
42851
|
childNs.push({ prefix: nodePrefix, namespace: uri });
|
|
42595
42852
|
}
|
|
42596
42853
|
|
|
@@ -42623,7 +42880,7 @@ function requireDom () {
|
|
|
42623
42880
|
return { ns: ns.slice(), isHTML: html, tag: null };
|
|
42624
42881
|
|
|
42625
42882
|
case ATTRIBUTE_NODE:
|
|
42626
|
-
addSerializedAttribute(buf, n.name, n.value);
|
|
42883
|
+
addSerializedAttribute(buf, n.name, n.value, requireWellFormed);
|
|
42627
42884
|
return null;
|
|
42628
42885
|
|
|
42629
42886
|
case TEXT_NODE:
|
|
@@ -42662,6 +42919,9 @@ function requireDom () {
|
|
|
42662
42919
|
|
|
42663
42920
|
case DOCUMENT_TYPE_NODE:
|
|
42664
42921
|
if (requireWellFormed) {
|
|
42922
|
+
if (!tagNamePattern.test(n.name)) {
|
|
42923
|
+
throw new DOMException(INVALID_STATE_ERR, 'The doctype name "' + n.name + '" is not a valid XML Name');
|
|
42924
|
+
}
|
|
42665
42925
|
if (n.publicId && !/^("[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%']*"|'[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%'"]*')$/.test(n.publicId)) {
|
|
42666
42926
|
throw new DOMException(INVALID_STATE_ERR, 'DocumentType publicId is not a valid PubidLiteral');
|
|
42667
42927
|
}
|
|
@@ -42693,13 +42953,27 @@ function requireDom () {
|
|
|
42693
42953
|
return null;
|
|
42694
42954
|
|
|
42695
42955
|
case PROCESSING_INSTRUCTION_NODE:
|
|
42696
|
-
if (requireWellFormed
|
|
42697
|
-
|
|
42956
|
+
if (requireWellFormed) {
|
|
42957
|
+
if (!tagNamePattern.test(n.target) || n.target.indexOf(':') !== -1 || n.target.toLowerCase() === 'xml') {
|
|
42958
|
+
throw new DOMException(
|
|
42959
|
+
INVALID_STATE_ERR,
|
|
42960
|
+
'The processing instruction target "' + n.target + '" is not a valid XML NCName or is reserved'
|
|
42961
|
+
);
|
|
42962
|
+
}
|
|
42963
|
+
if (n.data.indexOf('?>') !== -1) {
|
|
42964
|
+
throw new DOMException(INVALID_STATE_ERR, 'The ProcessingInstruction data contains "?>"');
|
|
42965
|
+
}
|
|
42698
42966
|
}
|
|
42699
42967
|
buf.push('<?', n.target, ' ', n.data, '?>');
|
|
42700
42968
|
return null;
|
|
42701
42969
|
|
|
42702
42970
|
case ENTITY_REFERENCE_NODE:
|
|
42971
|
+
if (requireWellFormed && !tagNamePattern.test(n.nodeName)) {
|
|
42972
|
+
throw new DOMException(
|
|
42973
|
+
INVALID_STATE_ERR,
|
|
42974
|
+
'The entity reference name "' + n.nodeName + '" is not a valid XML Name'
|
|
42975
|
+
);
|
|
42976
|
+
}
|
|
42703
42977
|
buf.push('&', n.nodeName, ';');
|
|
42704
42978
|
return null;
|
|
42705
42979
|
|
|
@@ -45080,14 +45354,8 @@ function requireSax () {
|
|
|
45080
45354
|
if (hasRequiredSax) return sax;
|
|
45081
45355
|
hasRequiredSax = 1;
|
|
45082
45356
|
var NAMESPACE = requireConventions().NAMESPACE;
|
|
45357
|
+
var tagNamePattern = requireConventions().tagNamePattern;
|
|
45083
45358
|
|
|
45084
|
-
//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
|
45085
|
-
//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
|
|
45086
|
-
//[5] Name ::= NameStartChar (NameChar)*
|
|
45087
|
-
var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;//\u10000-\uEFFFF
|
|
45088
|
-
var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
|
|
45089
|
-
var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
|
|
45090
|
-
//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
|
|
45091
45359
|
//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
|
|
45092
45360
|
|
|
45093
45361
|
//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
|
|
@@ -45198,7 +45466,13 @@ function requireSax () {
|
|
|
45198
45466
|
switch(source.charAt(tagStart+1)){
|
|
45199
45467
|
case '/':
|
|
45200
45468
|
var end = source.indexOf('>',tagStart+3);
|
|
45201
|
-
|
|
45469
|
+
// Anchored trailing-whitespace trim. The former `/[ \t\n\r]+$/g` backtracked
|
|
45470
|
+
// quadratically on a name shaped `whitespace-run + non-whitespace char`
|
|
45471
|
+
// (an end tag `</ … x>`): from every start position it extended `[ws]+`
|
|
45472
|
+
// to the end and then failed the `$` anchor. This anchored form matches the
|
|
45473
|
+
// whole string once and captures everything up to the last non-whitespace
|
|
45474
|
+
// character, so it trims in linear time with byte-identical output.
|
|
45475
|
+
var tagName = source.substring(tagStart + 2, end).replace(/^([\s\S]*?[^ \t\n\r])?[ \t\n\r]*$/, '$1');
|
|
45202
45476
|
var config = parseStack.pop();
|
|
45203
45477
|
if(end<0){
|
|
45204
45478
|
|
|
@@ -45209,6 +45483,14 @@ function requireSax () {
|
|
|
45209
45483
|
tagName = tagName.replace(/[\s<].*/,'');
|
|
45210
45484
|
errorHandler.error("end tag name: "+tagName+' maybe not complete');
|
|
45211
45485
|
end = tagStart+1+tagName.length;
|
|
45486
|
+
}else if(/[ \t\n\r]/.test(tagName) && tagNamePattern.test(tagName.split(/[ \t\n\r]/)[0])){
|
|
45487
|
+
// The XML `ETag` production is `'</' Name S? '>'`: only optional whitespace may follow
|
|
45488
|
+
// the `Name`. A valid `Name` followed by whitespace and non-whitespace residue (e.g.
|
|
45489
|
+
// `</a\nbogus>` or `</a bogus>`) is not well-formed, but historically it was silently
|
|
45490
|
+
// accepted (the malformed end tag ignored, the residue dropped, the element left on the
|
|
45491
|
+
// stack). Report it as a recoverable `error` (which a custom errorHandler may escalate to
|
|
45492
|
+
// fatal) while keeping the existing recovery so the parsed DOM stays byte-identical.
|
|
45493
|
+
errorHandler.error('end tag name is followed by whitespace and trailing content: "'+tagName+'"');
|
|
45212
45494
|
}
|
|
45213
45495
|
var localNSMap = config.localNSMap;
|
|
45214
45496
|
var endMatch = config.tagName == tagName;
|
|
@@ -45332,6 +45614,15 @@ function requireSax () {
|
|
|
45332
45614
|
var s = S_TAG;//status
|
|
45333
45615
|
while(true){
|
|
45334
45616
|
var c = source.charAt(p);
|
|
45617
|
+
if (s === S_TAG && c === '<') {
|
|
45618
|
+
// A `<` can never occur inside a tag name. Without this guard the scan runs
|
|
45619
|
+
// on to the next `>` (or EOF) before the tag name is rejected, so a document
|
|
45620
|
+
// with many `<` inside a malformed tag makes each one-character recovery step
|
|
45621
|
+
// re-scan to the distant `>` — O(n^2). Stopping at the `<` keeps each recovery
|
|
45622
|
+
// step bounded. The candidate scanned so far is reported raw, consistent with
|
|
45623
|
+
// the sibling invalid-tag-name throw below.
|
|
45624
|
+
throw new Error('unexpected < in tag name: ' + source.slice(start, p));
|
|
45625
|
+
}
|
|
45335
45626
|
switch(c){
|
|
45336
45627
|
case '=':
|
|
45337
45628
|
if(s === S_ATTR){//attrName
|
|
@@ -45524,9 +45815,13 @@ function requireSax () {
|
|
|
45524
45815
|
if(nsPrefix !== false){//hack!!
|
|
45525
45816
|
if(localNSMap == null){
|
|
45526
45817
|
localNSMap = {};
|
|
45527
|
-
//
|
|
45528
|
-
|
|
45529
|
-
//
|
|
45818
|
+
// Derive the child scope's namespace map by prototype-chain inheritance
|
|
45819
|
+
// instead of a flat copy: lookups inherit ancestor prefixes transparently,
|
|
45820
|
+
// so a document nesting N scopes retains O(N) map entries rather than
|
|
45821
|
+
// sum(1..N) = O(N^2). localNSMap stays a flat own-only record of the
|
|
45822
|
+
// prefixes declared at THIS element, so own-property enumeration
|
|
45823
|
+
// (endPrefixMapping below) still reports only local declarations.
|
|
45824
|
+
currentNSMap = Object.create(currentNSMap);
|
|
45530
45825
|
}
|
|
45531
45826
|
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
|
|
45532
45827
|
a.uri = NAMESPACE.XMLNS;
|
|
@@ -53297,7 +53592,7 @@ var momentTimezoneExports = requireMomentTimezone();
|
|
|
53297
53592
|
var momentTimezone = /*@__PURE__*/getDefaultExportFromCjs(momentTimezoneExports);
|
|
53298
53593
|
|
|
53299
53594
|
/**
|
|
53300
|
-
* @license Angular v20.3.
|
|
53595
|
+
* @license Angular v20.3.28
|
|
53301
53596
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
53302
53597
|
* License: MIT
|
|
53303
53598
|
*/
|
|
@@ -53331,7 +53626,7 @@ function isNotFound(e) {
|
|
|
53331
53626
|
}
|
|
53332
53627
|
|
|
53333
53628
|
/**
|
|
53334
|
-
* @license Angular v20.3.
|
|
53629
|
+
* @license Angular v20.3.28
|
|
53335
53630
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
53336
53631
|
* License: MIT
|
|
53337
53632
|
*/
|
|
@@ -53876,7 +54171,7 @@ function signalValueChanged(node) {
|
|
|
53876
54171
|
}
|
|
53877
54172
|
|
|
53878
54173
|
/**
|
|
53879
|
-
* @license Angular v20.3.
|
|
54174
|
+
* @license Angular v20.3.28
|
|
53880
54175
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
53881
54176
|
* License: MIT
|
|
53882
54177
|
*/
|
|
@@ -54013,7 +54308,7 @@ function runEffect(node) {
|
|
|
54013
54308
|
}
|
|
54014
54309
|
|
|
54015
54310
|
/**
|
|
54016
|
-
* @license Angular v20.3.
|
|
54311
|
+
* @license Angular v20.3.28
|
|
54017
54312
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
54018
54313
|
* License: MIT
|
|
54019
54314
|
*/
|
|
@@ -54023,7 +54318,7 @@ function setAlternateWeakRefImpl(impl) {
|
|
|
54023
54318
|
}
|
|
54024
54319
|
|
|
54025
54320
|
/**
|
|
54026
|
-
* @license Angular v20.3.
|
|
54321
|
+
* @license Angular v20.3.28
|
|
54027
54322
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
54028
54323
|
* License: MIT
|
|
54029
54324
|
*/
|
|
@@ -54163,7 +54458,7 @@ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
|
54163
54458
|
}
|
|
54164
54459
|
|
|
54165
54460
|
/**
|
|
54166
|
-
* @license Angular v20.3.
|
|
54461
|
+
* @license Angular v20.3.28
|
|
54167
54462
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
54168
54463
|
* License: MIT
|
|
54169
54464
|
*/
|
|
@@ -54190,7 +54485,7 @@ class Version {
|
|
|
54190
54485
|
/**
|
|
54191
54486
|
* @publicApi
|
|
54192
54487
|
*/
|
|
54193
|
-
const VERSION = /* @__PURE__ */ new Version('20.3.
|
|
54488
|
+
const VERSION = /* @__PURE__ */ new Version('20.3.28');
|
|
54194
54489
|
|
|
54195
54490
|
/**
|
|
54196
54491
|
* Base URL for the error details page.
|
|
@@ -56800,8 +57095,166 @@ function assertNodeInjector(lView, injectorIndex) {
|
|
|
56800
57095
|
assertNumber(lView[injectorIndex + 8 /* NodeInjectorOffset.PARENT */], 'injectorIndex should point to parent injector');
|
|
56801
57096
|
}
|
|
56802
57097
|
|
|
56803
|
-
|
|
56804
|
-
|
|
57098
|
+
/**
|
|
57099
|
+
* A SecurityContext marks a location that has dangerous security implications, e.g. a DOM property
|
|
57100
|
+
* like `innerHTML` that could cause Cross Site Scripting (XSS) security bugs when improperly
|
|
57101
|
+
* handled.
|
|
57102
|
+
*
|
|
57103
|
+
* See DomSanitizer for more details on security in Angular applications.
|
|
57104
|
+
*
|
|
57105
|
+
* @publicApi
|
|
57106
|
+
*/
|
|
57107
|
+
var SecurityContext;
|
|
57108
|
+
(function (SecurityContext) {
|
|
57109
|
+
SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
|
|
57110
|
+
SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
|
|
57111
|
+
SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
|
|
57112
|
+
SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
|
|
57113
|
+
SecurityContext[SecurityContext["URL"] = 4] = "URL";
|
|
57114
|
+
SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
|
|
57115
|
+
SecurityContext[SecurityContext["ATTRIBUTE_NO_BINDING"] = 6] = "ATTRIBUTE_NO_BINDING";
|
|
57116
|
+
})(SecurityContext || (SecurityContext = {}));
|
|
57117
|
+
// =================================================================================================
|
|
57118
|
+
// =================================================================================================
|
|
57119
|
+
// =========== S T O P - S T O P - S T O P - S T O P - S T O P - S T O P ===========
|
|
57120
|
+
// =================================================================================================
|
|
57121
|
+
// =================================================================================================
|
|
57122
|
+
//
|
|
57123
|
+
// DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW!
|
|
57124
|
+
//
|
|
57125
|
+
// =================================================================================================
|
|
57126
|
+
/**
|
|
57127
|
+
* Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'.
|
|
57128
|
+
*/
|
|
57129
|
+
let _SECURITY_SCHEMA;
|
|
57130
|
+
const SVG_NAMESPACE$1 = 'svg';
|
|
57131
|
+
const MATH_ML_NAMESPACE$1 = 'math';
|
|
57132
|
+
/**
|
|
57133
|
+
* @remarks Keep is a copy of DOM Security Schema.
|
|
57134
|
+
* @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
|
|
57135
|
+
*/
|
|
57136
|
+
function SECURITY_SCHEMA() {
|
|
57137
|
+
if (!_SECURITY_SCHEMA) {
|
|
57138
|
+
_SECURITY_SCHEMA = {};
|
|
57139
|
+
// Case is insignificant below, all element and attribute names are lower-cased for lookup.
|
|
57140
|
+
registerContext(SecurityContext.HTML, /** Namespace */ undefined, [
|
|
57141
|
+
['iframe', ['srcdoc']],
|
|
57142
|
+
['*', ['innerHTML', 'outerHTML']],
|
|
57143
|
+
]);
|
|
57144
|
+
registerContext(SecurityContext.STYLE, /** Namespace */ undefined, [['*', ['style']]]);
|
|
57145
|
+
// NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them.
|
|
57146
|
+
registerContext(SecurityContext.URL, /** Namespace */ undefined, [
|
|
57147
|
+
['*', ['formAction']],
|
|
57148
|
+
['area', ['href']],
|
|
57149
|
+
['a', ['href', 'xlink:href']],
|
|
57150
|
+
['form', ['action']],
|
|
57151
|
+
// The below two items are safe and should be removed but they require a G3 clean-up as a small number of tests fail.
|
|
57152
|
+
['img', ['src']],
|
|
57153
|
+
['video', ['src']],
|
|
57154
|
+
]);
|
|
57155
|
+
registerContext(SecurityContext.URL, MATH_ML_NAMESPACE$1, [
|
|
57156
|
+
// MathML namespace
|
|
57157
|
+
// https://crsrc.org/c/third_party/blink/renderer/core/sanitizer/sanitizer.cc;l=753-768;drc=b3eb16372dcd3317d65e9e0265015e322494edcd;bpv=1;bpt=1
|
|
57158
|
+
['*', ['href', 'xlink:href']],
|
|
57159
|
+
['annotation', ['href', 'xlink:href']],
|
|
57160
|
+
['annotation-xml', ['href', 'xlink:href']],
|
|
57161
|
+
['maction', ['href', 'xlink:href']],
|
|
57162
|
+
['malignmark', ['href', 'xlink:href']],
|
|
57163
|
+
['math', ['href', 'xlink:href']],
|
|
57164
|
+
['mroot', ['href', 'xlink:href']],
|
|
57165
|
+
['msqrt', ['href', 'xlink:href']],
|
|
57166
|
+
['merror', ['href', 'xlink:href']],
|
|
57167
|
+
['mfrac', ['href', 'xlink:href']],
|
|
57168
|
+
['mglyph', ['href', 'xlink:href']],
|
|
57169
|
+
['msub', ['href', 'xlink:href']],
|
|
57170
|
+
['msup', ['href', 'xlink:href']],
|
|
57171
|
+
['msubsup', ['href', 'xlink:href']],
|
|
57172
|
+
['mmultiscripts', ['href', 'xlink:href']],
|
|
57173
|
+
['mprescripts', ['href', 'xlink:href']],
|
|
57174
|
+
['mi', ['href', 'xlink:href']],
|
|
57175
|
+
['mn', ['href', 'xlink:href']],
|
|
57176
|
+
['mo', ['href', 'xlink:href']],
|
|
57177
|
+
['mpadded', ['href', 'xlink:href']],
|
|
57178
|
+
['mphantom', ['href', 'xlink:href']],
|
|
57179
|
+
['mrow', ['href', 'xlink:href']],
|
|
57180
|
+
['ms', ['href', 'xlink:href']],
|
|
57181
|
+
['mspace', ['href', 'xlink:href']],
|
|
57182
|
+
['mstyle', ['href', 'xlink:href']],
|
|
57183
|
+
['mtable', ['href', 'xlink:href']],
|
|
57184
|
+
['mtd', ['href', 'xlink:href']],
|
|
57185
|
+
['mtr', ['href', 'xlink:href']],
|
|
57186
|
+
['mtext', ['href', 'xlink:href']],
|
|
57187
|
+
['mover', ['href', 'xlink:href']],
|
|
57188
|
+
['munder', ['href', 'xlink:href']],
|
|
57189
|
+
['munderover', ['href', 'xlink:href']],
|
|
57190
|
+
['semantics', ['href', 'xlink:href']],
|
|
57191
|
+
['none', ['href', 'xlink:href']],
|
|
57192
|
+
]);
|
|
57193
|
+
registerContext(SecurityContext.RESOURCE_URL, /** Namespace */ undefined, [
|
|
57194
|
+
['base', ['href']],
|
|
57195
|
+
['embed', ['src']],
|
|
57196
|
+
['frame', ['src']],
|
|
57197
|
+
['iframe', ['src']],
|
|
57198
|
+
['link', ['href']],
|
|
57199
|
+
['object', ['codebase', 'data']],
|
|
57200
|
+
]);
|
|
57201
|
+
registerContext(SecurityContext.URL, SVG_NAMESPACE$1, [['a', ['href', 'xlink:href']]]);
|
|
57202
|
+
// Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts
|
|
57203
|
+
// Unknown is the internal tag name for unknown elements example used for host-bindings.
|
|
57204
|
+
// These are unsafe as `attributeName` can be `href` or `xlink:href`
|
|
57205
|
+
// See: http://b/463880509#comment7
|
|
57206
|
+
registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, SVG_NAMESPACE$1, [
|
|
57207
|
+
['animate', ['attributeName', 'values', 'to', 'from']],
|
|
57208
|
+
['set', ['to', 'attributeName']],
|
|
57209
|
+
['animateMotion', ['attributeName']],
|
|
57210
|
+
['animateTransform', ['attributeName']],
|
|
57211
|
+
]);
|
|
57212
|
+
registerContext(SecurityContext.ATTRIBUTE_NO_BINDING, /** Namespace */ undefined, [
|
|
57213
|
+
[
|
|
57214
|
+
'unknown',
|
|
57215
|
+
[
|
|
57216
|
+
'attributeName',
|
|
57217
|
+
'values',
|
|
57218
|
+
'to',
|
|
57219
|
+
'from',
|
|
57220
|
+
'sandbox',
|
|
57221
|
+
'allow',
|
|
57222
|
+
'allowFullscreen',
|
|
57223
|
+
'referrerPolicy',
|
|
57224
|
+
'csp',
|
|
57225
|
+
'fetchPriority',
|
|
57226
|
+
],
|
|
57227
|
+
],
|
|
57228
|
+
['iframe', ['sandbox', 'allow', 'allowFullscreen', 'referrerPolicy', 'csp', 'fetchPriority']],
|
|
57229
|
+
]);
|
|
57230
|
+
}
|
|
57231
|
+
return _SECURITY_SCHEMA;
|
|
57232
|
+
}
|
|
57233
|
+
function registerContext(ctx, namespace, specs) {
|
|
57234
|
+
for (const [element, attributeNames] of specs) {
|
|
57235
|
+
let tagName = namespace && element !== 'unknown' ? `:${namespace}:${element}` : element;
|
|
57236
|
+
tagName = tagName.toLowerCase();
|
|
57237
|
+
for (const attr of attributeNames) {
|
|
57238
|
+
_SECURITY_SCHEMA[`${tagName}|${attr.toLowerCase()}`] = ctx;
|
|
57239
|
+
}
|
|
57240
|
+
}
|
|
57241
|
+
}
|
|
57242
|
+
function checkSecurityContext(tagName, propName, namespace) {
|
|
57243
|
+
const schema = SECURITY_SCHEMA();
|
|
57244
|
+
const normalizedTagName = tagName.toLowerCase();
|
|
57245
|
+
const normalizedPropName = propName.toLowerCase();
|
|
57246
|
+
const namespacedContext = namespace && normalizedTagName !== '*' && normalizedTagName !== 'unknown'
|
|
57247
|
+
? schema[`:${namespace}:${normalizedTagName}|${normalizedPropName}`]
|
|
57248
|
+
: undefined;
|
|
57249
|
+
const namespacedWildcardContext = namespace
|
|
57250
|
+
? schema[`:${namespace}:*|${normalizedPropName}`]
|
|
57251
|
+
: undefined;
|
|
57252
|
+
return (namespacedContext ??
|
|
57253
|
+
namespacedWildcardContext ??
|
|
57254
|
+
schema[`${normalizedTagName}|${normalizedPropName}`] ??
|
|
57255
|
+
schema[`*|${normalizedPropName}`] ??
|
|
57256
|
+
SecurityContext.NONE);
|
|
57257
|
+
}
|
|
56805
57258
|
|
|
56806
57259
|
/**
|
|
56807
57260
|
* For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`)
|
|
@@ -57586,7 +58039,7 @@ function getSelectedTNode() {
|
|
|
57586
58039
|
* @codeGenApi
|
|
57587
58040
|
*/
|
|
57588
58041
|
function ɵɵnamespaceSVG() {
|
|
57589
|
-
instructionState.lFrame.currentNamespace = SVG_NAMESPACE;
|
|
58042
|
+
instructionState.lFrame.currentNamespace = SVG_NAMESPACE$1;
|
|
57590
58043
|
}
|
|
57591
58044
|
/**
|
|
57592
58045
|
* Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.
|
|
@@ -57594,7 +58047,7 @@ function ɵɵnamespaceSVG() {
|
|
|
57594
58047
|
* @codeGenApi
|
|
57595
58048
|
*/
|
|
57596
58049
|
function ɵɵnamespaceMathML() {
|
|
57597
|
-
instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE;
|
|
58050
|
+
instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE$1;
|
|
57598
58051
|
}
|
|
57599
58052
|
/**
|
|
57600
58053
|
* Sets the namespace used to create elements to `null`, which forces element creation to use
|
|
@@ -58209,7 +58662,7 @@ class ZoneAwareEffectScheduler {
|
|
|
58209
58662
|
}
|
|
58210
58663
|
|
|
58211
58664
|
/**
|
|
58212
|
-
* @license Angular v20.3.
|
|
58665
|
+
* @license Angular v20.3.28
|
|
58213
58666
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
58214
58667
|
* License: MIT
|
|
58215
58668
|
*/
|
|
@@ -58231,7 +58684,7 @@ const Attribute$1 = {
|
|
|
58231
58684
|
};
|
|
58232
58685
|
|
|
58233
58686
|
/**
|
|
58234
|
-
* @license Angular v20.3.
|
|
58687
|
+
* @license Angular v20.3.28
|
|
58235
58688
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
58236
58689
|
* License: MIT
|
|
58237
58690
|
*/
|
|
@@ -61997,7 +62450,7 @@ function retrieveTransferredState(doc, appId) {
|
|
|
61997
62450
|
// Locate the script tag with the JSON data transferred from the server.
|
|
61998
62451
|
// The id of the script tag is set to the Angular appId + 'state'.
|
|
61999
62452
|
const script = doc.getElementById(appId + '-state');
|
|
62000
|
-
if (script?.textContent) {
|
|
62453
|
+
if (script?.tagName === 'SCRIPT' && script.textContent) {
|
|
62001
62454
|
try {
|
|
62002
62455
|
// Avoid using any here as it triggers lint errors in google3 (any is not allowed).
|
|
62003
62456
|
// Decoding of `<` is done of the box by browsers and node.js, same behaviour as G3
|
|
@@ -63419,6 +63872,13 @@ function matchingSchemas(schemas, tagName) {
|
|
|
63419
63872
|
return false;
|
|
63420
63873
|
}
|
|
63421
63874
|
|
|
63875
|
+
const SVG_NAMESPACE = 'svg';
|
|
63876
|
+
const MATH_ML_NAMESPACE = 'math';
|
|
63877
|
+
const NAMESPACE_URIS = {
|
|
63878
|
+
'http://www.w3.org/2000/svg': SVG_NAMESPACE,
|
|
63879
|
+
'http://www.w3.org/1998/Math/MathML': MATH_ML_NAMESPACE,
|
|
63880
|
+
};
|
|
63881
|
+
|
|
63422
63882
|
/**
|
|
63423
63883
|
* @fileoverview
|
|
63424
63884
|
* A module to facilitate use of a Trusted Types policy internally within
|
|
@@ -63848,13 +64308,6 @@ const VALID_ATTRS = merge(URI_ATTRS, HTML_ATTRS, ARIA_ATTRS);
|
|
|
63848
64308
|
// `Some content`, but strip `invalid-element` opening/closing tags. For some elements, though, we
|
|
63849
64309
|
// don't want to preserve the content, if the elements themselves are going to be removed.
|
|
63850
64310
|
const SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS = tagSet('script,style,template');
|
|
63851
|
-
/**
|
|
63852
|
-
* Attributes that are potential attach vectors and may need to be sanitized.
|
|
63853
|
-
*/
|
|
63854
|
-
const SENSITIVE_ATTRS = merge(URI_ATTRS,
|
|
63855
|
-
// Note: we don't include these attributes in `URI_ATTRS`, because `URI_ATTRS` also
|
|
63856
|
-
// determines whether an attribute should be dropped when sanitizing an HTML string.
|
|
63857
|
-
tagSet('action,formaction,data,codebase'));
|
|
63858
64311
|
/**
|
|
63859
64312
|
* SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
|
|
63860
64313
|
* attributes.
|
|
@@ -64242,23 +64695,27 @@ function enforceIframeSecurity(iframe) {
|
|
|
64242
64695
|
}
|
|
64243
64696
|
|
|
64244
64697
|
/**
|
|
64245
|
-
*
|
|
64246
|
-
* like `innerHTML` that could cause Cross Site Scripting (XSS) security bugs when improperly
|
|
64247
|
-
* handled.
|
|
64698
|
+
* Splits an element name into its namespace and local name.
|
|
64248
64699
|
*
|
|
64249
|
-
*
|
|
64250
|
-
*
|
|
64251
|
-
* @
|
|
64700
|
+
* @param elementName The element name to split, in the format ":namespace:name".
|
|
64701
|
+
* @param fatal If true, throws an error if the element name is not in the correct format.
|
|
64702
|
+
* @returns A tuple containing the namespace and local name.
|
|
64252
64703
|
*/
|
|
64253
|
-
|
|
64254
|
-
(
|
|
64255
|
-
|
|
64256
|
-
|
|
64257
|
-
|
|
64258
|
-
|
|
64259
|
-
|
|
64260
|
-
|
|
64261
|
-
}
|
|
64704
|
+
function splitNsName(elementName, fatal = true) {
|
|
64705
|
+
if (elementName[0] != ':') {
|
|
64706
|
+
return [null, elementName];
|
|
64707
|
+
}
|
|
64708
|
+
const colonIndex = elementName.indexOf(':', 1);
|
|
64709
|
+
if (colonIndex === -1) {
|
|
64710
|
+
if (fatal) {
|
|
64711
|
+
throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
|
|
64712
|
+
}
|
|
64713
|
+
else {
|
|
64714
|
+
return [null, elementName];
|
|
64715
|
+
}
|
|
64716
|
+
}
|
|
64717
|
+
return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
|
|
64718
|
+
}
|
|
64262
64719
|
|
|
64263
64720
|
/**
|
|
64264
64721
|
* An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
|
|
@@ -64275,7 +64732,12 @@ var SecurityContext;
|
|
|
64275
64732
|
*
|
|
64276
64733
|
* @codeGenApi
|
|
64277
64734
|
*/
|
|
64278
|
-
function ɵɵsanitizeHtml(unsafeHtml) {
|
|
64735
|
+
function ɵɵsanitizeHtml(unsafeHtml, tagName, propName) {
|
|
64736
|
+
if (tagName !== undefined &&
|
|
64737
|
+
propName !== undefined &&
|
|
64738
|
+
getSecurityContext(tagName, propName) !== SecurityContext.HTML) {
|
|
64739
|
+
return unsafeHtml;
|
|
64740
|
+
}
|
|
64279
64741
|
const sanitizer = getSanitizer();
|
|
64280
64742
|
if (sanitizer) {
|
|
64281
64743
|
return trustedHTMLFromStringBypass(sanitizer.sanitize(SecurityContext.HTML, unsafeHtml) || '');
|
|
@@ -64425,21 +64887,22 @@ function ɵɵtrustConstantResourceUrl(url) {
|
|
|
64425
64887
|
}
|
|
64426
64888
|
return trustedScriptURLFromString(url[0]);
|
|
64427
64889
|
}
|
|
64428
|
-
// Define sets outside the function for O(1) lookups and memory efficiency
|
|
64429
|
-
const SRC_RESOURCE_TAGS = new Set(['embed', 'frame', 'iframe', 'media', 'script']);
|
|
64430
|
-
const HREF_RESOURCE_TAGS = new Set(['base', 'link', 'script']);
|
|
64431
64890
|
/**
|
|
64432
64891
|
* Detects which sanitizer to use for URL property, based on tag name and prop name.
|
|
64433
64892
|
*
|
|
64434
|
-
* The rules are based on the RESOURCE_URL context config from
|
|
64893
|
+
* The rules are based on the URL and RESOURCE_URL context config from
|
|
64435
64894
|
* `packages/compiler/src/schema/dom_security_schema.ts`.
|
|
64436
|
-
* If tag and prop names don't match Resource URL schema,
|
|
64895
|
+
* If tag and prop names don't match URL or Resource URL schema, no sanitizer is required.
|
|
64437
64896
|
*/
|
|
64438
64897
|
function getUrlSanitizer(tag, prop) {
|
|
64439
|
-
|
|
64440
|
-
|
|
64441
|
-
|
|
64442
|
-
|
|
64898
|
+
switch (getSecurityContext(tag, prop)) {
|
|
64899
|
+
case SecurityContext.RESOURCE_URL:
|
|
64900
|
+
return ɵɵsanitizeResourceUrl;
|
|
64901
|
+
case SecurityContext.URL:
|
|
64902
|
+
return ɵɵsanitizeUrl;
|
|
64903
|
+
default:
|
|
64904
|
+
return null;
|
|
64905
|
+
}
|
|
64443
64906
|
}
|
|
64444
64907
|
/**
|
|
64445
64908
|
* Sanitizes URL, selecting sanitizer function based on tag and property names.
|
|
@@ -64457,7 +64920,7 @@ function getUrlSanitizer(tag, prop) {
|
|
|
64457
64920
|
* @codeGenApi
|
|
64458
64921
|
*/
|
|
64459
64922
|
function ɵɵsanitizeUrlOrResourceUrl(unsafeUrl, tag, prop) {
|
|
64460
|
-
return getUrlSanitizer(tag, prop)(unsafeUrl);
|
|
64923
|
+
return getUrlSanitizer(tag, prop)?.(unsafeUrl) ?? unsafeUrl;
|
|
64461
64924
|
}
|
|
64462
64925
|
function validateAgainstEventProperties(name) {
|
|
64463
64926
|
if (name.toLowerCase().startsWith('on')) {
|
|
@@ -64468,35 +64931,50 @@ function validateAgainstEventProperties(name) {
|
|
|
64468
64931
|
throw new RuntimeError(306 /* RuntimeErrorCode.INVALID_EVENT_BINDING */, errorMessage);
|
|
64469
64932
|
}
|
|
64470
64933
|
}
|
|
64471
|
-
function validateAgainstEventAttributes(name) {
|
|
64472
|
-
if (name.toLowerCase().startsWith('on')) {
|
|
64473
|
-
const errorMessage = `Binding to event attribute '${name}' is disallowed for security reasons, ` +
|
|
64474
|
-
`please use (${name.slice(2)})=...`;
|
|
64475
|
-
throw new RuntimeError(306 /* RuntimeErrorCode.INVALID_EVENT_BINDING */, errorMessage);
|
|
64476
|
-
}
|
|
64477
|
-
}
|
|
64478
64934
|
function getSanitizer() {
|
|
64479
64935
|
const lView = getLView();
|
|
64480
64936
|
return lView && lView[ENVIRONMENT].sanitizer;
|
|
64481
64937
|
}
|
|
64482
|
-
|
|
64938
|
+
function getSecurityContext(tagName, propName) {
|
|
64939
|
+
const [namespace, resolvedTagName] = resolveElement(tagName);
|
|
64940
|
+
return checkSecurityContext(resolvedTagName, propName, namespace);
|
|
64941
|
+
}
|
|
64942
|
+
function resolveElement(tagName) {
|
|
64943
|
+
tagName = tagName.toLowerCase();
|
|
64944
|
+
const splitResult = splitNsName(tagName, false);
|
|
64945
|
+
if (splitResult[0]) {
|
|
64946
|
+
return splitResult;
|
|
64947
|
+
}
|
|
64948
|
+
const index = getSelectedIndex();
|
|
64949
|
+
const tNode = index === -1 ? null : getSelectedTNode();
|
|
64950
|
+
let namespace = tNode?.namespace;
|
|
64951
|
+
if (tagName === "#host" /* TNodeName.DynamicHost */ && tNode?.type === 2 /* TNodeType.Element */) {
|
|
64952
|
+
const element = getNativeByTNode(tNode, getLView());
|
|
64953
|
+
if (element.tagName) {
|
|
64954
|
+
tagName = element.tagName.toLowerCase();
|
|
64955
|
+
}
|
|
64956
|
+
if (namespace == null) {
|
|
64957
|
+
const namespaceURI = element.namespaceURI;
|
|
64958
|
+
namespace = namespaceURI && NAMESPACE_URIS[namespaceURI];
|
|
64959
|
+
}
|
|
64960
|
+
}
|
|
64961
|
+
return [namespace, tagName];
|
|
64962
|
+
}
|
|
64963
|
+
/**
|
|
64964
|
+
* Set of attributes that are sensitive and should be sanitized.
|
|
64965
|
+
*/
|
|
64966
|
+
const SECURITY_SENSITIVE_ATTRIBUTE_NAMES = new Set(['href', 'xlink:href']);
|
|
64483
64967
|
/**
|
|
64484
64968
|
* @remarks Keep this in sync with DOM Security Schema.
|
|
64485
64969
|
* @see [SECURITY_SCHEMA](../../../compiler/src/schema/dom_security_schema.ts)
|
|
64486
64970
|
*/
|
|
64487
|
-
const
|
|
64488
|
-
'
|
|
64489
|
-
'
|
|
64490
|
-
'
|
|
64491
|
-
'
|
|
64492
|
-
|
|
64493
|
-
|
|
64494
|
-
'fetchpriority',
|
|
64495
|
-
]),
|
|
64496
|
-
'animate': attributeName,
|
|
64497
|
-
'set': attributeName,
|
|
64498
|
-
'animatemotion': attributeName,
|
|
64499
|
-
'animatetransform': attributeName,
|
|
64971
|
+
const SVG_ANIMATION_SENSITIVE_STATIC_VALUES = {
|
|
64972
|
+
'animate': {
|
|
64973
|
+
'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
|
|
64974
|
+
'values': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
|
|
64975
|
+
'from': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
|
|
64976
|
+
},
|
|
64977
|
+
'set': { 'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES },
|
|
64500
64978
|
};
|
|
64501
64979
|
/**
|
|
64502
64980
|
* Validates that the attribute binding is safe to use.
|
|
@@ -64506,29 +64984,62 @@ const SECURITY_SENSITIVE_ELEMENTS = {
|
|
|
64506
64984
|
* @param attributeName The name of the attribute.
|
|
64507
64985
|
*/
|
|
64508
64986
|
function ɵɵvalidateAttribute(value, tagName, attributeName) {
|
|
64509
|
-
const
|
|
64510
|
-
const
|
|
64511
|
-
if (
|
|
64987
|
+
const index = getSelectedIndex();
|
|
64988
|
+
const tNode = index === -1 ? null : getSelectedTNode();
|
|
64989
|
+
if (tNode && tNode.type !== 2 /* TNodeType.Element */) {
|
|
64512
64990
|
return value;
|
|
64513
64991
|
}
|
|
64514
|
-
const
|
|
64515
|
-
|
|
64992
|
+
const [namespace, resolvedTagName] = resolveElement(tagName);
|
|
64993
|
+
const securityContext = checkSecurityContext(resolvedTagName, attributeName, namespace);
|
|
64994
|
+
if (securityContext !== SecurityContext.ATTRIBUTE_NO_BINDING) {
|
|
64516
64995
|
return value;
|
|
64517
64996
|
}
|
|
64518
64997
|
const lView = getLView();
|
|
64519
|
-
if (
|
|
64520
|
-
|
|
64521
|
-
|
|
64998
|
+
if (tNode) {
|
|
64999
|
+
if (resolvedTagName === 'iframe') {
|
|
65000
|
+
const element = getNativeByTNode(tNode, lView);
|
|
65001
|
+
enforceIframeSecurity(element);
|
|
65002
|
+
}
|
|
65003
|
+
else if (namespace === SVG_NAMESPACE$1) {
|
|
65004
|
+
const config = SVG_ANIMATION_SENSITIVE_STATIC_VALUES[resolvedTagName]?.[attributeName.toLowerCase()];
|
|
65005
|
+
if (config) {
|
|
65006
|
+
const element = getNativeByTNode(tNode, lView);
|
|
65007
|
+
const attributeNameValue = getSecuritySensitiveSVGAnimationAttributeName(element, config);
|
|
65008
|
+
if (attributeNameValue) {
|
|
65009
|
+
const errorMessage = ngDevMode &&
|
|
65010
|
+
`Angular has detected that the \`${attributeName}\` was applied ` +
|
|
65011
|
+
`as a binding to the <${resolvedTagName}> element${getTemplateLocationDetails(lView)}. ` +
|
|
65012
|
+
`For security reasons, the \`${attributeName}\` can be set on the <${resolvedTagName}> element ` +
|
|
65013
|
+
`as a static attribute only when the "attributeName" is set to \'${attributeNameValue}\'. \n` +
|
|
65014
|
+
`To fix this, switch the \`${attributeNameValue}\` binding to a static attribute ` +
|
|
65015
|
+
`in a template or in host bindings section.`;
|
|
65016
|
+
throw new RuntimeError(-910 /* RuntimeErrorCode.UNSAFE_ATTRIBUTE_BINDING */, errorMessage);
|
|
65017
|
+
}
|
|
65018
|
+
return value;
|
|
65019
|
+
}
|
|
65020
|
+
}
|
|
64522
65021
|
}
|
|
64523
65022
|
const errorMessage = ngDevMode &&
|
|
64524
65023
|
`Angular has detected that the \`${attributeName}\` was applied ` +
|
|
64525
|
-
`as a binding to the <${
|
|
64526
|
-
`For security reasons, the \`${attributeName}\` can be set on the <${
|
|
65024
|
+
`as a binding to the <${resolvedTagName}> element${tNode ? getTemplateLocationDetails(lView) : ''}. ` +
|
|
65025
|
+
`For security reasons, the \`${attributeName}\` can be set on the <${resolvedTagName}> element ` +
|
|
64527
65026
|
`as a static attribute only. \n` +
|
|
64528
65027
|
`To fix this, switch the \`${attributeName}\` binding to a static attribute ` +
|
|
64529
65028
|
`in a template or in host bindings section.`;
|
|
64530
65029
|
throw new RuntimeError(-910 /* RuntimeErrorCode.UNSAFE_ATTRIBUTE_BINDING */, errorMessage);
|
|
64531
65030
|
}
|
|
65031
|
+
function getSecuritySensitiveSVGAnimationAttributeName(element, validationConfig) {
|
|
65032
|
+
for (const attributeName of element.getAttributeNames()) {
|
|
65033
|
+
if (attributeName.toLowerCase() !== 'attributename') {
|
|
65034
|
+
continue;
|
|
65035
|
+
}
|
|
65036
|
+
const attributeNameValue = element.getAttribute(attributeName);
|
|
65037
|
+
if (attributeNameValue !== null && validationConfig.has(attributeNameValue.toLowerCase())) {
|
|
65038
|
+
return attributeNameValue;
|
|
65039
|
+
}
|
|
65040
|
+
}
|
|
65041
|
+
return null;
|
|
65042
|
+
}
|
|
64532
65043
|
|
|
64533
65044
|
/** Defines the default value of the `NG_REFLECT_ATTRS_FLAG` flag. */
|
|
64534
65045
|
const NG_REFLECT_ATTRS_FLAG_DEFAULT = false;
|
|
@@ -67507,7 +68018,9 @@ function setDomProperty(tNode, lView, propName, value, renderer, sanitizer) {
|
|
|
67507
68018
|
if (tNode.type & 3 /* TNodeType.AnyRNode */) {
|
|
67508
68019
|
const element = getNativeByTNode(tNode, lView);
|
|
67509
68020
|
if (ngDevMode) {
|
|
67510
|
-
|
|
68021
|
+
if (lView[TVIEW].firstUpdatePass) {
|
|
68022
|
+
validateAgainstEventProperties(propName);
|
|
68023
|
+
}
|
|
67511
68024
|
if (!isPropertyValid(element, propName, tNode.value, lView[TVIEW].schemas)) {
|
|
67512
68025
|
handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
|
|
67513
68026
|
}
|
|
@@ -67674,7 +68187,6 @@ function findDirectiveDefMatches(tView, tNode) {
|
|
|
67674
68187
|
function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace) {
|
|
67675
68188
|
if (ngDevMode) {
|
|
67676
68189
|
assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
|
|
67677
|
-
validateAgainstEventAttributes(name);
|
|
67678
68190
|
assertTNodeType(tNode, 2 /* TNodeType.Element */, `Attempted to set attribute \`${name}\` on a container node. ` +
|
|
67679
68191
|
`Host bindings are not valid on ng-container or ng-template.`);
|
|
67680
68192
|
}
|
|
@@ -69830,6 +70342,7 @@ function createTNode(tView, tParent, type, index, value, attrs) {
|
|
|
69830
70342
|
flags,
|
|
69831
70343
|
providerIndexes: 0,
|
|
69832
70344
|
value: value,
|
|
70345
|
+
namespace: getNamespace(),
|
|
69833
70346
|
attrs: attrs,
|
|
69834
70347
|
mergedAttrs: null,
|
|
69835
70348
|
localNames: null,
|
|
@@ -72845,9 +73358,14 @@ function createHostElement(componentDef, renderer) {
|
|
|
72845
73358
|
// dynamically. Default to 'div' if this component did not specify any tag name in its
|
|
72846
73359
|
// selector.
|
|
72847
73360
|
const tagName = inferTagNameFromDefinition(componentDef);
|
|
72848
|
-
const namespace = tagName === 'svg' ? SVG_NAMESPACE : tagName === 'math' ? MATH_ML_NAMESPACE : null;
|
|
73361
|
+
const namespace = tagName === 'svg' ? SVG_NAMESPACE$1 : tagName === 'math' ? MATH_ML_NAMESPACE$1 : null;
|
|
72849
73362
|
return createElementNode(renderer, tagName, namespace);
|
|
72850
73363
|
}
|
|
73364
|
+
function assertNotScriptHostElement(tagName) {
|
|
73365
|
+
if (tagName?.toLowerCase() === 'script') {
|
|
73366
|
+
throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, ngDevMode && `"<script>" tag is not allowed as a component host element.`);
|
|
73367
|
+
}
|
|
73368
|
+
}
|
|
72851
73369
|
/**
|
|
72852
73370
|
* Infers the tag name that should be used for a component based on its definition.
|
|
72853
73371
|
* @param componentDef Definition for which to resolve the tag name.
|
|
@@ -72903,6 +73421,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
72903
73421
|
const hostElement = rootSelectorOrNode
|
|
72904
73422
|
? locateHostElement(hostRenderer, rootSelectorOrNode, cmpDef.encapsulation, rootViewInjector)
|
|
72905
73423
|
: createHostElement(cmpDef, hostRenderer);
|
|
73424
|
+
assertNotScriptHostElement(hostElement?.tagName);
|
|
72906
73425
|
const hasInputBindings = componentBindings?.some(isInputBinding) ||
|
|
72907
73426
|
directives?.some((d) => typeof d !== 'function' && d.bindings.some(isInputBinding));
|
|
72908
73427
|
const rootLView = createLView(null, rootTView, null, 512 /* LViewFlags.IsRoot */ | getInitialLViewFlagsFromDef(cmpDef), null, null, environment, hostRenderer, rootViewInjector, null, retrieveHydrationInfo(hostElement, rootViewInjector, true /* isRootView */));
|
|
@@ -72915,7 +73434,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
72915
73434
|
enterView(rootLView);
|
|
72916
73435
|
let componentView = null;
|
|
72917
73436
|
try {
|
|
72918
|
-
const hostTNode = directiveHostFirstCreatePass(HEADER_OFFSET, rootLView, 2 /* TNodeType.Element */,
|
|
73437
|
+
const hostTNode = directiveHostFirstCreatePass(HEADER_OFFSET, rootLView, 2 /* TNodeType.Element */, "#host" /* TNodeName.DynamicHost */, () => rootTView.directiveRegistry, true, 0);
|
|
72919
73438
|
// ---- element instruction
|
|
72920
73439
|
setupStaticAttributes(hostRenderer, hostElement, hostTNode);
|
|
72921
73440
|
attachPatchData(hostElement, rootLView);
|
|
@@ -72953,7 +73472,7 @@ class ComponentFactory extends ComponentFactory$1 {
|
|
|
72953
73472
|
}
|
|
72954
73473
|
function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
|
|
72955
73474
|
const tAttributes = rootSelectorOrNode
|
|
72956
|
-
? ['ng-version', '20.3.
|
|
73475
|
+
? ['ng-version', '20.3.28']
|
|
72957
73476
|
: // Extract attributes and classes from the first selector only to match VE behavior.
|
|
72958
73477
|
extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
|
|
72959
73478
|
let creationBindings = null;
|
|
@@ -82146,11 +82665,19 @@ function getLocalePluralCase(locale) {
|
|
|
82146
82665
|
*/
|
|
82147
82666
|
function getLocaleData(normalizedLocale) {
|
|
82148
82667
|
if (!(normalizedLocale in LOCALE_DATA)) {
|
|
82149
|
-
|
|
82150
|
-
_global.ng &&
|
|
82151
|
-
|
|
82152
|
-
|
|
82153
|
-
|
|
82668
|
+
const globalLocaleData = _global.ng &&
|
|
82669
|
+
_global.ng.common &&
|
|
82670
|
+
_global.ng.common.locales &&
|
|
82671
|
+
_global.ng.common.locales[normalizedLocale];
|
|
82672
|
+
// Only cache global locale data when an entry is actually found, to avoid
|
|
82673
|
+
// caching missing lookups. In SSR this cache is process-wide across requests,
|
|
82674
|
+
// so caching `undefined` would retain attacker-controlled locale identifiers
|
|
82675
|
+
// indefinitely. It would also make the `in` check above short-circuit on
|
|
82676
|
+
// subsequent lookups and skip the global fallback.
|
|
82677
|
+
if (globalLocaleData !== undefined) {
|
|
82678
|
+
LOCALE_DATA[normalizedLocale] = globalLocaleData;
|
|
82679
|
+
}
|
|
82680
|
+
return globalLocaleData;
|
|
82154
82681
|
}
|
|
82155
82682
|
return LOCALE_DATA[normalizedLocale];
|
|
82156
82683
|
}
|
|
@@ -82570,7 +83097,14 @@ function applyUpdateOpCodes(tView, lView, updateOpCodes, bindingsStartIndex, cha
|
|
|
82570
83097
|
setElementAttribute(lView[RENDERER], lView[nodeIndex], null, tNodeOrTagName, propName, value, sanitizeFn);
|
|
82571
83098
|
}
|
|
82572
83099
|
else {
|
|
82573
|
-
|
|
83100
|
+
const prevSelectedIndex = getSelectedIndex();
|
|
83101
|
+
setSelectedIndex(nodeIndex);
|
|
83102
|
+
try {
|
|
83103
|
+
setPropertyAndInputs(tNodeOrTagName, lView, propName, value, lView[RENDERER], sanitizeFn);
|
|
83104
|
+
}
|
|
83105
|
+
finally {
|
|
83106
|
+
setSelectedIndex(prevSelectedIndex);
|
|
83107
|
+
}
|
|
82574
83108
|
}
|
|
82575
83109
|
break;
|
|
82576
83110
|
case 0 /* I18nUpdateOpCode.Text */:
|
|
@@ -83150,7 +83684,10 @@ function i18nAttributesFirstPass(tView, index, values) {
|
|
|
83150
83684
|
// the compiler treats static i18n attributes as regular attribute bindings.
|
|
83151
83685
|
// Since this may not be the first i18n attribute on this element we need to pass in how
|
|
83152
83686
|
// many previous bindings there have already been.
|
|
83153
|
-
|
|
83687
|
+
const tagName = previousElement.namespace
|
|
83688
|
+
? `:${previousElement.namespace}:${previousElement.value}`
|
|
83689
|
+
: previousElement.value;
|
|
83690
|
+
generateBindingUpdateOpCodes(updateOpCodes, message, previousElementIndex, attrName, countBindings(updateOpCodes), i18nResolveSanitizer(attrName, tagName));
|
|
83154
83691
|
}
|
|
83155
83692
|
}
|
|
83156
83693
|
tView.data[index] = updateOpCodes;
|
|
@@ -83476,9 +84013,12 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
|
|
|
83476
84013
|
const attr = elAttrs.item(i);
|
|
83477
84014
|
const lowerAttrName = attr.name.toLowerCase();
|
|
83478
84015
|
const hasBinding = !!attr.value.match(BINDING_REGEXP);
|
|
84016
|
+
const namespaceUri = element.namespaceURI;
|
|
84017
|
+
const namespace = namespaceUri && NAMESPACE_URIS[namespaceUri];
|
|
84018
|
+
const tagNameWithNamespace = namespace ? `:${namespace}:${tagName}` : tagName;
|
|
83479
84019
|
if (hasBinding) {
|
|
83480
84020
|
if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
|
|
83481
|
-
generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0,
|
|
84021
|
+
generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace));
|
|
83482
84022
|
}
|
|
83483
84023
|
else {
|
|
83484
84024
|
ngDevMode &&
|
|
@@ -83488,9 +84028,9 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
|
|
|
83488
84028
|
}
|
|
83489
84029
|
}
|
|
83490
84030
|
else if (VALID_ATTRS[lowerAttrName]) {
|
|
83491
|
-
|
|
83492
|
-
|
|
83493
|
-
|
|
84031
|
+
let val = attr.value;
|
|
84032
|
+
const sanitizer = i18nResolveSanitizer(lowerAttrName, tagNameWithNamespace);
|
|
84033
|
+
if (sanitizer) {
|
|
83494
84034
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
83495
84035
|
console.warn(`WARNING: ignoring unsafe attribute ` +
|
|
83496
84036
|
`${lowerAttrName} on element ${tagName} ` +
|
|
@@ -83499,7 +84039,7 @@ function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remov
|
|
|
83499
84039
|
addCreateAttribute(create, newIndex, attr.name, 'unsafe:blocked');
|
|
83500
84040
|
}
|
|
83501
84041
|
else {
|
|
83502
|
-
addCreateAttribute(create, newIndex, attr.name,
|
|
84042
|
+
addCreateAttribute(create, newIndex, attr.name, val);
|
|
83503
84043
|
}
|
|
83504
84044
|
}
|
|
83505
84045
|
else {
|
|
@@ -83579,6 +84119,37 @@ function addCreateNodeAndAppend(create, marker, text, appendToParentIdx, createA
|
|
|
83579
84119
|
function addCreateAttribute(create, newIndex, attrName, attrValue) {
|
|
83580
84120
|
create.push((newIndex << 1 /* IcuCreateOpCode.SHIFT_REF */) | 1 /* IcuCreateOpCode.Attr */, attrName, attrValue);
|
|
83581
84121
|
}
|
|
84122
|
+
function normalizeTagName(tagName) {
|
|
84123
|
+
const tagNameLower = tagName.toLowerCase();
|
|
84124
|
+
const [ns, name] = splitNsName(tagNameLower, false);
|
|
84125
|
+
return ns === SVG_NAMESPACE || ns === MATH_ML_NAMESPACE ? `:${ns}:${name}` : name;
|
|
84126
|
+
}
|
|
84127
|
+
function i18nResolveSanitizer(attrName, tagName) {
|
|
84128
|
+
const lowerAttrName = attrName.toLowerCase();
|
|
84129
|
+
const lowerTagName = tagName ? normalizeTagName(tagName) : '*';
|
|
84130
|
+
const [namespace] = splitNsName(lowerTagName, false);
|
|
84131
|
+
const schema = SECURITY_SCHEMA();
|
|
84132
|
+
const schemaContext = schema[`${lowerTagName}|${lowerAttrName}`] ||
|
|
84133
|
+
(namespace ? schema[`:${namespace}:*|${lowerAttrName}`] : undefined) ||
|
|
84134
|
+
schema[`*|${lowerAttrName}`] ||
|
|
84135
|
+
SecurityContext.NONE;
|
|
84136
|
+
switch (schemaContext) {
|
|
84137
|
+
case SecurityContext.HTML:
|
|
84138
|
+
return ɵɵsanitizeHtml;
|
|
84139
|
+
case SecurityContext.STYLE:
|
|
84140
|
+
return ɵɵsanitizeStyle;
|
|
84141
|
+
case SecurityContext.SCRIPT:
|
|
84142
|
+
return ɵɵsanitizeScript;
|
|
84143
|
+
case SecurityContext.URL:
|
|
84144
|
+
return _sanitizeUrl;
|
|
84145
|
+
case SecurityContext.RESOURCE_URL:
|
|
84146
|
+
return ɵɵsanitizeResourceUrl;
|
|
84147
|
+
case SecurityContext.ATTRIBUTE_NO_BINDING:
|
|
84148
|
+
return ɵɵvalidateAttribute;
|
|
84149
|
+
default:
|
|
84150
|
+
return null;
|
|
84151
|
+
}
|
|
84152
|
+
}
|
|
83582
84153
|
|
|
83583
84154
|
// i18nPostprocess consts
|
|
83584
84155
|
const ROOT_TEMPLATE_ID = 0;
|
|
@@ -90294,7 +90865,7 @@ function getDebugNode(nativeNode) {
|
|
|
90294
90865
|
}
|
|
90295
90866
|
|
|
90296
90867
|
/**
|
|
90297
|
-
* @license Angular v20.3.
|
|
90868
|
+
* @license Angular v20.3.28
|
|
90298
90869
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
90299
90870
|
* License: MIT
|
|
90300
90871
|
*/
|
|
@@ -90909,7 +91480,7 @@ class ResourceWrappedError extends Error {
|
|
|
90909
91480
|
}
|
|
90910
91481
|
|
|
90911
91482
|
/**
|
|
90912
|
-
* @license Angular v20.3.
|
|
91483
|
+
* @license Angular v20.3.28
|
|
90913
91484
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
90914
91485
|
* License: MIT
|
|
90915
91486
|
*/
|
|
@@ -92368,7 +92939,7 @@ function clearAppScopedEarlyEventContract(appId, dataContainer = window) {
|
|
|
92368
92939
|
}
|
|
92369
92940
|
|
|
92370
92941
|
/**
|
|
92371
|
-
* @license Angular v20.3.
|
|
92942
|
+
* @license Angular v20.3.28
|
|
92372
92943
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
92373
92944
|
* License: MIT
|
|
92374
92945
|
*/
|
|
@@ -97404,7 +97975,7 @@ var i0 = /*#__PURE__*/Object.freeze({
|
|
|
97404
97975
|
});
|
|
97405
97976
|
|
|
97406
97977
|
/**
|
|
97407
|
-
* @license Angular v20.3.
|
|
97978
|
+
* @license Angular v20.3.28
|
|
97408
97979
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
97409
97980
|
* License: MIT
|
|
97410
97981
|
*/
|
|
@@ -97430,7 +98001,7 @@ class XhrFactory {
|
|
|
97430
98001
|
}
|
|
97431
98002
|
|
|
97432
98003
|
/**
|
|
97433
|
-
* @license Angular v20.3.
|
|
98004
|
+
* @license Angular v20.3.28
|
|
97434
98005
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
97435
98006
|
* License: MIT
|
|
97436
98007
|
*/
|
|
@@ -97627,10 +98198,10 @@ class HttpHeaders {
|
|
|
97627
98198
|
}
|
|
97628
98199
|
copyFrom(other) {
|
|
97629
98200
|
other.init();
|
|
97630
|
-
|
|
97631
|
-
this.headers.set(key,
|
|
98201
|
+
for (const [key, values] of other.headers.entries()) {
|
|
98202
|
+
this.headers.set(key, values);
|
|
97632
98203
|
this.normalizedNames.set(key, other.normalizedNames.get(key));
|
|
97633
|
-
}
|
|
98204
|
+
}
|
|
97634
98205
|
}
|
|
97635
98206
|
clone(update) {
|
|
97636
98207
|
const clone = new HttpHeaders();
|
|
@@ -97651,22 +98222,23 @@ class HttpHeaders {
|
|
|
97651
98222
|
return;
|
|
97652
98223
|
}
|
|
97653
98224
|
this.maybeSetNormalizedName(update.name, key);
|
|
97654
|
-
const base =
|
|
98225
|
+
const base = update.op === 'a' ? (this.headers.get(key) || []).slice() : [];
|
|
97655
98226
|
base.push(...value);
|
|
97656
98227
|
this.headers.set(key, base);
|
|
97657
98228
|
break;
|
|
97658
98229
|
case 'd':
|
|
97659
98230
|
const toDelete = update.value;
|
|
97660
|
-
if (
|
|
98231
|
+
if (toDelete === undefined) {
|
|
97661
98232
|
this.headers.delete(key);
|
|
97662
98233
|
this.normalizedNames.delete(key);
|
|
97663
98234
|
}
|
|
97664
98235
|
else {
|
|
98236
|
+
const valuesToDelete = Array.isArray(toDelete) ? toDelete : [toDelete];
|
|
97665
98237
|
let existing = this.headers.get(key);
|
|
97666
98238
|
if (!existing) {
|
|
97667
98239
|
return;
|
|
97668
98240
|
}
|
|
97669
|
-
existing = existing.filter((value) =>
|
|
98241
|
+
existing = existing.filter((value) => valuesToDelete.indexOf(value) === -1);
|
|
97670
98242
|
if (existing.length === 0) {
|
|
97671
98243
|
this.headers.delete(key);
|
|
97672
98244
|
this.normalizedNames.delete(key);
|
|
@@ -97955,18 +98527,20 @@ class HttpParams {
|
|
|
97955
98527
|
}
|
|
97956
98528
|
if (this.cloneFrom !== null) {
|
|
97957
98529
|
this.cloneFrom.init();
|
|
97958
|
-
|
|
98530
|
+
for (const [key, values] of this.cloneFrom.map.entries()) {
|
|
98531
|
+
this.map.set(key, values);
|
|
98532
|
+
}
|
|
97959
98533
|
this.updates.forEach((update) => {
|
|
97960
98534
|
switch (update.op) {
|
|
97961
98535
|
case 'a':
|
|
97962
98536
|
case 's':
|
|
97963
|
-
const base =
|
|
98537
|
+
const base = update.op === 'a' ? (this.map.get(update.param) || []).slice() : [];
|
|
97964
98538
|
base.push(valueToString(update.value));
|
|
97965
98539
|
this.map.set(update.param, base);
|
|
97966
98540
|
break;
|
|
97967
98541
|
case 'd':
|
|
97968
98542
|
if (update.value !== undefined) {
|
|
97969
|
-
|
|
98543
|
+
const base = (this.map.get(update.param) || []).slice();
|
|
97970
98544
|
const idx = base.indexOf(valueToString(update.value));
|
|
97971
98545
|
if (idx !== -1) {
|
|
97972
98546
|
base.splice(idx, 1);
|
|
@@ -98337,7 +98911,7 @@ class HttpRequest {
|
|
|
98337
98911
|
if (options.integrity) {
|
|
98338
98912
|
this.integrity = options.integrity;
|
|
98339
98913
|
}
|
|
98340
|
-
if (options.referrer) {
|
|
98914
|
+
if (options.referrer !== undefined) {
|
|
98341
98915
|
this.referrer = options.referrer;
|
|
98342
98916
|
}
|
|
98343
98917
|
// We do want to assign transferCache even if it's falsy (false is valid value)
|
|
@@ -98459,7 +99033,7 @@ class HttpRequest {
|
|
|
98459
99033
|
const mode = update.mode || this.mode;
|
|
98460
99034
|
const redirect = update.redirect || this.redirect;
|
|
98461
99035
|
const credentials = update.credentials || this.credentials;
|
|
98462
|
-
const referrer = update.referrer
|
|
99036
|
+
const referrer = update.referrer ?? this.referrer;
|
|
98463
99037
|
const integrity = update.integrity || this.integrity;
|
|
98464
99038
|
// Carefully handle the transferCache to differentiate between
|
|
98465
99039
|
// `false` and `undefined` in the update args.
|
|
@@ -99108,8 +99682,8 @@ class HttpClient {
|
|
|
99108
99682
|
put(url, body, options = {}) {
|
|
99109
99683
|
return this.request('PUT', url, addBody(options, body));
|
|
99110
99684
|
}
|
|
99111
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
99112
|
-
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
99685
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClient, deps: [{ token: HttpHandler }], target: FactoryTarget.Injectable });
|
|
99686
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClient });
|
|
99113
99687
|
}
|
|
99114
99688
|
ɵɵngDeclareClassMetadata({ type: HttpClient, decorators: [{
|
|
99115
99689
|
type: Injectable
|
|
@@ -99398,8 +99972,8 @@ class FetchBackend {
|
|
|
99398
99972
|
}
|
|
99399
99973
|
return chunksAll;
|
|
99400
99974
|
}
|
|
99401
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
99402
|
-
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
99975
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: FetchBackend, deps: [], target: FactoryTarget.Injectable });
|
|
99976
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: FetchBackend });
|
|
99403
99977
|
}
|
|
99404
99978
|
ɵɵngDeclareClassMetadata({ type: FetchBackend, decorators: [{
|
|
99405
99979
|
type: Injectable
|
|
@@ -99529,10 +100103,10 @@ class HttpInterceptorHandler extends HttpHandler {
|
|
|
99529
100103
|
}
|
|
99530
100104
|
handle(initialRequest) {
|
|
99531
100105
|
if (this.chain === null) {
|
|
99532
|
-
const
|
|
99533
|
-
|
|
99534
|
-
|
|
99535
|
-
]));
|
|
100106
|
+
const parentHandler = this.injector.get(HttpHandler, null, { skipSelf: true });
|
|
100107
|
+
const isDelegating = parentHandler !== null && this.backend === parentHandler;
|
|
100108
|
+
const rootInterceptorFns = this.injector.get(HTTP_ROOT_INTERCEPTOR_FNS, [], isDelegating ? { self: true } : undefined);
|
|
100109
|
+
const dedupedInterceptorFns = Array.from(new Set([...this.injector.get(HTTP_INTERCEPTOR_FNS), ...rootInterceptorFns]));
|
|
99536
100110
|
// Note: interceptors are wrapped right-to-left so that final execution order is
|
|
99537
100111
|
// left-to-right. That is, if `dedupedInterceptorFns` is the array `[a, b, c]`, we want to
|
|
99538
100112
|
// produce a chain that is conceptually `c(b(a(end)))`, which we build from the inside
|
|
@@ -99547,8 +100121,8 @@ class HttpInterceptorHandler extends HttpHandler {
|
|
|
99547
100121
|
return this.chain(initialRequest, (downstreamRequest) => this.backend.handle(downstreamRequest));
|
|
99548
100122
|
}
|
|
99549
100123
|
}
|
|
99550
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
99551
|
-
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
100124
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpInterceptorHandler, deps: [{ token: HttpBackend }, { token: EnvironmentInjector }], target: FactoryTarget.Injectable });
|
|
100125
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpInterceptorHandler });
|
|
99552
100126
|
}
|
|
99553
100127
|
ɵɵngDeclareClassMetadata({ type: HttpInterceptorHandler, decorators: [{
|
|
99554
100128
|
type: Injectable
|
|
@@ -99574,6 +100148,8 @@ const JSONP_ERR_WRONG_RESPONSE_TYPE = 'JSONP requests must use Json response typ
|
|
|
99574
100148
|
// Error text given when a request is passed to the JsonpClientBackend that has
|
|
99575
100149
|
// headers set
|
|
99576
100150
|
const JSONP_ERR_HEADERS_NOT_SUPPORTED = 'JSONP requests do not support headers.';
|
|
100151
|
+
// Error text given when a JSONP request URL is not absolute HTTP(S).
|
|
100152
|
+
const JSONP_ERR_UNSAFE_URL = 'JSONP requests only support absolute URLs with HTTP(S) protocols.';
|
|
99577
100153
|
/**
|
|
99578
100154
|
* DI token/abstract type representing a map of JSONP callbacks.
|
|
99579
100155
|
*
|
|
@@ -99642,6 +100218,9 @@ class JsonpClientBackend {
|
|
|
99642
100218
|
if (req.headers.keys().length > 0) {
|
|
99643
100219
|
throw new RuntimeError(2812 /* RuntimeErrorCode.JSONP_HEADERS_NOT_SUPPORTED */, ngDevMode && JSONP_ERR_HEADERS_NOT_SUPPORTED);
|
|
99644
100220
|
}
|
|
100221
|
+
if (!this.isAllowedJsonpUrl(req.urlWithParams)) {
|
|
100222
|
+
throw new RuntimeError(2826 /* RuntimeErrorCode.JSONP_UNSAFE_URL */, ngDevMode && JSONP_ERR_UNSAFE_URL);
|
|
100223
|
+
}
|
|
99645
100224
|
// Everything else happens inside the Observable boundary.
|
|
99646
100225
|
return new Observable((observer) => {
|
|
99647
100226
|
// The first step to make a request is to generate the callback name, and replace the
|
|
@@ -99752,8 +100331,11 @@ class JsonpClientBackend {
|
|
|
99752
100331
|
foreignDocument ??= this.document.implementation.createHTMLDocument();
|
|
99753
100332
|
foreignDocument.adoptNode(script);
|
|
99754
100333
|
}
|
|
99755
|
-
|
|
99756
|
-
|
|
100334
|
+
isAllowedJsonpUrl(url) {
|
|
100335
|
+
return /^https?:\/\//i.test(url);
|
|
100336
|
+
}
|
|
100337
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: JsonpClientBackend, deps: [{ token: JsonpCallbackContext }, { token: DOCUMENT$1 }], target: FactoryTarget.Injectable });
|
|
100338
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: JsonpClientBackend });
|
|
99757
100339
|
}
|
|
99758
100340
|
ɵɵngDeclareClassMetadata({ type: JsonpClientBackend, decorators: [{
|
|
99759
100341
|
type: Injectable
|
|
@@ -99794,8 +100376,8 @@ class JsonpInterceptor {
|
|
|
99794
100376
|
intercept(initialRequest, next) {
|
|
99795
100377
|
return runInInjectionContext(this.injector, () => jsonpInterceptorFn(initialRequest, (downstreamRequest) => next.handle(downstreamRequest)));
|
|
99796
100378
|
}
|
|
99797
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
99798
|
-
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
100379
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: JsonpInterceptor, deps: [{ token: EnvironmentInjector }], target: FactoryTarget.Injectable });
|
|
100380
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: JsonpInterceptor });
|
|
99799
100381
|
}
|
|
99800
100382
|
ɵɵngDeclareClassMetadata({ type: JsonpInterceptor, decorators: [{
|
|
99801
100383
|
type: Injectable
|
|
@@ -100149,8 +100731,8 @@ class HttpXhrBackend {
|
|
|
100149
100731
|
});
|
|
100150
100732
|
}));
|
|
100151
100733
|
}
|
|
100152
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
100153
|
-
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
100734
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpXhrBackend, deps: [{ token: XhrFactory }], target: FactoryTarget.Injectable });
|
|
100735
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpXhrBackend });
|
|
100154
100736
|
}
|
|
100155
100737
|
ɵɵngDeclareClassMetadata({ type: HttpXhrBackend, decorators: [{
|
|
100156
100738
|
type: Injectable
|
|
@@ -100202,8 +100784,8 @@ class HttpXsrfCookieExtractor {
|
|
|
100202
100784
|
}
|
|
100203
100785
|
return this.lastToken;
|
|
100204
100786
|
}
|
|
100205
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
100206
|
-
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
100787
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpXsrfCookieExtractor, deps: [{ token: DOCUMENT$1 }, { token: XSRF_COOKIE_NAME }], target: FactoryTarget.Injectable });
|
|
100788
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpXsrfCookieExtractor });
|
|
100207
100789
|
}
|
|
100208
100790
|
ɵɵngDeclareClassMetadata({ type: HttpXsrfCookieExtractor, decorators: [{
|
|
100209
100791
|
type: Injectable
|
|
@@ -100248,8 +100830,8 @@ class HttpXsrfInterceptor {
|
|
|
100248
100830
|
intercept(initialRequest, next) {
|
|
100249
100831
|
return runInInjectionContext(this.injector, () => xsrfInterceptorFn(initialRequest, (downstreamRequest) => next.handle(downstreamRequest)));
|
|
100250
100832
|
}
|
|
100251
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
100252
|
-
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
100833
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpXsrfInterceptor, deps: [{ token: EnvironmentInjector }], target: FactoryTarget.Injectable });
|
|
100834
|
+
static ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpXsrfInterceptor });
|
|
100253
100835
|
}
|
|
100254
100836
|
ɵɵngDeclareClassMetadata({ type: HttpXsrfInterceptor, decorators: [{
|
|
100255
100837
|
type: Injectable
|
|
@@ -100310,9 +100892,11 @@ function provideHttpClient(...features) {
|
|
|
100310
100892
|
const featureKinds = new Set(features.map((f) => f.ɵkind));
|
|
100311
100893
|
if (featureKinds.has(HttpFeatureKind.NoXsrfProtection) &&
|
|
100312
100894
|
featureKinds.has(HttpFeatureKind.CustomXsrfConfiguration)) {
|
|
100313
|
-
throw new Error(
|
|
100314
|
-
|
|
100315
|
-
|
|
100895
|
+
throw new Error(`Configuration error: found both withXsrfConfiguration() and withNoXsrfProtection() in the same call to provideHttpClient(), which is a contradiction.`);
|
|
100896
|
+
}
|
|
100897
|
+
if (featureKinds.has(HttpFeatureKind.RequestsMadeViaParent) &&
|
|
100898
|
+
featureKinds.has(HttpFeatureKind.Fetch)) {
|
|
100899
|
+
throw new Error(`Configuration error: withRequestsMadeViaParent() cannot be combined with withFetch() in the same call to provideHttpClient().`);
|
|
100316
100900
|
}
|
|
100317
100901
|
}
|
|
100318
100902
|
const providers = [
|
|
@@ -100452,9 +101036,9 @@ class HttpClientXsrfModule {
|
|
|
100452
101036
|
providers: withXsrfConfiguration(options).ɵproviders,
|
|
100453
101037
|
};
|
|
100454
101038
|
}
|
|
100455
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
100456
|
-
static ɵmod = ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
100457
|
-
static ɵinj = ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
101039
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClientXsrfModule, deps: [], target: FactoryTarget.NgModule });
|
|
101040
|
+
static ɵmod = ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.28", ngImport: i0, type: HttpClientXsrfModule });
|
|
101041
|
+
static ɵinj = ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClientXsrfModule, providers: [
|
|
100458
101042
|
HttpXsrfInterceptor,
|
|
100459
101043
|
{ provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true },
|
|
100460
101044
|
{ provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor },
|
|
@@ -100491,9 +101075,9 @@ class HttpClientXsrfModule {
|
|
|
100491
101075
|
* @deprecated use `provideHttpClient(withInterceptorsFromDi())` as providers instead
|
|
100492
101076
|
*/
|
|
100493
101077
|
class HttpClientModule {
|
|
100494
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
100495
|
-
static ɵmod = ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
100496
|
-
static ɵinj = ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
101078
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClientModule, deps: [], target: FactoryTarget.NgModule });
|
|
101079
|
+
static ɵmod = ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.28", ngImport: i0, type: HttpClientModule });
|
|
101080
|
+
static ɵinj = ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClientModule, providers: [provideHttpClient(withInterceptorsFromDi())] });
|
|
100497
101081
|
}
|
|
100498
101082
|
ɵɵngDeclareClassMetadata({ type: HttpClientModule, decorators: [{
|
|
100499
101083
|
type: NgModule,
|
|
@@ -100515,9 +101099,9 @@ class HttpClientModule {
|
|
|
100515
101099
|
* @deprecated `withJsonpSupport()` as providers instead
|
|
100516
101100
|
*/
|
|
100517
101101
|
class HttpClientJsonpModule {
|
|
100518
|
-
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
100519
|
-
static ɵmod = ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
100520
|
-
static ɵinj = ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
101102
|
+
static ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClientJsonpModule, deps: [], target: FactoryTarget.NgModule });
|
|
101103
|
+
static ɵmod = ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.28", ngImport: i0, type: HttpClientJsonpModule });
|
|
101104
|
+
static ɵinj = ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: HttpClientJsonpModule, providers: [withJsonpSupport().ɵproviders] });
|
|
100521
101105
|
}
|
|
100522
101106
|
ɵɵngDeclareClassMetadata({ type: HttpClientJsonpModule, decorators: [{
|
|
100523
101107
|
type: NgModule,
|
|
@@ -103327,8 +103911,8 @@ class Viewport {
|
|
|
103327
103911
|
}
|
|
103328
103912
|
this.mediaQuery = null;
|
|
103329
103913
|
}
|
|
103330
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103331
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
103914
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: Viewport, deps: [], target: FactoryTarget.Injectable }); }
|
|
103915
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: Viewport, providedIn: 'root' }); }
|
|
103332
103916
|
}
|
|
103333
103917
|
ɵɵngDeclareClassMetadata({ type: Viewport, decorators: [{
|
|
103334
103918
|
type: Injectable,
|
|
@@ -103349,8 +103933,8 @@ class ConstantService {
|
|
|
103349
103933
|
};
|
|
103350
103934
|
this.VALIDATOR = VALIDATOR;
|
|
103351
103935
|
}
|
|
103352
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103353
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
103936
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ConstantService, deps: [], target: FactoryTarget.Injectable }); }
|
|
103937
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ConstantService, providedIn: 'root' }); }
|
|
103354
103938
|
}
|
|
103355
103939
|
ɵɵngDeclareClassMetadata({ type: ConstantService, decorators: [{
|
|
103356
103940
|
type: Injectable,
|
|
@@ -103361,8 +103945,8 @@ class UtilsService {
|
|
|
103361
103945
|
constructor() {
|
|
103362
103946
|
assign(this, Utils);
|
|
103363
103947
|
}
|
|
103364
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103365
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
103948
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: UtilsService, deps: [], target: FactoryTarget.Injectable }); }
|
|
103949
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: UtilsService, providedIn: 'root' }); }
|
|
103366
103950
|
}
|
|
103367
103951
|
ɵɵngDeclareClassMetadata({ type: UtilsService, decorators: [{
|
|
103368
103952
|
type: Injectable,
|
|
@@ -103393,8 +103977,8 @@ class FieldTypeService {
|
|
|
103393
103977
|
BLOB: 'blob'
|
|
103394
103978
|
});
|
|
103395
103979
|
}
|
|
103396
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103397
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
103980
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: FieldTypeService, deps: [], target: FactoryTarget.Injectable }); }
|
|
103981
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: FieldTypeService, providedIn: 'root' }); }
|
|
103398
103982
|
}
|
|
103399
103983
|
ɵɵngDeclareClassMetadata({ type: FieldTypeService, decorators: [{
|
|
103400
103984
|
type: Injectable,
|
|
@@ -103427,8 +104011,8 @@ class FieldWidgetService {
|
|
|
103427
104011
|
COLORPICKER: 'colorpicker'
|
|
103428
104012
|
});
|
|
103429
104013
|
}
|
|
103430
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103431
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
104014
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: FieldWidgetService, deps: [], target: FactoryTarget.Injectable }); }
|
|
104015
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: FieldWidgetService, providedIn: 'root' }); }
|
|
103432
104016
|
}
|
|
103433
104017
|
ɵɵngDeclareClassMetadata({ type: FieldWidgetService, decorators: [{
|
|
103434
104018
|
type: Injectable,
|
|
@@ -103497,8 +104081,8 @@ class ScriptLoaderService {
|
|
|
103497
104081
|
document.getElementsByTagName('head')[0].appendChild(script);
|
|
103498
104082
|
});
|
|
103499
104083
|
}
|
|
103500
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103501
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
104084
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ScriptLoaderService, deps: [{ token: HttpClient }], target: FactoryTarget.Injectable }); }
|
|
104085
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: ScriptLoaderService, providedIn: 'root' }); }
|
|
103502
104086
|
}
|
|
103503
104087
|
ɵɵngDeclareClassMetadata({ type: ScriptLoaderService, decorators: [{
|
|
103504
104088
|
type: Injectable,
|
|
@@ -103518,8 +104102,8 @@ class CustomPipeManager {
|
|
|
103518
104102
|
hasCustomPipe(key) {
|
|
103519
104103
|
return this.customPipes.has(key);
|
|
103520
104104
|
}
|
|
103521
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103522
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
104105
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: CustomPipeManager, deps: [], target: FactoryTarget.Injectable }); }
|
|
104106
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: CustomPipeManager, providedIn: 'root' }); }
|
|
103523
104107
|
}
|
|
103524
104108
|
ɵɵngDeclareClassMetadata({ type: CustomPipeManager, decorators: [{
|
|
103525
104109
|
type: Injectable,
|
|
@@ -103535,8 +104119,8 @@ class CustomIconsLoaderService {
|
|
|
103535
104119
|
.map(font => font.csspath);
|
|
103536
104120
|
loadStyleSheets(cssPaths);
|
|
103537
104121
|
}
|
|
103538
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
103539
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
104122
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: CustomIconsLoaderService, deps: [], target: FactoryTarget.Injectable }); }
|
|
104123
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: CustomIconsLoaderService, providedIn: 'root' }); }
|
|
103540
104124
|
}
|
|
103541
104125
|
ɵɵngDeclareClassMetadata({ type: CustomIconsLoaderService, decorators: [{
|
|
103542
104126
|
type: Injectable,
|
|
@@ -104032,8 +104616,8 @@ class StatePersistence {
|
|
|
104032
104616
|
}
|
|
104033
104617
|
return response;
|
|
104034
104618
|
}
|
|
104035
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
104036
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
104619
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: StatePersistence, deps: [], target: FactoryTarget.Injectable }); }
|
|
104620
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: StatePersistence, providedIn: 'root' }); }
|
|
104037
104621
|
}
|
|
104038
104622
|
ɵɵngDeclareClassMetadata({ type: StatePersistence, decorators: [{
|
|
104039
104623
|
type: Injectable,
|
|
@@ -104364,8 +104948,8 @@ class PaginationService {
|
|
|
104364
104948
|
lastScrollTop = scrollTop;
|
|
104365
104949
|
});
|
|
104366
104950
|
}
|
|
104367
|
-
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
104368
|
-
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
104951
|
+
static { this.ɵfac = ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: PaginationService, deps: [], target: FactoryTarget.Injectable }); }
|
|
104952
|
+
static { this.ɵprov = ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.28", ngImport: i0, type: PaginationService, providedIn: 'root' }); }
|
|
104369
104953
|
}
|
|
104370
104954
|
ɵɵngDeclareClassMetadata({ type: PaginationService, decorators: [{
|
|
104371
104955
|
type: Injectable,
|