feat(core): view engine - add missing DI features (#14225)
Part of #14013 PR Close #14225
This commit is contained in:
parent
ae7f5f37d2
commit
a05e50fda3
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
export {anchorDef, elementDef} from './element';
|
export {anchorDef, elementDef} from './element';
|
||||||
export {ngContentDef} from './ng_content';
|
export {ngContentDef} from './ng_content';
|
||||||
export {providerDef} from './provider';
|
export {directiveDef, providerDef} from './provider';
|
||||||
export {pureArrayDef, pureObjectDef, purePipeDef} from './pure_expression';
|
export {pureArrayDef, pureObjectDef, purePipeDef} from './pure_expression';
|
||||||
export {queryDef} from './query';
|
export {queryDef} from './query';
|
||||||
export {textDef} from './text';
|
export {textDef} from './text';
|
||||||
|
@ -7,17 +7,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {isDevMode} from '../application_ref';
|
import {isDevMode} from '../application_ref';
|
||||||
import {SimpleChange, SimpleChanges} from '../change_detection/change_detection';
|
import {ChangeDetectorRef, SimpleChange, SimpleChanges} from '../change_detection/change_detection';
|
||||||
import {Injector} from '../di';
|
import {Injector} from '../di';
|
||||||
import {stringify} from '../facade/lang';
|
import {stringify} from '../facade/lang';
|
||||||
import {ElementRef} from '../linker/element_ref';
|
import {ElementRef} from '../linker/element_ref';
|
||||||
import {TemplateRef} from '../linker/template_ref';
|
import {TemplateRef} from '../linker/template_ref';
|
||||||
import {ViewContainerRef} from '../linker/view_container_ref';
|
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||||
import {Renderer} from '../render/api';
|
import {Renderer} from '../render/api';
|
||||||
|
import {Type} from '../type';
|
||||||
|
|
||||||
import {queryDef} from './query';
|
import {queryDef} from './query';
|
||||||
import {BindingDef, BindingType, DepDef, DepFlags, DisposableFn, EntryAction, NodeData, NodeDef, NodeFlags, NodeType, ProviderData, ProviderOutputDef, QueryBindingType, QueryDef, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewState, asElementData, asProviderData} from './types';
|
import {BindingDef, BindingType, DepDef, DepFlags, DisposableFn, EntryAction, NodeData, NodeDef, NodeFlags, NodeType, ProviderData, ProviderOutputDef, ProviderType, QueryBindingType, QueryDef, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewState, asElementData, asProviderData} from './types';
|
||||||
import {checkAndUpdateBinding, dispatchEvent, entryAction, setBindingDebugInfo, setCurrentNode, unwrapValue} from './util';
|
import {checkAndUpdateBinding, dispatchEvent, entryAction, findElementDef, setBindingDebugInfo, setCurrentNode, unwrapValue} from './util';
|
||||||
|
|
||||||
const _tokenKeyCache = new Map<any, string>();
|
const _tokenKeyCache = new Map<any, string>();
|
||||||
|
|
||||||
@ -25,11 +26,31 @@ const RendererTokenKey = tokenKey(Renderer);
|
|||||||
const ElementRefTokenKey = tokenKey(ElementRef);
|
const ElementRefTokenKey = tokenKey(ElementRef);
|
||||||
const ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
|
const ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
|
||||||
const TemplateRefTokenKey = tokenKey(TemplateRef);
|
const TemplateRefTokenKey = tokenKey(TemplateRef);
|
||||||
|
const ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
|
||||||
|
const InjectorRefTokenKey = tokenKey(Injector);
|
||||||
|
|
||||||
export function providerDef(
|
const NOT_CREATED = new Object();
|
||||||
|
|
||||||
|
export function directiveDef(
|
||||||
flags: NodeFlags, matchedQueries: [string, QueryValueType][], childCount: number, ctor: any,
|
flags: NodeFlags, matchedQueries: [string, QueryValueType][], childCount: number, ctor: any,
|
||||||
deps: ([DepFlags, any] | any)[], props?: {[name: string]: [number, string]},
|
deps: ([DepFlags, any] | any)[], props?: {[name: string]: [number, string]},
|
||||||
outputs?: {[name: string]: string}, component?: () => ViewDefinition): NodeDef {
|
outputs?: {[name: string]: string}, component?: () => ViewDefinition): NodeDef {
|
||||||
|
return _providerDef(
|
||||||
|
flags, matchedQueries, childCount, ProviderType.Class, ctor, ctor, deps, props, outputs,
|
||||||
|
component);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function providerDef(
|
||||||
|
flags: NodeFlags, matchedQueries: [string, QueryValueType][], type: ProviderType, token: any,
|
||||||
|
value: any, deps: ([DepFlags, any] | any)[]): NodeDef {
|
||||||
|
return _providerDef(flags, matchedQueries, 0, type, token, value, deps);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _providerDef(
|
||||||
|
flags: NodeFlags, matchedQueries: [string, QueryValueType][], childCount: number,
|
||||||
|
type: ProviderType, token: any, value: any, deps: ([DepFlags, any] | any)[],
|
||||||
|
props?: {[name: string]: [number, string]}, outputs?: {[name: string]: string},
|
||||||
|
component?: () => ViewDefinition): NodeDef {
|
||||||
const matchedQueryDefs: {[queryId: string]: QueryValueType} = {};
|
const matchedQueryDefs: {[queryId: string]: QueryValueType} = {};
|
||||||
if (matchedQueries) {
|
if (matchedQueries) {
|
||||||
matchedQueries.forEach(([queryId, valueType]) => { matchedQueryDefs[queryId] = valueType; });
|
matchedQueries.forEach(([queryId, valueType]) => { matchedQueryDefs[queryId] = valueType; });
|
||||||
@ -85,8 +106,9 @@ export function providerDef(
|
|||||||
disposableCount: outputDefs.length,
|
disposableCount: outputDefs.length,
|
||||||
element: undefined,
|
element: undefined,
|
||||||
provider: {
|
provider: {
|
||||||
tokenKey: tokenKey(ctor),
|
type,
|
||||||
token: ctor, ctor,
|
token,
|
||||||
|
tokenKey: tokenKey(token), value,
|
||||||
deps: depDefs,
|
deps: depDefs,
|
||||||
outputs: outputDefs, component
|
outputs: outputDefs, component
|
||||||
},
|
},
|
||||||
@ -106,19 +128,9 @@ export function tokenKey(token: any): string {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createProvider(
|
export function createProviderInstance(view: ViewData, def: NodeDef): any {
|
||||||
view: ViewData, def: NodeDef, componentView: ViewData): ProviderData {
|
|
||||||
const providerDef = def.provider;
|
const providerDef = def.provider;
|
||||||
const provider = createInstance(view, def.parent, providerDef.ctor, providerDef.deps);
|
return def.flags & NodeFlags.LazyProvider ? NOT_CREATED : createInstance(view, def);
|
||||||
if (providerDef.outputs.length) {
|
|
||||||
for (let i = 0; i < providerDef.outputs.length; i++) {
|
|
||||||
const output = providerDef.outputs[i];
|
|
||||||
const subscription = provider[output.propName].subscribe(
|
|
||||||
eventHandlerClosure(view, def.parent, output.eventName));
|
|
||||||
view.disposables[def.disposableIndex + i] = subscription.unsubscribe.bind(subscription);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {instance: provider, componentView: componentView};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function eventHandlerClosure(view: ViewData, index: number, eventName: string) {
|
function eventHandlerClosure(view: ViewData, index: number, eventName: string) {
|
||||||
@ -182,7 +194,38 @@ export function checkAndUpdateProviderDynamic(view: ViewData, def: NodeDef, valu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createInstance(view: ViewData, elIndex: number, ctor: any, deps: DepDef[]): any {
|
function createInstance(view: ViewData, nodeDef: NodeDef): any {
|
||||||
|
const providerDef = nodeDef.provider;
|
||||||
|
let injectable: any;
|
||||||
|
switch (providerDef.type) {
|
||||||
|
case ProviderType.Class:
|
||||||
|
injectable =
|
||||||
|
createClass(view, nodeDef.index, nodeDef.parent, providerDef.value, providerDef.deps);
|
||||||
|
break;
|
||||||
|
case ProviderType.Factory:
|
||||||
|
injectable =
|
||||||
|
callFactory(view, nodeDef.index, nodeDef.parent, providerDef.value, providerDef.deps);
|
||||||
|
break;
|
||||||
|
case ProviderType.UseExisting:
|
||||||
|
injectable = resolveDep(view, nodeDef.index, nodeDef.parent, providerDef.deps[0]);
|
||||||
|
break;
|
||||||
|
case ProviderType.Value:
|
||||||
|
injectable = providerDef.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (providerDef.outputs.length) {
|
||||||
|
for (let i = 0; i < providerDef.outputs.length; i++) {
|
||||||
|
const output = providerDef.outputs[i];
|
||||||
|
const subscription = injectable[output.propName].subscribe(
|
||||||
|
eventHandlerClosure(view, nodeDef.parent, output.eventName));
|
||||||
|
view.disposables[nodeDef.disposableIndex + i] = subscription.unsubscribe.bind(subscription);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return injectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createClass(
|
||||||
|
view: ViewData, requestorNodeIndex: number, elIndex: number, ctor: any, deps: DepDef[]): any {
|
||||||
const len = deps.length;
|
const len = deps.length;
|
||||||
let injectable: any;
|
let injectable: any;
|
||||||
switch (len) {
|
switch (len) {
|
||||||
@ -190,32 +233,69 @@ function createInstance(view: ViewData, elIndex: number, ctor: any, deps: DepDef
|
|||||||
injectable = new ctor();
|
injectable = new ctor();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
injectable = new ctor(resolveDep(view, elIndex, deps[0]));
|
injectable = new ctor(resolveDep(view, requestorNodeIndex, elIndex, deps[0]));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
injectable = new ctor(resolveDep(view, elIndex, deps[0]), resolveDep(view, elIndex, deps[1]));
|
injectable = new ctor(
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[0]),
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[1]));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
injectable = new ctor(
|
injectable = new ctor(
|
||||||
resolveDep(view, elIndex, deps[0]), resolveDep(view, elIndex, deps[1]),
|
resolveDep(view, requestorNodeIndex, elIndex, deps[0]),
|
||||||
resolveDep(view, elIndex, deps[2]));
|
resolveDep(view, requestorNodeIndex, elIndex, deps[1]),
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[2]));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
const depValues = new Array(len);
|
const depValues = new Array(len);
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
depValues[i] = resolveDep(view, elIndex, deps[i]);
|
depValues[i] = resolveDep(view, requestorNodeIndex, elIndex, deps[i]);
|
||||||
}
|
}
|
||||||
injectable = new ctor(...depValues);
|
injectable = new ctor(...depValues);
|
||||||
}
|
}
|
||||||
return injectable;
|
return injectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function callFactory(
|
||||||
|
view: ViewData, requestorNodeIndex: number, elIndex: number, factory: any,
|
||||||
|
deps: DepDef[]): any {
|
||||||
|
const len = deps.length;
|
||||||
|
let injectable: any;
|
||||||
|
switch (len) {
|
||||||
|
case 0:
|
||||||
|
injectable = factory();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
injectable = factory(resolveDep(view, requestorNodeIndex, elIndex, deps[0]));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
injectable = factory(
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[0]),
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[1]));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
injectable = factory(
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[0]),
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[1]),
|
||||||
|
resolveDep(view, requestorNodeIndex, elIndex, deps[2]));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const depValues = Array(len);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
depValues[i] = resolveDep(view, requestorNodeIndex, elIndex, deps[i]);
|
||||||
|
}
|
||||||
|
injectable = factory(...depValues);
|
||||||
|
}
|
||||||
|
return injectable;
|
||||||
|
}
|
||||||
|
|
||||||
export function resolveDep(
|
export function resolveDep(
|
||||||
view: ViewData, elIndex: number, depDef: DepDef,
|
view: ViewData, requestNodeIndex: number, elIndex: number, depDef: DepDef): any {
|
||||||
notFoundValue: any = Injector.THROW_IF_NOT_FOUND): any {
|
const notFoundValue = depDef.flags & DepFlags.Optional ? null : Injector.THROW_IF_NOT_FOUND;
|
||||||
const tokenKey = depDef.tokenKey;
|
const tokenKey = depDef.tokenKey;
|
||||||
|
|
||||||
if (depDef.flags & DepFlags.SkipSelf) {
|
if (depDef.flags & DepFlags.SkipSelf) {
|
||||||
|
requestNodeIndex = null;
|
||||||
const elDef = view.def.nodes[elIndex];
|
const elDef = view.def.nodes[elIndex];
|
||||||
if (elDef.parent != null) {
|
if (elDef.parent != null) {
|
||||||
elIndex = elDef.parent;
|
elIndex = elDef.parent;
|
||||||
@ -240,12 +320,30 @@ export function resolveDep(
|
|||||||
return view.services.createViewContainerRef(asElementData(view, elIndex));
|
return view.services.createViewContainerRef(asElementData(view, elIndex));
|
||||||
case TemplateRefTokenKey:
|
case TemplateRefTokenKey:
|
||||||
return view.services.createTemplateRef(view, elDef);
|
return view.services.createTemplateRef(view, elDef);
|
||||||
|
case ChangeDetectorRefTokenKey:
|
||||||
|
let cdView = view;
|
||||||
|
// If we are still checking dependencies on the initial element...
|
||||||
|
if (requestNodeIndex != null) {
|
||||||
|
const requestorNodeDef = view.def.nodes[requestNodeIndex];
|
||||||
|
if (requestorNodeDef.flags & NodeFlags.HasComponent) {
|
||||||
|
cdView = asProviderData(view, requestNodeIndex).componentView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// A ViewRef is also a ChangeDetectorRef
|
||||||
|
return view.services.createViewRef(cdView);
|
||||||
|
case InjectorRefTokenKey:
|
||||||
|
return createInjector(view, elIndex);
|
||||||
default:
|
default:
|
||||||
const providerIndex = elDef.element.providerIndices[tokenKey];
|
const providerIndex = elDef.element.providerIndices[tokenKey];
|
||||||
if (providerIndex != null) {
|
if (providerIndex != null) {
|
||||||
return asProviderData(view, providerIndex).instance;
|
const providerData = asProviderData(view, providerIndex);
|
||||||
|
if (providerData.instance === NOT_CREATED) {
|
||||||
|
providerData.instance = createInstance(view, view.def.nodes[providerIndex]);
|
||||||
|
}
|
||||||
|
return providerData.instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
requestNodeIndex = null;
|
||||||
elIndex = parentDiIndex(view);
|
elIndex = parentDiIndex(view);
|
||||||
view = view.parent;
|
view = view.parent;
|
||||||
}
|
}
|
||||||
@ -274,7 +372,8 @@ class Injector_ implements Injector {
|
|||||||
constructor(private view: ViewData, private elIndex: number) {}
|
constructor(private view: ViewData, private elIndex: number) {}
|
||||||
get(token: any, notFoundValue?: any): any {
|
get(token: any, notFoundValue?: any): any {
|
||||||
return resolveDep(
|
return resolveDep(
|
||||||
this.view, this.elIndex, {flags: DepFlags.None, token, tokenKey: tokenKey(token)});
|
this.view, undefined, this.elIndex,
|
||||||
|
{flags: DepFlags.None, token, tokenKey: tokenKey(token)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ function _pureExpressionDef(
|
|||||||
|
|
||||||
export function createPureExpression(view: ViewData, def: NodeDef): PureExpressionData {
|
export function createPureExpression(view: ViewData, def: NodeDef): PureExpressionData {
|
||||||
const pipe = def.pureExpression.pipeDep ?
|
const pipe = def.pureExpression.pipeDep ?
|
||||||
resolveDep(view, def.parent, def.pureExpression.pipeDep) :
|
resolveDep(view, def.index, def.parent, def.pureExpression.pipeDep) :
|
||||||
undefined;
|
undefined;
|
||||||
return {value: undefined, pipe};
|
return {value: undefined, pipe};
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import {Sanitizer, SecurityContext} from '../security';
|
|||||||
import {createInjector} from './provider';
|
import {createInjector} from './provider';
|
||||||
import {getQueryValue} from './query';
|
import {getQueryValue} from './query';
|
||||||
import {DebugContext, ElementData, NodeData, NodeDef, NodeType, Services, ViewData, ViewDefinition, ViewState, asElementData} from './types';
|
import {DebugContext, ElementData, NodeData, NodeDef, NodeType, Services, ViewData, ViewDefinition, ViewState, asElementData} from './types';
|
||||||
import {isComponentView, renderNode, rootRenderNodes} from './util';
|
import {findElementDef, isComponentView, renderNode, rootRenderNodes} from './util';
|
||||||
import {checkAndUpdateView, checkNoChangesView, createEmbeddedView, destroyView} from './view';
|
import {checkAndUpdateView, checkNoChangesView, createEmbeddedView, destroyView} from './view';
|
||||||
import {attachEmbeddedView, detachEmbeddedView} from './view_attach';
|
import {attachEmbeddedView, detachEmbeddedView} from './view_attach';
|
||||||
|
|
||||||
@ -33,6 +33,7 @@ export class DefaultServices implements Services {
|
|||||||
sanitize(context: SecurityContext, value: string): string {
|
sanitize(context: SecurityContext, value: string): string {
|
||||||
return this._sanitizer.sanitize(context, value);
|
return this._sanitizer.sanitize(context, value);
|
||||||
}
|
}
|
||||||
|
createViewRef(data: ViewData): ViewRef { return new ViewRef_(data); }
|
||||||
createViewContainerRef(data: ElementData): ViewContainerRef {
|
createViewContainerRef(data: ElementData): ViewContainerRef {
|
||||||
return new ViewContainerRef_(data);
|
return new ViewContainerRef_(data);
|
||||||
}
|
}
|
||||||
@ -120,8 +121,16 @@ class ViewRef_ implements EmbeddedViewRef<any> {
|
|||||||
this._view.state = ViewState.ChecksDisabled;
|
this._view.state = ViewState.ChecksDisabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
detectChanges(): void { checkAndUpdateView(this._view); }
|
detectChanges(): void {
|
||||||
checkNoChanges(): void { checkNoChangesView(this._view); }
|
if (this._view.state !== ViewState.FirstCheck) {
|
||||||
|
checkAndUpdateView(this._view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkNoChanges(): void {
|
||||||
|
if (this._view.state !== ViewState.FirstCheck) {
|
||||||
|
checkNoChangesView(this._view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reattach(): void {
|
reattach(): void {
|
||||||
if (this._view.state === ViewState.ChecksDisabled) {
|
if (this._view.state === ViewState.ChecksDisabled) {
|
||||||
@ -217,18 +226,6 @@ function findHostElement(view: ViewData): ElementData {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function findElementDef(view: ViewData, nodeIndex: number): NodeDef {
|
|
||||||
const viewDef = view.def;
|
|
||||||
let nodeDef = viewDef.nodes[nodeIndex];
|
|
||||||
while (nodeDef) {
|
|
||||||
if (nodeDef.type === NodeType.Element) {
|
|
||||||
return nodeDef;
|
|
||||||
}
|
|
||||||
nodeDef = nodeDef.parent != null ? viewDef.nodes[nodeDef.parent] : undefined;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function collectReferences(view: ViewData, nodeDef: NodeDef, references: {[key: string]: any}) {
|
function collectReferences(view: ViewData, nodeDef: NodeDef, references: {[key: string]: any}) {
|
||||||
for (let queryId in nodeDef.matchedQueries) {
|
for (let queryId in nodeDef.matchedQueries) {
|
||||||
if (queryId.startsWith('#')) {
|
if (queryId.startsWith('#')) {
|
||||||
|
@ -10,6 +10,7 @@ import {PipeTransform} from '../change_detection/change_detection';
|
|||||||
import {QueryList} from '../linker/query_list';
|
import {QueryList} from '../linker/query_list';
|
||||||
import {TemplateRef} from '../linker/template_ref';
|
import {TemplateRef} from '../linker/template_ref';
|
||||||
import {ViewContainerRef} from '../linker/view_container_ref';
|
import {ViewContainerRef} from '../linker/view_container_ref';
|
||||||
|
import {ViewRef} from '../linker/view_ref';
|
||||||
import {RenderComponentType, RenderDebugInfo, Renderer, RootRenderer} from '../render/api';
|
import {RenderComponentType, RenderDebugInfo, Renderer, RootRenderer} from '../render/api';
|
||||||
import {Sanitizer, SecurityContext} from '../security';
|
import {Sanitizer, SecurityContext} from '../security';
|
||||||
|
|
||||||
@ -126,6 +127,7 @@ export enum NodeFlags {
|
|||||||
HasComponent = 1 << 9,
|
HasComponent = 1 << 9,
|
||||||
HasContentQuery = 1 << 10,
|
HasContentQuery = 1 << 10,
|
||||||
HasViewQuery = 1 << 11,
|
HasViewQuery = 1 << 11,
|
||||||
|
LazyProvider = 1 << 12
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BindingDef {
|
export interface BindingDef {
|
||||||
@ -162,8 +164,6 @@ export interface ElementDef {
|
|||||||
/**
|
/**
|
||||||
* visible providers for DI in the view,
|
* visible providers for DI in the view,
|
||||||
* as see from this element.
|
* as see from this element.
|
||||||
* Note: We use protoypical inheritance
|
|
||||||
* to indices in parent ElementDefs.
|
|
||||||
*/
|
*/
|
||||||
providerIndices: {[tokenKey: string]: number};
|
providerIndices: {[tokenKey: string]: number};
|
||||||
source: string;
|
source: string;
|
||||||
@ -175,15 +175,23 @@ export interface ElementOutputDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ProviderDef {
|
export interface ProviderDef {
|
||||||
|
type: ProviderType;
|
||||||
token: any;
|
token: any;
|
||||||
tokenKey: string;
|
tokenKey: string;
|
||||||
ctor: any;
|
value: any;
|
||||||
deps: DepDef[];
|
deps: DepDef[];
|
||||||
outputs: ProviderOutputDef[];
|
outputs: ProviderOutputDef[];
|
||||||
// closure to allow recursive components
|
// closure to allow recursive components
|
||||||
component: ViewDefinitionFactory;
|
component: ViewDefinitionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ProviderType {
|
||||||
|
Value,
|
||||||
|
Class,
|
||||||
|
Factory,
|
||||||
|
UseExisting
|
||||||
|
}
|
||||||
|
|
||||||
export interface DepDef {
|
export interface DepDef {
|
||||||
flags: DepFlags;
|
flags: DepFlags;
|
||||||
token: any;
|
token: any;
|
||||||
@ -195,7 +203,8 @@ export interface DepDef {
|
|||||||
*/
|
*/
|
||||||
export enum DepFlags {
|
export enum DepFlags {
|
||||||
None = 0,
|
None = 0,
|
||||||
SkipSelf = 1 << 0
|
SkipSelf = 1 << 0,
|
||||||
|
Optional = 1 << 1
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProviderOutputDef {
|
export interface ProviderOutputDef {
|
||||||
@ -377,6 +386,8 @@ export interface Services {
|
|||||||
renderComponent(rcp: RenderComponentType): Renderer;
|
renderComponent(rcp: RenderComponentType): Renderer;
|
||||||
sanitize(context: SecurityContext, value: string): string;
|
sanitize(context: SecurityContext, value: string): string;
|
||||||
// Note: This needs to be here to prevent a cycle in source files.
|
// Note: This needs to be here to prevent a cycle in source files.
|
||||||
|
createViewRef(data: ViewData): ViewRef;
|
||||||
|
// Note: This needs to be here to prevent a cycle in source files.
|
||||||
createViewContainerRef(data: ElementData): ViewContainerRef;
|
createViewContainerRef(data: ElementData): ViewContainerRef;
|
||||||
// Note: This needs to be here to prevent a cycle in source files.
|
// Note: This needs to be here to prevent a cycle in source files.
|
||||||
createTemplateRef(parentView: ViewData, def: NodeDef): TemplateRef<any>;
|
createTemplateRef(parentView: ViewData, def: NodeDef): TemplateRef<any>;
|
||||||
|
@ -88,6 +88,18 @@ export function declaredViewContainer(view: ViewData): ElementData {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function findElementDef(view: ViewData, nodeIndex: number): NodeDef {
|
||||||
|
const viewDef = view.def;
|
||||||
|
let nodeDef = viewDef.nodes[nodeIndex];
|
||||||
|
while (nodeDef) {
|
||||||
|
if (nodeDef.type === NodeType.Element) {
|
||||||
|
return nodeDef;
|
||||||
|
}
|
||||||
|
nodeDef = nodeDef.parent != null ? viewDef.nodes[nodeDef.parent] : undefined;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export function renderNode(view: ViewData, def: NodeDef): any {
|
export function renderNode(view: ViewData, def: NodeDef): any {
|
||||||
switch (def.type) {
|
switch (def.type) {
|
||||||
case NodeType.Element:
|
case NodeType.Element:
|
||||||
|
@ -12,7 +12,7 @@ import {RenderComponentType, Renderer} from '../render/api';
|
|||||||
import {checkAndUpdateElementDynamic, checkAndUpdateElementInline, createElement} from './element';
|
import {checkAndUpdateElementDynamic, checkAndUpdateElementInline, createElement} from './element';
|
||||||
import {expressionChangedAfterItHasBeenCheckedError} from './errors';
|
import {expressionChangedAfterItHasBeenCheckedError} from './errors';
|
||||||
import {appendNgContent} from './ng_content';
|
import {appendNgContent} from './ng_content';
|
||||||
import {callLifecycleHooksChildrenFirst, checkAndUpdateProviderDynamic, checkAndUpdateProviderInline, createProvider} from './provider';
|
import {callLifecycleHooksChildrenFirst, checkAndUpdateProviderDynamic, checkAndUpdateProviderInline, createProviderInstance} from './provider';
|
||||||
import {checkAndUpdatePureExpressionDynamic, checkAndUpdatePureExpressionInline, createPureExpression} from './pure_expression';
|
import {checkAndUpdatePureExpressionDynamic, checkAndUpdatePureExpressionInline, createPureExpression} from './pure_expression';
|
||||||
import {checkAndUpdateQuery, createQuery, queryDef} from './query';
|
import {checkAndUpdateQuery, createQuery, queryDef} from './query';
|
||||||
import {checkAndUpdateTextDynamic, checkAndUpdateTextInline, createText} from './text';
|
import {checkAndUpdateTextDynamic, checkAndUpdateTextInline, createText} from './text';
|
||||||
@ -58,6 +58,7 @@ export function viewDef(
|
|||||||
});
|
});
|
||||||
if (node.element) {
|
if (node.element) {
|
||||||
node.element = cloneAndModifyElement(node.element, {
|
node.element = cloneAndModifyElement(node.element, {
|
||||||
|
// Use protoypical inheritance to not get O(n^2) complexity...
|
||||||
providerIndices:
|
providerIndices:
|
||||||
Object.create(currentParent ? currentParent.element.providerIndices : null),
|
Object.create(currentParent ? currentParent.element.providerIndices : null),
|
||||||
});
|
});
|
||||||
@ -284,43 +285,49 @@ function _createViewNodes(view: ViewData) {
|
|||||||
const nodes = view.nodes;
|
const nodes = view.nodes;
|
||||||
for (let i = 0; i < def.nodes.length; i++) {
|
for (let i = 0; i < def.nodes.length; i++) {
|
||||||
const nodeDef = def.nodes[i];
|
const nodeDef = def.nodes[i];
|
||||||
let nodeData: any;
|
|
||||||
// As the current node is being created, we have to use
|
// As the current node is being created, we have to use
|
||||||
// the parent node as the current node for error messages, ...
|
// the parent node as the current node for error messages, ...
|
||||||
setCurrentNode(view, nodeDef.parent);
|
setCurrentNode(view, nodeDef.parent);
|
||||||
switch (nodeDef.type) {
|
switch (nodeDef.type) {
|
||||||
case NodeType.Element:
|
case NodeType.Element:
|
||||||
nodeData = createElement(view, renderHost, nodeDef);
|
nodes[i] = createElement(view, renderHost, nodeDef) as any;
|
||||||
break;
|
break;
|
||||||
case NodeType.Text:
|
case NodeType.Text:
|
||||||
nodeData = createText(view, renderHost, nodeDef);
|
nodes[i] = createText(view, renderHost, nodeDef) as any;
|
||||||
break;
|
break;
|
||||||
case NodeType.Provider:
|
case NodeType.Provider:
|
||||||
let componentView: ViewData;
|
|
||||||
if (nodeDef.provider.component) {
|
if (nodeDef.provider.component) {
|
||||||
const hostElIndex = nodeDef.parent;
|
// Components can inject a ChangeDetectorRef that needs a references to
|
||||||
componentView = createView(
|
// the component view. Therefore, we create the component view first
|
||||||
view.services, view, hostElIndex, resolveViewDefinition(nodeDef.provider.component));
|
// and set the ProviderData in ViewData, and then instantiate the provider.
|
||||||
}
|
const componentView = createView(
|
||||||
const providerData = nodeData = createProvider(view, nodeDef, componentView);
|
view.services, view, nodeDef.parent,
|
||||||
if (componentView) {
|
resolveViewDefinition(nodeDef.provider.component));
|
||||||
initView(componentView, providerData.instance, providerData.instance);
|
const providerData = <ProviderData>{componentView, instance: undefined};
|
||||||
|
nodes[i] = providerData as any;
|
||||||
|
const instance = providerData.instance = createProviderInstance(view, nodeDef);
|
||||||
|
initView(componentView, instance, instance);
|
||||||
|
} else {
|
||||||
|
const instance = createProviderInstance(view, nodeDef);
|
||||||
|
const providerData = <ProviderData>{componentView: undefined, instance};
|
||||||
|
nodes[i] = providerData as any;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NodeType.PureExpression:
|
case NodeType.PureExpression:
|
||||||
nodeData = createPureExpression(view, nodeDef);
|
nodes[i] = createPureExpression(view, nodeDef) as any;
|
||||||
break;
|
break;
|
||||||
case NodeType.Query:
|
case NodeType.Query:
|
||||||
nodeData = createQuery();
|
nodes[i] = createQuery() as any;
|
||||||
break;
|
break;
|
||||||
case NodeType.NgContent:
|
case NodeType.NgContent:
|
||||||
appendNgContent(view, renderHost, nodeDef);
|
appendNgContent(view, renderHost, nodeDef);
|
||||||
// no runtime data needed for NgContent...
|
// no runtime data needed for NgContent...
|
||||||
nodeData = undefined;
|
nodes[i] = undefined;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nodes[i] = nodeData;
|
|
||||||
}
|
}
|
||||||
|
// Create the ViewData.nodes of component views after we created everything else,
|
||||||
|
// so that e.g. ng-content works
|
||||||
execComponentViewsAction(view, ViewAction.CreateViewNodes);
|
execComponentViewsAction(view, ViewAction.CreateViewNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||||
import {BindingType, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, anchorDef, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, elementDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {BindingType, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, anchorDef, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
import {inject} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, AComp, [], null, null,
|
NodeFlags.None, null, 0, AComp, [], null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 0, 'span'),
|
elementDef(NodeFlags.None, null, null, 0, 'span'),
|
||||||
@ -85,7 +85,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(
|
const {view, rootNodes} = createAndGetRootNodes(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(NodeFlags.None, null, 0, AComp, [], null, null, () => compViewDef(
|
directiveDef(NodeFlags.None, null, 0, AComp, [], null, null, () => compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 0, 'span', null, [[BindingType.ElementAttribute, 'a', SecurityContext.NONE]]),
|
elementDef(NodeFlags.None, null, null, 0, 'span', null, [[BindingType.ElementAttribute, 'a', SecurityContext.NONE]]),
|
||||||
], update
|
], update
|
||||||
@ -118,7 +118,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, AComp, [], null, null,
|
NodeFlags.None, null, 0, AComp, [], null, null,
|
||||||
() => compViewDef(
|
() => compViewDef(
|
||||||
[
|
[
|
||||||
@ -156,7 +156,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
compViewDef(
|
compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, AComp, [], {a: [0, 'a']}, null,
|
NodeFlags.None, null, 0, AComp, [], {a: [0, 'a']}, null,
|
||||||
() =>
|
() =>
|
||||||
compViewDef(
|
compViewDef(
|
||||||
@ -212,7 +212,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, AComp, [], null, null,
|
NodeFlags.None, null, 0, AComp, [], null, null,
|
||||||
() => compViewDef(
|
() => compViewDef(
|
||||||
[
|
[
|
||||||
@ -249,11 +249,11 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, AComp, [], null, null,
|
NodeFlags.None, null, 0, AComp, [], null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.OnDestroy, null, 0, ChildProvider, [])
|
directiveDef(NodeFlags.OnDestroy, null, 0, ChildProvider, [])
|
||||||
])),
|
])),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||||
import {BindingType, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, elementDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {BindingType, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
import {inject} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 0, embeddedViewDef([
|
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 0, embeddedViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.OnDestroy, null, 0, ChildProvider, [])
|
directiveDef(NodeFlags.OnDestroy, null, 0, ChildProvider, [])
|
||||||
]))
|
]))
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||||
import {DebugContext, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, detachEmbeddedView, elementDef, ngContentDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {DebugContext, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, detachEmbeddedView, directiveDef, elementDef, ngContentDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
import {inject} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
elementDef(NodeFlags.None, null, null, 1 + contentNodes.length, 'acomp'),
|
elementDef(NodeFlags.None, null, null, 1 + contentNodes.length, 'acomp'),
|
||||||
providerDef(NodeFlags.None, null, 0, AComp, [], null, null, () => aCompViewDef),
|
directiveDef(NodeFlags.None, null, 0, AComp, [], null, null, () => aCompViewDef),
|
||||||
...contentNodes
|
...contentNodes
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
[
|
[
|
||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.HasEmbeddedViews, null, 0, 1, embeddedViewDef([textDef(null, ['a'])])),
|
NodeFlags.HasEmbeddedViews, null, 0, 1, embeddedViewDef([textDef(null, ['a'])])),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, CreateViewService, [TemplateRef, ViewContainerRef])
|
NodeFlags.None, null, 0, CreateViewService, [TemplateRef, ViewContainerRef])
|
||||||
],
|
],
|
||||||
[elementDef(NodeFlags.None, null, null, 1, 'div'), ngContentDef(null, 0)])));
|
[elementDef(NodeFlags.None, null, null, 1, 'div'), ngContentDef(null, 0)])));
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, ElementRef, EventEmitter, OnChanges, OnDestroy, OnInit, RenderComponentType, Renderer, RootRenderer, Sanitizer, SecurityContext, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectorRef, DoCheck, ElementRef, EventEmitter, Injector, OnChanges, OnDestroy, OnInit, RenderComponentType, Renderer, RootRenderer, Sanitizer, SecurityContext, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
||||||
import {BindingType, DebugContext, DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, elementDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {BindingType, DebugContext, DefaultServices, DepFlags, NodeDef, NodeFlags, ProviderType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, destroyView, directiveDef, elementDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
import {inject} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -50,18 +50,74 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
|
let instance: SomeService;
|
||||||
|
|
||||||
|
class SomeService {
|
||||||
|
constructor(public dep: any) { instance = this; }
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => { instance = null; });
|
||||||
|
|
||||||
it('should create providers eagerly', () => {
|
it('should create providers eagerly', () => {
|
||||||
let instances: SomeService[] = [];
|
createAndGetRootNodes(compViewDef([
|
||||||
class SomeService {
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
constructor() { instances.push(this); }
|
directiveDef(NodeFlags.None, null, 0, SomeService, [])
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(instance instanceof SomeService).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create providers lazily', () => {
|
||||||
|
let lazy: LazyService;
|
||||||
|
class LazyService {
|
||||||
|
constructor() { lazy = this; }
|
||||||
}
|
}
|
||||||
|
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [])
|
directiveDef(NodeFlags.LazyProvider, null, 0, LazyService, []),
|
||||||
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Injector])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instances.length).toBe(1);
|
expect(lazy).toBeUndefined();
|
||||||
|
instance.dep.get(LazyService);
|
||||||
|
expect(lazy instanceof LazyService).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create value providers', () => {
|
||||||
|
createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
|
providerDef(NodeFlags.None, null, ProviderType.Value, 'someToken', 'someValue', []),
|
||||||
|
directiveDef(NodeFlags.None, null, 0, SomeService, ['someToken']),
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(instance.dep).toBe('someValue');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create factory providers', () => {
|
||||||
|
function someFactory() { return 'someValue'; }
|
||||||
|
|
||||||
|
createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
|
providerDef(NodeFlags.None, null, ProviderType.Factory, 'someToken', someFactory, []),
|
||||||
|
directiveDef(NodeFlags.None, null, 0, SomeService, ['someToken']),
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(instance.dep).toBe('someValue');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create useExisting providers', () => {
|
||||||
|
createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 3, 'span'),
|
||||||
|
providerDef(
|
||||||
|
NodeFlags.None, null, ProviderType.Value, 'someExistingToken', 'someValue', []),
|
||||||
|
providerDef(
|
||||||
|
NodeFlags.None, null, ProviderType.UseExisting, 'someToken', null,
|
||||||
|
['someExistingToken']),
|
||||||
|
directiveDef(NodeFlags.None, null, 0, SomeService, ['someToken']),
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(instance.dep).toBe('someValue');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add a DebugContext to errors in provider factories', () => {
|
it('should add a DebugContext to errors in provider factories', () => {
|
||||||
@ -73,7 +129,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
try {
|
try {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [])
|
||||||
]));
|
]));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err = e;
|
err = e;
|
||||||
@ -87,20 +143,13 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('deps', () => {
|
describe('deps', () => {
|
||||||
let instance: SomeService;
|
|
||||||
class Dep {}
|
class Dep {}
|
||||||
|
|
||||||
class SomeService {
|
|
||||||
constructor(public dep: any) { instance = this; }
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(() => { instance = null; });
|
|
||||||
|
|
||||||
it('should inject deps from the same element', () => {
|
it('should inject deps from the same element', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, Dep, []),
|
directiveDef(NodeFlags.None, null, 0, Dep, []),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep instanceof Dep).toBeTruthy();
|
expect(instance.dep instanceof Dep).toBeTruthy();
|
||||||
@ -109,9 +158,9 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
it('should inject deps from a parent element', () => {
|
it('should inject deps from a parent element', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 3, 'span'),
|
elementDef(NodeFlags.None, null, null, 3, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, Dep, []),
|
directiveDef(NodeFlags.None, null, 0, Dep, []),
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep instanceof Dep).toBeTruthy();
|
expect(instance.dep instanceof Dep).toBeTruthy();
|
||||||
@ -120,9 +169,9 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
it('should not inject deps from sibling root elements', () => {
|
it('should not inject deps from sibling root elements', () => {
|
||||||
const nodes = [
|
const nodes = [
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, Dep, []),
|
directiveDef(NodeFlags.None, null, 0, Dep, []),
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
||||||
];
|
];
|
||||||
|
|
||||||
// root elements
|
// root elements
|
||||||
@ -139,22 +188,52 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
it('should inject from a parent elment in a parent view', () => {
|
it('should inject from a parent elment in a parent view', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, Dep, [], null, null,
|
NodeFlags.None, null, 0, Dep, [], null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Dep])
|
||||||
])),
|
])),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep instanceof Dep).toBeTruthy();
|
expect(instance.dep instanceof Dep).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw for missing dependencies', () => {
|
||||||
|
expect(() => createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
|
directiveDef(NodeFlags.None, null, 0, SomeService, ['nonExistingDep'])
|
||||||
|
])))
|
||||||
|
.toThrowError('No provider for nonExistingDep!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use null for optional missing dependencies', () => {
|
||||||
|
createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
|
directiveDef(
|
||||||
|
NodeFlags.None, null, 0, SomeService, [[DepFlags.Optional, 'nonExistingDep']])
|
||||||
|
]));
|
||||||
|
expect(instance.dep).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should skip the current element when using SkipSelf', () => {
|
||||||
|
createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 4, 'span'),
|
||||||
|
providerDef(
|
||||||
|
NodeFlags.None, null, ProviderType.Value, 'someToken', 'someParentValue', []),
|
||||||
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
|
providerDef(NodeFlags.None, null, ProviderType.Value, 'someToken', 'someValue', []),
|
||||||
|
directiveDef(
|
||||||
|
NodeFlags.None, null, 0, SomeService, [[DepFlags.SkipSelf, 'someToken']])
|
||||||
|
]));
|
||||||
|
expect(instance.dep).toBe('someParentValue');
|
||||||
|
});
|
||||||
|
|
||||||
describe('builtin tokens', () => {
|
describe('builtin tokens', () => {
|
||||||
it('should inject ViewContainerRef', () => {
|
it('should inject ViewContainerRef', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 1),
|
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 1),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [ViewContainerRef])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [ViewContainerRef])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
||||||
@ -164,7 +243,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(NodeFlags.None, null, null, 1, embeddedViewDef([anchorDef(
|
anchorDef(NodeFlags.None, null, null, 1, embeddedViewDef([anchorDef(
|
||||||
NodeFlags.None, null, null, 0)])),
|
NodeFlags.None, null, null, 0)])),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [TemplateRef])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [TemplateRef])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
||||||
@ -173,17 +252,49 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
it('should inject ElementRef', () => {
|
it('should inject ElementRef', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [ElementRef])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [ElementRef])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.nativeElement).toBe(asElementData(view, 0).renderElement);
|
expect(instance.dep.nativeElement).toBe(asElementData(view, 0).renderElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should inject Injector', () => {
|
||||||
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Injector])
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(instance.dep.get(SomeService)).toBe(instance);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject ChangeDetectorRef for non component providers', () => {
|
||||||
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
|
directiveDef(NodeFlags.None, null, 0, SomeService, [ChangeDetectorRef])
|
||||||
|
]));
|
||||||
|
|
||||||
|
expect(instance.dep._view).toBe(view);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject ChangeDetectorRef for component providers', () => {
|
||||||
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
|
directiveDef(
|
||||||
|
NodeFlags.None, null, 0, SomeService, [ChangeDetectorRef], null, null,
|
||||||
|
() => compViewDef([
|
||||||
|
elementDef(NodeFlags.None, null, null, 0, 'span'),
|
||||||
|
])),
|
||||||
|
]));
|
||||||
|
|
||||||
|
const compView = asProviderData(view, 1).componentView;
|
||||||
|
expect(instance.dep._view).toBe(compView);
|
||||||
|
});
|
||||||
|
|
||||||
if (config.directDom) {
|
if (config.directDom) {
|
||||||
it('should not inject Renderer when using directDom', () => {
|
it('should not inject Renderer when using directDom', () => {
|
||||||
expect(() => createAndGetRootNodes(compViewDef([
|
expect(() => createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [Renderer])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Renderer])
|
||||||
])))
|
])))
|
||||||
.toThrowError('No provider for Renderer!');
|
.toThrowError('No provider for Renderer!');
|
||||||
});
|
});
|
||||||
@ -191,7 +302,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
it('should inject Renderer when not using directDom', () => {
|
it('should inject Renderer when not using directDom', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [Renderer])
|
directiveDef(NodeFlags.None, null, 0, SomeService, [Renderer])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.createElement).toBeTruthy();
|
expect(instance.dep.createElement).toBeTruthy();
|
||||||
@ -217,7 +328,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [], {a: [0, 'a'], b: [1, 'b']})
|
directiveDef(NodeFlags.None, null, 0, SomeService, [], {a: [0, 'a'], b: [1, 'b']})
|
||||||
],
|
],
|
||||||
(view) => {
|
(view) => {
|
||||||
setCurrentNode(view, 1);
|
setCurrentNode(view, 1);
|
||||||
@ -246,7 +357,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomeService, [], {a: [0, 'a']})
|
directiveDef(NodeFlags.None, null, 0, SomeService, [], {a: [0, 'a']})
|
||||||
],
|
],
|
||||||
(view) => {
|
(view) => {
|
||||||
setCurrentNode(view, 1);
|
setCurrentNode(view, 1);
|
||||||
@ -291,7 +402,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, SomeService, [], null, {emitter: 'someEventName'})
|
NodeFlags.None, null, 0, SomeService, [], null, {emitter: 'someEventName'})
|
||||||
],
|
],
|
||||||
null, handleEvent));
|
null, handleEvent));
|
||||||
@ -313,7 +424,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, SomeService, [], null, {emitter: 'someEventName'})
|
NodeFlags.None, null, 0, SomeService, [], null, {emitter: 'someEventName'})
|
||||||
],
|
],
|
||||||
null, () => { throw new Error('Test'); }));
|
null, () => { throw new Error('Test'); }));
|
||||||
@ -358,9 +469,9 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 3, 'span'),
|
elementDef(NodeFlags.None, null, null, 3, 'span'),
|
||||||
providerDef(allFlags, null, 0, SomeService, [], {a: [0, 'a']}),
|
directiveDef(allFlags, null, 0, SomeService, [], {a: [0, 'a']}),
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(allFlags, null, 0, SomeService, [], {a: [0, 'a']})
|
directiveDef(allFlags, null, 0, SomeService, [], {a: [0, 'a']})
|
||||||
],
|
],
|
||||||
(updater) => {
|
(updater) => {
|
||||||
setCurrentNode(view, 1);
|
setCurrentNode(view, 1);
|
||||||
@ -419,7 +530,8 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.OnChanges, null, 0, SomeService, [], {a: [0, 'nonMinifiedA']})
|
directiveDef(
|
||||||
|
NodeFlags.OnChanges, null, 0, SomeService, [], {a: [0, 'nonMinifiedA']})
|
||||||
],
|
],
|
||||||
(updater) => {
|
(updater) => {
|
||||||
setCurrentNode(view, 1);
|
setCurrentNode(view, 1);
|
||||||
@ -442,7 +554,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.AfterContentChecked, null, 0, SomeService, [], {a: [0, 'a']}),
|
directiveDef(NodeFlags.AfterContentChecked, null, 0, SomeService, [], {a: [0, 'a']}),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err: any;
|
let err: any;
|
||||||
@ -465,7 +577,7 @@ function defineTests(config: {directDom: boolean, viewFlags: number}) {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.OnDestroy, null, 0, SomeService, [], {a: [0, 'a']}),
|
directiveDef(NodeFlags.OnDestroy, null, 0, SomeService, [], {a: [0, 'a']}),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err: any;
|
let err: any;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {PipeTransform, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue} from '@angular/core';
|
import {PipeTransform, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue} from '@angular/core';
|
||||||
import {DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asProviderData, asPureExpressionData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, elementDef, providerDef, pureArrayDef, pureObjectDef, purePipeDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {DefaultServices, NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asProviderData, asPureExpressionData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, directiveDef, elementDef, pureArrayDef, pureObjectDef, purePipeDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
import {inject} from '@angular/core/testing';
|
||||||
|
|
||||||
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic} from './helper';
|
import {INLINE_DYNAMIC_VALUES, InlineDynamic, checkNodeInlineOrDynamic} from './helper';
|
||||||
@ -48,7 +48,7 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'), pureArrayDef(2),
|
elementDef(NodeFlags.None, null, null, 2, 'span'), pureArrayDef(2),
|
||||||
providerDef(NodeFlags.None, null, 0, Service, [], {data: [0, 'data']})
|
directiveDef(NodeFlags.None, null, 0, Service, [], {data: [0, 'data']})
|
||||||
],
|
],
|
||||||
(view) => {
|
(view) => {
|
||||||
setCurrentNode(view, 1);
|
setCurrentNode(view, 1);
|
||||||
@ -114,7 +114,7 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'), pureObjectDef(['a', 'b']),
|
elementDef(NodeFlags.None, null, null, 2, 'span'), pureObjectDef(['a', 'b']),
|
||||||
providerDef(NodeFlags.None, null, 0, Service, [], {data: [0, 'data']})
|
directiveDef(NodeFlags.None, null, 0, Service, [], {data: [0, 'data']})
|
||||||
],
|
],
|
||||||
(view) => {
|
(view) => {
|
||||||
setCurrentNode(view, 1);
|
setCurrentNode(view, 1);
|
||||||
@ -183,8 +183,8 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 3, 'span'),
|
elementDef(NodeFlags.None, null, null, 3, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomePipe, []), purePipeDef(SomePipe, 2),
|
directiveDef(NodeFlags.None, null, 0, SomePipe, []), purePipeDef(SomePipe, 2),
|
||||||
providerDef(NodeFlags.None, null, 0, Service, [], {data: [0, 'data']})
|
directiveDef(NodeFlags.None, null, 0, Service, [], {data: [0, 'data']})
|
||||||
],
|
],
|
||||||
(view) => {
|
(view) => {
|
||||||
setCurrentNode(view, 2);
|
setCurrentNode(view, 2);
|
||||||
@ -222,7 +222,7 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, SomePipe, []),
|
directiveDef(NodeFlags.None, null, 0, SomePipe, []),
|
||||||
purePipeDef(SomePipe, 1),
|
purePipeDef(SomePipe, 1),
|
||||||
],
|
],
|
||||||
(view) => {
|
(view) => {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementRef, QueryList, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
import {ElementRef, QueryList, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||||
import {BindingType, DebugContext, DefaultServices, NodeDef, NodeFlags, QueryBindingType, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, elementDef, providerDef, queryDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {BindingType, DebugContext, DefaultServices, NodeDef, NodeFlags, QueryBindingType, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, attachEmbeddedView, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createEmbeddedView, createRootView, destroyView, detachEmbeddedView, directiveDef, elementDef, queryDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
import {inject} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -47,20 +47,20 @@ export function main() {
|
|||||||
|
|
||||||
function contentQueryProviders() {
|
function contentQueryProviders() {
|
||||||
return [
|
return [
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, []),
|
directiveDef(NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.All})
|
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.All})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function viewQueryProviders(compView: ViewDefinition) {
|
function viewQueryProviders(compView: ViewDefinition) {
|
||||||
return [
|
return [
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, [], null, null, () => compView),
|
directiveDef(NodeFlags.None, null, 1, QueryService, [], null, null, () => compView),
|
||||||
queryDef(NodeFlags.HasViewQuery, 'query1', {'a': QueryBindingType.All})
|
queryDef(NodeFlags.HasViewQuery, 'query1', {'a': QueryBindingType.All})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function aServiceProvider() {
|
function aServiceProvider() {
|
||||||
return providerDef(NodeFlags.None, [['query1', QueryValueType.Provider]], 0, AService, []);
|
return directiveDef(NodeFlags.None, [['query1', QueryValueType.Provider]], 0, AService, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('content queries', () => {
|
describe('content queries', () => {
|
||||||
@ -272,7 +272,7 @@ export function main() {
|
|||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 4, 'div'),
|
elementDef(NodeFlags.None, null, null, 4, 'div'),
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, []),
|
directiveDef(NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.All}),
|
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.All}),
|
||||||
aServiceProvider(),
|
aServiceProvider(),
|
||||||
aServiceProvider(),
|
aServiceProvider(),
|
||||||
@ -295,7 +295,7 @@ export function main() {
|
|||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 4, 'div'),
|
elementDef(NodeFlags.None, null, null, 4, 'div'),
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, []),
|
directiveDef(NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
||||||
aServiceProvider(),
|
aServiceProvider(),
|
||||||
aServiceProvider(),
|
aServiceProvider(),
|
||||||
@ -316,7 +316,7 @@ export function main() {
|
|||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, [['query1', QueryValueType.ElementRef]], null, 2, 'div'),
|
elementDef(NodeFlags.None, [['query1', QueryValueType.ElementRef]], null, 2, 'div'),
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, []),
|
directiveDef(NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
@ -335,7 +335,7 @@ export function main() {
|
|||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.None, [['query1', QueryValueType.TemplateRef]], null, 2,
|
NodeFlags.None, [['query1', QueryValueType.TemplateRef]], null, 2,
|
||||||
viewDef(ViewFlags.None, [anchorDef(NodeFlags.None, null, null, 0)])),
|
viewDef(ViewFlags.None, [anchorDef(NodeFlags.None, null, null, 0)])),
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, []),
|
directiveDef(NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
@ -352,7 +352,7 @@ export function main() {
|
|||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(NodeFlags.None, [['query1', QueryValueType.ViewContainerRef]], null, 2),
|
anchorDef(NodeFlags.None, [['query1', QueryValueType.ViewContainerRef]], null, 2),
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, []),
|
directiveDef(NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.First}),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
@ -406,7 +406,7 @@ export function main() {
|
|||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 3, 'div'),
|
elementDef(NodeFlags.None, null, null, 3, 'div'),
|
||||||
providerDef(NodeFlags.None, null, 1, QueryService, []),
|
directiveDef(NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.All}),
|
queryDef(NodeFlags.HasContentQuery, 'query1', {'a': QueryBindingType.All}),
|
||||||
aServiceProvider(),
|
aServiceProvider(),
|
||||||
]));
|
]));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
import {RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
||||||
import {DebugContext, DefaultServices, NodeDef, NodeFlags, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, elementDef, providerDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {DebugContext, DefaultServices, NodeDef, NodeFlags, QueryValueType, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, createRootView, directiveDef, elementDef, rootRenderNodes, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
import {inject} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -45,11 +45,11 @@ export function main() {
|
|||||||
function createViewWithData() {
|
function createViewWithData() {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
elementDef(NodeFlags.None, null, null, 1, 'div'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, AComp, [], null, null,
|
NodeFlags.None, null, 0, AComp, [], null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, [['#ref', QueryValueType.ElementRef]], null, 2, 'span'),
|
elementDef(NodeFlags.None, [['#ref', QueryValueType.ElementRef]], null, 2, 'span'),
|
||||||
providerDef(NodeFlags.None, null, 0, AService, []), textDef(null, ['a'])
|
directiveDef(NodeFlags.None, null, 0, AService, []), textDef(null, ['a'])
|
||||||
])),
|
])),
|
||||||
]));
|
]));
|
||||||
return view;
|
return view;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {NodeFlags, QueryValueType, ViewData, ViewDefinition, ViewFlags, anchorDef, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, elementDef, providerDef, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {NodeFlags, QueryValueType, ViewData, ViewDefinition, ViewFlags, anchorDef, checkAndUpdateView, checkNoChangesView, checkNodeDynamic, checkNodeInline, directiveDef, elementDef, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('viewDef', () => {
|
describe('viewDef', () => {
|
||||||
@ -124,7 +124,7 @@ export function main() {
|
|||||||
it('should calculate childFlags for one level', () => {
|
it('should calculate childFlags for one level', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.AfterContentChecked, null, 0, AService, [])
|
directiveDef(NodeFlags.AfterContentChecked, null, 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([NodeFlags.AfterContentChecked, NodeFlags.None]);
|
expect(childFlags(vd)).toEqual([NodeFlags.AfterContentChecked, NodeFlags.None]);
|
||||||
@ -134,7 +134,7 @@ export function main() {
|
|||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.AfterContentChecked, null, 0, AService, [])
|
directiveDef(NodeFlags.AfterContentChecked, null, 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([
|
expect(childFlags(vd)).toEqual([
|
||||||
@ -145,10 +145,10 @@ export function main() {
|
|||||||
it('should calculate childFlags for one level, multiple roots', () => {
|
it('should calculate childFlags for one level, multiple roots', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.AfterContentChecked, null, 0, AService, []),
|
directiveDef(NodeFlags.AfterContentChecked, null, 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.AfterContentInit, null, 0, AService, []),
|
directiveDef(NodeFlags.AfterContentInit, null, 0, AService, []),
|
||||||
providerDef(NodeFlags.AfterViewChecked, null, 0, AService, []),
|
directiveDef(NodeFlags.AfterViewChecked, null, 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([
|
expect(childFlags(vd)).toEqual([
|
||||||
@ -161,10 +161,10 @@ export function main() {
|
|||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.AfterContentChecked, null, 0, AService, []),
|
directiveDef(NodeFlags.AfterContentChecked, null, 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.AfterContentInit, null, 0, AService, []),
|
directiveDef(NodeFlags.AfterContentInit, null, 0, AService, []),
|
||||||
providerDef(NodeFlags.AfterViewInit, null, 0, AService, []),
|
directiveDef(NodeFlags.AfterViewInit, null, 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([
|
expect(childFlags(vd)).toEqual([
|
||||||
@ -182,7 +182,7 @@ export function main() {
|
|||||||
it('should calculate childMatchedQueries for one level', () => {
|
it('should calculate childMatchedQueries for one level', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, [])
|
directiveDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([['q1'], []]);
|
expect(childMatchedQueries(vd)).toEqual([['q1'], []]);
|
||||||
@ -192,7 +192,7 @@ export function main() {
|
|||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, [])
|
directiveDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([['q1'], ['q1'], []]);
|
expect(childMatchedQueries(vd)).toEqual([['q1'], ['q1'], []]);
|
||||||
@ -201,10 +201,10 @@ export function main() {
|
|||||||
it('should calculate childMatchedQueries for one level, multiple roots', () => {
|
it('should calculate childMatchedQueries for one level, multiple roots', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, []),
|
directiveDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.None, [['q2', QueryValueType.Provider]], 0, AService, []),
|
directiveDef(NodeFlags.None, [['q2', QueryValueType.Provider]], 0, AService, []),
|
||||||
providerDef(NodeFlags.None, [['q3', QueryValueType.Provider]], 0, AService, []),
|
directiveDef(NodeFlags.None, [['q3', QueryValueType.Provider]], 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([['q1'], [], ['q2', 'q3'], [], []]);
|
expect(childMatchedQueries(vd)).toEqual([['q1'], [], ['q2', 'q3'], [], []]);
|
||||||
@ -214,10 +214,10 @@ export function main() {
|
|||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||||
providerDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, []),
|
directiveDef(NodeFlags.None, [['q1', QueryValueType.Provider]], 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
elementDef(NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.None, [['q2', QueryValueType.Provider]], 0, AService, []),
|
directiveDef(NodeFlags.None, [['q2', QueryValueType.Provider]], 0, AService, []),
|
||||||
providerDef(NodeFlags.None, [['q3', QueryValueType.Provider]], 0, AService, []),
|
directiveDef(NodeFlags.None, [['q3', QueryValueType.Provider]], 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([['q1'], ['q1'], [], ['q2', 'q3'], [], []]);
|
expect(childMatchedQueries(vd)).toEqual([['q1'], ['q1'], [], ['q2', 'q3'], [], []]);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import {NgIf} from '@angular/common';
|
import {NgIf} from '@angular/common';
|
||||||
import {Component, NgModule, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
import {Component, NgModule, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
||||||
import {BindingType, DefaultServices, NodeFlags, ViewData, ViewDefinition, ViewFlags, anchorDef, asElementData, asProviderData, checkAndUpdateView, checkNodeInline, createRootView, elementDef, providerDef, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
import {BindingType, DefaultServices, NodeFlags, ViewData, ViewDefinition, ViewFlags, anchorDef, asElementData, asProviderData, checkAndUpdateView, checkNodeInline, createRootView, directiveDef, elementDef, setCurrentNode, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {DomSanitizer, DomSanitizerImpl, SafeStyle} from '@angular/platform-browser/src/security/dom_sanitization_service';
|
import {DomSanitizer, DomSanitizerImpl, SafeStyle} from '@angular/platform-browser/src/security/dom_sanitization_service';
|
||||||
|
|
||||||
import {TreeNode, emptyTree} from '../util';
|
import {TreeNode, emptyTree} from '../util';
|
||||||
@ -26,7 +26,7 @@ let viewFlags = ViewFlags.DirectDom;
|
|||||||
function TreeComponent_Host(): ViewDefinition {
|
function TreeComponent_Host(): ViewDefinition {
|
||||||
return viewDef(viewFlags, [
|
return viewDef(viewFlags, [
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'tree'),
|
elementDef(NodeFlags.None, null, null, 1, 'tree'),
|
||||||
providerDef(NodeFlags.None, null, 0, TreeComponent, [], null, null, TreeComponent_0),
|
directiveDef(NodeFlags.None, null, 0, TreeComponent, [], null, null, TreeComponent_0),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ function TreeComponent_0(): ViewDefinition {
|
|||||||
viewFlags,
|
viewFlags,
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'tree'),
|
elementDef(NodeFlags.None, null, null, 1, 'tree'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, TreeComponent, [], {data: [0, 'data']}, null, TreeComponent_0),
|
NodeFlags.None, null, 0, TreeComponent, [], {data: [0, 'data']}, null, TreeComponent_0),
|
||||||
],
|
],
|
||||||
(view: ViewData) => {
|
(view: ViewData) => {
|
||||||
@ -48,7 +48,7 @@ function TreeComponent_0(): ViewDefinition {
|
|||||||
viewFlags,
|
viewFlags,
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'tree'),
|
elementDef(NodeFlags.None, null, null, 1, 'tree'),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, TreeComponent, [], {data: [0, 'data']}, null, TreeComponent_0),
|
NodeFlags.None, null, 0, TreeComponent, [], {data: [0, 'data']}, null, TreeComponent_0),
|
||||||
],
|
],
|
||||||
(view: ViewData) => {
|
(view: ViewData) => {
|
||||||
@ -65,10 +65,10 @@ function TreeComponent_0(): ViewDefinition {
|
|||||||
[[BindingType.ElementStyle, 'backgroundColor', null]]),
|
[[BindingType.ElementStyle, 'backgroundColor', null]]),
|
||||||
textDef(null, [' ', ' ']),
|
textDef(null, [' ', ' ']),
|
||||||
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 1, TreeComponent_1),
|
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 1, TreeComponent_1),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
||||||
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 1, TreeComponent_2),
|
anchorDef(NodeFlags.HasEmbeddedViews, null, null, 1, TreeComponent_2),
|
||||||
providerDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
||||||
],
|
],
|
||||||
(view: ViewData) => {
|
(view: ViewData) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user