diff --git a/packages/core/src/render3/node_manipulation.ts b/packages/core/src/render3/node_manipulation.ts
index 79ec137a94..a8cc9e8ffd 100644
--- a/packages/core/src/render3/node_manipulation.ts
+++ b/packages/core/src/render3/node_manipulation.ts
@@ -6,9 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
+import {ViewEncapsulation} from '../core';
+
import {attachPatchData} from './context_discovery';
import {callHooks} from './hooks';
import {LContainer, NATIVE, VIEWS, unusedValueExportToPlacateAjd as unused1} from './interfaces/container';
+import {ComponentDef} from './interfaces/definition';
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeType, TProjectionNode, TViewNode, unusedValueExportToPlacateAjd as unused2} from './interfaces/node';
import {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection';
import {ProceduralRenderer3, RComment, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer';
@@ -486,7 +489,7 @@ function executeOnDestroys(view: LView): void {
* `delayed due to projection`
* - Parent container is disconnected: This can happen when we are inserting a view into
* parent container, which itself is disconnected. For example the parent container is part
- * of a View which has not be inserted or is mare for projection but has not been inserted
+ * of a View which has not be inserted or is made for projection but has not been inserted
* into destination.
*/
function getRenderParent(tNode: TNode, currentView: LView): RElement|null {
@@ -519,15 +522,24 @@ function getRenderParent(tNode: TNode, currentView: LView): RElement|null {
}
} else {
ngDevMode && assertNodeType(parent, TNodeType.Element);
- // We've got a parent which is an element in the current view. We just need to verify if the
- // parent element is not a component. Component's content nodes are not inserted immediately
- // because they will be projected, and so doing insert at this point would be wasteful.
- // Since the projection would then move it to its final destination.
if (parent.flags & TNodeFlags.isComponent) {
- return null;
- } else {
- return getNativeByTNode(parent, currentView) as RElement;
+ const tData = currentView[TVIEW].data;
+ const tNode = tData[parent.index] as TNode;
+ const encapsulation = (tData[tNode.directiveStart] as ComponentDef).encapsulation;
+
+ // We've got a parent which is an element in the current view. We just need to verify if the
+ // parent element is not a component. Component's content nodes are not inserted immediately
+ // because they will be projected, and so doing insert at this point would be wasteful.
+ // Since the projection would then move it to its final destination. Note that we can't
+ // make this assumption when using the Shadow DOM, because the native projection placeholders
+ // ( or ) have to be in place as elements are being inserted.
+ if (encapsulation !== ViewEncapsulation.ShadowDom &&
+ encapsulation !== ViewEncapsulation.Native) {
+ return null;
+ }
}
+
+ return getNativeByTNode(parent, currentView) as RElement;
}
}
diff --git a/packages/core/test/linker/projection_integration_spec.ts b/packages/core/test/linker/projection_integration_spec.ts
index 1b52edfafc..65a2233fdc 100644
--- a/packages/core/test/linker/projection_integration_spec.ts
+++ b/packages/core/test/linker/projection_integration_spec.ts
@@ -381,22 +381,21 @@ describe('projection', () => {
});
if (getDOM().supportsNativeShadowDOM()) {
- fixmeIvy('FW-841: Content projection with ShadovDom v0 doesn\'t work')
- .it('should support native content projection and isolate styles per component', () => {
- TestBed.configureTestingModule({declarations: [SimpleNative1, SimpleNative2]});
- TestBed.overrideComponent(MainComp, {
- set: {
- template: 'A
' +
- 'B
'
- }
- });
- const main = TestBed.createComponent(MainComp);
+ it('should support native content projection and isolate styles per component', () => {
+ TestBed.configureTestingModule({declarations: [SimpleNative1, SimpleNative2]});
+ TestBed.overrideComponent(MainComp, {
+ set: {
+ template: 'A
' +
+ 'B
'
+ }
+ });
+ const main = TestBed.createComponent(MainComp);
- const childNodes = getDOM().childNodes(main.nativeElement);
- expect(childNodes[0]).toHaveText('div {color: red}SIMPLE1(A)');
- expect(childNodes[1]).toHaveText('div {color: blue}SIMPLE2(B)');
- main.destroy();
- });
+ const childNodes = getDOM().childNodes(main.nativeElement);
+ expect(childNodes[0]).toHaveText('div {color: red}SIMPLE1(A)');
+ expect(childNodes[1]).toHaveText('div {color: blue}SIMPLE2(B)');
+ main.destroy();
+ });
}
if (getDOM().supportsDOMEvents()) {