@angular/core 22.0.0-next.4 → 22.0.0-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/fesm2022/_attribute-chunk.mjs +1 -1
  2. package/fesm2022/_debug_node-chunk.mjs +162 -21
  3. package/fesm2022/_debug_node-chunk.mjs.map +1 -1
  4. package/fesm2022/_effect-chunk.mjs +1 -1
  5. package/fesm2022/_not_found-chunk.mjs +1 -1
  6. package/fesm2022/_pending_tasks-chunk.mjs +2 -2
  7. package/fesm2022/_pending_tasks-chunk.mjs.map +1 -1
  8. package/fesm2022/_resource-chunk.mjs +1 -1
  9. package/fesm2022/_resource-chunk.mjs.map +1 -1
  10. package/fesm2022/_untracked-chunk.mjs +1 -1
  11. package/fesm2022/_weak_ref-chunk.mjs +1 -1
  12. package/fesm2022/core.mjs +40 -17
  13. package/fesm2022/core.mjs.map +1 -1
  14. package/fesm2022/primitives-di.mjs +1 -1
  15. package/fesm2022/primitives-event-dispatch.mjs +1 -1
  16. package/fesm2022/primitives-signals.mjs +1 -1
  17. package/fesm2022/rxjs-interop.mjs +1 -1
  18. package/fesm2022/testing.mjs +1 -1
  19. package/fesm2022/testing.mjs.map +1 -1
  20. package/package.json +2 -2
  21. package/schematics/bundles/apply_import_manager-CxA_YYgB.cjs +1 -1
  22. package/schematics/bundles/change-detection-eager.cjs +1 -1
  23. package/schematics/bundles/cleanup-unused-imports.cjs +1 -1
  24. package/schematics/bundles/common-to-standalone-migration.cjs +1 -1
  25. package/schematics/bundles/compiler_host-CY14HvaP.cjs +1 -1
  26. package/schematics/bundles/control-flow-migration.cjs +1 -1
  27. package/schematics/bundles/http-xhr-backend.cjs +6 -11
  28. package/schematics/bundles/imports-CKV-ITqD.cjs +1 -1
  29. package/schematics/bundles/index-BtLcQH8g.cjs +1 -1
  30. package/schematics/bundles/inject-migration.cjs +26 -18
  31. package/schematics/bundles/leading_space-BTPRV0wu.cjs +1 -1
  32. package/schematics/bundles/migrate_ts_type_references-Dp33iyGx.cjs +1 -1
  33. package/schematics/bundles/ng_component_template-DPAF1aEA.cjs +1 -1
  34. package/schematics/bundles/ng_decorators-IVztR9rk.cjs +1 -1
  35. package/schematics/bundles/ngclass-to-class-migration.cjs +1 -1
  36. package/schematics/bundles/ngstyle-to-style-migration.cjs +1 -1
  37. package/schematics/bundles/nodes-ZSQ7WZRB.cjs +1 -1
  38. package/schematics/bundles/output-migration.cjs +1 -1
  39. package/schematics/bundles/parse_html-C8eKA9px.cjs +1 -1
  40. package/schematics/bundles/project_paths-D2V-Uh2L.cjs +1 -1
  41. package/schematics/bundles/project_tsconfig_paths-DkkMibv-.cjs +1 -1
  42. package/schematics/bundles/property_name-BCpALNpZ.cjs +1 -1
  43. package/schematics/bundles/route-lazy-loading.cjs +22 -2
  44. package/schematics/bundles/router-testing-module-migration.cjs +1 -1
  45. package/schematics/bundles/self-closing-tags-migration.cjs +1 -1
  46. package/schematics/bundles/signal-input-migration.cjs +1 -1
  47. package/schematics/bundles/signal-queries-migration.cjs +1 -1
  48. package/schematics/bundles/signals.cjs +1 -1
  49. package/schematics/bundles/standalone-migration.cjs +1 -1
  50. package/schematics/bundles/strict-templates.cjs +55 -0
  51. package/schematics/migrations.json +5 -0
  52. package/types/_api-chunk.d.ts +7 -2
  53. package/types/_chrome_dev_tools_performance-chunk.d.ts +1 -1
  54. package/types/_debug_node-chunk.d.ts +18 -13
  55. package/types/_effect-chunk.d.ts +1 -1
  56. package/types/_event_dispatcher-chunk.d.ts +1 -1
  57. package/types/_formatter-chunk.d.ts +1 -1
  58. package/types/_weak_ref-chunk.d.ts +1 -1
  59. package/types/core.d.ts +13 -21
  60. package/types/primitives-di.d.ts +1 -1
  61. package/types/primitives-event-dispatch.d.ts +1 -1
  62. package/types/primitives-signals.d.ts +1 -1
  63. package/types/rxjs-interop.d.ts +1 -1
  64. package/types/testing.d.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v22.0.0-next.4
