@angular/core 17.0.5 → 17.0.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.
package/fesm2022/core.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v17.0.5
2
+ * @license Angular v17.0.6
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -8267,7 +8267,6 @@ function detachView(lContainer, removeIndex) {
8267
8267
  function destroyLView(tView, lView) {
8268
8268
  if (!(lView[FLAGS] & 256 /* LViewFlags.Destroyed */)) {
8269
8269
  const renderer = lView[RENDERER];
8270
- lView[REACTIVE_TEMPLATE_CONSUMER] && consumerDestroy$1(lView[REACTIVE_TEMPLATE_CONSUMER]);
8271
8270
  if (renderer.destroyNode) {
8272
8271
  applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
8273
8272
  }
@@ -8293,6 +8292,7 @@ function cleanUpView(tView, lView) {
8293
8292
  // This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
8294
8293
  // really more of an "afterDestroy" hook if you think about it.
8295
8294
  lView[FLAGS] |= 256 /* LViewFlags.Destroyed */;
8295
+ lView[REACTIVE_TEMPLATE_CONSUMER] && consumerDestroy$1(lView[REACTIVE_TEMPLATE_CONSUMER]);
8296
8296
  executeOnDestroys(tView, lView);
8297
8297
  processCleanups(tView, lView);
8298
8298
  // For component views only, the local renderer is destroyed at clean up time.
@@ -10427,7 +10427,7 @@ class Version {
10427
10427
  /**
10428
10428
  * @publicApi
10429
10429
  */
10430
- const VERSION = new Version('17.0.5');
10430
+ const VERSION = new Version('17.0.6');
10431
10431
 
10432
10432
  // This default value is when checking the hierarchy for a token.
10433
10433
  //
@@ -19117,6 +19117,17 @@ function isFirstElementInNgContainer(tNode) {
19117
19117
  function getNoOffsetIndex(tNode) {
19118
19118
  return tNode.index - HEADER_OFFSET;
19119
19119
  }
19120
+ /**
19121
+ * Check whether a given node exists, but is disconnected from the DOM.
19122
+ *
19123
+ * Note: we leverage the fact that we have this information available in the DOM emulation
19124
+ * layer (in Domino) for now. Longer-term solution should not rely on the DOM emulation and
19125
+ * only use internal data structures and state to compute this information.
19126
+ */
19127
+ function isDisconnectedNode(tNode, lView) {
19128
+ return !(tNode.type & 16 /* TNodeType.Projection */) && !!lView[tNode.index] &&
19129
+ !unwrapRNode(lView[tNode.index])?.isConnected;
19130
+ }
19120
19131
  /**
19121
19132
  * Locate a node in DOM tree that corresponds to a given TNode.
19122
19133
  *
@@ -19318,10 +19329,20 @@ function calcPathBetween(from, to, fromNodeName) {
19318
19329
  * instructions needs to be generated for a TNode.
19319
19330
  */
19320
19331
  function calcPathForNode(tNode, lView) {
19321
- const parentTNode = tNode.parent;
19332
+ let parentTNode = tNode.parent;
19322
19333
  let parentIndex;
19323
19334
  let parentRNode;
19324
19335
  let referenceNodeName;
19336
+ // Skip over all parent nodes that are disconnected from the DOM, such nodes
19337
+ // can not be used as anchors.
19338
+ //
19339
+ // This might happen in certain content projection-based use-cases, where
19340
+ // a content of an element is projected and used, when a parent element
19341
+ // itself remains detached from DOM. In this scenario we try to find a parent
19342
+ // element that is attached to DOM and can act as an anchor instead.
19343
+ while (parentTNode !== null && isDisconnectedNode(parentTNode, lView)) {
19344
+ parentTNode = parentTNode.parent;
19345
+ }
19325
19346
  if (parentTNode === null || !(parentTNode.type & 3 /* TNodeType.AnyRNode */)) {
19326
19347
  // If there is no parent TNode or a parent TNode does not represent an RNode
19327
19348
  // (i.e. not a DOM node), use component host element as a reference node.
@@ -19755,13 +19776,14 @@ function getLViewFromLContainer(lContainer, index) {
19755
19776
  * block (in which case view contents was re-created, thus needing insertion).
19756
19777
  */
19757
19778
  function shouldAddViewToDom(tNode, dehydratedView) {
19758
- return !dehydratedView || hasInSkipHydrationBlockFlag(tNode);
19779
+ return !dehydratedView || dehydratedView.firstChild === null ||
19780
+ hasInSkipHydrationBlockFlag(tNode);
19759
19781
  }
19760
19782
  function addLViewToLContainer(lContainer, lView, index, addToDOM = true) {
19761
19783
  const tView = lView[TVIEW];
19762
- // insert to the view tree so the new view can be change-detected
19784
+ // Insert into the view tree so the new view can be change-detected
19763
19785
  insertView(tView, lView, lContainer, index);
19764
- // insert to the view to the DOM tree
19786
+ // Insert elements that belong to this view into the DOM tree
19765
19787
  if (addToDOM) {
19766
19788
  const beforeNode = getBeforeNodeForView(index, lContainer);
19767
19789
  const renderer = lView[RENDERER];
@@ -19770,6 +19792,13 @@ function addLViewToLContainer(lContainer, lView, index, addToDOM = true) {
19770
19792
  addViewToDOM(tView, lContainer[T_HOST], renderer, lView, parentRNode, beforeNode);
19771
19793
  }
19772
19794
  }
19795
+ // When in hydration mode, reset the pointer to the first child in
19796
+ // the dehydrated view. This indicates that the view was hydrated and
19797
+ // further attaching/detaching should work with this view as normal.
19798
+ const hydrationInfo = lView[HYDRATION];
19799
+ if (hydrationInfo !== null && hydrationInfo.firstChild !== null) {
19800
+ hydrationInfo.firstChild = null;
19801
+ }
19773
19802
  }
19774
19803
  function removeLViewFromLContainer(lContainer, index) {
19775
19804
  const lView = detachView(lContainer, index);
@@ -34304,6 +34333,7 @@ function serializeLView(lView, context) {
34304
34333
  }
34305
34334
  }
34306
34335
  }
34336
+ conditionallyAnnotateNodePath(ngh, tNode, lView);
34307
34337
  if (isLContainer(lView[i])) {
34308
34338
  // Serialize information about a template.
34309
34339
  const embeddedTView = tNode.tView;
@@ -34395,18 +34425,38 @@ function serializeLView(lView, context) {
34395
34425
  context.corruptedTextNodes.set(rNode, "ngtns" /* TextNodeMarker.Separator */);
34396
34426
  }
34397
34427
  }
34398
- if (tNode.projectionNext && tNode.projectionNext !== tNode.next &&
34399
- !isInSkipHydrationBlock(tNode.projectionNext)) {
34400
- // Check if projection next is not the same as next, in which case
34401
- // the node would not be found at creation time at runtime and we
34402
- // need to provide a location for that node.
34403
- appendSerializedNodePath(ngh, tNode.projectionNext, lView);
34404
- }
34405
34428
  }
34406
34429
  }
34407
34430
  }
34408
34431
  return ngh;
34409
34432
  }
34433
+ /**
34434
+ * Serializes node location in cases when it's needed, specifically:
34435
+ *
34436
+ * 1. If `tNode.projectionNext` is different from `tNode.next` - it means that
34437
+ * the next `tNode` after projection is different from the one in the original
34438
+ * template. Since hydration relies on `tNode.next`, this serialized info
34439
+ * if required to help runtime code find the node at the correct location.
34440
+ * 2. In certain content projection-based use-cases, it's possible that only
34441
+ * a content of a projected element is rendered. In this case, content nodes
34442
+ * require an extra annotation, since runtime logic can't rely on parent-child
34443
+ * connection to identify the location of a node.
34444
+ */
34445
+ function conditionallyAnnotateNodePath(ngh, tNode, lView) {
34446
+ // Handle case #1 described above.
34447
+ if (tNode.projectionNext && tNode.projectionNext !== tNode.next &&
34448
+ !isInSkipHydrationBlock(tNode.projectionNext)) {
34449
+ appendSerializedNodePath(ngh, tNode.projectionNext, lView);
34450
+ }
34451
+ // Handle case #2 described above.
34452
+ // Note: we only do that for the first node (i.e. when `tNode.prev === null`),
34453
+ // the rest of the nodes would rely on the current node location, so no extra
34454
+ // annotation is needed.
34455
+ if (tNode.prev === null && tNode.parent !== null && isDisconnectedNode(tNode.parent, lView) &&
34456
+ !isDisconnectedNode(tNode, lView)) {
34457
+ appendSerializedNodePath(ngh, tNode, lView);
34458
+ }
34459
+ }
34410
34460
  /**
34411
34461
  * Determines whether a component instance that is represented
34412
34462
  * by a given LView uses `ViewEncapsulation.ShadowDom`.
@@ -34478,17 +34528,6 @@ function isContentProjectedNode(tNode) {
34478
34528
  }
34479
34529
  return false;
34480
34530
  }
34481
- /**
34482
- * Check whether a given node exists, but is disconnected from the DOM.
34483
- *
34484
- * Note: we leverage the fact that we have this information available in the DOM emulation
34485
- * layer (in Domino) for now. Longer-term solution should not rely on the DOM emulation and
34486
- * only use internal data structures and state to compute this information.
34487
- */
34488
- function isDisconnectedNode(tNode, lView) {
34489
- return !(tNode.type & 16 /* TNodeType.Projection */) && !!lView[tNode.index] &&
34490
- !unwrapRNode(lView[tNode.index]).isConnected;
34491
- }
34492
34531
 
34493
34532
  /**
34494
34533
  * Indicates whether the hydration-related code was added,