feat(core): remove ViewEncapsulation.Native (#38882)
Removes `ViewEncapsulation.Native` which has been deprecated for several major versions. BREAKING CHANGES: * `ViewEncapsulation.Native` has been removed. Use `ViewEncapsulation.ShadowDom` instead. Existing usages will be updated automatically by `ng update`. PR Close #38882
This commit is contained in:
parent
0e733f3689
commit
4a1c12c773
|
@ -13,8 +13,8 @@ import { Component, ViewEncapsulation } from '@angular/core';
|
|||
export class QuestSummaryComponent { }
|
||||
// #enddocregion
|
||||
/*
|
||||
// #docregion encapsulation.native
|
||||
// #docregion encapsulation.shadow
|
||||
// warning: few browsers support shadow DOM encapsulation at this time
|
||||
encapsulation: ViewEncapsulation.Native
|
||||
// #enddocregion encapsulation.native
|
||||
encapsulation: ViewEncapsulation.ShadowDom
|
||||
// #enddocregion encapsulation.shadow
|
||||
*/
|
||||
|
|
|
@ -41,7 +41,6 @@ v9 - v12
|
|||
| `@angular/core` | [`DefaultIterableDiffer`](#core) | <!--v7--> v11 |
|
||||
| `@angular/core` | [`ReflectiveKey`](#core) | <!--v8--> v11 |
|
||||
| `@angular/core` | [`RenderComponentType`](#core) | <!--v7--> v11 |
|
||||
| `@angular/core` | [`ViewEncapsulation.Native`](#core) | <!--v6--> v11 |
|
||||
| `@angular/core` | [`WrappedValue`](#core) | <!--v10--> v12 |
|
||||
| `@angular/forms` | [`ngModel` with reactive forms](#ngmodel-reactive) | <!--v6--> v11 |
|
||||
| `@angular/router` | [`preserveQueryParams`](#router) | <!--v7--> v11 |
|
||||
|
@ -89,7 +88,6 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
|
|||
| [`DefaultIterableDiffer`](api/core/DefaultIterableDiffer) | n/a | v4 | Not part of public API. |
|
||||
| [`ReflectiveInjector`](api/core/ReflectiveInjector) | [`Injector.create`](api/core/Injector#create) | v5 | See [`ReflectiveInjector`](#reflectiveinjector) |
|
||||
| [`ReflectiveKey`](api/core/ReflectiveKey) | none | v5 | none |
|
||||
| [`ViewEncapsulation.Native`](api/core/ViewEncapsulation#Native) | [`ViewEncapsulation.ShadowDom`](api/core/ViewEncapsulation#ShadowDom) | v6 | Use the native encapsulation mechanism of the renderer. See [view.ts](https://github.com/angular/angular/blob/3e992e18ebf51d6036818f26c3d77b52d3ec48eb/packages/core/src/metadata/view.ts#L32).
|
||||
| [`defineInjectable`](api/core/defineInjectable) | `ɵɵdefineInjectable` | v8 | Used only in generated code. No source code should depend on this API. |
|
||||
| [`entryComponents`](api/core/NgModule#entryComponents) | none | v9 | See [`entryComponents`](#entryComponents) |
|
||||
| [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) |
|
||||
|
|
|
@ -13,8 +13,6 @@ Choose from the following modes:
|
|||
to attach a shadow DOM to the component's host element, and then puts the component
|
||||
view inside that shadow DOM. The component's styles are included within the shadow DOM.
|
||||
|
||||
* `Native` view encapsulation uses a now deprecated version of the browser's native shadow DOM implementation - [learn about the changes](https://hayato.io/2016/shadowdomv1/).
|
||||
|
||||
* `Emulated` view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing
|
||||
(and renaming) the CSS code to effectively scope the CSS to the component's view.
|
||||
For details, see [Inspecting generated CSS](guide/view-encapsulation#inspect-generated-css) below.
|
||||
|
@ -26,7 +24,7 @@ Choose from the following modes:
|
|||
|
||||
To set the components encapsulation mode, use the `encapsulation` property in the component metadata:
|
||||
|
||||
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" header="src/app/quest-summary.component.ts"></code-example>
|
||||
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.shadow" header="src/app/quest-summary.component.ts"></code-example>
|
||||
|
||||
`ShadowDom` view encapsulation only works on browsers that have native support
|
||||
for shadow DOM (see [Shadow DOM v1](https://caniuse.com/#feat=shadowdomv1) on the
|
||||
|
@ -80,4 +78,4 @@ by the generated component styles, which are in the `<head>` section of the DOM:
|
|||
|
||||
These styles are post-processed so that each selector is augmented
|
||||
with `_nghost` or `_ngcontent` attribute selectors.
|
||||
These extra selectors enable the scoping rules described in this page.
|
||||
These extra selectors enable the scoping rules described in this page.
|
||||
|
|
|
@ -21,7 +21,7 @@ const initialDocViewerContent = initialDocViewerElement ? initialDocViewerElemen
|
|||
selector: 'aio-doc-viewer',
|
||||
template: ''
|
||||
// TODO(robwormald): shadow DOM and emulated don't work here (?!)
|
||||
// encapsulation: ViewEncapsulation.Native
|
||||
// encapsulation: ViewEncapsulation.ShadowDom
|
||||
})
|
||||
export class DocViewerComponent implements OnDestroy {
|
||||
// Enable/Disable view transition animations.
|
||||
|
|
|
@ -1032,7 +1032,6 @@ export declare abstract class ViewContainerRef {
|
|||
|
||||
export declare enum ViewEncapsulation {
|
||||
Emulated = 0,
|
||||
Native = 1,
|
||||
None = 2,
|
||||
ShadowDom = 3
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 1485,
|
||||
"main-es2015": 134891,
|
||||
"main-es2015": 135003,
|
||||
"polyfills-es2015": 37248
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,6 @@ export declare enum Style {
|
|||
*/
|
||||
export declare enum ViewEncapsulation {
|
||||
Emulated = 'Emulated',
|
||||
Native = 'Native',
|
||||
None = 'None',
|
||||
ShadowDom = 'ShadowDom'
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ describe('compiler compliance: styling', () => {
|
|||
expectEmit(result.source, template, 'Incorrect template');
|
||||
});
|
||||
|
||||
it('should pass in the component metadata styles into the component definition but skip shimming when style encapsulation is set to native',
|
||||
it('should pass in the component metadata styles into the component definition but skip shimming when style encapsulation is set to shadow dom',
|
||||
() => {
|
||||
const files = {
|
||||
app: {
|
||||
|
@ -80,7 +80,7 @@ describe('compiler compliance: styling', () => {
|
|||
import {Component, NgModule, ViewEncapsulation} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
encapsulation: ViewEncapsulation.Native,
|
||||
encapsulation: ViewEncapsulation.ShadowDom,
|
||||
selector: "my-component",
|
||||
styles: ["div.cool { color: blue; }", ":host.nice p { color: gold; }"],
|
||||
template: "..."
|
||||
|
@ -98,7 +98,7 @@ describe('compiler compliance: styling', () => {
|
|||
MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({
|
||||
…
|
||||
styles: ["div.cool { color: blue; }", ":host.nice p { color: gold; }"],
|
||||
encapsulation: 1
|
||||
encapsulation: 3
|
||||
})
|
||||
`;
|
||||
const result = compile(files, angularFiles);
|
||||
|
|
|
@ -77,7 +77,7 @@ export type ɵɵPipeDefWithMeta<PipeT, NameT> = any;
|
|||
|
||||
export enum ViewEncapsulation {
|
||||
Emulated = 0,
|
||||
Native = 1,
|
||||
// Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
|
||||
None = 2,
|
||||
ShadowDom = 3
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ export interface R3FactoryDefMetadataFacade {
|
|||
|
||||
export enum ViewEncapsulation {
|
||||
Emulated = 0,
|
||||
Native = 1,
|
||||
// Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
|
||||
None = 2,
|
||||
ShadowDom = 3
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ export interface Component extends Directive {
|
|||
}
|
||||
export enum ViewEncapsulation {
|
||||
Emulated = 0,
|
||||
Native = 1,
|
||||
// Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
|
||||
None = 2,
|
||||
ShadowDom = 3
|
||||
}
|
||||
|
|
|
@ -163,8 +163,6 @@ export interface R3ComponentMetadata extends R3DirectiveMetadata {
|
|||
|
||||
/**
|
||||
* An encapsulation policy for the template and CSS styles. One of:
|
||||
* - `ViewEncapsulation.Native`: Use shadow roots. This works only if natively available on the
|
||||
* platform (note that this is marked the as the "deprecated shadow DOM" as of Angular v6.1.
|
||||
* - `ViewEncapsulation.Emulated`: Use shimmed CSS that emulates the native behavior.
|
||||
* - `ViewEncapsulation.None`: Use global CSS without any encapsulation.
|
||||
* - `ViewEncapsulation.ShadowDom`: Use the latest ShadowDOM API to natively encapsulate styles
|
||||
|
|
|
@ -226,7 +226,7 @@ function normalizeTemplate(normalizer: DirectiveNormalizer, o: {
|
|||
describe('normalizeLoadedTemplate', () => {
|
||||
it('should store the viewEncapsulation in the result',
|
||||
inject([DirectiveNormalizer], (normalizer: DirectiveNormalizer) => {
|
||||
const viewEncapsulation = ViewEncapsulation.Native;
|
||||
const viewEncapsulation = ViewEncapsulation.ShadowDom;
|
||||
const template = <CompileTemplateMetadata>normalizeTemplate(normalizer, {
|
||||
encapsulation: viewEncapsulation,
|
||||
template: '',
|
||||
|
|
|
@ -173,7 +173,7 @@ export interface R3FactoryDefMetadataFacade {
|
|||
|
||||
export enum ViewEncapsulation {
|
||||
Emulated = 0,
|
||||
Native = 1,
|
||||
// Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
|
||||
None = 2,
|
||||
ShadowDom = 3
|
||||
}
|
||||
|
|
|
@ -518,7 +518,6 @@ export interface Component extends Directive {
|
|||
|
||||
/**
|
||||
* An encapsulation policy for the template and CSS styles. One of:
|
||||
* - `ViewEncapsulation.Native`: Deprecated. Use `ViewEncapsulation.ShadowDom` instead.
|
||||
* - `ViewEncapsulation.Emulated`: Use shimmed CSS that
|
||||
* emulates the native behavior.
|
||||
* - `ViewEncapsulation.None`: Use global CSS without any
|
||||
|
|
|
@ -28,15 +28,9 @@ export enum ViewEncapsulation {
|
|||
* This is the default option.
|
||||
*/
|
||||
Emulated = 0,
|
||||
/**
|
||||
* @deprecated v6.1.0 - use {ViewEncapsulation.ShadowDom} instead.
|
||||
* Use the native encapsulation mechanism of the renderer.
|
||||
*
|
||||
* For the DOM this means using the deprecated [Shadow DOM
|
||||
* v0](https://w3c.github.io/webcomponents/spec/shadow/) and
|
||||
* creating a ShadowRoot for Component's Host Element.
|
||||
*/
|
||||
Native = 1,
|
||||
|
||||
// Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
|
||||
|
||||
/**
|
||||
* Don't provide any template or style encapsulation.
|
||||
*/
|
||||
|
|
|
@ -517,8 +517,8 @@ function getRenderParent(tView: TView, tNode: TNode, currentView: LView): REleme
|
|||
// 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
|
||||
// (<content> or <slot>) have to be in place as elements are being inserted.
|
||||
if (encapsulation !== ViewEncapsulation.ShadowDom &&
|
||||
encapsulation !== ViewEncapsulation.Native) {
|
||||
if (encapsulation === ViewEncapsulation.None ||
|
||||
encapsulation === ViewEncapsulation.Emulated) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,7 +230,10 @@ export function getParentRenderElement(view: ViewData, renderHost: any, def: Nod
|
|||
if ((renderParent.flags & NodeFlags.TypeElement) === 0 ||
|
||||
(renderParent.flags & NodeFlags.ComponentView) === 0 ||
|
||||
(renderParent.element!.componentRendererType &&
|
||||
renderParent.element!.componentRendererType!.encapsulation === ViewEncapsulation.Native)) {
|
||||
(renderParent.element!.componentRendererType!.encapsulation ===
|
||||
ViewEncapsulation.ShadowDom ||
|
||||
// TODO(FW-2290): remove the `encapsulation === 1` fallback logic in v12.
|
||||
renderParent.element!.componentRendererType!.encapsulation === 1))) {
|
||||
// only children of non components, or children of components with native encapsulation should
|
||||
// be attached.
|
||||
return asElementData(view, def.renderParent!.nodeIndex).renderElement;
|
||||
|
|
|
@ -490,13 +490,13 @@ describe('projection', () => {
|
|||
expect(main.nativeElement).toHaveText('TREE(0:TREE2(1:TREE(2:)))');
|
||||
});
|
||||
|
||||
if (supportsNativeShadowDOM()) {
|
||||
it('should support native content projection and isolate styles per component', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleNative1, SimpleNative2]});
|
||||
if (supportsShadowDOM()) {
|
||||
it('should support shadow dom content projection and isolate styles per component', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleShadowDom1, SimpleShadowDom2]});
|
||||
TestBed.overrideComponent(MainComp, {
|
||||
set: {
|
||||
template: '<simple-native1><div>A</div></simple-native1>' +
|
||||
'<simple-native2><div>B</div></simple-native2>'
|
||||
template: '<simple-shadow-dom1><div>A</div></simple-shadow-dom1>' +
|
||||
'<simple-shadow-dom2><div>B</div></simple-shadow-dom2>'
|
||||
}
|
||||
});
|
||||
const main = TestBed.createComponent(MainComp);
|
||||
|
@ -857,21 +857,21 @@ class Simple {
|
|||
}
|
||||
|
||||
@Component({
|
||||
selector: 'simple-native1',
|
||||
template: 'SIMPLE1(<content></content>)',
|
||||
encapsulation: ViewEncapsulation.Native,
|
||||
selector: 'simple-shadow-dom1',
|
||||
template: 'SIMPLE1(<slot></slot>)',
|
||||
encapsulation: ViewEncapsulation.ShadowDom,
|
||||
styles: ['div {color: red}']
|
||||
})
|
||||
class SimpleNative1 {
|
||||
class SimpleShadowDom1 {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'simple-native2',
|
||||
template: 'SIMPLE2(<content></content>)',
|
||||
encapsulation: ViewEncapsulation.Native,
|
||||
selector: 'simple-shadow-dom2',
|
||||
template: 'SIMPLE2(<slot></slot>)',
|
||||
encapsulation: ViewEncapsulation.ShadowDom,
|
||||
styles: ['div {color: blue}']
|
||||
})
|
||||
class SimpleNative2 {
|
||||
class SimpleShadowDom2 {
|
||||
}
|
||||
|
||||
@Component({selector: 'empty', template: ''})
|
||||
|
@ -1043,6 +1043,6 @@ class CmpA1 {
|
|||
class CmpA2 {
|
||||
}
|
||||
|
||||
function supportsNativeShadowDOM(): boolean {
|
||||
return typeof (<any>document.body).createShadowRoot === 'function';
|
||||
function supportsShadowDOM(): boolean {
|
||||
return typeof (<any>document.body).attachShadow !== 'undefined';
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ function decoratePreventDefault(eventHandler: Function): Function {
|
|||
};
|
||||
}
|
||||
|
||||
let hasLoggedNativeEncapsulationWarning = false;
|
||||
|
||||
@Injectable()
|
||||
export class DomRendererFactory2 implements RendererFactory2 {
|
||||
private rendererByCompId = new Map<string, Renderer2>();
|
||||
|
@ -100,8 +102,16 @@ export class DomRendererFactory2 implements RendererFactory2 {
|
|||
(<EmulatedEncapsulationDomRenderer2>renderer).applyToHost(element);
|
||||
return renderer;
|
||||
}
|
||||
case ViewEncapsulation.Native:
|
||||
case 1:
|
||||
case ViewEncapsulation.ShadowDom:
|
||||
// TODO(FW-2290): remove the `case 1:` fallback logic and the warning in v12.
|
||||
if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
|
||||
!hasLoggedNativeEncapsulationWarning && type.encapsulation === 1) {
|
||||
hasLoggedNativeEncapsulationWarning = true;
|
||||
console.warn(
|
||||
'ViewEncapsulation.Native is no longer supported. Falling back to ViewEncapsulation.ShadowDom. The fallback will be removed in v12.');
|
||||
}
|
||||
|
||||
return new ShadowDomRenderer(this.eventManager, this.sharedStylesHost, element, type);
|
||||
default: {
|
||||
if (!this.rendererByCompId.has(type.id)) {
|
||||
|
@ -302,13 +312,9 @@ class ShadowDomRenderer extends DefaultDomRenderer2 {
|
|||
|
||||
constructor(
|
||||
eventManager: EventManager, private sharedStylesHost: DomSharedStylesHost,
|
||||
private hostEl: any, private component: RendererType2) {
|
||||
private hostEl: any, component: RendererType2) {
|
||||
super(eventManager);
|
||||
if (component.encapsulation === ViewEncapsulation.ShadowDom) {
|
||||
this.shadowRoot = (hostEl as any).attachShadow({mode: 'open'});
|
||||
} else {
|
||||
this.shadowRoot = (hostEl as any).createShadowRoot();
|
||||
}
|
||||
this.shadowRoot = (hostEl as any).attachShadow({mode: 'open'});
|
||||
this.sharedStylesHost.addHost(this.shadowRoot);
|
||||
const styles = flattenStyles(component.id, component.styles, []);
|
||||
for (let i = 0; i < styles.length; i++) {
|
||||
|
|
|
@ -20,8 +20,8 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
|||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
TestCmp, SomeApp, CmpEncapsulationEmulated, CmpEncapsulationNative, CmpEncapsulationNone,
|
||||
CmpEncapsulationNative
|
||||
TestCmp, SomeApp, CmpEncapsulationEmulated, CmpEncapsulationShadow, CmpEncapsulationNone,
|
||||
CmpEncapsulationShadow
|
||||
]
|
||||
});
|
||||
renderer = TestBed.createComponent(TestCmp).componentInstance.renderer;
|
||||
|
@ -98,16 +98,14 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
|||
});
|
||||
});
|
||||
|
||||
if (browserDetection.supportsDeprecatedShadowDomV0) {
|
||||
if (browserDetection.supportsShadowDom) {
|
||||
it('should allow to style components with emulated encapsulation and no encapsulation inside of components with shadow DOM',
|
||||
() => {
|
||||
const fixture = TestBed.createComponent(SomeApp);
|
||||
const cmp = fixture.debugElement.query(By.css('cmp-shadow')).nativeElement;
|
||||
const shadow = cmp.shadowRoot.querySelector('.shadow');
|
||||
|
||||
const cmp = fixture.debugElement.query(By.css('cmp-native')).nativeElement;
|
||||
|
||||
|
||||
const native = cmp.shadowRoot.querySelector('.native');
|
||||
expect(window.getComputedStyle(native).color).toEqual('rgb(255, 0, 0)');
|
||||
expect(window.getComputedStyle(shadow).color).toEqual('rgb(255, 0, 0)');
|
||||
|
||||
const emulated = cmp.shadowRoot.querySelector('.emulated');
|
||||
expect(window.getComputedStyle(emulated).color).toEqual('rgb(0, 0, 255)');
|
||||
|
@ -119,15 +117,6 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
|||
});
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cmp-native',
|
||||
template: `<div class="native"></div><cmp-emulated></cmp-emulated><cmp-none></cmp-none>`,
|
||||
styles: [`.native { color: red; }`],
|
||||
encapsulation: ViewEncapsulation.Native
|
||||
})
|
||||
class CmpEncapsulationNative {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cmp-emulated',
|
||||
template: `<div class="emulated"></div>`,
|
||||
|
@ -149,7 +138,7 @@ class CmpEncapsulationNone {
|
|||
@Component({
|
||||
selector: 'cmp-shadow',
|
||||
template: `<div class="shadow"></div><cmp-emulated></cmp-emulated><cmp-none></cmp-none>`,
|
||||
styles: [`.native { color: red; }`],
|
||||
styles: [`.shadow { color: red; }`],
|
||||
encapsulation: ViewEncapsulation.ShadowDom
|
||||
})
|
||||
class CmpEncapsulationShadow {
|
||||
|
@ -158,7 +147,7 @@ class CmpEncapsulationShadow {
|
|||
@Component({
|
||||
selector: 'some-app',
|
||||
template: `
|
||||
<cmp-native></cmp-native>
|
||||
<cmp-shadow></cmp-shadow>
|
||||
<cmp-emulated></cmp-emulated>
|
||||
<cmp-none></cmp-none>
|
||||
`,
|
||||
|
|
|
@ -15,13 +15,11 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
|||
|
||||
if (browserDetection.supportsShadowDom) {
|
||||
describe('ShadowDOM Support', () => {
|
||||
let testContainer: HTMLDivElement;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({imports: [TestModule]});
|
||||
});
|
||||
|
||||
it('should attach and use a shadowRoot when ViewEncapsulation.Native is set', () => {
|
||||
it('should attach and use a shadowRoot when ViewEncapsulation.ShadowDom is set', () => {
|
||||
const compEl = TestBed.createComponent(ShadowComponent).nativeElement;
|
||||
expect(compEl.shadowRoot!.textContent).toEqual('Hello World');
|
||||
});
|
||||
|
|
|
@ -305,8 +305,14 @@ function elementText(n: any): string {
|
|||
return '';
|
||||
}
|
||||
|
||||
if (getDOM().isElementNode(n) && (n as Element).tagName == 'CONTENT') {
|
||||
return elementText(Array.prototype.slice.apply((<any>n).getDistributedNodes()));
|
||||
if (getDOM().isElementNode(n)) {
|
||||
const tagName = (n as Element).tagName;
|
||||
|
||||
if (tagName === 'CONTENT') {
|
||||
return elementText(Array.prototype.slice.apply((<any>n).getDistributedNodes()));
|
||||
} else if (tagName === 'SLOT') {
|
||||
return elementText(Array.prototype.slice.apply((<any>n).assignedNodes()));
|
||||
}
|
||||
}
|
||||
|
||||
if (hasShadowRoot(n)) {
|
||||
|
|
|
@ -32,7 +32,6 @@ export class ServerRendererFactory2 implements RendererFactory2 {
|
|||
return this.defaultRenderer;
|
||||
}
|
||||
switch (type.encapsulation) {
|
||||
case ViewEncapsulation.Native:
|
||||
case ViewEncapsulation.Emulated: {
|
||||
let renderer = this.rendererByCompId.get(type.id);
|
||||
if (!renderer) {
|
||||
|
|
|
@ -272,19 +272,19 @@ class ImageExampleModule {
|
|||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
template: 'Native works',
|
||||
encapsulation: ViewEncapsulation.Native,
|
||||
template: 'Shadow DOM works',
|
||||
encapsulation: ViewEncapsulation.ShadowDom,
|
||||
styles: [':host { color: red; }']
|
||||
})
|
||||
class NativeEncapsulationApp {
|
||||
class ShadowDomEncapsulationApp {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [NativeEncapsulationApp],
|
||||
declarations: [ShadowDomEncapsulationApp],
|
||||
imports: [BrowserModule.withServerTransition({appId: 'test'}), ServerModule],
|
||||
bootstrap: [NativeEncapsulationApp]
|
||||
bootstrap: [ShadowDomEncapsulationApp]
|
||||
})
|
||||
class NativeExampleModule {
|
||||
class ShadowDomExampleModule {
|
||||
}
|
||||
|
||||
@Component({selector: 'my-child', template: 'Works!'})
|
||||
|
@ -666,8 +666,8 @@ describe('platform-server integration', () => {
|
|||
});
|
||||
}));
|
||||
|
||||
it('should handle ViewEncapsulation.Native', waitForAsync(() => {
|
||||
renderModule(NativeExampleModule, {document: doc}).then(output => {
|
||||
it('should handle ViewEncapsulation.ShadowDom', waitForAsync(() => {
|
||||
renderModule(ShadowDomExampleModule, {document: doc}).then(output => {
|
||||
expect(output).not.toBe('');
|
||||
expect(output).toContain('color: red');
|
||||
called = true;
|
||||
|
|
Loading…
Reference in New Issue