2
+ * @license Angular v22.0.0-next.6
3
3
  * (c) 2010-2026 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v22.0.0-next.4
2
+ * @license Angular v22.0.0-next.6
3
3
  * (c) 2010-2026 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -3354,10 +3354,37 @@ function ɵɵtrustConstantResourceUrl(url) {
3354
3354
  }
3355
3355
  return trustedScriptURLFromString(url[0]);
3356
3356
  }
3357
- const SRC_RESOURCE_TAGS = new Set(['embed', 'frame', 'iframe', 'media', 'script']);
3358
- const HREF_RESOURCE_TAGS = new Set(['base', 'link', 'script']);
3357
+ const RESOURCE_MAP = {
3358
+ 'embed': {
3359
+ 'src': true
3360
+ },
3361
+ 'frame': {
3362
+ 'src': true
3363
+ },
3364
+ 'iframe': {
3365
+ 'src': true
3366
+ },
3367
+ 'media': {
3368
+ 'src': true
3369
+ },
3370
+ 'script': {
3371
+ 'src': true,
3372
+ 'href': true,
3373
+ 'xlink:href': true
3374
+ },
3375
+ 'base': {
3376
+ 'href': true
3377
+ },
3378
+ 'link': {
3379
+ 'href': true
3380
+ },
3381
+ 'object': {
3382
+ 'data': true,
3383
+ 'codebase': true
3384
+ }
3385
+ };
3359
3386
  function getUrlSanitizer(tag, prop) {
3360
- const isResource = prop === 'src' && SRC_RESOURCE_TAGS.has(tag) || prop === 'href' && HREF_RESOURCE_TAGS.has(tag) || prop === 'xlink:href' && tag === 'script';
3387
+ const isResource = RESOURCE_MAP[tag]?.[prop] === true;
3361
3388
  return isResource ? ɵɵsanitizeResourceUrl : ɵɵsanitizeUrl;
3362
3389
  }
