mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
refactor(core): only annotate disconnected nodes in content projection (#49549)
Previously, we've annotated all disconnected DOM nodes, even if they are not used in content projection. However, this situation is only possible in content projection and if it happens in other cases (for example, when a node was removed using direct DOM manipulations), this should be a mismatch error. PR Close #49549
This commit is contained in:
parent
03d1d00ad9
commit
f1d3be3dee
2 changed files with 20 additions and 5 deletions
|
|
@ -12,7 +12,7 @@ import {CONTAINER_HEADER_OFFSET, LContainer} from '../render3/interfaces/contain
|
|||
import {TI18n} from '../render3/interfaces/i18n';
|
||||
import {TNode, TNodeType} from '../render3/interfaces/node';
|
||||
import {RElement} from '../render3/interfaces/renderer_dom';
|
||||
import {isLContainer, isProjectionTNode, isRootView} from '../render3/interfaces/type_checks';
|
||||
import {isComponentHost, isLContainer, isProjectionTNode, isRootView} from '../render3/interfaces/type_checks';
|
||||
import {HEADER_OFFSET, HOST, LView, RENDERER, TView, TVIEW, TViewType} from '../render3/interfaces/view';
|
||||
import {unwrapRNode} from '../render3/util/view_utils';
|
||||
import {TransferState} from '../transfer_state';
|
||||
|
|
@ -240,7 +240,7 @@ function serializeLView(lView: LView, context: HydrationContext): SerializedView
|
|||
// layer (in Domino) for now. Longer-term solution should not rely on the DOM emulation and
|
||||
// only use internal data structures and state to compute this information.
|
||||
if (!(tNode.type & TNodeType.Projection) && !!lView[i] &&
|
||||
!(unwrapRNode(lView[i]) as Node).isConnected) {
|
||||
!(unwrapRNode(lView[i]) as Node).isConnected && isContentProjectedNode(tNode)) {
|
||||
ngh[DISCONNECTED_NODES] ??= [];
|
||||
ngh[DISCONNECTED_NODES].push(noOffsetIndex);
|
||||
continue;
|
||||
|
|
@ -413,3 +413,20 @@ function insertCorruptedTextNodeMarkers(
|
|||
textNode.after(doc.createComment(marker));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects whether a given TNode represents a node that
|
||||
* is being content projected.
|
||||
*/
|
||||
function isContentProjectedNode(tNode: TNode): boolean {
|
||||
let currentTNode = tNode;
|
||||
while (currentTNode != null) {
|
||||
// If we come across a component host node in parent nodes -
|
||||
// this TNode is in the content projection section.
|
||||
if (isComponentHost(currentTNode)) {
|
||||
return true;
|
||||
}
|
||||
currentTNode = currentTNode.parent as TNode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3173,9 +3173,7 @@ describe('platform-server integration', () => {
|
|||
});
|
||||
});
|
||||
|
||||
// TODO(akushnir): we should only mark nodes within a content projection block as
|
||||
// "disconnected" (avoid marking other disconnected nodes in a template)
|
||||
xit('should handle element node mismatch', async () => {
|
||||
it('should handle element node mismatch', async () => {
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app',
|
||||
|
|
|
|||
Loading…
Reference in a new issue