@angular/core 18.0.4 → 18.0.5
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/esm2022/primitives/event-dispatch/src/eventcontract.mjs +2 -2
- package/esm2022/src/change_detection/change_detector_ref.mjs +3 -2
- package/esm2022/src/defer/instructions.mjs +2 -2
- package/esm2022/src/di/host_tag_name_token.mjs +4 -1
- package/esm2022/src/errors.mjs +1 -1
- package/esm2022/src/event_delegation_utils.mjs +3 -2
- package/esm2022/src/hydration/annotate.mjs +27 -16
- package/esm2022/src/hydration/error_handling.mjs +3 -1
- package/esm2022/src/hydration/event_replay.mjs +3 -2
- package/esm2022/src/hydration/i18n.mjs +102 -18
- package/esm2022/src/hydration/node_lookup_utils.mjs +12 -6
- package/esm2022/src/render3/after_render_hooks.mjs +3 -1
- package/esm2022/src/render3/collect_native_nodes.mjs +6 -1
- package/esm2022/src/render3/component_ref.mjs +1 -1
- package/esm2022/src/render3/instructions/i18n_icu_container_visitor.mjs +61 -51
- package/esm2022/src/render3/instructions/let_declaration.mjs +30 -7
- package/esm2022/src/render3/instructions/projection.mjs +14 -11
- package/esm2022/src/render3/instructions/shared.mjs +1 -1
- package/esm2022/src/render3/interfaces/node.mjs +2 -1
- package/esm2022/src/render3/node_assert.mjs +9 -8
- package/esm2022/src/render3/node_manipulation.mjs +10 -3
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/testing/src/logger.mjs +3 -3
- package/fesm2022/core.mjs +291 -140
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +2 -2
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/index.d.ts +11 -3
- package/package.json +1 -1
- package/primitives/event-dispatch/index.d.ts +2 -2
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/migrations/http-providers/bundle.js +15 -15
- package/schematics/migrations/invalid-two-way-bindings/bundle.js +167 -162
- package/schematics/migrations/invalid-two-way-bindings/bundle.js.map +2 -2
- package/schematics/ng-generate/control-flow-migration/bundle.js +175 -170
- package/schematics/ng-generate/control-flow-migration/bundle.js.map +2 -2
- package/schematics/ng-generate/standalone-migration/bundle.js +453 -448
- package/schematics/ng-generate/standalone-migration/bundle.js.map +3 -3
- package/testing/index.d.ts +1 -1
package/fesm2022/core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v18.0.
|
|
2
|
+
* @license Angular v18.0.5
|
|
3
3
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -5317,6 +5317,7 @@ function toTNodeTypeAsString(tNodeType) {
|
|
|
5317
5317
|
tNodeType & 16 /* TNodeType.Projection */ && (text += '|Projection');
|
|
5318
5318
|
tNodeType & 32 /* TNodeType.Icu */ && (text += '|IcuContainer');
|
|
5319
5319
|
tNodeType & 64 /* TNodeType.Placeholder */ && (text += '|Placeholder');
|
|
5320
|
+
tNodeType & 128 /* TNodeType.LetDeclaration */ && (text += '|LetDeclaration');
|
|
5320
5321
|
return text.length > 0 ? text.substring(1) : text;
|
|
5321
5322
|
}
|
|
5322
5323
|
/**
|
|
@@ -5392,13 +5393,14 @@ function assertTNodeType(tNode, expectedTypes, message) {
|
|
|
5392
5393
|
}
|
|
5393
5394
|
}
|
|
5394
5395
|
function assertPureTNodeType(type) {
|
|
5395
|
-
if (!(type === 2 /* TNodeType.Element */ ||
|
|
5396
|
-
type === 1 /* TNodeType.Text */ ||
|
|
5397
|
-
type === 4 /* TNodeType.Container */ ||
|
|
5398
|
-
type === 8 /* TNodeType.ElementContainer */ ||
|
|
5399
|
-
type === 32 /* TNodeType.Icu */ ||
|
|
5400
|
-
type === 16 /* TNodeType.Projection */ ||
|
|
5401
|
-
type === 64 /* TNodeType.Placeholder */
|
|
5396
|
+
if (!(type === 2 /* TNodeType.Element */ ||
|
|
5397
|
+
type === 1 /* TNodeType.Text */ ||
|
|
5398
|
+
type === 4 /* TNodeType.Container */ ||
|
|
5399
|
+
type === 8 /* TNodeType.ElementContainer */ ||
|
|
5400
|
+
type === 32 /* TNodeType.Icu */ ||
|
|
5401
|
+
type === 16 /* TNodeType.Projection */ ||
|
|
5402
|
+
type === 64 /* TNodeType.Placeholder */ ||
|
|
5403
|
+
type === 128 /* TNodeType.LetDeclaration */)) {
|
|
5402
5404
|
throwError(`Expected TNodeType to have only a single type selected, but got ${toTNodeTypeAsString(type)}.`);
|
|
5403
5405
|
}
|
|
5404
5406
|
}
|
|
@@ -6596,6 +6598,9 @@ function getDevModeNodeName(tNode) {
|
|
|
6596
6598
|
else if (tNode.type & 4 /* TNodeType.Container */) {
|
|
6597
6599
|
return 'an <ng-template>';
|
|
6598
6600
|
}
|
|
6601
|
+
else if (tNode.type & 128 /* TNodeType.LetDeclaration */) {
|
|
6602
|
+
return 'an @let declaration';
|
|
6603
|
+
}
|
|
6599
6604
|
else {
|
|
6600
6605
|
return 'a node';
|
|
6601
6606
|
}
|
|
@@ -10840,8 +10845,10 @@ function getParentRElement(tView, tNode, lView) {
|
|
|
10840
10845
|
function getClosestRElement(tView, tNode, lView) {
|
|
10841
10846
|
let parentTNode = tNode;
|
|
10842
10847
|
// Skip over element and ICU containers as those are represented by a comment node and
|
|
10843
|
-
// can't be used as a render parent.
|
|
10844
|
-
|
|
10848
|
+
// can't be used as a render parent. Also skip let declarations since they don't have a
|
|
10849
|
+
// corresponding DOM node at all.
|
|
10850
|
+
while (parentTNode !== null &&
|
|
10851
|
+
parentTNode.type & (8 /* TNodeType.ElementContainer */ | 32 /* TNodeType.Icu */ | 128 /* TNodeType.LetDeclaration */)) {
|
|
10845
10852
|
tNode = parentTNode;
|
|
10846
10853
|
parentTNode = tNode.parent;
|
|
10847
10854
|
}
|
|
@@ -11091,6 +11098,11 @@ function clearElementContents(rElement) {
|
|
|
11091
11098
|
function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode, isProjection) {
|
|
11092
11099
|
while (tNode != null) {
|
|
11093
11100
|
ngDevMode && assertTNodeForLView(tNode, lView);
|
|
11101
|
+
// Let declarations don't have corresponding DOM nodes so we skip over them.
|
|
11102
|
+
if (tNode.type === 128 /* TNodeType.LetDeclaration */) {
|
|
11103
|
+
tNode = tNode.next;
|
|
11104
|
+
continue;
|
|
11105
|
+
}
|
|
11094
11106
|
ngDevMode &&
|
|
11095
11107
|
assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 16 /* TNodeType.Projection */ | 32 /* TNodeType.Icu */);
|
|
11096
11108
|
const rawSlotValue = lView[tNode.index];
|
|
@@ -12941,6 +12953,11 @@ function removeLViewFromLContainer(lContainer, index) {
|
|
|
12941
12953
|
|
|
12942
12954
|
function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
|
|
12943
12955
|
while (tNode !== null) {
|
|
12956
|
+
// Let declarations don't have corresponding DOM nodes so we skip over them.
|
|
12957
|
+
if (tNode.type === 128 /* TNodeType.LetDeclaration */) {
|
|
12958
|
+
tNode = isProjection ? tNode.projectionNext : tNode.next;
|
|
12959
|
+
continue;
|
|
12960
|
+
}
|
|
12944
12961
|
ngDevMode &&
|
|
12945
12962
|
assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 16 /* TNodeType.Projection */ | 32 /* TNodeType.Icu */);
|
|
12946
12963
|
const lNode = lView[tNode.index];
|
|
@@ -13882,6 +13899,8 @@ function getFriendlyStringFromTNodeType(tNodeType) {
|
|
|
13882
13899
|
return 'projection';
|
|
13883
13900
|
case 1 /* TNodeType.Text */:
|
|
13884
13901
|
return 'text';
|
|
13902
|
+
case 128 /* TNodeType.LetDeclaration */:
|
|
13903
|
+
return '@let';
|
|
13885
13904
|
default:
|
|
13886
13905
|
// This should not happen as we cover all possible TNode types above.
|
|
13887
13906
|
return '<unknown>';
|
|
@@ -14476,6 +14495,89 @@ function isRootTemplateMessage(subTemplateIndex) {
|
|
|
14476
14495
|
return subTemplateIndex === -1;
|
|
14477
14496
|
}
|
|
14478
14497
|
|
|
14498
|
+
function enterIcu(state, tIcu, lView) {
|
|
14499
|
+
state.index = 0;
|
|
14500
|
+
const currentCase = getCurrentICUCaseIndex(tIcu, lView);
|
|
14501
|
+
if (currentCase !== null) {
|
|
14502
|
+
ngDevMode && assertNumberInRange(currentCase, 0, tIcu.cases.length - 1);
|
|
14503
|
+
state.removes = tIcu.remove[currentCase];
|
|
14504
|
+
}
|
|
14505
|
+
else {
|
|
14506
|
+
state.removes = EMPTY_ARRAY;
|
|
14507
|
+
}
|
|
14508
|
+
}
|
|
14509
|
+
function icuContainerIteratorNext(state) {
|
|
14510
|
+
if (state.index < state.removes.length) {
|
|
14511
|
+
const removeOpCode = state.removes[state.index++];
|
|
14512
|
+
ngDevMode && assertNumber(removeOpCode, 'Expecting OpCode number');
|
|
14513
|
+
if (removeOpCode > 0) {
|
|
14514
|
+
const rNode = state.lView[removeOpCode];
|
|
14515
|
+
ngDevMode && assertDomNode(rNode);
|
|
14516
|
+
return rNode;
|
|
14517
|
+
}
|
|
14518
|
+
else {
|
|
14519
|
+
state.stack.push(state.index, state.removes);
|
|
14520
|
+
// ICUs are represented by negative indices
|
|
14521
|
+
const tIcuIndex = ~removeOpCode;
|
|
14522
|
+
const tIcu = state.lView[TVIEW].data[tIcuIndex];
|
|
14523
|
+
ngDevMode && assertTIcu(tIcu);
|
|
14524
|
+
enterIcu(state, tIcu, state.lView);
|
|
14525
|
+
return icuContainerIteratorNext(state);
|
|
14526
|
+
}
|
|
14527
|
+
}
|
|
14528
|
+
else {
|
|
14529
|
+
if (state.stack.length === 0) {
|
|
14530
|
+
return null;
|
|
14531
|
+
}
|
|
14532
|
+
else {
|
|
14533
|
+
state.removes = state.stack.pop();
|
|
14534
|
+
state.index = state.stack.pop();
|
|
14535
|
+
return icuContainerIteratorNext(state);
|
|
14536
|
+
}
|
|
14537
|
+
}
|
|
14538
|
+
}
|
|
14539
|
+
function loadIcuContainerVisitor() {
|
|
14540
|
+
const _state = {
|
|
14541
|
+
stack: [],
|
|
14542
|
+
index: -1,
|
|
14543
|
+
};
|
|
14544
|
+
/**
|
|
14545
|
+
* Retrieves a set of root nodes from `TIcu.remove`. Used by `TNodeType.ICUContainer`
|
|
14546
|
+
* to determine which root belong to the ICU.
|
|
14547
|
+
*
|
|
14548
|
+
* Example of usage.
|
|
14549
|
+
* ```
|
|
14550
|
+
* const nextRNode = icuContainerIteratorStart(tIcuContainerNode, lView);
|
|
14551
|
+
* let rNode: RNode|null;
|
|
14552
|
+
* while(rNode = nextRNode()) {
|
|
14553
|
+
* console.log(rNode);
|
|
14554
|
+
* }
|
|
14555
|
+
* ```
|
|
14556
|
+
*
|
|
14557
|
+
* @param tIcuContainerNode Current `TIcuContainerNode`
|
|
14558
|
+
* @param lView `LView` where the `RNode`s should be looked up.
|
|
14559
|
+
*/
|
|
14560
|
+
function icuContainerIteratorStart(tIcuContainerNode, lView) {
|
|
14561
|
+
_state.lView = lView;
|
|
14562
|
+
while (_state.stack.length)
|
|
14563
|
+
_state.stack.pop();
|
|
14564
|
+
ngDevMode && assertTNodeForLView(tIcuContainerNode, lView);
|
|
14565
|
+
enterIcu(_state, tIcuContainerNode.value, lView);
|
|
14566
|
+
return icuContainerIteratorNext.bind(null, _state);
|
|
14567
|
+
}
|
|
14568
|
+
return icuContainerIteratorStart;
|
|
14569
|
+
}
|
|
14570
|
+
function createIcuIterator(tIcu, lView) {
|
|
14571
|
+
const state = {
|
|
14572
|
+
stack: [],
|
|
14573
|
+
index: -1,
|
|
14574
|
+
lView,
|
|
14575
|
+
};
|
|
14576
|
+
ngDevMode && assertTIcu(tIcu);
|
|
14577
|
+
enterIcu(state, tIcu, lView);
|
|
14578
|
+
return icuContainerIteratorNext.bind(null, state);
|
|
14579
|
+
}
|
|
14580
|
+
|
|
14479
14581
|
/**
|
|
14480
14582
|
* Regexp that extracts a reference node information from the compressed node location.
|
|
14481
14583
|
* The reference node is represented as either:
|
|
@@ -14547,15 +14649,21 @@ function getNoOffsetIndex(tNode) {
|
|
|
14547
14649
|
}
|
|
14548
14650
|
/**
|
|
14549
14651
|
* Check whether a given node exists, but is disconnected from the DOM.
|
|
14652
|
+
*/
|
|
14653
|
+
function isDisconnectedNode(tNode, lView) {
|
|
14654
|
+
return (!(tNode.type & (16 /* TNodeType.Projection */ | 128 /* TNodeType.LetDeclaration */)) &&
|
|
14655
|
+
!!lView[tNode.index] &&
|
|
14656
|
+
isDisconnectedRNode(unwrapRNode(lView[tNode.index])));
|
|
14657
|
+
}
|
|
14658
|
+
/**
|
|
14659
|
+
* Check whether the given node exists, but is disconnected from the DOM.
|
|
14550
14660
|
*
|
|
14551
14661
|
* Note: we leverage the fact that we have this information available in the DOM emulation
|
|
14552
14662
|
* layer (in Domino) for now. Longer-term solution should not rely on the DOM emulation and
|
|
14553
14663
|
* only use internal data structures and state to compute this information.
|
|
14554
14664
|
*/
|
|
14555
|
-
function
|
|
14556
|
-
return
|
|
14557
|
-
!!lView[tNode.index] &&
|
|
14558
|
-
!unwrapRNode(lView[tNode.index])?.isConnected);
|
|
14665
|
+
function isDisconnectedRNode(rNode) {
|
|
14666
|
+
return !!rNode && !rNode.isConnected;
|
|
14559
14667
|
}
|
|
14560
14668
|
/**
|
|
14561
14669
|
* Locate a node in an i18n tree that corresponds to a given instruction index.
|
|
@@ -14819,7 +14927,7 @@ function calcPathForNode(tNode, lView, excludedParentNodes) {
|
|
|
14819
14927
|
referenceNodeName = renderStringify(parentIndex - HEADER_OFFSET);
|
|
14820
14928
|
}
|
|
14821
14929
|
let rNode = unwrapRNode(lView[tNode.index]);
|
|
14822
|
-
if (tNode.type & 12 /* TNodeType.AnyContainer */) {
|
|
14930
|
+
if (tNode.type & (12 /* TNodeType.AnyContainer */ | 32 /* TNodeType.Icu */)) {
|
|
14823
14931
|
// For <ng-container> nodes, instead of serializing a reference
|
|
14824
14932
|
// to the anchor comment node, serialize a location of the first
|
|
14825
14933
|
// DOM element. Paired with the container size (serialized as a part
|
|
@@ -14951,30 +15059,104 @@ function trySerializeI18nBlock(lView, index, context) {
|
|
|
14951
15059
|
if (!tI18n || !tI18n.ast) {
|
|
14952
15060
|
return null;
|
|
14953
15061
|
}
|
|
14954
|
-
const
|
|
14955
|
-
|
|
14956
|
-
|
|
15062
|
+
const serializedI18nBlock = {
|
|
15063
|
+
caseQueue: [],
|
|
15064
|
+
disconnectedNodes: new Set(),
|
|
15065
|
+
disjointNodes: new Set(),
|
|
15066
|
+
};
|
|
15067
|
+
serializeI18nBlock(lView, serializedI18nBlock, context, tI18n.ast);
|
|
15068
|
+
return serializedI18nBlock.caseQueue.length === 0 &&
|
|
15069
|
+
serializedI18nBlock.disconnectedNodes.size === 0 &&
|
|
15070
|
+
serializedI18nBlock.disjointNodes.size === 0
|
|
15071
|
+
? null
|
|
15072
|
+
: serializedI18nBlock;
|
|
15073
|
+
}
|
|
15074
|
+
function serializeI18nBlock(lView, serializedI18nBlock, context, nodes) {
|
|
15075
|
+
let prevRNode = null;
|
|
15076
|
+
for (const node of nodes) {
|
|
15077
|
+
const nextRNode = serializeI18nNode(lView, serializedI18nBlock, context, node);
|
|
15078
|
+
if (nextRNode) {
|
|
15079
|
+
if (isDisjointNode(prevRNode, nextRNode)) {
|
|
15080
|
+
serializedI18nBlock.disjointNodes.add(node.index - HEADER_OFFSET);
|
|
15081
|
+
}
|
|
15082
|
+
prevRNode = nextRNode;
|
|
15083
|
+
}
|
|
15084
|
+
}
|
|
15085
|
+
return prevRNode;
|
|
14957
15086
|
}
|
|
14958
|
-
|
|
15087
|
+
/**
|
|
15088
|
+
* Helper to determine whether the given nodes are "disjoint".
|
|
15089
|
+
*
|
|
15090
|
+
* The i18n hydration process walks through the DOM and i18n nodes
|
|
15091
|
+
* at the same time. It expects the sibling DOM node of the previous
|
|
15092
|
+
* i18n node to be the first node of the next i18n node.
|
|
15093
|
+
*
|
|
15094
|
+
* In cases of content projection, this won't always be the case. So
|
|
15095
|
+
* when we detect that, we mark the node as "disjoint", ensuring that
|
|
15096
|
+
* we will serialize the path to the node. This way, when we hydrate the
|
|
15097
|
+
* i18n node, we will be able to find the correct place to start.
|
|
15098
|
+
*/
|
|
15099
|
+
function isDisjointNode(prevNode, nextNode) {
|
|
15100
|
+
return prevNode && prevNode.nextSibling !== nextNode;
|
|
15101
|
+
}
|
|
15102
|
+
/**
|
|
15103
|
+
* Process the given i18n node for serialization.
|
|
15104
|
+
* Returns the first RNode for the i18n node to begin hydration.
|
|
15105
|
+
*/
|
|
15106
|
+
function serializeI18nNode(lView, serializedI18nBlock, context, node) {
|
|
15107
|
+
const maybeRNode = unwrapRNode(lView[node.index]);
|
|
15108
|
+
if (!maybeRNode || isDisconnectedRNode(maybeRNode)) {
|
|
15109
|
+
serializedI18nBlock.disconnectedNodes.add(node.index - HEADER_OFFSET);
|
|
15110
|
+
return null;
|
|
15111
|
+
}
|
|
15112
|
+
const rNode = maybeRNode;
|
|
14959
15113
|
switch (node.kind) {
|
|
14960
|
-
case 0 /* I18nNodeKind.TEXT */:
|
|
14961
|
-
const rNode = unwrapRNode(lView[node.index]);
|
|
15114
|
+
case 0 /* I18nNodeKind.TEXT */: {
|
|
14962
15115
|
processTextNodeBeforeSerialization(context, rNode);
|
|
14963
15116
|
break;
|
|
15117
|
+
}
|
|
14964
15118
|
case 1 /* I18nNodeKind.ELEMENT */:
|
|
14965
|
-
case 2 /* I18nNodeKind.PLACEHOLDER */:
|
|
14966
|
-
|
|
15119
|
+
case 2 /* I18nNodeKind.PLACEHOLDER */: {
|
|
15120
|
+
serializeI18nBlock(lView, serializedI18nBlock, context, node.children);
|
|
14967
15121
|
break;
|
|
14968
|
-
|
|
15122
|
+
}
|
|
15123
|
+
case 3 /* I18nNodeKind.ICU */: {
|
|
14969
15124
|
const currentCase = lView[node.currentCaseLViewIndex];
|
|
14970
15125
|
if (currentCase != null) {
|
|
14971
15126
|
// i18n uses a negative value to signal a change to a new case, so we
|
|
14972
15127
|
// need to invert it to get the proper value.
|
|
14973
15128
|
const caseIdx = currentCase < 0 ? ~currentCase : currentCase;
|
|
14974
|
-
caseQueue.push(caseIdx);
|
|
14975
|
-
|
|
15129
|
+
serializedI18nBlock.caseQueue.push(caseIdx);
|
|
15130
|
+
serializeI18nBlock(lView, serializedI18nBlock, context, node.cases[caseIdx]);
|
|
14976
15131
|
}
|
|
14977
15132
|
break;
|
|
15133
|
+
}
|
|
15134
|
+
}
|
|
15135
|
+
return getFirstNativeNodeForI18nNode(lView, node);
|
|
15136
|
+
}
|
|
15137
|
+
/**
|
|
15138
|
+
* Helper function to get the first native node to begin hydrating
|
|
15139
|
+
* the given i18n node.
|
|
15140
|
+
*/
|
|
15141
|
+
function getFirstNativeNodeForI18nNode(lView, node) {
|
|
15142
|
+
const tView = lView[TVIEW];
|
|
15143
|
+
const maybeTNode = tView.data[node.index];
|
|
15144
|
+
if (isTNodeShape(maybeTNode)) {
|
|
15145
|
+
// If the node is backed by an actual TNode, we can simply delegate.
|
|
15146
|
+
return getFirstNativeNode(lView, maybeTNode);
|
|
15147
|
+
}
|
|
15148
|
+
else if (node.kind === 3 /* I18nNodeKind.ICU */) {
|
|
15149
|
+
// A nested ICU container won't have an actual TNode. In that case, we can use
|
|
15150
|
+
// an iterator to find the first child.
|
|
15151
|
+
const icuIterator = createIcuIterator(maybeTNode, lView);
|
|
15152
|
+
let rNode = icuIterator();
|
|
15153
|
+
// If the ICU container has no nodes, then we use the ICU anchor as the node.
|
|
15154
|
+
return rNode ?? unwrapRNode(lView[node.index]);
|
|
15155
|
+
}
|
|
15156
|
+
else {
|
|
15157
|
+
// Otherwise, the node is a text or trivial element in an ICU container,
|
|
15158
|
+
// and we can just use the RNode directly.
|
|
15159
|
+
return unwrapRNode(lView[node.index]) ?? null;
|
|
14978
15160
|
}
|
|
14979
15161
|
}
|
|
14980
15162
|
function setCurrentNode(state, node) {
|
|
@@ -15067,16 +15249,24 @@ function prepareI18nBlockForHydrationImpl(lView, index, parentTNode, subTemplate
|
|
|
15067
15249
|
}
|
|
15068
15250
|
function collectI18nNodesFromDom(context, state, nodeOrNodes) {
|
|
15069
15251
|
if (Array.isArray(nodeOrNodes)) {
|
|
15252
|
+
let nextState = state;
|
|
15070
15253
|
for (const node of nodeOrNodes) {
|
|
15071
|
-
//
|
|
15072
|
-
//
|
|
15073
|
-
//
|
|
15254
|
+
// Whenever a node doesn't directly follow the previous RNode, it
|
|
15255
|
+
// is given a path. We need to resume collecting nodes from that location
|
|
15256
|
+
// until and unless we find another disjoint node.
|
|
15074
15257
|
const targetNode = tryLocateRNodeByPath(context.hydrationInfo, context.lView, node.index - HEADER_OFFSET);
|
|
15075
|
-
|
|
15258
|
+
if (targetNode) {
|
|
15259
|
+
nextState = forkHydrationState(state, targetNode);
|
|
15260
|
+
}
|
|
15076
15261
|
collectI18nNodesFromDom(context, nextState, node);
|
|
15077
15262
|
}
|
|
15078
15263
|
}
|
|
15079
15264
|
else {
|
|
15265
|
+
if (context.disconnectedNodes.has(nodeOrNodes.index - HEADER_OFFSET)) {
|
|
15266
|
+
// i18n nodes can be considered disconnected if e.g. they were projected.
|
|
15267
|
+
// In that case, we have to make sure to skip over them.
|
|
15268
|
+
return;
|
|
15269
|
+
}
|
|
15080
15270
|
switch (nodeOrNodes.kind) {
|
|
15081
15271
|
case 0 /* I18nNodeKind.TEXT */: {
|
|
15082
15272
|
// Claim a text node for hydration
|
|
@@ -16157,6 +16347,7 @@ function internalAfterNextRender(callback, options) {
|
|
|
16157
16347
|
* </div>
|
|
16158
16348
|
*
|
|
16159
16349
|
* @param callback A callback function to register
|
|
16350
|
+
* @param options Options to control the behavior of the callback
|
|
16160
16351
|
*
|
|
16161
16352
|
* @usageNotes
|
|
16162
16353
|
*
|
|
@@ -16229,6 +16420,7 @@ function afterRender(callback, options) {
|
|
|
16229
16420
|
* </div>
|
|
16230
16421
|
*
|
|
16231
16422
|
* @param callback A callback function to register
|
|
16423
|
+
* @param options Options to control the behavior of the callback
|
|
16232
16424
|
*
|
|
16233
16425
|
* @usageNotes
|
|
16234
16426
|
*
|
|
@@ -17064,7 +17256,7 @@ function createRootComponent(componentView, rootComponentDef, rootDirectives, ho
|
|
|
17064
17256
|
function setRootNodeAttributes(hostRenderer, componentDef, hostRNode, rootSelectorOrNode) {
|
|
17065
17257
|
if (rootSelectorOrNode) {
|
|
17066
17258
|
// The placeholder will be replaced with the actual version at build time.
|
|
17067
|
-
setUpAttributes(hostRenderer, hostRNode, ['ng-version', '18.0.
|
|
17259
|
+
setUpAttributes(hostRenderer, hostRNode, ['ng-version', '18.0.5']);
|
|
17068
17260
|
}
|
|
17069
17261
|
else {
|
|
17070
17262
|
// If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
|
|
@@ -20866,7 +21058,7 @@ function triggerResourceLoading(tDetails, lView, tNode) {
|
|
|
20866
21058
|
if (failed) {
|
|
20867
21059
|
tDetails.loadingState = DeferDependenciesLoadingState.FAILED;
|
|
20868
21060
|
if (tDetails.errorTmplIndex === null) {
|
|
20869
|
-
const templateLocation = getTemplateLocationDetails(lView);
|
|
21061
|
+
const templateLocation = ngDevMode ? getTemplateLocationDetails(lView) : '';
|
|
20870
21062
|
const error = new RuntimeError(750 /* RuntimeErrorCode.DEFER_LOADING_FAILED */, ngDevMode &&
|
|
20871
21063
|
'Loading dependencies for `@defer` block failed, ' +
|
|
20872
21064
|
`but no \`@error\` block was configured${templateLocation}. ` +
|
|
@@ -25149,79 +25341,6 @@ function getCaseIndex(icuExpression, bindingValue) {
|
|
|
25149
25341
|
return index === -1 ? null : index;
|
|
25150
25342
|
}
|
|
25151
25343
|
|
|
25152
|
-
function loadIcuContainerVisitor() {
|
|
25153
|
-
const _stack = [];
|
|
25154
|
-
let _index = -1;
|
|
25155
|
-
let _lView;
|
|
25156
|
-
let _removes;
|
|
25157
|
-
/**
|
|
25158
|
-
* Retrieves a set of root nodes from `TIcu.remove`. Used by `TNodeType.ICUContainer`
|
|
25159
|
-
* to determine which root belong to the ICU.
|
|
25160
|
-
*
|
|
25161
|
-
* Example of usage.
|
|
25162
|
-
* ```
|
|
25163
|
-
* const nextRNode = icuContainerIteratorStart(tIcuContainerNode, lView);
|
|
25164
|
-
* let rNode: RNode|null;
|
|
25165
|
-
* while(rNode = nextRNode()) {
|
|
25166
|
-
* console.log(rNode);
|
|
25167
|
-
* }
|
|
25168
|
-
* ```
|
|
25169
|
-
*
|
|
25170
|
-
* @param tIcuContainerNode Current `TIcuContainerNode`
|
|
25171
|
-
* @param lView `LView` where the `RNode`s should be looked up.
|
|
25172
|
-
*/
|
|
25173
|
-
function icuContainerIteratorStart(tIcuContainerNode, lView) {
|
|
25174
|
-
_lView = lView;
|
|
25175
|
-
while (_stack.length)
|
|
25176
|
-
_stack.pop();
|
|
25177
|
-
ngDevMode && assertTNodeForLView(tIcuContainerNode, lView);
|
|
25178
|
-
enterIcu(tIcuContainerNode.value, lView);
|
|
25179
|
-
return icuContainerIteratorNext;
|
|
25180
|
-
}
|
|
25181
|
-
function enterIcu(tIcu, lView) {
|
|
25182
|
-
_index = 0;
|
|
25183
|
-
const currentCase = getCurrentICUCaseIndex(tIcu, lView);
|
|
25184
|
-
if (currentCase !== null) {
|
|
25185
|
-
ngDevMode && assertNumberInRange(currentCase, 0, tIcu.cases.length - 1);
|
|
25186
|
-
_removes = tIcu.remove[currentCase];
|
|
25187
|
-
}
|
|
25188
|
-
else {
|
|
25189
|
-
_removes = EMPTY_ARRAY;
|
|
25190
|
-
}
|
|
25191
|
-
}
|
|
25192
|
-
function icuContainerIteratorNext() {
|
|
25193
|
-
if (_index < _removes.length) {
|
|
25194
|
-
const removeOpCode = _removes[_index++];
|
|
25195
|
-
ngDevMode && assertNumber(removeOpCode, 'Expecting OpCode number');
|
|
25196
|
-
if (removeOpCode > 0) {
|
|
25197
|
-
const rNode = _lView[removeOpCode];
|
|
25198
|
-
ngDevMode && assertDomNode(rNode);
|
|
25199
|
-
return rNode;
|
|
25200
|
-
}
|
|
25201
|
-
else {
|
|
25202
|
-
_stack.push(_index, _removes);
|
|
25203
|
-
// ICUs are represented by negative indices
|
|
25204
|
-
const tIcuIndex = ~removeOpCode;
|
|
25205
|
-
const tIcu = _lView[TVIEW].data[tIcuIndex];
|
|
25206
|
-
ngDevMode && assertTIcu(tIcu);
|
|
25207
|
-
enterIcu(tIcu, _lView);
|
|
25208
|
-
return icuContainerIteratorNext();
|
|
25209
|
-
}
|
|
25210
|
-
}
|
|
25211
|
-
else {
|
|
25212
|
-
if (_stack.length === 0) {
|
|
25213
|
-
return null;
|
|
25214
|
-
}
|
|
25215
|
-
else {
|
|
25216
|
-
_removes = _stack.pop();
|
|
25217
|
-
_index = _stack.pop();
|
|
25218
|
-
return icuContainerIteratorNext();
|
|
25219
|
-
}
|
|
25220
|
-
}
|
|
25221
|
-
}
|
|
25222
|
-
return icuContainerIteratorStart;
|
|
25223
|
-
}
|
|
25224
|
-
|
|
25225
25344
|
/**
|
|
25226
25345
|
* Converts `I18nCreateOpCodes` array into a human readable format.
|
|
25227
25346
|
*
|
|
@@ -26674,17 +26793,20 @@ function ɵɵprojectionDef(projectionSlots) {
|
|
|
26674
26793
|
const tails = projectionHeads.slice();
|
|
26675
26794
|
let componentChild = componentNode.child;
|
|
26676
26795
|
while (componentChild !== null) {
|
|
26677
|
-
|
|
26678
|
-
|
|
26679
|
-
|
|
26680
|
-
|
|
26681
|
-
|
|
26682
|
-
|
|
26683
|
-
|
|
26684
|
-
|
|
26685
|
-
|
|
26796
|
+
// Do not project let declarations so they don't occupy a slot.
|
|
26797
|
+
if (componentChild.type !== 128 /* TNodeType.LetDeclaration */) {
|
|
26798
|
+
const slotIndex = projectionSlots
|
|
26799
|
+
? matchingProjectionSlotIndex(componentChild, projectionSlots)
|
|
26800
|
+
: 0;
|
|
26801
|
+
if (slotIndex !== null) {
|
|
26802
|
+
if (tails[slotIndex]) {
|
|
26803
|
+
tails[slotIndex].projectionNext = componentChild;
|
|
26804
|
+
}
|
|
26805
|
+
else {
|
|
26806
|
+
projectionHeads[slotIndex] = componentChild;
|
|
26807
|
+
}
|
|
26808
|
+
tails[slotIndex] = componentChild;
|
|
26686
26809
|
}
|
|
26687
|
-
tails[slotIndex] = componentChild;
|
|
26688
26810
|
}
|
|
26689
26811
|
componentChild = componentChild.next;
|
|
26690
26812
|
}
|
|
@@ -28413,36 +28535,52 @@ function ɵɵtwoWayListener(eventName, listenerFn) {
|
|
|
28413
28535
|
* Use of this source code is governed by an MIT-style license that can be
|
|
28414
28536
|
* found in the LICENSE file at https://angular.io/license
|
|
28415
28537
|
*/
|
|
28538
|
+
/** Object that indicates the value of a `@let` declaration that hasn't been initialized yet. */
|
|
28539
|
+
const UNINITIALIZED_LET = {};
|
|
28416
28540
|
/**
|
|
28417
|
-
* Declares an `@let` at a specific data slot.
|
|
28541
|
+
* Declares an `@let` at a specific data slot. Returns itself to allow chaining.
|
|
28418
28542
|
*
|
|
28419
28543
|
* @param index Index at which to declare the `@let`.
|
|
28420
28544
|
*
|
|
28421
28545
|
* @codeGenApi
|
|
28422
28546
|
*/
|
|
28423
28547
|
function ɵɵdeclareLet(index) {
|
|
28424
|
-
|
|
28548
|
+
const tView = getTView();
|
|
28549
|
+
const lView = getLView();
|
|
28550
|
+
const adjustedIndex = index + HEADER_OFFSET;
|
|
28551
|
+
const tNode = getOrCreateTNode(tView, adjustedIndex, 128 /* TNodeType.LetDeclaration */, null, null);
|
|
28552
|
+
setCurrentTNode(tNode, false);
|
|
28553
|
+
store(tView, lView, adjustedIndex, UNINITIALIZED_LET);
|
|
28425
28554
|
return ɵɵdeclareLet;
|
|
28426
28555
|
}
|
|
28427
28556
|
/**
|
|
28428
28557
|
* Instruction that stores the value of a `@let` declaration on the current view.
|
|
28558
|
+
* Returns the value to allow usage inside variable initializers.
|
|
28429
28559
|
*
|
|
28430
28560
|
* @codeGenApi
|
|
28431
28561
|
*/
|
|
28432
28562
|
function ɵɵstoreLet(value) {
|
|
28433
|
-
|
|
28563
|
+
performanceMarkFeature('NgLet');
|
|
28564
|
+
const tView = getTView();
|
|
28565
|
+
const lView = getLView();
|
|
28566
|
+
const index = getSelectedIndex();
|
|
28567
|
+
store(tView, lView, index, value);
|
|
28434
28568
|
return value;
|
|
28435
28569
|
}
|
|
28436
28570
|
/**
|
|
28437
|
-
* Retrieves the value of a `@let` declaration defined
|
|
28571
|
+
* Retrieves the value of a `@let` declaration defined in a parent view.
|
|
28438
28572
|
*
|
|
28439
28573
|
* @param index Index of the declaration within the view.
|
|
28440
28574
|
*
|
|
28441
28575
|
* @codeGenApi
|
|
28442
28576
|
*/
|
|
28443
28577
|
function ɵɵreadContextLet(index) {
|
|
28444
|
-
|
|
28445
|
-
|
|
28578
|
+
const contextLView = getContextLView();
|
|
28579
|
+
const value = load(contextLView, HEADER_OFFSET + index);
|
|
28580
|
+
if (value === UNINITIALIZED_LET) {
|
|
28581
|
+
throw new RuntimeError(314 /* RuntimeErrorCode.UNINITIALIZED_LET_ACCESS */, ngDevMode && 'Attempting to access a @let declaration whose value is not available yet');
|
|
28582
|
+
}
|
|
28583
|
+
return value;
|
|
28446
28584
|
}
|
|
28447
28585
|
|
|
28448
28586
|
/*
|
|
@@ -30898,7 +31036,7 @@ class Version {
|
|
|
30898
31036
|
/**
|
|
30899
31037
|
* @publicApi
|
|
30900
31038
|
*/
|
|
30901
|
-
const VERSION = new Version('18.0.
|
|
31039
|
+
const VERSION = new Version('18.0.5');
|
|
30902
31040
|
|
|
30903
31041
|
/*
|
|
30904
31042
|
* This file exists to support compilation of @angular/core in Ivy mode.
|
|
@@ -34098,7 +34236,8 @@ function createViewRef(tNode, lView, isPipe) {
|
|
|
34098
34236
|
const componentView = getComponentLViewByIndex(tNode.index, lView); // look down
|
|
34099
34237
|
return new ViewRef$1(componentView, componentView);
|
|
34100
34238
|
}
|
|
34101
|
-
else if (tNode.type &
|
|
34239
|
+
else if (tNode.type &
|
|
34240
|
+
(3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 32 /* TNodeType.Icu */ | 128 /* TNodeType.LetDeclaration */)) {
|
|
34102
34241
|
// The LView represents the location where the injection is requested from.
|
|
34103
34242
|
// We need to locate the containing LView (in case where the `lView` is an embedded view)
|
|
34104
34243
|
const hostComponentView = lView[DECLARATION_COMPONENT_VIEW]; // look up
|
|
@@ -36713,7 +36852,8 @@ const initGlobalEventDelegation = (eventDelegation, injector) => {
|
|
|
36713
36852
|
if (injector.get(IS_EVENT_REPLAY_ENABLED, EVENT_REPLAY_ENABLED_DEFAULT)) {
|
|
36714
36853
|
return;
|
|
36715
36854
|
}
|
|
36716
|
-
eventDelegation.eventContract = new EventContract(new EventContractContainer(document.body)
|
|
36855
|
+
eventDelegation.eventContract = new EventContract(new EventContractContainer(document.body),
|
|
36856
|
+
/* useActionResolver= */ false);
|
|
36717
36857
|
const dispatcher = new EventDispatcher(invokeRegisteredListeners);
|
|
36718
36858
|
registerDispatcher(eventDelegation.eventContract, dispatcher);
|
|
36719
36859
|
};
|
|
@@ -36807,7 +36947,8 @@ const initEventReplay = (eventDelegation, injector) => {
|
|
|
36807
36947
|
// This is set in packages/platform-server/src/utils.ts
|
|
36808
36948
|
const container = globalThis[CONTRACT_PROPERTY]?.[appId];
|
|
36809
36949
|
const earlyJsactionData = getJsactionData(container);
|
|
36810
|
-
const eventContract = (eventDelegation.eventContract = new EventContract(new EventContractContainer(earlyJsactionData.c)
|
|
36950
|
+
const eventContract = (eventDelegation.eventContract = new EventContract(new EventContractContainer(earlyJsactionData.c),
|
|
36951
|
+
/* useActionResolver= */ false));
|
|
36811
36952
|
for (const et of earlyJsactionData.et) {
|
|
36812
36953
|
eventContract.addEvent(et);
|
|
36813
36954
|
}
|
|
@@ -37106,15 +37247,18 @@ function serializeLContainer(lContainer, context) {
|
|
|
37106
37247
|
function appendSerializedNodePath(ngh, tNode, lView, excludedParentNodes) {
|
|
37107
37248
|
const noOffsetIndex = tNode.index - HEADER_OFFSET;
|
|
37108
37249
|
ngh[NODES] ??= {};
|
|
37109
|
-
|
|
37250
|
+
// Ensure we don't calculate the path multiple times.
|
|
37251
|
+
ngh[NODES][noOffsetIndex] ??= calcPathForNode(tNode, lView, excludedParentNodes);
|
|
37110
37252
|
}
|
|
37111
37253
|
/**
|
|
37112
37254
|
* Helper function to append information about a disconnected node.
|
|
37113
37255
|
* This info is needed at runtime to avoid DOM lookups for this element
|
|
37114
37256
|
* and instead, the element would be created from scratch.
|
|
37115
37257
|
*/
|
|
37116
|
-
function appendDisconnectedNodeIndex(ngh,
|
|
37117
|
-
const noOffsetIndex =
|
|
37258
|
+
function appendDisconnectedNodeIndex(ngh, tNodeOrNoOffsetIndex) {
|
|
37259
|
+
const noOffsetIndex = typeof tNodeOrNoOffsetIndex === 'number'
|
|
37260
|
+
? tNodeOrNoOffsetIndex
|
|
37261
|
+
: tNodeOrNoOffsetIndex.index - HEADER_OFFSET;
|
|
37118
37262
|
ngh[DISCONNECTED_NODES] ??= [];
|
|
37119
37263
|
if (!ngh[DISCONNECTED_NODES].includes(noOffsetIndex)) {
|
|
37120
37264
|
ngh[DISCONNECTED_NODES].push(noOffsetIndex);
|
|
@@ -37145,7 +37289,15 @@ function serializeLView(lView, context) {
|
|
|
37145
37289
|
const i18nData = trySerializeI18nBlock(lView, i, context);
|
|
37146
37290
|
if (i18nData) {
|
|
37147
37291
|
ngh[I18N_DATA] ??= {};
|
|
37148
|
-
ngh[I18N_DATA][noOffsetIndex] = i18nData;
|
|
37292
|
+
ngh[I18N_DATA][noOffsetIndex] = i18nData.caseQueue;
|
|
37293
|
+
for (const nodeNoOffsetIndex of i18nData.disconnectedNodes) {
|
|
37294
|
+
appendDisconnectedNodeIndex(ngh, nodeNoOffsetIndex);
|
|
37295
|
+
}
|
|
37296
|
+
for (const nodeNoOffsetIndex of i18nData.disjointNodes) {
|
|
37297
|
+
const tNode = tView.data[nodeNoOffsetIndex + HEADER_OFFSET];
|
|
37298
|
+
ngDevMode && assertTNode(tNode);
|
|
37299
|
+
appendSerializedNodePath(ngh, tNode, lView, i18nChildren);
|
|
37300
|
+
}
|
|
37149
37301
|
continue;
|
|
37150
37302
|
}
|
|
37151
37303
|
// Skip processing of a given slot in the following cases:
|
|
@@ -37258,13 +37410,14 @@ function serializeLView(lView, context) {
|
|
|
37258
37410
|
ngh[ELEMENT_CONTAINERS] ??= {};
|
|
37259
37411
|
ngh[ELEMENT_CONTAINERS][noOffsetIndex] = calcNumRootNodes(tView, lView, tNode.child);
|
|
37260
37412
|
}
|
|
37261
|
-
else if (tNode.type & 16 /* TNodeType.Projection */) {
|
|
37262
|
-
// Current TNode represents an `<ng-content>` slot
|
|
37263
|
-
// DOM elements associated with it, so the **next sibling**
|
|
37264
|
-
// not be able to find an anchor. In this case, use full path instead.
|
|
37413
|
+
else if (tNode.type & (16 /* TNodeType.Projection */ | 128 /* TNodeType.LetDeclaration */)) {
|
|
37414
|
+
// Current TNode represents an `<ng-content>` slot or `@let` declaration,
|
|
37415
|
+
// thus it has no DOM elements associated with it, so the **next sibling**
|
|
37416
|
+
// node would not be able to find an anchor. In this case, use full path instead.
|
|
37265
37417
|
let nextTNode = tNode.next;
|
|
37266
|
-
// Skip over all `<ng-content>` slots in a row.
|
|
37267
|
-
while (nextTNode !== null &&
|
|
37418
|
+
// Skip over all `<ng-content>` slots and `@let` declarations in a row.
|
|
37419
|
+
while (nextTNode !== null &&
|
|
37420
|
+
nextTNode.type & (16 /* TNodeType.Projection */ | 128 /* TNodeType.LetDeclaration */)) {
|
|
37268
37421
|
nextTNode = nextTNode.next;
|
|
37269
37422
|
}
|
|
37270
37423
|
if (nextTNode && !isInSkipHydrationBlock(nextTNode)) {
|
|
@@ -37272,11 +37425,9 @@ function serializeLView(lView, context) {
|
|
|
37272
37425
|
appendSerializedNodePath(ngh, nextTNode, lView, i18nChildren);
|
|
37273
37426
|
}
|
|
37274
37427
|
}
|
|
37275
|
-
else {
|
|
37276
|
-
|
|
37277
|
-
|
|
37278
|
-
processTextNodeBeforeSerialization(context, rNode);
|
|
37279
|
-
}
|
|
37428
|
+
else if (tNode.type & 1 /* TNodeType.Text */) {
|
|
37429
|
+
const rNode = unwrapRNode(lView[i]);
|
|
37430
|
+
processTextNodeBeforeSerialization(context, rNode);
|
|
37280
37431
|
}
|
|
37281
37432
|
}
|
|
37282
37433
|
}
|