3363
3390
  function ɵɵsanitizeUrlOrResourceUrl(unsafeUrl, tag, prop) {
@@ -3379,18 +3406,38 @@ function getSanitizer() {
3379
3406
  const lView = getLView();
3380
3407
  return lView && lView[ENVIRONMENT].sanitizer;
3381
3408
  }
3382
- const attributeName = new Set(['attributename']);
3409
+ const SECURITY_SENSITIVE_ATTRIBUTE_NAMES = new Set(['href', 'xlink:href']);
3383
3410
  const SECURITY_SENSITIVE_ELEMENTS = {
3384
- 'iframe': new Set(['sandbox', 'allow', 'allowfullscreen', 'referrerpolicy', 'csp', 'fetchpriority']),
3385
- 'animate': attributeName,
3386
- 'set': attributeName,
3387
- 'animatemotion': attributeName,
3388
- 'animatetransform': attributeName
3411
+ 'iframe': {
3412
+ 'sandbox': true,
3413
+ 'allow': true,
3414
+ 'allowfullscreen': true,
3415
+ 'referrerpolicy': true,
3416
+ 'csp': true,
3417
+ 'fetchpriority': true
3418
+ },
3419
+ 'animate': {
3420
+ 'attributename': true,
3421
+ 'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
3422
+ 'values': SECURITY_SENSITIVE_ATTRIBUTE_NAMES,
3423
+ 'from': SECURITY_SENSITIVE_ATTRIBUTE_NAMES
3424
+ },
3425
+ 'set': {
3426
+ 'attributename': true,
3427
+ 'to': SECURITY_SENSITIVE_ATTRIBUTE_NAMES
3428
+ },
3429
+ 'animatemotion': {
3430
+ 'attributename': true
3431
+ },
3432
+ 'animatetransform': {
3433
+ 'attributename': true
3434
+ }
3389
3435
  };
3390
3436
  function ɵɵvalidateAttribute(value, tagName, attributeName) {
3391
3437
  const lowerCaseTagName = tagName.toLowerCase();
3392
3438
  const lowerCaseAttrName = attributeName.toLowerCase();
3393
- if (!SECURITY_SENSITIVE_ELEMENTS[lowerCaseTagName]?.has(lowerCaseAttrName)) {
3439
+ const validationConfig = SECURITY_SENSITIVE_ELEMENTS[lowerCaseTagName]?.[lowerCaseAttrName];
3440
+ if (!validationConfig) {
3394
3441
  return value;
3395
3442
  }
3396
3443
  const tNode = getSelectedTNode();
@@ -3402,6 +3449,15 @@ function ɵɵvalidateAttribute(value, tagName, attributeName) {
3402
3449
  const element = getNativeByTNode(tNode, lView);
3403
3450
  enforceIframeSecurity(element);
3404
3451
  }
3452
+ if (typeof validationConfig !== 'boolean') {
3453
+ const element = getNativeByTNode(tNode, lView);
3454
+ const attributeNameValue = element.getAttribute('attributeName');
3455
+ if (attributeNameValue && validationConfig.has(attributeNameValue.toLowerCase())) {
3456
+ const errorMessage = ngDevMode && `Angular has detected that the \`${attributeName}\` was applied ` + `as a binding to the <${tagName}> element${getTemplateLocationDetails(lView)}. ` + `For security reasons, the \`${attributeName}\` can be set on the <${tagName}> element ` + `as a static attribute only when the "attributeName" is set to \'${attributeNameValue}\'. \n` + `To fix this, switch the \`${attributeNameValue}\` binding to a static attribute ` + `in a template or in host bindings section.`;
3457
+ throw new RuntimeError(-910, errorMessage);
3458
+ }
3459
+ return value;
3460
+ }
3405
3461
  const errorMessage = ngDevMode && `Angular has detected that the \`${attributeName}\` was applied ` + `as a binding to the <${tagName}> element${getTemplateLocationDetails(lView)}. ` + `For security reasons, the \`${attributeName}\` can be set on the <${tagName}> element ` + `as a static attribute only. \n` + `To fix this, switch the \`${attributeName}\` binding to a static attribute ` + `in a template or in host bindings section.`;
3406
3462
  throw new RuntimeError(-910, errorMessage);
3407
3463
  }
@@ -4716,6 +4772,7 @@ function applyToElementOrContainer(action, renderer, injector, parent, lNodeToHa
4716
4772
  if (parentLView?.[ANIMATIONS]?.leave?.has(tNode.index)) {
4717
4773
  trackLeavingNodes(tNode, rNode);
4718
4774
  }
4775
+ reusedNodes.delete(rNode);
4719
4776
  runLeaveAnimationsWithCallback(parentLView, tNode, injector, nodeHasLeaveAnimations => {
4720
4777
  if (reusedNodes.has(rNode)) {
4721
4778
  reusedNodes.delete(rNode);
@@ -4724,6 +4781,7 @@ function applyToElementOrContainer(action, renderer, injector, parent, lNodeToHa
4724
4781
  nativeRemoveNode(renderer, rNode, isComponent, nodeHasLeaveAnimations);
4725
4782
  });
4726
4783
  } else if (action === 3) {
4784
+ reusedNodes.delete(rNode);
4727
4785
  runLeaveAnimationsWithCallback(parentLView, tNode, injector, () => {
4728
4786
  renderer.destroyNode(rNode);
4729
4787
  });
@@ -8429,14 +8487,13 @@ class ControlDirectiveHostImpl {
8429
8487
  return `<${this.tNode.value}>`;
8430
8488
  }
8431
8489
  listenToCustomControlOutput(outputName, callback) {
8432
- if (!hasOutput(this.tView.data[this.tNode.customControlIndex], outputName)) {
8433
- return;
8434
- }
8435
- listenToOutput(this.tNode, this.lView, this.tNode.customControlIndex, outputName, outputName, wrapListener(this.tNode, this.lView, callback));
8490
+ const directiveDef = this.tView.data[this.tNode.customControlIndex];
8491
+ listenToDirectiveOutput(this.tNode, this.lView, directiveDef, outputName, wrapListener(this.tNode, this.lView, callback));
8436
8492
  }
8437
8493
  listenToCustomControlModel(listener) {
8438
8494
  const modelName = this.tNode.flags & 1024 ? 'valueChange' : 'checkedChange';
8439
- listenToOutput(this.tNode, this.lView, this.tNode.customControlIndex, modelName, modelName, wrapListener(this.tNode, this.lView, listener));
8495
+ const directiveDef = this.tView.data[this.tNode.customControlIndex];
8496
+ listenToDirectiveOutput(this.tNode, this.lView, directiveDef, modelName, wrapListener(this.tNode, this.lView, listener));
8440
8497
  }
8441
8498
  listenToDom(eventName, listener) {
8442
8499
  listenToDomEvent(this.tNode, this.tView, this.lView, undefined, this.lView[RENDERER], eventName, listener, wrapListener(this.tNode, this.lView, listener));
@@ -8475,19 +8532,63 @@ class ControlDirectiveHostImpl {
8475
8532
  return wasSet;
8476
8533
  }
8477
8534
  setCustomControlModelInput(value) {
8478
- const directive = this.lView[this.tNode.customControlIndex];
8479
8535
  const directiveDef = this.tView.data[this.tNode.customControlIndex];
8480
8536
  const modelName = this.tNode.flags & 1024 ? 'value' : 'checked';
8481
- writeToDirectiveInput(directiveDef, directive, modelName, value);
8537
+ setDirectiveInput(this.tNode, this.tView, this.lView, directiveDef, modelName, value);
8482
8538
  }
8483
8539
  customControlHasInput(inputName) {
8484
8540
  if (this.tNode.customControlIndex === -1) {
8485
8541
  return false;
8486
8542
  }
8487
8543
  const directiveDef = this.tView.data[this.tNode.customControlIndex];
8488
- return directiveDef.inputs[inputName] != undefined;
8544
+ const presence = directiveDef.signalFormsInputPresence ??= this._buildCustomControlInputCache(directiveDef);
8545
+ return presence[inputName] === true;
8546
+ }
8547
+ _buildCustomControlInputCache(directiveDef) {
8548
+ const cache = {};
8549
+ for (const key in directiveDef.inputs) {
8550
+ cache[key] = true;
8551
+ }
8552
+ if (directiveDef.hostDirectives !== null) {
8553
+ const queue = [...directiveDef.hostDirectives];
8554
+ while (queue.length > 0) {
8555
+ const hostDir = queue.shift();
8556
+ if (typeof hostDir !== 'function') {
8557
+ for (const key in hostDir.inputs) {
8558
+ cache[hostDir.inputs[key]] = true;
8559
+ }
8560
+ const hostDirectives = getHostDirectives(hostDir.directive);
8561
+ if (hostDirectives !== null) {
8562
+ queue.push(...hostDirectives);
8563
+ }
8564
+ continue;
8565
+ }
8566
+ for (const config of hostDir()) {
8567
+ if (typeof config === 'function') {
8568
+ continue;
8569
+ }
8570
+ if (config.inputs) {
8571
+ for (let i = 0; i < config.inputs.length; i += 2) {
8572
+ const exposedName = config.inputs[i + 1] || config.inputs[i];
8573
+ cache[exposedName] = true;
8574
+ }
8575
+ }
8576
+ const hostDirectives = getHostDirectives(config.directive);
8577
+ if (hostDirectives !== null) {
8578
+ queue.push(...hostDirectives);
8579
+ }
8580
+ }
8581
+ }
8582
+ }
8583
+ return cache;
8489
8584
  }
8490
8585
  }
8586
+ function getHostDirectives(directiveType) {
8587
+ if (typeof directiveType === 'function' && 'ɵdir' in directiveType) {
8588
+ return directiveType.ɵdir.hostDirectives ?? null;
8589
+ }
8590
+ return null;
8591
+ }
8491
8592
  function initializeControlFirstCreatePass(tView, tNode, lView) {
8492
8593
  ngDevMode && assertFirstCreatePass(tView);
8493
8594
  for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
@@ -8512,6 +8613,9 @@ function initializeControlFirstCreatePass(tView, tNode, lView) {
8512
8613
  function initializeCustomControlStatus(tView, tNode) {
8513
8614
  for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
8514
8615
  const directiveDef = tView.data[i];
8616
+ if (tNode.directiveToIndex && !tNode.directiveToIndex.has(directiveDef.type)) {
8617
+ continue;
8618
+ }
8515
8619
  if (hasModelInput(directiveDef, 'value')) {
8516
8620
  tNode.flags |= 1024;
8517
8621
  tNode.customControlIndex = i;
@@ -8523,6 +8627,42 @@ function initializeCustomControlStatus(tView, tNode) {
8523
8627
  return;
8524
8628
  }
8525
8629
  }
8630
+ if (tNode.hostDirectiveInputs !== null && tNode.hostDirectiveOutputs !== null && tNode.directiveToIndex !== null) {
8631
+ const checkModel = (modelName, flag) => {
8632
+ const inputs = tNode.hostDirectiveInputs[modelName];
8633
+ const outputs = tNode.hostDirectiveOutputs[modelName + 'Change'];
8634
+ if (!inputs || !outputs) {
8635
+ return false;
8636
+ }
8637
+ for (let i = 0; i < inputs.length; i += 2) {
8638
+ const inputIndex = inputs[i];
8639
+ for (let j = 0; j < outputs.length; j += 2) {
8640
+ const outputIndex = outputs[j];
8641
+ if (inputIndex !== outputIndex) {
8642
+ continue;
8643
+ }
8644
+ for (const data of tNode.directiveToIndex.values()) {
8645
+ if (!Array.isArray(data)) {
8646
+ continue;
8647
+ }
8648
+ const [hostIndex, start, end] = data;
8649
+ if (inputIndex >= start && inputIndex <= end) {
8650
+ tNode.flags |= flag;
8651
+ tNode.customControlIndex = hostIndex;
8652
+ return true;
8653
+ }
8654
+ }
8655
+ }
8656
+ }
8657
+ return false;
8658
+ };
8659
+ if (checkModel('value', 1024)) {
8660
+ return;
8661
+ }
8662
+ if (checkModel('checked', 2048)) {
8663
+ return;
8664
+ }
8665
+ }
8526
8666
  }
8527
8667
  function hasModelInput(directiveDef, name) {
8528
8668
  return hasInput(directiveDef, name) && hasOutput(directiveDef, name + 'Change');
@@ -8806,7 +8946,7 @@ class ComponentFactory extends ComponentFactory$1 {
8806
8946
  }
8807
8947
  }
8808
8948
  function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
8809
- const tAttributes = rootSelectorOrNode ? ['ng-version', '22.0.0-next.4'] : extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
8949
+ const tAttributes = rootSelectorOrNode ? ['ng-version', '22.0.0-next.6'] : extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
8810
8950
  let creationBindings = null;
8811
8951
  let updateBindings = null;
8812
8952
  let varsToAllocate = 0;
@@ -9730,7 +9870,7 @@ function ɵɵdefineComponent(componentDefinition) {
9730
9870
  template: componentDefinition.template,
9731
9871
  consts: componentDefinition.consts || null,
9732
9872
  ngContentSelectors: componentDefinition.ngContentSelectors,
9733
- onPush: componentDefinition.changeDetection === ChangeDetectionStrategy.OnPush,
9873
+ onPush: componentDefinition.changeDetection !== ChangeDetectionStrategy.Eager,
9734
9874
  directiveDefs: null,
9735
9875
  pipeDefs: null,
9736
9876
  dependencies: baseDef.standalone && componentDefinition.dependencies || null,
@@ -9853,6 +9993,7 @@ function getNgDirectiveDef(directiveDefinition) {
9853
9993
  resolveHostDirectives: null,
9854
9994
  hostDirectives: null,
9855
9995
  controlDef: null,
9996
+ signalFormsInputPresence: null,
9856
9997
  inputs: parseAndConvertInputsForDefinition(directiveDefinition.inputs, declaredInputs),
9857
9998
  outputs: parseAndConvertOutputsForDefinition(directiveDefinition.outputs),
9858
9999
  debugInfo: null