refactor(core): add a checkIndex to the compiler view nodes
Each node now has two index: nodeIndex and checkIndex. nodeIndex is the index in both the view definition and the view data. checkIndex is the index in in the update function (update directives and update renderer). While nodeIndex and checkIndex have the same value for now, having both of them will allow changing the structure of view definition after compilation (ie for runtime translations).
This commit is contained in:

committed by
Alex Rickabaugh

parent
caa51950e8
commit
0833b59aab
@ -13,8 +13,8 @@ import {BindingDef, BindingFlags, ElementData, ElementHandleEventFn, NodeDef, No
|
||||
import {NOOP, calcBindingFlags, checkAndUpdateBinding, dispatchEvent, elementEventFullName, getParentRenderElement, resolveDefinition, resolveRendererType2, splitMatchedQueriesDsl, splitNamespace} from './util';
|
||||
|
||||
export function anchorDef(
|
||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
||||
ngContentIndex: number, childCount: number, handleEvent?: ElementHandleEventFn,
|
||||
flags: NodeFlags, matchedQueriesDsl: null | [string | number, QueryValueType][],
|
||||
ngContentIndex: null | number, childCount: number, handleEvent?: null | ElementHandleEventFn,
|
||||
templateFactory?: ViewDefinitionFactory): NodeDef {
|
||||
flags |= NodeFlags.TypeElement;
|
||||
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
||||
@ -22,13 +22,14 @@ export function anchorDef(
|
||||
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
index: -1,
|
||||
nodeIndex: -1,
|
||||
parent: null,
|
||||
renderParent: null,
|
||||
bindingIndex: -1,
|
||||
outputIndex: -1,
|
||||
// regular values
|
||||
flags,
|
||||
checkIndex: -1,
|
||||
childFlags: 0,
|
||||
directChildFlags: 0,
|
||||
childMatchedQueries: 0, matchedQueries, matchedQueryIds, references, ngContentIndex, childCount,
|
||||
@ -54,11 +55,12 @@ export function anchorDef(
|
||||
}
|
||||
|
||||
export function elementDef(
|
||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
||||
ngContentIndex: number, childCount: number, namespaceAndName: string | null,
|
||||
fixedAttrs: [string, string][] = [],
|
||||
bindings?: [BindingFlags, string, string | SecurityContext][], outputs?: ([string, string])[],
|
||||
handleEvent?: ElementHandleEventFn, componentView?: ViewDefinitionFactory,
|
||||
checkIndex: number, flags: NodeFlags,
|
||||
matchedQueriesDsl: null | [string | number, QueryValueType][], ngContentIndex: null | number,
|
||||
childCount: number, namespaceAndName: string | null, fixedAttrs: null | [string, string][] = [],
|
||||
bindings?: null | [BindingFlags, string, string | SecurityContext | null][],
|
||||
outputs?: null | ([string, string])[], handleEvent?: null | ElementHandleEventFn,
|
||||
componentView?: null | ViewDefinitionFactory,
|
||||
componentRendererType?: RendererType2 | null): NodeDef {
|
||||
if (!handleEvent) {
|
||||
handleEvent = NOOP;
|
||||
@ -111,12 +113,13 @@ export function elementDef(
|
||||
flags |= NodeFlags.TypeElement;
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
index: -1,
|
||||
nodeIndex: -1,
|
||||
parent: null,
|
||||
renderParent: null,
|
||||
bindingIndex: -1,
|
||||
outputIndex: -1,
|
||||
// regular values
|
||||
checkIndex,
|
||||
flags,
|
||||
childFlags: 0,
|
||||
directChildFlags: 0,
|
||||
@ -175,7 +178,7 @@ export function listenToElementOutputs(view: ViewData, compView: ViewData, def:
|
||||
for (let i = 0; i < def.outputs.length; i++) {
|
||||
const output = def.outputs[i];
|
||||
const handleEventClosure = renderEventHandlerClosure(
|
||||
view, def.index, elementEventFullName(output.target, output.eventName));
|
||||
view, def.nodeIndex, elementEventFullName(output.target, output.eventName));
|
||||
let listenTarget: 'window'|'document'|'body'|'component'|null = output.target;
|
||||
let listenerView = view;
|
||||
if (output.target === 'component') {
|
||||
@ -224,7 +227,7 @@ function checkAndUpdateElementValue(view: ViewData, def: NodeDef, bindingIdx: nu
|
||||
return false;
|
||||
}
|
||||
const binding = def.bindings[bindingIdx];
|
||||
const elData = asElementData(view, def.index);
|
||||
const elData = asElementData(view, def.nodeIndex);
|
||||
const renderNode = elData.renderElement;
|
||||
const name = binding.name !;
|
||||
switch (binding.flags & BindingFlags.Types) {
|
||||
|
@ -9,15 +9,16 @@
|
||||
import {NodeDef, NodeFlags, ViewData} from './types';
|
||||
import {RenderNodeAction, getParentRenderElement, visitProjectedRenderNodes} from './util';
|
||||
|
||||
export function ngContentDef(ngContentIndex: number, index: number): NodeDef {
|
||||
export function ngContentDef(ngContentIndex: null | number, index: number): NodeDef {
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
index: -1,
|
||||
nodeIndex: -1,
|
||||
parent: null,
|
||||
renderParent: null,
|
||||
bindingIndex: -1,
|
||||
outputIndex: -1,
|
||||
// regular values
|
||||
checkIndex: -1,
|
||||
flags: NodeFlags.TypeNgContent,
|
||||
childFlags: 0,
|
||||
directChildFlags: 0,
|
||||
|
@ -7,10 +7,10 @@
|
||||
*/
|
||||
|
||||
import {resolveForwardRef} from '../di/forward_ref';
|
||||
import {Injector, THROW_IF_NOT_FOUND} from '../di/injector';
|
||||
import {Injector} from '../di/injector';
|
||||
import {NgModuleRef} from '../linker/ng_module_factory';
|
||||
|
||||
import {DepDef, DepFlags, NgModuleData, NgModuleDefinition, NgModuleDefinitionFactory, NgModuleProviderDef, NodeFlags} from './types';
|
||||
import {DepDef, DepFlags, NgModuleData, NgModuleDefinition, NgModuleProviderDef, NodeFlags} from './types';
|
||||
import {splitDepsDsl, tokenKey} from './util';
|
||||
|
||||
const NOT_CREATED = new Object();
|
||||
@ -89,80 +89,60 @@ export function resolveNgModuleDep(
|
||||
|
||||
|
||||
function _createProviderInstance(ngModule: NgModuleData, providerDef: NgModuleProviderDef): any {
|
||||
let injectable: any;
|
||||
switch (providerDef.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypeClassProvider:
|
||||
injectable = _createClass(ngModule, providerDef.value, providerDef.deps);
|
||||
break;
|
||||
return _createClass(ngModule, providerDef.value, providerDef.deps);
|
||||
case NodeFlags.TypeFactoryProvider:
|
||||
injectable = _callFactory(ngModule, providerDef.value, providerDef.deps);
|
||||
break;
|
||||
return _callFactory(ngModule, providerDef.value, providerDef.deps);
|
||||
case NodeFlags.TypeUseExistingProvider:
|
||||
injectable = resolveNgModuleDep(ngModule, providerDef.deps[0]);
|
||||
break;
|
||||
return resolveNgModuleDep(ngModule, providerDef.deps[0]);
|
||||
case NodeFlags.TypeValueProvider:
|
||||
injectable = providerDef.value;
|
||||
break;
|
||||
return providerDef.value;
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
function _createClass(ngModule: NgModuleData, ctor: any, deps: DepDef[]): any {
|
||||
const len = deps.length;
|
||||
let injectable: any;
|
||||
switch (len) {
|
||||
case 0:
|
||||
injectable = new ctor();
|
||||
break;
|
||||
return new ctor();
|
||||
case 1:
|
||||
injectable = new ctor(resolveNgModuleDep(ngModule, deps[0]));
|
||||
break;
|
||||
return new ctor(resolveNgModuleDep(ngModule, deps[0]));
|
||||
case 2:
|
||||
injectable =
|
||||
new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||
break;
|
||||
return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||
case 3:
|
||||
injectable = new ctor(
|
||||
return new ctor(
|
||||
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
||||
resolveNgModuleDep(ngModule, deps[2]));
|
||||
break;
|
||||
default:
|
||||
const depValues = new Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
|
||||
}
|
||||
injectable = new ctor(...depValues);
|
||||
return new ctor(...depValues);
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
function _callFactory(ngModule: NgModuleData, factory: any, deps: DepDef[]): any {
|
||||
const len = deps.length;
|
||||
let injectable: any;
|
||||
switch (len) {
|
||||
case 0:
|
||||
injectable = factory();
|
||||
break;
|
||||
return factory();
|
||||
case 1:
|
||||
injectable = factory(resolveNgModuleDep(ngModule, deps[0]));
|
||||
break;
|
||||
return factory(resolveNgModuleDep(ngModule, deps[0]));
|
||||
case 2:
|
||||
injectable =
|
||||
factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||
break;
|
||||
return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||
case 3:
|
||||
injectable = factory(
|
||||
return factory(
|
||||
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
||||
resolveNgModuleDep(ngModule, deps[2]));
|
||||
break;
|
||||
default:
|
||||
const depValues = Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
|
||||
}
|
||||
injectable = factory(...depValues);
|
||||
return factory(...depValues);
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
export function callNgModuleLifecycle(ngModule: NgModuleData, lifecycles: NodeFlags) {
|
||||
|
@ -28,9 +28,10 @@ const InjectorRefTokenKey = tokenKey(Injector);
|
||||
const NOT_CREATED = new Object();
|
||||
|
||||
export function directiveDef(
|
||||
flags: NodeFlags, matchedQueries: [string | number, QueryValueType][], childCount: number,
|
||||
ctor: any, deps: ([DepFlags, any] | any)[], props?: {[name: string]: [number, string]},
|
||||
outputs?: {[name: string]: string}): NodeDef {
|
||||
checkIndex: number, flags: NodeFlags,
|
||||
matchedQueries: null | [string | number, QueryValueType][], childCount: number, ctor: any,
|
||||
deps: ([DepFlags, any] | any)[], props?: null | {[name: string]: [number, string]},
|
||||
outputs?: null | {[name: string]: string}): NodeDef {
|
||||
const bindings: BindingDef[] = [];
|
||||
if (props) {
|
||||
for (let prop in props) {
|
||||
@ -52,24 +53,26 @@ export function directiveDef(
|
||||
}
|
||||
}
|
||||
flags |= NodeFlags.TypeDirective;
|
||||
return _def(flags, matchedQueries, childCount, ctor, ctor, deps, bindings, outputDefs);
|
||||
return _def(
|
||||
checkIndex, flags, matchedQueries, childCount, ctor, ctor, deps, bindings, outputDefs);
|
||||
}
|
||||
|
||||
export function pipeDef(flags: NodeFlags, ctor: any, deps: ([DepFlags, any] | any)[]): NodeDef {
|
||||
flags |= NodeFlags.TypePipe;
|
||||
return _def(flags, null, 0, ctor, ctor, deps);
|
||||
return _def(-1, flags, null, 0, ctor, ctor, deps);
|
||||
}
|
||||
|
||||
export function providerDef(
|
||||
flags: NodeFlags, matchedQueries: [string | number, QueryValueType][], token: any, value: any,
|
||||
deps: ([DepFlags, any] | any)[]): NodeDef {
|
||||
return _def(flags, matchedQueries, 0, token, value, deps);
|
||||
flags: NodeFlags, matchedQueries: null | [string | number, QueryValueType][], token: any,
|
||||
value: any, deps: ([DepFlags, any] | any)[]): NodeDef {
|
||||
return _def(-1, flags, matchedQueries, 0, token, value, deps);
|
||||
}
|
||||
|
||||
export function _def(
|
||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][] | null,
|
||||
childCount: number, token: any, value: any, deps: ([DepFlags, any] | any)[],
|
||||
bindings?: BindingDef[], outputs?: OutputDef[]): NodeDef {
|
||||
checkIndex: number, flags: NodeFlags,
|
||||
matchedQueriesDsl: [string | number, QueryValueType][] | null, childCount: number, token: any,
|
||||
value: any, deps: ([DepFlags, any] | any)[], bindings?: BindingDef[],
|
||||
outputs?: OutputDef[]): NodeDef {
|
||||
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
||||
if (!outputs) {
|
||||
outputs = [];
|
||||
@ -86,12 +89,13 @@ export function _def(
|
||||
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
index: -1,
|
||||
nodeIndex: -1,
|
||||
parent: null,
|
||||
renderParent: null,
|
||||
bindingIndex: -1,
|
||||
outputIndex: -1,
|
||||
// regular values
|
||||
checkIndex,
|
||||
flags,
|
||||
childFlags: 0,
|
||||
directChildFlags: 0,
|
||||
@ -134,7 +138,7 @@ export function createDirectiveInstance(view: ViewData, def: NodeDef): any {
|
||||
for (let i = 0; i < def.outputs.length; i++) {
|
||||
const output = def.outputs[i];
|
||||
const subscription = instance[output.propName !].subscribe(
|
||||
eventHandlerClosure(view, def.parent !.index, output.eventName));
|
||||
eventHandlerClosure(view, def.parent !.nodeIndex, output.eventName));
|
||||
view.disposables ![def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
|
||||
}
|
||||
}
|
||||
@ -148,7 +152,7 @@ function eventHandlerClosure(view: ViewData, index: number, eventName: string) {
|
||||
export function checkAndUpdateDirectiveInline(
|
||||
view: ViewData, def: NodeDef, v0: any, v1: any, v2: any, v3: any, v4: any, v5: any, v6: any,
|
||||
v7: any, v8: any, v9: any): boolean {
|
||||
const providerData = asProviderData(view, def.index);
|
||||
const providerData = asProviderData(view, def.nodeIndex);
|
||||
const directive = providerData.instance;
|
||||
let changed = false;
|
||||
let changes: SimpleChanges = undefined !;
|
||||
@ -207,7 +211,7 @@ export function checkAndUpdateDirectiveInline(
|
||||
|
||||
export function checkAndUpdateDirectiveDynamic(
|
||||
view: ViewData, def: NodeDef, values: any[]): boolean {
|
||||
const providerData = asProviderData(view, def.index);
|
||||
const providerData = asProviderData(view, def.nodeIndex);
|
||||
const directive = providerData.instance;
|
||||
let changed = false;
|
||||
let changes: SimpleChanges = undefined !;
|
||||
@ -233,89 +237,71 @@ function _createProviderInstance(view: ViewData, def: NodeDef): any {
|
||||
// private services can see other private services
|
||||
const allowPrivateServices = (def.flags & NodeFlags.PrivateProvider) > 0;
|
||||
const providerDef = def.provider;
|
||||
let injectable: any;
|
||||
switch (def.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypeClassProvider:
|
||||
injectable = createClass(
|
||||
return createClass(
|
||||
view, def.parent !, allowPrivateServices, providerDef !.value, providerDef !.deps);
|
||||
break;
|
||||
case NodeFlags.TypeFactoryProvider:
|
||||
injectable = callFactory(
|
||||
return callFactory(
|
||||
view, def.parent !, allowPrivateServices, providerDef !.value, providerDef !.deps);
|
||||
break;
|
||||
case NodeFlags.TypeUseExistingProvider:
|
||||
injectable = resolveDep(view, def.parent !, allowPrivateServices, providerDef !.deps[0]);
|
||||
break;
|
||||
return resolveDep(view, def.parent !, allowPrivateServices, providerDef !.deps[0]);
|
||||
case NodeFlags.TypeValueProvider:
|
||||
injectable = providerDef !.value;
|
||||
break;
|
||||
return providerDef !.value;
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
function createClass(
|
||||
view: ViewData, elDef: NodeDef, allowPrivateServices: boolean, ctor: any, deps: DepDef[]): any {
|
||||
const len = deps.length;
|
||||
let injectable: any;
|
||||
switch (len) {
|
||||
case 0:
|
||||
injectable = new ctor();
|
||||
break;
|
||||
return new ctor();
|
||||
case 1:
|
||||
injectable = new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
||||
break;
|
||||
return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
||||
case 2:
|
||||
injectable = new ctor(
|
||||
return new ctor(
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[1]));
|
||||
break;
|
||||
case 3:
|
||||
injectable = new ctor(
|
||||
return new ctor(
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[1]),
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[2]));
|
||||
break;
|
||||
default:
|
||||
const depValues = new Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
|
||||
}
|
||||
injectable = new ctor(...depValues);
|
||||
return new ctor(...depValues);
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
function callFactory(
|
||||
view: ViewData, elDef: NodeDef, allowPrivateServices: boolean, factory: any,
|
||||
deps: DepDef[]): any {
|
||||
const len = deps.length;
|
||||
let injectable: any;
|
||||
switch (len) {
|
||||
case 0:
|
||||
injectable = factory();
|
||||
break;
|
||||
return factory();
|
||||
case 1:
|
||||
injectable = factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
||||
break;
|
||||
return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
||||
case 2:
|
||||
injectable = factory(
|
||||
return factory(
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[1]));
|
||||
break;
|
||||
case 3:
|
||||
injectable = factory(
|
||||
return factory(
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[1]),
|
||||
resolveDep(view, elDef, allowPrivateServices, deps[2]));
|
||||
break;
|
||||
default:
|
||||
const depValues = Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
|
||||
}
|
||||
injectable = factory(...depValues);
|
||||
return factory(...depValues);
|
||||
}
|
||||
return injectable;
|
||||
}
|
||||
|
||||
// This default value is when checking the hierarchy for a token.
|
||||
@ -372,12 +358,12 @@ export function resolveDep(
|
||||
return compView.renderer;
|
||||
}
|
||||
case ElementRefTokenKey:
|
||||
return new ElementRef(asElementData(view, elDef.index).renderElement);
|
||||
return new ElementRef(asElementData(view, elDef.nodeIndex).renderElement);
|
||||
case ViewContainerRefTokenKey:
|
||||
return asElementData(view, elDef.index).viewContainer;
|
||||
return asElementData(view, elDef.nodeIndex).viewContainer;
|
||||
case TemplateRefTokenKey: {
|
||||
if (elDef.element !.template) {
|
||||
return asElementData(view, elDef.index).template;
|
||||
return asElementData(view, elDef.nodeIndex).template;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -392,7 +378,7 @@ export function resolveDep(
|
||||
(allowPrivateServices ? elDef.element !.allProviders :
|
||||
elDef.element !.publicProviders) ![tokenKey];
|
||||
if (providerDef) {
|
||||
const providerData = asProviderData(view, providerDef.index);
|
||||
const providerData = asProviderData(view, providerDef.nodeIndex);
|
||||
if (providerData.instance === NOT_CREATED) {
|
||||
providerData.instance = _createProviderInstance(view, providerDef);
|
||||
}
|
||||
@ -423,7 +409,7 @@ export function resolveDep(
|
||||
function findCompView(view: ViewData, elDef: NodeDef, allowPrivateServices: boolean) {
|
||||
let compView: ViewData;
|
||||
if (allowPrivateServices) {
|
||||
compView = asElementData(view, elDef.index).componentView;
|
||||
compView = asElementData(view, elDef.nodeIndex).componentView;
|
||||
} else {
|
||||
compView = view;
|
||||
while (compView.parent && !isComponentView(compView)) {
|
||||
@ -437,7 +423,7 @@ function updateProp(
|
||||
view: ViewData, providerData: ProviderData, def: NodeDef, bindingIdx: number, value: any,
|
||||
changes: SimpleChanges): SimpleChanges {
|
||||
if (def.flags & NodeFlags.Component) {
|
||||
const compView = asElementData(view, def.parent !.index).componentView;
|
||||
const compView = asElementData(view, def.parent !.nodeIndex).componentView;
|
||||
if (compView.def.flags & ViewFlags.OnPush) {
|
||||
compView.state |= ViewState.ChecksEnabled;
|
||||
}
|
||||
@ -479,7 +465,7 @@ export function callLifecycleHooksChildrenFirst(view: ViewData, lifecycles: Node
|
||||
i += nodeDef.childCount;
|
||||
}
|
||||
while (parent && (parent.flags & NodeFlags.TypeElement) &&
|
||||
i === parent.index + parent.childCount) {
|
||||
i === parent.nodeIndex + parent.childCount) {
|
||||
// last child of an element
|
||||
if (parent.directChildFlags & lifecycles) {
|
||||
callElementProvidersLifecycles(view, parent, lifecycles);
|
||||
@ -490,7 +476,7 @@ export function callLifecycleHooksChildrenFirst(view: ViewData, lifecycles: Node
|
||||
}
|
||||
|
||||
function callElementProvidersLifecycles(view: ViewData, elDef: NodeDef, lifecycles: NodeFlags) {
|
||||
for (let i = elDef.index + 1; i <= elDef.index + elDef.childCount; i++) {
|
||||
for (let i = elDef.nodeIndex + 1; i <= elDef.nodeIndex + elDef.childCount; i++) {
|
||||
const nodeDef = view.def.nodes[i];
|
||||
if (nodeDef.flags & lifecycles) {
|
||||
callProviderLifecycles(view, i, nodeDef.flags & lifecycles);
|
||||
|
@ -9,16 +9,16 @@
|
||||
import {BindingDef, BindingFlags, NodeDef, NodeFlags, PureExpressionData, ViewData, asPureExpressionData} from './types';
|
||||
import {calcBindingFlags, checkAndUpdateBinding} from './util';
|
||||
|
||||
export function purePipeDef(argCount: number): NodeDef {
|
||||
export function purePipeDef(checkIndex: number, argCount: number): NodeDef {
|
||||
// argCount + 1 to include the pipe as first arg
|
||||
return _pureExpressionDef(NodeFlags.TypePurePipe, new Array(argCount + 1));
|
||||
return _pureExpressionDef(NodeFlags.TypePurePipe, checkIndex, new Array(argCount + 1));
|
||||
}
|
||||
|
||||
export function pureArrayDef(argCount: number): NodeDef {
|
||||
return _pureExpressionDef(NodeFlags.TypePureArray, new Array(argCount));
|
||||
export function pureArrayDef(checkIndex: number, argCount: number): NodeDef {
|
||||
return _pureExpressionDef(NodeFlags.TypePureArray, checkIndex, new Array(argCount));
|
||||
}
|
||||
|
||||
export function pureObjectDef(propToIndex: {[p: string]: number}): NodeDef {
|
||||
export function pureObjectDef(checkIndex: number, propToIndex: {[p: string]: number}): NodeDef {
|
||||
const keys = Object.keys(propToIndex);
|
||||
const nbKeys = keys.length;
|
||||
const propertyNames = new Array(nbKeys);
|
||||
@ -28,10 +28,11 @@ export function pureObjectDef(propToIndex: {[p: string]: number}): NodeDef {
|
||||
propertyNames[index] = key;
|
||||
}
|
||||
|
||||
return _pureExpressionDef(NodeFlags.TypePureObject, propertyNames);
|
||||
return _pureExpressionDef(NodeFlags.TypePureObject, checkIndex, propertyNames);
|
||||
}
|
||||
|
||||
function _pureExpressionDef(flags: NodeFlags, propertyNames: string[]): NodeDef {
|
||||
function _pureExpressionDef(
|
||||
flags: NodeFlags, checkIndex: number, propertyNames: string[]): NodeDef {
|
||||
const bindings: BindingDef[] = new Array(propertyNames.length);
|
||||
for (let i = 0; i < propertyNames.length; i++) {
|
||||
const prop = propertyNames[i];
|
||||
@ -46,12 +47,13 @@ function _pureExpressionDef(flags: NodeFlags, propertyNames: string[]): NodeDef
|
||||
}
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
index: -1,
|
||||
nodeIndex: -1,
|
||||
parent: null,
|
||||
renderParent: null,
|
||||
bindingIndex: -1,
|
||||
outputIndex: -1,
|
||||
// regular values
|
||||
checkIndex,
|
||||
flags,
|
||||
childFlags: 0,
|
||||
directChildFlags: 0,
|
||||
@ -93,7 +95,7 @@ export function checkAndUpdatePureExpressionInline(
|
||||
if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9)) changed = true;
|
||||
|
||||
if (changed) {
|
||||
const data = asPureExpressionData(view, def.index);
|
||||
const data = asPureExpressionData(view, def.nodeIndex);
|
||||
let value: any;
|
||||
switch (def.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypePureArray:
|
||||
@ -175,7 +177,7 @@ export function checkAndUpdatePureExpressionDynamic(
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
const data = asPureExpressionData(view, def.index);
|
||||
const data = asPureExpressionData(view, def.nodeIndex);
|
||||
let value: any;
|
||||
switch (def.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypePureArray:
|
||||
|
@ -22,13 +22,14 @@ export function queryDef(
|
||||
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
index: -1,
|
||||
nodeIndex: -1,
|
||||
parent: null,
|
||||
renderParent: null,
|
||||
bindingIndex: -1,
|
||||
outputIndex: -1,
|
||||
// regular values
|
||||
flags,
|
||||
// TODO(vicb): check
|
||||
checkIndex: -1, flags,
|
||||
childFlags: 0,
|
||||
directChildFlags: 0,
|
||||
childMatchedQueries: 0,
|
||||
@ -58,7 +59,7 @@ export function dirtyParentQueries(view: ViewData) {
|
||||
let tplDef = view.parentNodeDef !;
|
||||
view = view.parent;
|
||||
// content queries
|
||||
const end = tplDef.index + tplDef.childCount;
|
||||
const end = tplDef.nodeIndex + tplDef.childCount;
|
||||
for (let i = 0; i <= end; i++) {
|
||||
const nodeDef = view.def.nodes[i];
|
||||
if ((nodeDef.flags & NodeFlags.TypeContentQuery) &&
|
||||
@ -66,7 +67,7 @@ export function dirtyParentQueries(view: ViewData) {
|
||||
(nodeDef.query !.filterId & queryIds) === nodeDef.query !.filterId) {
|
||||
asQueryList(view, i).setDirty();
|
||||
}
|
||||
if ((nodeDef.flags & NodeFlags.TypeElement && i + nodeDef.childCount < tplDef.index) ||
|
||||
if ((nodeDef.flags & NodeFlags.TypeElement && i + nodeDef.childCount < tplDef.nodeIndex) ||
|
||||
!(nodeDef.childFlags & NodeFlags.TypeContentQuery) ||
|
||||
!(nodeDef.childFlags & NodeFlags.DynamicQuery)) {
|
||||
// skip elements that don't contain the template element or no query.
|
||||
@ -89,7 +90,7 @@ export function dirtyParentQueries(view: ViewData) {
|
||||
}
|
||||
|
||||
export function checkAndUpdateQuery(view: ViewData, nodeDef: NodeDef) {
|
||||
const queryList = asQueryList(view, nodeDef.index);
|
||||
const queryList = asQueryList(view, nodeDef.nodeIndex);
|
||||
if (!queryList.dirty) {
|
||||
return;
|
||||
}
|
||||
@ -98,8 +99,9 @@ export function checkAndUpdateQuery(view: ViewData, nodeDef: NodeDef) {
|
||||
if (nodeDef.flags & NodeFlags.TypeContentQuery) {
|
||||
const elementDef = nodeDef.parent !.parent !;
|
||||
newValues = calcQueryValues(
|
||||
view, elementDef.index, elementDef.index + elementDef.childCount, nodeDef.query !, []);
|
||||
directiveInstance = asProviderData(view, nodeDef.parent !.index).instance;
|
||||
view, elementDef.nodeIndex, elementDef.nodeIndex + elementDef.childCount, nodeDef.query !,
|
||||
[]);
|
||||
directiveInstance = asProviderData(view, nodeDef.parent !.nodeIndex).instance;
|
||||
} else if (nodeDef.flags & NodeFlags.TypeViewQuery) {
|
||||
newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, nodeDef.query !, []);
|
||||
directiveInstance = view.component;
|
||||
@ -175,24 +177,17 @@ export function getQueryValue(
|
||||
view: ViewData, nodeDef: NodeDef, queryValueType: QueryValueType): any {
|
||||
if (queryValueType != null) {
|
||||
// a match
|
||||
let value: any;
|
||||
switch (queryValueType) {
|
||||
case QueryValueType.RenderElement:
|
||||
value = asElementData(view, nodeDef.index).renderElement;
|
||||
break;
|
||||
return asElementData(view, nodeDef.nodeIndex).renderElement;
|
||||
case QueryValueType.ElementRef:
|
||||
value = new ElementRef(asElementData(view, nodeDef.index).renderElement);
|
||||
break;
|
||||
return new ElementRef(asElementData(view, nodeDef.nodeIndex).renderElement);
|
||||
case QueryValueType.TemplateRef:
|
||||
value = asElementData(view, nodeDef.index).template;
|
||||
break;
|
||||
return asElementData(view, nodeDef.nodeIndex).template;
|
||||
case QueryValueType.ViewContainerRef:
|
||||
value = asElementData(view, nodeDef.index).viewContainer;
|
||||
break;
|
||||
return asElementData(view, nodeDef.nodeIndex).viewContainer;
|
||||
case QueryValueType.Provider:
|
||||
value = asProviderData(view, nodeDef.index).instance;
|
||||
break;
|
||||
return asProviderData(view, nodeDef.nodeIndex).instance;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ class ComponentFactory_ extends ComponentFactory<any> {
|
||||
throw new Error('ngModule should be provided');
|
||||
}
|
||||
const viewDef = resolveDefinition(this.viewDefFactory);
|
||||
const componentNodeIndex = viewDef.nodes[0].element !.componentProvider !.index;
|
||||
const componentNodeIndex = viewDef.nodes[0].element !.componentProvider !.nodeIndex;
|
||||
const view = Services.createRootView(
|
||||
injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
|
||||
const component = asProviderData(view, componentNodeIndex).instance;
|
||||
@ -113,7 +113,7 @@ class ComponentRef_ extends ComponentRef<any> {
|
||||
this.instance = _component;
|
||||
}
|
||||
get location(): ElementRef {
|
||||
return new ElementRef(asElementData(this._view, this._elDef.index).renderElement);
|
||||
return new ElementRef(asElementData(this._view, this._elDef.nodeIndex).renderElement);
|
||||
}
|
||||
get injector(): Injector { return new Injector_(this._view, this._elDef); }
|
||||
get componentType(): Type<any> { return <any>this._component.constructor; }
|
||||
@ -318,7 +318,7 @@ class TemplateRef_ extends TemplateRef<any> implements TemplateData {
|
||||
}
|
||||
|
||||
get elementRef(): ElementRef {
|
||||
return new ElementRef(asElementData(this._parentView, this._def.index).renderElement);
|
||||
return new ElementRef(asElementData(this._parentView, this._def.nodeIndex).renderElement);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,12 +340,12 @@ class Injector_ implements Injector {
|
||||
export function nodeValue(view: ViewData, index: number): any {
|
||||
const def = view.def.nodes[index];
|
||||
if (def.flags & NodeFlags.TypeElement) {
|
||||
const elData = asElementData(view, def.index);
|
||||
const elData = asElementData(view, def.nodeIndex);
|
||||
return def.element !.template ? elData.template : elData.renderElement;
|
||||
} else if (def.flags & NodeFlags.TypeText) {
|
||||
return asTextData(view, def.index).renderText;
|
||||
return asTextData(view, def.nodeIndex).renderText;
|
||||
} else if (def.flags & (NodeFlags.CatProvider | NodeFlags.TypePipe)) {
|
||||
return asProviderData(view, def.index).instance;
|
||||
return asProviderData(view, def.nodeIndex).instance;
|
||||
}
|
||||
throw new Error(`Illegal state: read nodeValue for node index ${index}`);
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ function applyProviderOverridesToView(def: ViewDefinition): ViewDefinition {
|
||||
}
|
||||
if (lastElementDef && nodeDef.flags & NodeFlags.CatProviderNoDirective &&
|
||||
providerOverrides.has(nodeDef.provider !.token)) {
|
||||
elIndicesWithOverwrittenProviders.push(lastElementDef !.index);
|
||||
elIndicesWithOverwrittenProviders.push(lastElementDef !.nodeIndex);
|
||||
lastElementDef = null;
|
||||
}
|
||||
}
|
||||
@ -260,22 +260,22 @@ function applyProviderOverridesToNgModule(def: NgModuleDefinition): NgModuleDefi
|
||||
}
|
||||
|
||||
function prodCheckAndUpdateNode(
|
||||
view: ViewData, nodeIndex: number, argStyle: ArgumentType, v0?: any, v1?: any, v2?: any,
|
||||
view: ViewData, checkIndex: number, argStyle: ArgumentType, v0?: any, v1?: any, v2?: any,
|
||||
v3?: any, v4?: any, v5?: any, v6?: any, v7?: any, v8?: any, v9?: any): any {
|
||||
const nodeDef = view.def.nodes[nodeIndex];
|
||||
const nodeDef = view.def.nodes[checkIndex];
|
||||
checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||
asPureExpressionData(view, nodeIndex).value :
|
||||
asPureExpressionData(view, checkIndex).value :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function prodCheckNoChangesNode(
|
||||
view: ViewData, nodeIndex: number, argStyle: ArgumentType, v0?: any, v1?: any, v2?: any,
|
||||
view: ViewData, checkIndex: number, argStyle: ArgumentType, v0?: any, v1?: any, v2?: any,
|
||||
v3?: any, v4?: any, v5?: any, v6?: any, v7?: any, v8?: any, v9?: any): any {
|
||||
const nodeDef = view.def.nodes[nodeIndex];
|
||||
const nodeDef = view.def.nodes[checkIndex];
|
||||
checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||
asPureExpressionData(view, nodeIndex).value :
|
||||
asPureExpressionData(view, checkIndex).value :
|
||||
undefined;
|
||||
}
|
||||
|
||||
@ -333,7 +333,7 @@ function debugUpdateDirectives(view: ViewData, checkType: CheckType) {
|
||||
debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
|
||||
}
|
||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||
asPureExpressionData(view, nodeDef.index).value :
|
||||
asPureExpressionData(view, nodeDef.nodeIndex).value :
|
||||
undefined;
|
||||
}
|
||||
}
|
||||
@ -357,7 +357,7 @@ function debugUpdateRenderer(view: ViewData, checkType: CheckType) {
|
||||
debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
|
||||
}
|
||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||
asPureExpressionData(view, nodeDef.index).value :
|
||||
asPureExpressionData(view, nodeDef.nodeIndex).value :
|
||||
undefined;
|
||||
}
|
||||
}
|
||||
@ -378,7 +378,7 @@ function debugCheckAndUpdateNode(
|
||||
}
|
||||
}
|
||||
const elDef = nodeDef.parent !;
|
||||
const el = asElementData(view, elDef.index).renderElement;
|
||||
const el = asElementData(view, elDef.nodeIndex).renderElement;
|
||||
if (!elDef.element !.name) {
|
||||
// a comment.
|
||||
view.renderer.setValue(el, `bindings=${JSON.stringify(bindingValues, null, 2)}`);
|
||||
@ -468,7 +468,7 @@ class DebugContext_ implements DebugContext {
|
||||
}
|
||||
private get elOrCompView() {
|
||||
// Has to be done lazily as we use the DebugContext also during creation of elements...
|
||||
return asElementData(this.elView, this.elDef.index).componentView || this.view;
|
||||
return asElementData(this.elView, this.elDef.nodeIndex).componentView || this.view;
|
||||
}
|
||||
get injector(): Injector { return createInjector(this.elView, this.elDef); }
|
||||
get component(): any { return this.elOrCompView.component; }
|
||||
@ -476,7 +476,8 @@ class DebugContext_ implements DebugContext {
|
||||
get providerTokens(): any[] {
|
||||
const tokens: any[] = [];
|
||||
if (this.elDef) {
|
||||
for (let i = this.elDef.index + 1; i <= this.elDef.index + this.elDef.childCount; i++) {
|
||||
for (let i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount;
|
||||
i++) {
|
||||
const childDef = this.elView.def.nodes[i];
|
||||
if (childDef.flags & NodeFlags.CatProvider) {
|
||||
tokens.push(childDef.provider !.token);
|
||||
@ -491,7 +492,8 @@ class DebugContext_ implements DebugContext {
|
||||
if (this.elDef) {
|
||||
collectReferences(this.elView, this.elDef, references);
|
||||
|
||||
for (let i = this.elDef.index + 1; i <= this.elDef.index + this.elDef.childCount; i++) {
|
||||
for (let i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount;
|
||||
i++) {
|
||||
const childDef = this.elView.def.nodes[i];
|
||||
if (childDef.flags & NodeFlags.CatProvider) {
|
||||
collectReferences(this.elView, childDef, references);
|
||||
@ -514,10 +516,10 @@ class DebugContext_ implements DebugContext {
|
||||
let logNodeIndex: number;
|
||||
if (this.nodeDef.flags & NodeFlags.TypeText) {
|
||||
logViewDef = this.view.def;
|
||||
logNodeIndex = this.nodeDef.index;
|
||||
logNodeIndex = this.nodeDef.nodeIndex;
|
||||
} else {
|
||||
logViewDef = this.elView.def;
|
||||
logNodeIndex = this.elDef.index;
|
||||
logNodeIndex = this.elDef.nodeIndex;
|
||||
}
|
||||
// Note: we only generate a log function for text and element nodes
|
||||
// to make the generated code as small as possible.
|
||||
@ -555,7 +557,7 @@ function findHostElement(view: ViewData): ElementData|null {
|
||||
view = view.parent !;
|
||||
}
|
||||
if (view.parent) {
|
||||
return asElementData(view.parent, viewParentEl(view) !.index);
|
||||
return asElementData(view.parent, viewParentEl(view) !.nodeIndex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -9,7 +9,8 @@
|
||||
import {BindingDef, BindingFlags, NodeDef, NodeFlags, TextData, ViewData, asTextData} from './types';
|
||||
import {checkAndUpdateBinding, getParentRenderElement} from './util';
|
||||
|
||||
export function textDef(ngContentIndex: number, staticText: string[]): NodeDef {
|
||||
export function textDef(
|
||||
checkIndex: number, ngContentIndex: number | null, staticText: string[]): NodeDef {
|
||||
const bindings: BindingDef[] = new Array(staticText.length - 1);
|
||||
for (let i = 1; i < staticText.length; i++) {
|
||||
bindings[i - 1] = {
|
||||
@ -24,12 +25,13 @@ export function textDef(ngContentIndex: number, staticText: string[]): NodeDef {
|
||||
|
||||
return {
|
||||
// will bet set by the view definition
|
||||
index: -1,
|
||||
nodeIndex: -1,
|
||||
parent: null,
|
||||
renderParent: null,
|
||||
bindingIndex: -1,
|
||||
outputIndex: -1,
|
||||
// regular values
|
||||
checkIndex,
|
||||
flags: NodeFlags.TypeText,
|
||||
childFlags: 0,
|
||||
directChildFlags: 0,
|
||||
@ -88,7 +90,7 @@ export function checkAndUpdateTextInline(
|
||||
if (bindLen > 7) value += _addInterpolationPart(v7, bindings[7]);
|
||||
if (bindLen > 8) value += _addInterpolationPart(v8, bindings[8]);
|
||||
if (bindLen > 9) value += _addInterpolationPart(v9, bindings[9]);
|
||||
const renderNode = asTextData(view, def.index).renderText;
|
||||
const renderNode = asTextData(view, def.nodeIndex).renderText;
|
||||
view.renderer.setValue(renderNode, value);
|
||||
}
|
||||
return changed;
|
||||
@ -110,7 +112,7 @@ export function checkAndUpdateTextDynamic(view: ViewData, def: NodeDef, values:
|
||||
value = value + _addInterpolationPart(values[i], bindings[i]);
|
||||
}
|
||||
value = def.text !.prefix + value;
|
||||
const renderNode = asTextData(view, def.index).renderText;
|
||||
const renderNode = asTextData(view, def.nodeIndex).renderText;
|
||||
view.renderer.setValue(renderNode, value);
|
||||
}
|
||||
return changed;
|
||||
|
@ -103,11 +103,15 @@ export const enum ViewFlags {
|
||||
*/
|
||||
export interface NodeDef {
|
||||
flags: NodeFlags;
|
||||
index: number;
|
||||
// Index of the node in view data and view definition (those are the same)
|
||||
nodeIndex: number;
|
||||
// Index of the node in the check functions
|
||||
// Differ from nodeIndex when nodes are added or removed at runtime (ie after compilation)
|
||||
checkIndex: number;
|
||||
parent: NodeDef|null;
|
||||
renderParent: NodeDef|null;
|
||||
/** this is checked against NgContentDef.index to find matched nodes */
|
||||
ngContentIndex: number;
|
||||
ngContentIndex: number|null;
|
||||
/** number of transitive children */
|
||||
childCount: number;
|
||||
/** aggregated NodeFlags for all transitive children (does not include self) **/
|
||||
|
@ -102,7 +102,7 @@ export function checkBindingNoChanges(
|
||||
const oldValue = view.oldValues[def.bindingIndex + bindingIdx];
|
||||
if ((view.state & ViewState.BeforeFirstCheck) || !devModeEqual(oldValue, value)) {
|
||||
throw expressionChangedAfterItHasBeenCheckedError(
|
||||
Services.createDebugContext(view, def.index), oldValue, value,
|
||||
Services.createDebugContext(view, def.nodeIndex), oldValue, value,
|
||||
(view.state & ViewState.BeforeFirstCheck) !== 0);
|
||||
}
|
||||
}
|
||||
@ -143,7 +143,7 @@ export function dispatchEvent(
|
||||
export function declaredViewContainer(view: ViewData): ElementData|null {
|
||||
if (view.parent) {
|
||||
const parentView = view.parent;
|
||||
return asElementData(parentView, view.parentNodeDef !.index);
|
||||
return asElementData(parentView, view.parentNodeDef !.nodeIndex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -165,9 +165,9 @@ export function viewParentEl(view: ViewData): NodeDef|null {
|
||||
export function renderNode(view: ViewData, def: NodeDef): any {
|
||||
switch (def.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypeElement:
|
||||
return asElementData(view, def.index).renderElement;
|
||||
return asElementData(view, def.nodeIndex).renderElement;
|
||||
case NodeFlags.TypeText:
|
||||
return asTextData(view, def.index).renderText;
|
||||
return asTextData(view, def.nodeIndex).renderText;
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ export function getParentRenderElement(view: ViewData, renderHost: any, def: Nod
|
||||
ViewEncapsulation.Native)) {
|
||||
// only children of non components, or children of components with native encapsulation should
|
||||
// be attached.
|
||||
return asElementData(view, def.renderParent !.index).renderElement;
|
||||
return asElementData(view, def.renderParent !.nodeIndex).renderElement;
|
||||
}
|
||||
} else {
|
||||
return renderHost;
|
||||
@ -292,8 +292,8 @@ export function visitProjectedRenderNodes(
|
||||
}
|
||||
const hostView = compView !.parent;
|
||||
const hostElDef = viewParentEl(compView !);
|
||||
const startIndex = hostElDef !.index + 1;
|
||||
const endIndex = hostElDef !.index + hostElDef !.childCount;
|
||||
const startIndex = hostElDef !.nodeIndex + 1;
|
||||
const endIndex = hostElDef !.nodeIndex + hostElDef !.childCount;
|
||||
for (let i = startIndex; i <= endIndex; i++) {
|
||||
const nodeDef = hostView !.def.nodes[i];
|
||||
if (nodeDef.ngContentIndex === ngContentIndex) {
|
||||
@ -328,21 +328,21 @@ function visitRenderNode(
|
||||
execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
|
||||
}
|
||||
if (nodeDef.bindingFlags & (BindingFlags.SyntheticHostProperty)) {
|
||||
const compView = asElementData(view, nodeDef.index).componentView;
|
||||
const compView = asElementData(view, nodeDef.nodeIndex).componentView;
|
||||
execRenderNodeAction(compView, rn, action, parentNode, nextSibling, target);
|
||||
}
|
||||
} else {
|
||||
execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
|
||||
}
|
||||
if (nodeDef.flags & NodeFlags.EmbeddedViews) {
|
||||
const embeddedViews = asElementData(view, nodeDef.index).viewContainer !._embeddedViews;
|
||||
const embeddedViews = asElementData(view, nodeDef.nodeIndex).viewContainer !._embeddedViews;
|
||||
for (let k = 0; k < embeddedViews.length; k++) {
|
||||
visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
|
||||
}
|
||||
}
|
||||
if (nodeDef.flags & NodeFlags.TypeElement && !nodeDef.element !.name) {
|
||||
visitSiblingRenderNodes(
|
||||
view, action, nodeDef.index + 1, nodeDef.index + nodeDef.childCount, parentNode,
|
||||
view, action, nodeDef.nodeIndex + 1, nodeDef.nodeIndex + nodeDef.childCount, parentNode,
|
||||
nextSibling, target);
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ import {NOOP, checkBindingNoChanges, isComponentView, markParentViewsForCheckPro
|
||||
import {detachProjectedView} from './view_attach';
|
||||
|
||||
export function viewDef(
|
||||
flags: ViewFlags, nodes: NodeDef[], updateDirectives?: ViewUpdateFn,
|
||||
updateRenderer?: ViewUpdateFn): ViewDefinition {
|
||||
flags: ViewFlags, nodes: NodeDef[], updateDirectives?: null | ViewUpdateFn,
|
||||
updateRenderer?: null | ViewUpdateFn): ViewDefinition {
|
||||
// clone nodes and set auto calculated values
|
||||
let viewBindingCount = 0;
|
||||
let viewDisposableCount = 0;
|
||||
@ -36,7 +36,7 @@ export function viewDef(
|
||||
let lastRenderRootNode: NodeDef|null = null;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const node = nodes[i];
|
||||
node.index = i;
|
||||
node.nodeIndex = i;
|
||||
node.parent = currentParent;
|
||||
node.bindingIndex = viewBindingCount;
|
||||
node.outputIndex = viewDisposableCount;
|
||||
@ -117,7 +117,7 @@ export function viewDef(
|
||||
// The loop is required because an element could be the last transitive children of several
|
||||
// elements. We loop to either the root or the highest opened element (= with remaining
|
||||
// children)
|
||||
while (currentParent && i === currentParent.index + currentParent.childCount) {
|
||||
while (currentParent && i === currentParent.nodeIndex + currentParent.childCount) {
|
||||
const newParent: NodeDef|null = currentParent.parent;
|
||||
if (newParent) {
|
||||
newParent.childFlags |= currentParent.childFlags;
|
||||
@ -164,32 +164,32 @@ function validateNode(parent: NodeDef | null, node: NodeDef, nodeCount: number)
|
||||
if (template.lastRenderRootNode &&
|
||||
template.lastRenderRootNode.flags & NodeFlags.EmbeddedViews) {
|
||||
throw new Error(
|
||||
`Illegal State: Last root node of a template can't have embedded views, at index ${node.index}!`);
|
||||
`Illegal State: Last root node of a template can't have embedded views, at index ${node.nodeIndex}!`);
|
||||
}
|
||||
}
|
||||
if (node.flags & NodeFlags.CatProvider) {
|
||||
const parentFlags = parent ? parent.flags : 0;
|
||||
if ((parentFlags & NodeFlags.TypeElement) === 0) {
|
||||
throw new Error(
|
||||
`Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index ${node.index}!`);
|
||||
`Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index ${node.nodeIndex}!`);
|
||||
}
|
||||
}
|
||||
if (node.query) {
|
||||
if (node.flags & NodeFlags.TypeContentQuery &&
|
||||
(!parent || (parent.flags & NodeFlags.TypeDirective) === 0)) {
|
||||
throw new Error(
|
||||
`Illegal State: Content Query nodes need to be children of directives, at index ${node.index}!`);
|
||||
`Illegal State: Content Query nodes need to be children of directives, at index ${node.nodeIndex}!`);
|
||||
}
|
||||
if (node.flags & NodeFlags.TypeViewQuery && parent) {
|
||||
throw new Error(
|
||||
`Illegal State: View Query nodes have to be top level nodes, at index ${node.index}!`);
|
||||
`Illegal State: View Query nodes have to be top level nodes, at index ${node.nodeIndex}!`);
|
||||
}
|
||||
}
|
||||
if (node.childCount) {
|
||||
const parentEnd = parent ? parent.index + parent.childCount : nodeCount - 1;
|
||||
if (node.index <= parentEnd && node.index + node.childCount > parentEnd) {
|
||||
const parentEnd = parent ? parent.nodeIndex + parent.childCount : nodeCount - 1;
|
||||
if (node.nodeIndex <= parentEnd && node.nodeIndex + node.childCount > parentEnd) {
|
||||
throw new Error(
|
||||
`Illegal State: childCount of node leads outside of parent, at index ${node.index}!`);
|
||||
`Illegal State: childCount of node leads outside of parent, at index ${node.nodeIndex}!`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -250,7 +250,7 @@ function createViewNodes(view: ViewData) {
|
||||
let renderHost: any;
|
||||
if (isComponentView(view)) {
|
||||
const hostDef = view.parentNodeDef;
|
||||
renderHost = asElementData(view.parent !, hostDef !.parent !.index).renderElement;
|
||||
renderHost = asElementData(view.parent !, hostDef !.parent !.nodeIndex).renderElement;
|
||||
}
|
||||
const def = view.def;
|
||||
const nodes = view.nodes;
|
||||
@ -297,7 +297,7 @@ function createViewNodes(view: ViewData) {
|
||||
const instance = createDirectiveInstance(view, nodeDef);
|
||||
nodeData = <ProviderData>{instance};
|
||||
if (nodeDef.flags & NodeFlags.Component) {
|
||||
const compView = asElementData(view, nodeDef.parent !.index).componentView;
|
||||
const compView = asElementData(view, nodeDef.parent !.nodeIndex).componentView;
|
||||
initView(compView, instance, instance);
|
||||
}
|
||||
break;
|
||||
@ -410,47 +410,38 @@ function markProjectedViewsForCheck(view: ViewData) {
|
||||
function checkAndUpdateNodeInline(
|
||||
view: ViewData, nodeDef: NodeDef, v0?: any, v1?: any, v2?: any, v3?: any, v4?: any, v5?: any,
|
||||
v6?: any, v7?: any, v8?: any, v9?: any): boolean {
|
||||
let changed = false;
|
||||
switch (nodeDef.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypeElement:
|
||||
changed = checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
break;
|
||||
return checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
case NodeFlags.TypeText:
|
||||
changed = checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
break;
|
||||
return checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
case NodeFlags.TypeDirective:
|
||||
changed =
|
||||
checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
break;
|
||||
return checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
case NodeFlags.TypePureArray:
|
||||
case NodeFlags.TypePureObject:
|
||||
case NodeFlags.TypePurePipe:
|
||||
changed =
|
||||
checkAndUpdatePureExpressionInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
break;
|
||||
return checkAndUpdatePureExpressionInline(
|
||||
view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||
default:
|
||||
throw 'unreachable';
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
function checkAndUpdateNodeDynamic(view: ViewData, nodeDef: NodeDef, values: any[]): boolean {
|
||||
let changed = false;
|
||||
switch (nodeDef.flags & NodeFlags.Types) {
|
||||
case NodeFlags.TypeElement:
|
||||
changed = checkAndUpdateElementDynamic(view, nodeDef, values);
|
||||
break;
|
||||
return checkAndUpdateElementDynamic(view, nodeDef, values);
|
||||
case NodeFlags.TypeText:
|
||||
changed = checkAndUpdateTextDynamic(view, nodeDef, values);
|
||||
break;
|
||||
return checkAndUpdateTextDynamic(view, nodeDef, values);
|
||||
case NodeFlags.TypeDirective:
|
||||
changed = checkAndUpdateDirectiveDynamic(view, nodeDef, values);
|
||||
break;
|
||||
return checkAndUpdateDirectiveDynamic(view, nodeDef, values);
|
||||
case NodeFlags.TypePureArray:
|
||||
case NodeFlags.TypePureObject:
|
||||
case NodeFlags.TypePurePipe:
|
||||
changed = checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
|
||||
break;
|
||||
return checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
|
||||
default:
|
||||
throw 'unreachable';
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
export function checkNoChangesNode(
|
||||
@ -492,11 +483,12 @@ function checkNoChangesNodeDynamic(view: ViewData, nodeDef: NodeDef, values: any
|
||||
* @suppress {misplacedTypeAnnotation}
|
||||
*/
|
||||
function checkNoChangesQuery(view: ViewData, nodeDef: NodeDef) {
|
||||
const queryList = asQueryList(view, nodeDef.index);
|
||||
const queryList = asQueryList(view, nodeDef.nodeIndex);
|
||||
if (queryList.dirty) {
|
||||
throw expressionChangedAfterItHasBeenCheckedError(
|
||||
Services.createDebugContext(view, nodeDef.index), `Query ${nodeDef.query!.id} not dirty`,
|
||||
`Query ${nodeDef.query!.id} dirty`, (view.state & ViewState.BeforeFirstCheck) !== 0);
|
||||
Services.createDebugContext(view, nodeDef.nodeIndex),
|
||||
`Query ${nodeDef.query!.id} not dirty`, `Query ${nodeDef.query!.id} dirty`,
|
||||
(view.state & ViewState.BeforeFirstCheck) !== 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,7 +643,7 @@ function execQueriesAction(
|
||||
for (let i = 0; i < nodeCount; i++) {
|
||||
const nodeDef = view.def.nodes[i];
|
||||
if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
|
||||
Services.setCurrentNode(view, nodeDef.index);
|
||||
Services.setCurrentNode(view, nodeDef.nodeIndex);
|
||||
switch (checkType) {
|
||||
case CheckType.CheckAndUpdate:
|
||||
checkAndUpdateQuery(view, nodeDef);
|
||||
|
Reference in New Issue
Block a user