fix(ivy): remove ivy dependency on ViewEngine's resolveRendererType2 (#25396)

PR Close #25396
This commit is contained in:
Miško Hevery 2018-08-08 13:22:52 -07:00 committed by Ben Lesh
parent c8c1aa7fc0
commit 2016afdbff
10 changed files with 102 additions and 69 deletions

View File

@ -106,7 +106,7 @@ export function renderComponent<T>(
const rootContext = createRootContext(opts.scheduler || requestAnimationFrame.bind(window)); const rootContext = createRootContext(opts.scheduler || requestAnimationFrame.bind(window));
const rootView: LViewData = createLViewData( const rootView: LViewData = createLViewData(
rendererFactory.createRenderer(hostNode, componentDef.rendererType), rendererFactory.createRenderer(hostNode, componentDef),
createTView(-1, null, null, null, null), rootContext, createTView(-1, null, null, null, null), rootContext,
componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways); componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways);
rootView[INJECTOR] = opts.injector || null; rootView[INJECTOR] = opts.injector || null;

View File

@ -87,8 +87,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
const rendererFactory = const rendererFactory =
ngModule ? ngModule.injector.get(RendererFactory2) : domRendererFactory3; ngModule ? ngModule.injector.get(RendererFactory2) : domRendererFactory3;
const hostNode = isInternalRootView ? const hostNode = isInternalRootView ?
elementCreate( elementCreate(this.selector, rendererFactory.createRenderer(null, this.componentDef)) :
this.selector, rendererFactory.createRenderer(null, this.componentDef.rendererType)) :
locateHostElement(rendererFactory, rootSelectorOrNode); locateHostElement(rendererFactory, rootSelectorOrNode);
// The first index of the first selector is the tag name. // The first index of the first selector is the tag name.
@ -100,7 +99,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
// Create the root view. Uses empty TView and ContentTemplate. // Create the root view. Uses empty TView and ContentTemplate.
const rootView: LViewData = createLViewData( const rootView: LViewData = createLViewData(
rendererFactory.createRenderer(hostNode, this.componentDef.rendererType), rendererFactory.createRenderer(hostNode, this.componentDef),
createTView(-1, null, null, null, null), rootContext, createTView(-1, null, null, null, null), rootContext,
this.componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways); this.componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways);
rootView[INJECTOR] = ngModule && ngModule.injector || null; rootView[INJECTOR] = ngModule && ngModule.injector || null;

View File

@ -6,17 +6,22 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import './ng_dev_mode';
import {ChangeDetectionStrategy} from '../change_detection/constants'; import {ChangeDetectionStrategy} from '../change_detection/constants';
import {Provider} from '../core'; import {Provider, ViewEncapsulation} from '../core';
import {NgModuleDef, NgModuleDefInternal} from '../metadata/ng_module'; import {NgModuleDef, NgModuleDefInternal} from '../metadata/ng_module';
import {RendererType2} from '../render/api';
import {Type} from '../type'; import {Type} from '../type';
import {resolveRendererType2} from '../view/util';
import {BaseDef, ComponentDefFeature, ComponentDefInternal, ComponentQuery, ComponentTemplate, ComponentType, DirectiveDefFeature, DirectiveDefInternal, DirectiveType, DirectiveTypesOrFactory, PipeDefInternal, PipeType, PipeTypesOrFactory} from './interfaces/definition'; import {BaseDef, ComponentDefFeature, ComponentDefInternal, ComponentQuery, ComponentTemplate, ComponentType, DirectiveDefFeature, DirectiveDefInternal, DirectiveType, DirectiveTypesOrFactory, PipeDefInternal, PipeType, PipeTypesOrFactory} from './interfaces/definition';
import {CssSelectorList, SelectorFlags} from './interfaces/projection'; import {CssSelectorList, SelectorFlags} from './interfaces/projection';
const EMPTY: {} = {};
const EMPTY_ARRAY: any[] = [];
ngDevMode && Object.freeze(EMPTY);
ngDevMode && Object.freeze(EMPTY_ARRAY);
let _renderCompCount = 0;
/** /**
* Create a component definition object. * Create a component definition object.
@ -180,8 +185,28 @@ export function defineComponent<T>(componentDefinition: {
*/ */
features?: ComponentDefFeature[]; features?: ComponentDefFeature[];
rendererType?: RendererType2; /**
* Defines template and style encapsulation options available for Component's {@link Component}.
*/
encapsulation?: ViewEncapsulation;
/**
* Defines arbitrary developer-defined data to be stored on a renderer instance.
* This is useful for renderers that delegate to other renderers.
*
* see: animation
*/
data?: {[kind: string]: any};
/**
* A set of styles that the component needs to be present for component to render correctly.
*/
styles?: string[];
/**
* The strategy that the default change detector uses to detect changes.
* When set, takes effect the next time change detection is triggered.
*/
changeDetection?: ChangeDetectionStrategy; changeDetection?: ChangeDetectionStrategy;
/** /**
@ -215,6 +240,7 @@ export function defineComponent<T>(componentDefinition: {
const pipeTypes = componentDefinition.pipes !; const pipeTypes = componentDefinition.pipes !;
const directiveTypes = componentDefinition.directives !; const directiveTypes = componentDefinition.directives !;
const declaredInputs: {[key: string]: string} = {} as any; const declaredInputs: {[key: string]: string} = {} as any;
const encapsulation = componentDefinition.encapsulation;
const def: ComponentDefInternal<any> = { const def: ComponentDefInternal<any> = {
type: type, type: type,
diPublic: null, diPublic: null,
@ -227,7 +253,6 @@ export function defineComponent<T>(componentDefinition: {
inputs: invertObject(componentDefinition.inputs, declaredInputs), inputs: invertObject(componentDefinition.inputs, declaredInputs),
declaredInputs: declaredInputs, declaredInputs: declaredInputs,
outputs: invertObject(componentDefinition.outputs), outputs: invertObject(componentDefinition.outputs),
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
exportAs: componentDefinition.exportAs || null, exportAs: componentDefinition.exportAs || null,
onInit: type.prototype.ngOnInit || null, onInit: type.prototype.ngOnInit || null,
doCheck: type.prototype.ngDoCheck || null, doCheck: type.prototype.ngDoCheck || null,
@ -247,6 +272,12 @@ export function defineComponent<T>(componentDefinition: {
selectors: componentDefinition.selectors, selectors: componentDefinition.selectors,
viewQuery: componentDefinition.viewQuery || null, viewQuery: componentDefinition.viewQuery || null,
features: componentDefinition.features || null, features: componentDefinition.features || null,
data: componentDefinition.data || EMPTY,
// TODO(misko): convert ViewEncapsulation into const enum so that it can be used directly in the
// next line. Also `None` should be 0 not 2.
encapsulation: encapsulation == null ? 2 /* ViewEncapsulation.None */ : encapsulation,
id: `c${_renderCompCount++}`,
styles: EMPTY_ARRAY,
}; };
const feature = componentDefinition.features; const feature = componentDefinition.features;
feature && feature.forEach((fn) => fn(def)); feature && feature.forEach((fn) => fn(def));
@ -273,17 +304,15 @@ export function extractPipeDef(type: PipeType<any>): PipeDefInternal<any> {
export function defineNgModule<T>(def: {type: T} & Partial<NgModuleDef<T, any, any, any>>): never { export function defineNgModule<T>(def: {type: T} & Partial<NgModuleDef<T, any, any, any>>): never {
const res: NgModuleDefInternal<T> = { const res: NgModuleDefInternal<T> = {
type: def.type, type: def.type,
bootstrap: def.bootstrap || [], bootstrap: def.bootstrap || EMPTY_ARRAY,
declarations: def.declarations || [], declarations: def.declarations || EMPTY_ARRAY,
imports: def.imports || [], imports: def.imports || EMPTY_ARRAY,
exports: def.exports || [], exports: def.exports || EMPTY_ARRAY,
transitiveCompileScopes: null, transitiveCompileScopes: null,
}; };
return res as never; return res as never;
} }
const EMPTY = {};
/** /**
* Inverts an inputs or outputs lookup such that the keys, which were the * Inverts an inputs or outputs lookup such that the keys, which were the
* minified keys, are part of the values, and the values are parsed so that * minified keys, are part of the values, and the values are parsed so that

View File

@ -22,7 +22,7 @@ import {AttributeMarker, InitialInputData, InitialInputs, LContainerNode, LEleme
import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection'; import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection';
import {LQueries} from './interfaces/query'; import {LQueries} from './interfaces/query';
import {ProceduralRenderer3, RComment, RElement, RText, Renderer3, RendererFactory3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer'; import {ProceduralRenderer3, RComment, RElement, RText, Renderer3, RendererFactory3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, CurrentMatchesList, DECLARATION_VIEW, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, OpaqueViewState, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view'; import {BINDING_INDEX, CLEANUP, CONTENT_QUERIES, CONTEXT, CurrentMatchesList, DECLARATION_VIEW, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, OpaqueViewState, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert'; import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {appendChild, appendProjectedNode, canInsertNativeNode, createTextNode, findComponentHost, getChildLNode, getLViewChild, getNextLNode, getParentLNode, insertView, removeView} from './node_manipulation'; import {appendChild, appendProjectedNode, canInsertNativeNode, createTextNode, findComponentHost, getChildLNode, getLViewChild, getNextLNode, getParentLNode, insertView, removeView} from './node_manipulation';
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher'; import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
@ -1668,9 +1668,8 @@ function addComponentLogic<T>(
const componentView = addToViewTree( const componentView = addToViewTree(
viewData, previousOrParentNode.tNode.index as number, viewData, previousOrParentNode.tNode.index as number,
createLViewData( createLViewData(
rendererFactory.createRenderer(previousOrParentNode.native as RElement, def.rendererType), rendererFactory.createRenderer(previousOrParentNode.native as RElement, def), tView,
tView, instance, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, instance, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, getCurrentSanitizer()));
getCurrentSanitizer()));
// We need to set the host node/data here because when the component LNode was created, // We need to set the host node/data here because when the component LNode was created,
// we didn't yet know it was a component (just an element). // we didn't yet know it was a component (just an element).

View File

@ -6,8 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Provider} from '../../core'; import {Provider, ViewEncapsulation} from '../../core';
import {RendererType2} from '../../render/api';
import {Type} from '../../type'; import {Type} from '../../type';
import {CssSelectorList} from './projection'; import {CssSelectorList} from './projection';
@ -187,20 +186,42 @@ export type ComponentDefInternal<T> = ComponentDef<T, string>;
* See: {@link defineComponent} * See: {@link defineComponent}
*/ */
export interface ComponentDef<T, Selector extends string> extends DirectiveDef<T, Selector> { export interface ComponentDef<T, Selector extends string> extends DirectiveDef<T, Selector> {
/**
* Runtime unique component ID.
*/
id: string;
/** /**
* The View template of the component. * The View template of the component.
*/ */
readonly template: ComponentTemplate<T>; readonly template: ComponentTemplate<T>;
/**
* A set of styles that the component needs to be present for component to render correctly.
*/
readonly styles: string[];
/** /**
* Query-related instructions for a component. * Query-related instructions for a component.
*/ */
readonly viewQuery: ComponentQuery<T>|null; readonly viewQuery: ComponentQuery<T>|null;
/** /**
* Renderer type data of the component. * The view encapsulation type, which determines how styles are applied to
* DOM elements. One of
* - `Emulated` (default): Emulate native scoping of styles.
* - `Native`: Use the native encapsulation mechanism of the renderer.
* - `ShadowDom`: Use modern [ShadowDOM](https://w3c.github.io/webcomponents/spec/shadow/) and
* create a ShadowRoot for component's host element.
* - `None`: Do not provide any template or style encapsulation.
*/ */
readonly rendererType: RendererType2|null; readonly encapsulation: ViewEncapsulation;
/**
* Defines arbitrary developer-defined data to be stored on a renderer instance.
* This is useful for renderers that delegate to other renderers.
*/
readonly data: {[kind: string]: any};
/** Whether or not this component's ChangeDetectionStrategy is OnPush */ /** Whether or not this component's ChangeDetectionStrategy is OnPush */
readonly onPush: boolean; readonly onPush: boolean;

View File

@ -42,7 +42,8 @@ const __global: {ngDevMode: NgDevModePerfCounters | boolean} =
typeof global != 'undefined' && global; typeof global != 'undefined' && global;
export function ngDevModeResetPerfCounters(): NgDevModePerfCounters { export function ngDevModeResetPerfCounters(): NgDevModePerfCounters {
return __global.ngDevMode = { // Make sure to refer to ngDevMode as ['ngDevMode'] for clousre.
return __global['ngDevMode'] = {
firstTemplatePass: 0, firstTemplatePass: 0,
tNode: 0, tNode: 0,
tView: 0, tView: 0,
@ -75,5 +76,6 @@ export function ngDevModeResetPerfCounters(): NgDevModePerfCounters {
* as much early warning and errors as possible. * as much early warning and errors as possible.
*/ */
if (typeof ngDevMode === 'undefined' || ngDevMode) { if (typeof ngDevMode === 'undefined' || ngDevMode) {
__global.ngDevMode = ngDevModeResetPerfCounters(); // Make sure to refer to ngDevMode as ['ngDevMode'] for clousre.
__global['ngDevMode'] = ngDevModeResetPerfCounters();
} }

View File

@ -27,7 +27,7 @@
"name": "EMPTY$1" "name": "EMPTY$1"
}, },
{ {
"name": "EMPTY_RENDERER_TYPE_ID" "name": "EMPTY_ARRAY$2"
}, },
{ {
"name": "FLAGS" "name": "FLAGS"
@ -77,15 +77,9 @@
{ {
"name": "TVIEW" "name": "TVIEW"
}, },
{
"name": "UNDEFINED_RENDERER_TYPE_ID"
},
{ {
"name": "VIEWS" "name": "VIEWS"
}, },
{
"name": "ViewEncapsulation$1"
},
{ {
"name": "_CLEAN_PROMISE" "name": "_CLEAN_PROMISE"
}, },
@ -269,9 +263,6 @@
{ {
"name": "resetApplicationState" "name": "resetApplicationState"
}, },
{
"name": "resolveRendererType2"
},
{ {
"name": "setHostBindings" "name": "setHostBindings"
}, },

View File

@ -45,7 +45,7 @@
"name": "EMPTY$1" "name": "EMPTY$1"
}, },
{ {
"name": "EMPTY_RENDERER_TYPE_ID" "name": "EMPTY_ARRAY$2"
}, },
{ {
"name": "ElementRef" "name": "ElementRef"
@ -182,9 +182,6 @@
{ {
"name": "TodoStore" "name": "TodoStore"
}, },
{
"name": "UNDEFINED_RENDERER_TYPE_ID"
},
{ {
"name": "VIEWS" "name": "VIEWS"
}, },
@ -194,9 +191,6 @@
{ {
"name": "ViewContainerRef$1" "name": "ViewContainerRef$1"
}, },
{
"name": "ViewEncapsulation$1"
},
{ {
"name": "ViewRef" "name": "ViewRef"
}, },
@ -836,9 +830,6 @@
{ {
"name": "resolveDirective" "name": "resolveDirective"
}, },
{
"name": "resolveRendererType2"
},
{ {
"name": "restoreView" "name": "restoreView"
}, },

View File

@ -204,8 +204,9 @@ describe('encapsulation', () => {
} }
}, },
factory: () => new EncapsulatedComponent, factory: () => new EncapsulatedComponent,
rendererType: encapsulation: ViewEncapsulation.Emulated,
createRendererType2({encapsulation: ViewEncapsulation.Emulated, styles: [], data: {}}), styles: [],
data: {},
directives: () => [LeafComponent] directives: () => [LeafComponent]
}); });
} }
@ -250,8 +251,9 @@ describe('encapsulation', () => {
} }
}, },
factory: () => new WrapperComponentWith, factory: () => new WrapperComponentWith,
rendererType: encapsulation: ViewEncapsulation.Emulated,
createRendererType2({encapsulation: ViewEncapsulation.Emulated, styles: [], data: {}}), styles: [],
data: {},
directives: () => [LeafComponentwith] directives: () => [LeafComponentwith]
}); });
} }
@ -268,8 +270,9 @@ describe('encapsulation', () => {
} }
}, },
factory: () => new LeafComponentwith, factory: () => new LeafComponentwith,
rendererType: encapsulation: ViewEncapsulation.Emulated,
createRendererType2({encapsulation: ViewEncapsulation.Emulated, styles: [], data: {}}), styles: [],
data: {},
}); });
} }

View File

@ -158,24 +158,22 @@ describe('animation renderer factory', () => {
} }
}, },
factory: () => new SomeComponentWithAnimation, factory: () => new SomeComponentWithAnimation,
rendererType: createRendererType2({ encapsulation: ViewEncapsulation.None,
encapsulation: ViewEncapsulation.None, styles: [],
styles: [], data: {
data: { animation: [{
animation: [{ type: 7,
type: 7, name: 'myAnimation',
name: 'myAnimation', definitions: [{
definitions: [{ type: 1,
type: 1, expr: '* => on',
expr: '* => on', animation:
animation: [{type: 4, styles: {type: 6, styles: {opacity: 1}, offset: null}, timings: 10}],
[{type: 4, styles: {type: 6, styles: {opacity: 1}, offset: null}, timings: 10}], options: null
options: null }],
}], options: {}
options: {} }]
}] },
}
}),
}); });
} }