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:
parent
caa51950e8
commit
0833b59aab
@ -6,7 +6,7 @@ more functionality from codegen into runtime to reduce generated code size.
|
|||||||
As we introduce more runtime code, we need to be very careful to not
|
As we introduce more runtime code, we need to be very careful to not
|
||||||
regress in performance, compared to the pure codegen solution.
|
regress in performance, compared to the pure codegen solution.
|
||||||
|
|
||||||
## Initial resuls: size of Deep Tree Benchmark
|
## Initial results: size of Deep Tree Benchmark
|
||||||
|
|
||||||
File size for Tree benchmark template,
|
File size for Tree benchmark template,
|
||||||
view class of the component + the 2 embedded view classes (without imports nor host view factory):
|
view class of the component + the 2 embedded view classes (without imports nor host view factory):
|
||||||
|
@ -26,8 +26,8 @@ let viewFlags = ViewFlags.None;
|
|||||||
|
|
||||||
function TreeComponent_Host(): ViewDefinition {
|
function TreeComponent_Host(): ViewDefinition {
|
||||||
return viewDef(viewFlags, [
|
return viewDef(viewFlags, [
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'tree', null, null, null, null, TreeComponent_0),
|
elementDef(0, NodeFlags.None, null, null, 1, 'tree', null, null, null, null, TreeComponent_0),
|
||||||
directiveDef(NodeFlags.Component, null, 0, TreeComponent, []),
|
directiveDef(1, NodeFlags.Component, null, 0, TreeComponent, []),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +35,9 @@ function TreeComponent_1() {
|
|||||||
return viewDef(
|
return viewDef(
|
||||||
viewFlags,
|
viewFlags,
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'tree', null, null, null, null, TreeComponent_0),
|
elementDef(
|
||||||
directiveDef(NodeFlags.Component, null, 0, TreeComponent, [], {data: [0, 'data']}),
|
0, NodeFlags.None, null, null, 1, 'tree', null, null, null, null, TreeComponent_0),
|
||||||
|
directiveDef(1, NodeFlags.Component, null, 0, TreeComponent, [], {data: [0, 'data']}),
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
const cmp = view.component;
|
const cmp = view.component;
|
||||||
@ -48,8 +49,9 @@ function TreeComponent_2() {
|
|||||||
return viewDef(
|
return viewDef(
|
||||||
viewFlags,
|
viewFlags,
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null, null, 1, 'tree', null, null, null, null, TreeComponent_0),
|
elementDef(
|
||||||
directiveDef(NodeFlags.Component, null, 0, TreeComponent, [], {data: [0, 'data']}),
|
0, NodeFlags.None, null, null, 1, 'tree', null, null, null, null, TreeComponent_0),
|
||||||
|
directiveDef(1, NodeFlags.Component, null, 0, TreeComponent, [], {data: [0, 'data']}),
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
const cmp = view.component;
|
const cmp = view.component;
|
||||||
@ -62,15 +64,15 @@ function TreeComponent_0(): ViewDefinition {
|
|||||||
viewFlags,
|
viewFlags,
|
||||||
[
|
[
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null, null, 1, 'span', null,
|
0, NodeFlags.None, null, null, 1, 'span', null,
|
||||||
[[BindingFlags.TypeElementStyle, 'backgroundColor', null]]),
|
[[BindingFlags.TypeElementStyle, 'backgroundColor', null]]),
|
||||||
textDef(null, [' ', ' ']),
|
textDef(1, null, [' ', ' ']),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null, null, 1, null, TreeComponent_1),
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 1, null, TreeComponent_1),
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
3, NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null, null, 1, null, TreeComponent_2),
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 1, null, TreeComponent_2),
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
5, NodeFlags.None, null, 0, NgIf, [ViewContainerRef, TemplateRef], {ngIf: [0, 'ngIf']}),
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
const cmp = view.component;
|
const cmp = view.component;
|
||||||
|
@ -230,12 +230,15 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
visitText(ast: TextAst, context: any): any {
|
visitText(ast: TextAst, context: any): any {
|
||||||
// textDef(ngContentIndex: number, constants: string[]): NodeDef;
|
// Static text nodes have no check function
|
||||||
|
const checkIndex = -1;
|
||||||
this.nodes.push(() => ({
|
this.nodes.push(() => ({
|
||||||
sourceSpan: ast.sourceSpan,
|
sourceSpan: ast.sourceSpan,
|
||||||
nodeFlags: NodeFlags.TypeText,
|
nodeFlags: NodeFlags.TypeText,
|
||||||
nodeDef: o.importExpr(Identifiers.textDef).callFn([
|
nodeDef: o.importExpr(Identifiers.textDef).callFn([
|
||||||
o.literal(ast.ngContentIndex), o.literalArr([o.literal(ast.value)])
|
o.literal(checkIndex),
|
||||||
|
o.literal(ast.ngContentIndex),
|
||||||
|
o.literalArr([o.literal(ast.value)]),
|
||||||
])
|
])
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -252,12 +255,17 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
(expr, bindingIndex) => this._preprocessUpdateExpression(
|
(expr, bindingIndex) => this._preprocessUpdateExpression(
|
||||||
{nodeIndex, bindingIndex, sourceSpan: ast.sourceSpan, context: COMP_VAR, value: expr}));
|
{nodeIndex, bindingIndex, sourceSpan: ast.sourceSpan, context: COMP_VAR, value: expr}));
|
||||||
|
|
||||||
// textDef(ngContentIndex: number, constants: string[]): NodeDef;
|
// Check index is the same as the node index during compilation
|
||||||
|
// They might only differ at runtime
|
||||||
|
const checkIndex = nodeIndex;
|
||||||
|
|
||||||
this.nodes[nodeIndex] = () => ({
|
this.nodes[nodeIndex] = () => ({
|
||||||
sourceSpan: ast.sourceSpan,
|
sourceSpan: ast.sourceSpan,
|
||||||
nodeFlags: NodeFlags.TypeText,
|
nodeFlags: NodeFlags.TypeText,
|
||||||
nodeDef: o.importExpr(Identifiers.textDef).callFn([
|
nodeDef: o.importExpr(Identifiers.textDef).callFn([
|
||||||
o.literal(ast.ngContentIndex), o.literalArr(inter.strings.map(s => o.literal(s)))
|
o.literal(checkIndex),
|
||||||
|
o.literal(ast.ngContentIndex),
|
||||||
|
o.literalArr(inter.strings.map(s => o.literal(s))),
|
||||||
]),
|
]),
|
||||||
updateRenderer: updateRendererExpressions
|
updateRenderer: updateRendererExpressions
|
||||||
});
|
});
|
||||||
@ -344,18 +352,15 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
compRendererType = this.outputCtx.importExpr(compAst.directive.rendererType);
|
compRendererType = this.outputCtx.importExpr(compAst.directive.rendererType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// elementDef(
|
// Check index is the same as the node index during compilation
|
||||||
// flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
// They might only differ at runtime
|
||||||
// ngContentIndex: number, childCount: number, namespaceAndName: string,
|
const checkIndex = nodeIndex;
|
||||||
// fixedAttrs: [string, string][] = [],
|
|
||||||
// bindings?: [BindingFlags, string, string | SecurityContext][],
|
|
||||||
// outputs?: ([OutputType.ElementOutput | OutputType.DirectiveHostOutput, string, string])[],
|
|
||||||
// handleEvent?: ElementHandleEventFn,
|
|
||||||
// componentView?: () => ViewDefinition, componentRendererType?: RendererType2): NodeDef;
|
|
||||||
this.nodes[nodeIndex] = () => ({
|
this.nodes[nodeIndex] = () => ({
|
||||||
sourceSpan: ast.sourceSpan,
|
sourceSpan: ast.sourceSpan,
|
||||||
nodeFlags: NodeFlags.TypeElement | flags,
|
nodeFlags: NodeFlags.TypeElement | flags,
|
||||||
nodeDef: o.importExpr(Identifiers.elementDef).callFn([
|
nodeDef: o.importExpr(Identifiers.elementDef).callFn([
|
||||||
|
o.literal(checkIndex),
|
||||||
o.literal(flags),
|
o.literal(flags),
|
||||||
queryMatchesExpr,
|
queryMatchesExpr,
|
||||||
o.literal(ast.ngContentIndex),
|
o.literal(ast.ngContentIndex),
|
||||||
@ -561,20 +566,22 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
eventAst: hostEventAst, dirAst,
|
eventAst: hostEventAst, dirAst,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Check index is the same as the node index during compilation
|
||||||
|
// They might only differ at runtime
|
||||||
|
const checkIndex = nodeIndex;
|
||||||
|
|
||||||
// directiveDef(
|
|
||||||
// flags: NodeFlags, matchedQueries: [string, QueryValueType][], childCount: number, ctor:
|
|
||||||
// any,
|
|
||||||
// deps: ([DepFlags, any] | any)[], props?: {[name: string]: [number, string]},
|
|
||||||
// outputs?: {[name: string]: string}, component?: () => ViewDefinition): NodeDef;
|
|
||||||
this.nodes[nodeIndex] = () => ({
|
this.nodes[nodeIndex] = () => ({
|
||||||
sourceSpan: dirAst.sourceSpan,
|
sourceSpan: dirAst.sourceSpan,
|
||||||
nodeFlags: NodeFlags.TypeDirective | flags,
|
nodeFlags: NodeFlags.TypeDirective | flags,
|
||||||
nodeDef: o.importExpr(Identifiers.directiveDef).callFn([
|
nodeDef: o.importExpr(Identifiers.directiveDef).callFn([
|
||||||
o.literal(flags), queryMatchExprs.length ? o.literalArr(queryMatchExprs) : o.NULL_EXPR,
|
o.literal(checkIndex),
|
||||||
o.literal(childCount), providerExpr, depsExpr,
|
o.literal(flags),
|
||||||
|
queryMatchExprs.length ? o.literalArr(queryMatchExprs) : o.NULL_EXPR,
|
||||||
|
o.literal(childCount),
|
||||||
|
providerExpr,
|
||||||
|
depsExpr,
|
||||||
inputDefs.length ? new o.LiteralMapExpr(inputDefs) : o.NULL_EXPR,
|
inputDefs.length ? new o.LiteralMapExpr(inputDefs) : o.NULL_EXPR,
|
||||||
outputDefs.length ? new o.LiteralMapExpr(outputDefs) : o.NULL_EXPR
|
outputDefs.length ? new o.LiteralMapExpr(outputDefs) : o.NULL_EXPR,
|
||||||
]),
|
]),
|
||||||
updateDirectives: updateDirectiveExpressions,
|
updateDirectives: updateDirectiveExpressions,
|
||||||
directive: dirAst.directive.type,
|
directive: dirAst.directive.type,
|
||||||
@ -687,15 +694,18 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
return () => valueExpr;
|
return () => valueExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeIndex = this.nodes.length;
|
const checkIndex = this.nodes.length;
|
||||||
// pureArrayDef(argCount: number): NodeDef;
|
|
||||||
this.nodes.push(() => ({
|
this.nodes.push(() => ({
|
||||||
sourceSpan,
|
sourceSpan,
|
||||||
nodeFlags: NodeFlags.TypePureArray,
|
nodeFlags: NodeFlags.TypePureArray,
|
||||||
nodeDef: o.importExpr(Identifiers.pureArrayDef).callFn([o.literal(argCount)])
|
nodeDef: o.importExpr(Identifiers.pureArrayDef).callFn([
|
||||||
|
o.literal(checkIndex),
|
||||||
|
o.literal(argCount),
|
||||||
|
])
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (args: o.Expression[]) => callCheckStmt(nodeIndex, args);
|
return (args: o.Expression[]) => callCheckStmt(checkIndex, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createLiteralMapConverter(
|
private _createLiteralMapConverter(
|
||||||
@ -705,28 +715,32 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
return () => valueExpr;
|
return () => valueExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function pureObjectDef(propToIndex: {[p: string]: number}): NodeDef
|
|
||||||
const map = o.literalMap(keys.map((e, i) => ({...e, value: o.literal(i)})));
|
const map = o.literalMap(keys.map((e, i) => ({...e, value: o.literal(i)})));
|
||||||
const nodeIndex = this.nodes.length;
|
const checkIndex = this.nodes.length;
|
||||||
this.nodes.push(() => ({
|
this.nodes.push(() => ({
|
||||||
sourceSpan,
|
sourceSpan,
|
||||||
nodeFlags: NodeFlags.TypePureObject,
|
nodeFlags: NodeFlags.TypePureObject,
|
||||||
nodeDef: o.importExpr(Identifiers.pureObjectDef).callFn([map])
|
nodeDef: o.importExpr(Identifiers.pureObjectDef).callFn([
|
||||||
|
o.literal(checkIndex),
|
||||||
|
map,
|
||||||
|
])
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (args: o.Expression[]) => callCheckStmt(nodeIndex, args);
|
return (args: o.Expression[]) => callCheckStmt(checkIndex, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createPipeConverter(expression: UpdateExpression, name: string, argCount: number):
|
private _createPipeConverter(expression: UpdateExpression, name: string, argCount: number):
|
||||||
BuiltinConverter {
|
BuiltinConverter {
|
||||||
const pipe = this.usedPipes.find((pipeSummary) => pipeSummary.name === name) !;
|
const pipe = this.usedPipes.find((pipeSummary) => pipeSummary.name === name) !;
|
||||||
if (pipe.pure) {
|
if (pipe.pure) {
|
||||||
const nodeIndex = this.nodes.length;
|
const checkIndex = this.nodes.length;
|
||||||
// function purePipeDef(argCount: number): NodeDef;
|
|
||||||
this.nodes.push(() => ({
|
this.nodes.push(() => ({
|
||||||
sourceSpan: expression.sourceSpan,
|
sourceSpan: expression.sourceSpan,
|
||||||
nodeFlags: NodeFlags.TypePurePipe,
|
nodeFlags: NodeFlags.TypePurePipe,
|
||||||
nodeDef: o.importExpr(Identifiers.purePipeDef).callFn([o.literal(argCount)])
|
nodeDef: o.importExpr(Identifiers.purePipeDef).callFn([
|
||||||
|
o.literal(checkIndex),
|
||||||
|
o.literal(argCount),
|
||||||
|
])
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// find underlying pipe in the component view
|
// find underlying pipe in the component view
|
||||||
@ -742,7 +756,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
|
|
||||||
return (args: o.Expression[]) => callUnwrapValue(
|
return (args: o.Expression[]) => callUnwrapValue(
|
||||||
expression.nodeIndex, expression.bindingIndex,
|
expression.nodeIndex, expression.bindingIndex,
|
||||||
callCheckStmt(nodeIndex, [pipeValueExpr].concat(args)));
|
callCheckStmt(checkIndex, [pipeValueExpr].concat(args)));
|
||||||
} else {
|
} else {
|
||||||
const nodeIndex = this._createPipe(expression.sourceSpan, pipe);
|
const nodeIndex = this._createPipe(expression.sourceSpan, pipe);
|
||||||
const nodeValueExpr =
|
const nodeValueExpr =
|
||||||
|
@ -13,8 +13,8 @@ import {BindingDef, BindingFlags, ElementData, ElementHandleEventFn, NodeDef, No
|
|||||||
import {NOOP, calcBindingFlags, checkAndUpdateBinding, dispatchEvent, elementEventFullName, getParentRenderElement, resolveDefinition, resolveRendererType2, splitMatchedQueriesDsl, splitNamespace} from './util';
|
import {NOOP, calcBindingFlags, checkAndUpdateBinding, dispatchEvent, elementEventFullName, getParentRenderElement, resolveDefinition, resolveRendererType2, splitMatchedQueriesDsl, splitNamespace} from './util';
|
||||||
|
|
||||||
export function anchorDef(
|
export function anchorDef(
|
||||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
flags: NodeFlags, matchedQueriesDsl: null | [string | number, QueryValueType][],
|
||||||
ngContentIndex: number, childCount: number, handleEvent?: ElementHandleEventFn,
|
ngContentIndex: null | number, childCount: number, handleEvent?: null | ElementHandleEventFn,
|
||||||
templateFactory?: ViewDefinitionFactory): NodeDef {
|
templateFactory?: ViewDefinitionFactory): NodeDef {
|
||||||
flags |= NodeFlags.TypeElement;
|
flags |= NodeFlags.TypeElement;
|
||||||
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
||||||
@ -22,13 +22,14 @@ export function anchorDef(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
// will bet set by the view definition
|
// will bet set by the view definition
|
||||||
index: -1,
|
nodeIndex: -1,
|
||||||
parent: null,
|
parent: null,
|
||||||
renderParent: null,
|
renderParent: null,
|
||||||
bindingIndex: -1,
|
bindingIndex: -1,
|
||||||
outputIndex: -1,
|
outputIndex: -1,
|
||||||
// regular values
|
// regular values
|
||||||
flags,
|
flags,
|
||||||
|
checkIndex: -1,
|
||||||
childFlags: 0,
|
childFlags: 0,
|
||||||
directChildFlags: 0,
|
directChildFlags: 0,
|
||||||
childMatchedQueries: 0, matchedQueries, matchedQueryIds, references, ngContentIndex, childCount,
|
childMatchedQueries: 0, matchedQueries, matchedQueryIds, references, ngContentIndex, childCount,
|
||||||
@ -54,11 +55,12 @@ export function anchorDef(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function elementDef(
|
export function elementDef(
|
||||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
checkIndex: number, flags: NodeFlags,
|
||||||
ngContentIndex: number, childCount: number, namespaceAndName: string | null,
|
matchedQueriesDsl: null | [string | number, QueryValueType][], ngContentIndex: null | number,
|
||||||
fixedAttrs: [string, string][] = [],
|
childCount: number, namespaceAndName: string | null, fixedAttrs: null | [string, string][] = [],
|
||||||
bindings?: [BindingFlags, string, string | SecurityContext][], outputs?: ([string, string])[],
|
bindings?: null | [BindingFlags, string, string | SecurityContext | null][],
|
||||||
handleEvent?: ElementHandleEventFn, componentView?: ViewDefinitionFactory,
|
outputs?: null | ([string, string])[], handleEvent?: null | ElementHandleEventFn,
|
||||||
|
componentView?: null | ViewDefinitionFactory,
|
||||||
componentRendererType?: RendererType2 | null): NodeDef {
|
componentRendererType?: RendererType2 | null): NodeDef {
|
||||||
if (!handleEvent) {
|
if (!handleEvent) {
|
||||||
handleEvent = NOOP;
|
handleEvent = NOOP;
|
||||||
@ -111,12 +113,13 @@ export function elementDef(
|
|||||||
flags |= NodeFlags.TypeElement;
|
flags |= NodeFlags.TypeElement;
|
||||||
return {
|
return {
|
||||||
// will bet set by the view definition
|
// will bet set by the view definition
|
||||||
index: -1,
|
nodeIndex: -1,
|
||||||
parent: null,
|
parent: null,
|
||||||
renderParent: null,
|
renderParent: null,
|
||||||
bindingIndex: -1,
|
bindingIndex: -1,
|
||||||
outputIndex: -1,
|
outputIndex: -1,
|
||||||
// regular values
|
// regular values
|
||||||
|
checkIndex,
|
||||||
flags,
|
flags,
|
||||||
childFlags: 0,
|
childFlags: 0,
|
||||||
directChildFlags: 0,
|
directChildFlags: 0,
|
||||||
@ -175,7 +178,7 @@ export function listenToElementOutputs(view: ViewData, compView: ViewData, def:
|
|||||||
for (let i = 0; i < def.outputs.length; i++) {
|
for (let i = 0; i < def.outputs.length; i++) {
|
||||||
const output = def.outputs[i];
|
const output = def.outputs[i];
|
||||||
const handleEventClosure = renderEventHandlerClosure(
|
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 listenTarget: 'window'|'document'|'body'|'component'|null = output.target;
|
||||||
let listenerView = view;
|
let listenerView = view;
|
||||||
if (output.target === 'component') {
|
if (output.target === 'component') {
|
||||||
@ -224,7 +227,7 @@ function checkAndUpdateElementValue(view: ViewData, def: NodeDef, bindingIdx: nu
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const binding = def.bindings[bindingIdx];
|
const binding = def.bindings[bindingIdx];
|
||||||
const elData = asElementData(view, def.index);
|
const elData = asElementData(view, def.nodeIndex);
|
||||||
const renderNode = elData.renderElement;
|
const renderNode = elData.renderElement;
|
||||||
const name = binding.name !;
|
const name = binding.name !;
|
||||||
switch (binding.flags & BindingFlags.Types) {
|
switch (binding.flags & BindingFlags.Types) {
|
||||||
|
@ -9,15 +9,16 @@
|
|||||||
import {NodeDef, NodeFlags, ViewData} from './types';
|
import {NodeDef, NodeFlags, ViewData} from './types';
|
||||||
import {RenderNodeAction, getParentRenderElement, visitProjectedRenderNodes} from './util';
|
import {RenderNodeAction, getParentRenderElement, visitProjectedRenderNodes} from './util';
|
||||||
|
|
||||||
export function ngContentDef(ngContentIndex: number, index: number): NodeDef {
|
export function ngContentDef(ngContentIndex: null | number, index: number): NodeDef {
|
||||||
return {
|
return {
|
||||||
// will bet set by the view definition
|
// will bet set by the view definition
|
||||||
index: -1,
|
nodeIndex: -1,
|
||||||
parent: null,
|
parent: null,
|
||||||
renderParent: null,
|
renderParent: null,
|
||||||
bindingIndex: -1,
|
bindingIndex: -1,
|
||||||
outputIndex: -1,
|
outputIndex: -1,
|
||||||
// regular values
|
// regular values
|
||||||
|
checkIndex: -1,
|
||||||
flags: NodeFlags.TypeNgContent,
|
flags: NodeFlags.TypeNgContent,
|
||||||
childFlags: 0,
|
childFlags: 0,
|
||||||
directChildFlags: 0,
|
directChildFlags: 0,
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {resolveForwardRef} from '../di/forward_ref';
|
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 {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';
|
import {splitDepsDsl, tokenKey} from './util';
|
||||||
|
|
||||||
const NOT_CREATED = new Object();
|
const NOT_CREATED = new Object();
|
||||||
@ -89,80 +89,60 @@ export function resolveNgModuleDep(
|
|||||||
|
|
||||||
|
|
||||||
function _createProviderInstance(ngModule: NgModuleData, providerDef: NgModuleProviderDef): any {
|
function _createProviderInstance(ngModule: NgModuleData, providerDef: NgModuleProviderDef): any {
|
||||||
let injectable: any;
|
|
||||||
switch (providerDef.flags & NodeFlags.Types) {
|
switch (providerDef.flags & NodeFlags.Types) {
|
||||||
case NodeFlags.TypeClassProvider:
|
case NodeFlags.TypeClassProvider:
|
||||||
injectable = _createClass(ngModule, providerDef.value, providerDef.deps);
|
return _createClass(ngModule, providerDef.value, providerDef.deps);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeFactoryProvider:
|
case NodeFlags.TypeFactoryProvider:
|
||||||
injectable = _callFactory(ngModule, providerDef.value, providerDef.deps);
|
return _callFactory(ngModule, providerDef.value, providerDef.deps);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeUseExistingProvider:
|
case NodeFlags.TypeUseExistingProvider:
|
||||||
injectable = resolveNgModuleDep(ngModule, providerDef.deps[0]);
|
return resolveNgModuleDep(ngModule, providerDef.deps[0]);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeValueProvider:
|
case NodeFlags.TypeValueProvider:
|
||||||
injectable = providerDef.value;
|
return providerDef.value;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return injectable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createClass(ngModule: NgModuleData, ctor: any, deps: DepDef[]): any {
|
function _createClass(ngModule: NgModuleData, ctor: any, deps: DepDef[]): any {
|
||||||
const len = deps.length;
|
const len = deps.length;
|
||||||
let injectable: any;
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 0:
|
case 0:
|
||||||
injectable = new ctor();
|
return new ctor();
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
injectable = new ctor(resolveNgModuleDep(ngModule, deps[0]));
|
return new ctor(resolveNgModuleDep(ngModule, deps[0]));
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
injectable =
|
return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||||
new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
injectable = new ctor(
|
return new ctor(
|
||||||
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
||||||
resolveNgModuleDep(ngModule, deps[2]));
|
resolveNgModuleDep(ngModule, deps[2]));
|
||||||
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] = resolveNgModuleDep(ngModule, deps[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 {
|
function _callFactory(ngModule: NgModuleData, factory: any, deps: DepDef[]): any {
|
||||||
const len = deps.length;
|
const len = deps.length;
|
||||||
let injectable: any;
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 0:
|
case 0:
|
||||||
injectable = factory();
|
return factory();
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
injectable = factory(resolveNgModuleDep(ngModule, deps[0]));
|
return factory(resolveNgModuleDep(ngModule, deps[0]));
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
injectable =
|
return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
||||||
factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
|
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
injectable = factory(
|
return factory(
|
||||||
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]),
|
||||||
resolveNgModuleDep(ngModule, deps[2]));
|
resolveNgModuleDep(ngModule, deps[2]));
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
const depValues = Array(len);
|
const depValues = Array(len);
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
|
depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
|
||||||
}
|
}
|
||||||
injectable = factory(...depValues);
|
return factory(...depValues);
|
||||||
}
|
}
|
||||||
return injectable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function callNgModuleLifecycle(ngModule: NgModuleData, lifecycles: NodeFlags) {
|
export function callNgModuleLifecycle(ngModule: NgModuleData, lifecycles: NodeFlags) {
|
||||||
|
@ -28,9 +28,10 @@ const InjectorRefTokenKey = tokenKey(Injector);
|
|||||||
const NOT_CREATED = new Object();
|
const NOT_CREATED = new Object();
|
||||||
|
|
||||||
export function directiveDef(
|
export function directiveDef(
|
||||||
flags: NodeFlags, matchedQueries: [string | number, QueryValueType][], childCount: number,
|
checkIndex: number, flags: NodeFlags,
|
||||||
ctor: any, deps: ([DepFlags, any] | any)[], props?: {[name: string]: [number, string]},
|
matchedQueries: null | [string | number, QueryValueType][], childCount: number, ctor: any,
|
||||||
outputs?: {[name: string]: string}): NodeDef {
|
deps: ([DepFlags, any] | any)[], props?: null | {[name: string]: [number, string]},
|
||||||
|
outputs?: null | {[name: string]: string}): NodeDef {
|
||||||
const bindings: BindingDef[] = [];
|
const bindings: BindingDef[] = [];
|
||||||
if (props) {
|
if (props) {
|
||||||
for (let prop in props) {
|
for (let prop in props) {
|
||||||
@ -52,24 +53,26 @@ export function directiveDef(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
flags |= NodeFlags.TypeDirective;
|
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 {
|
export function pipeDef(flags: NodeFlags, ctor: any, deps: ([DepFlags, any] | any)[]): NodeDef {
|
||||||
flags |= NodeFlags.TypePipe;
|
flags |= NodeFlags.TypePipe;
|
||||||
return _def(flags, null, 0, ctor, ctor, deps);
|
return _def(-1, flags, null, 0, ctor, ctor, deps);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function providerDef(
|
export function providerDef(
|
||||||
flags: NodeFlags, matchedQueries: [string | number, QueryValueType][], token: any, value: any,
|
flags: NodeFlags, matchedQueries: null | [string | number, QueryValueType][], token: any,
|
||||||
deps: ([DepFlags, any] | any)[]): NodeDef {
|
value: any, deps: ([DepFlags, any] | any)[]): NodeDef {
|
||||||
return _def(flags, matchedQueries, 0, token, value, deps);
|
return _def(-1, flags, matchedQueries, 0, token, value, deps);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _def(
|
export function _def(
|
||||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][] | null,
|
checkIndex: number, flags: NodeFlags,
|
||||||
childCount: number, token: any, value: any, deps: ([DepFlags, any] | any)[],
|
matchedQueriesDsl: [string | number, QueryValueType][] | null, childCount: number, token: any,
|
||||||
bindings?: BindingDef[], outputs?: OutputDef[]): NodeDef {
|
value: any, deps: ([DepFlags, any] | any)[], bindings?: BindingDef[],
|
||||||
|
outputs?: OutputDef[]): NodeDef {
|
||||||
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
||||||
if (!outputs) {
|
if (!outputs) {
|
||||||
outputs = [];
|
outputs = [];
|
||||||
@ -86,12 +89,13 @@ export function _def(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
// will bet set by the view definition
|
// will bet set by the view definition
|
||||||
index: -1,
|
nodeIndex: -1,
|
||||||
parent: null,
|
parent: null,
|
||||||
renderParent: null,
|
renderParent: null,
|
||||||
bindingIndex: -1,
|
bindingIndex: -1,
|
||||||
outputIndex: -1,
|
outputIndex: -1,
|
||||||
// regular values
|
// regular values
|
||||||
|
checkIndex,
|
||||||
flags,
|
flags,
|
||||||
childFlags: 0,
|
childFlags: 0,
|
||||||
directChildFlags: 0,
|
directChildFlags: 0,
|
||||||
@ -134,7 +138,7 @@ export function createDirectiveInstance(view: ViewData, def: NodeDef): any {
|
|||||||
for (let i = 0; i < def.outputs.length; i++) {
|
for (let i = 0; i < def.outputs.length; i++) {
|
||||||
const output = def.outputs[i];
|
const output = def.outputs[i];
|
||||||
const subscription = instance[output.propName !].subscribe(
|
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);
|
view.disposables ![def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,7 +152,7 @@ function eventHandlerClosure(view: ViewData, index: number, eventName: string) {
|
|||||||
export function checkAndUpdateDirectiveInline(
|
export function checkAndUpdateDirectiveInline(
|
||||||
view: ViewData, def: NodeDef, v0: any, v1: any, v2: any, v3: any, v4: any, v5: any, v6: any,
|
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 {
|
v7: any, v8: any, v9: any): boolean {
|
||||||
const providerData = asProviderData(view, def.index);
|
const providerData = asProviderData(view, def.nodeIndex);
|
||||||
const directive = providerData.instance;
|
const directive = providerData.instance;
|
||||||
let changed = false;
|
let changed = false;
|
||||||
let changes: SimpleChanges = undefined !;
|
let changes: SimpleChanges = undefined !;
|
||||||
@ -207,7 +211,7 @@ export function checkAndUpdateDirectiveInline(
|
|||||||
|
|
||||||
export function checkAndUpdateDirectiveDynamic(
|
export function checkAndUpdateDirectiveDynamic(
|
||||||
view: ViewData, def: NodeDef, values: any[]): boolean {
|
view: ViewData, def: NodeDef, values: any[]): boolean {
|
||||||
const providerData = asProviderData(view, def.index);
|
const providerData = asProviderData(view, def.nodeIndex);
|
||||||
const directive = providerData.instance;
|
const directive = providerData.instance;
|
||||||
let changed = false;
|
let changed = false;
|
||||||
let changes: SimpleChanges = undefined !;
|
let changes: SimpleChanges = undefined !;
|
||||||
@ -233,89 +237,71 @@ function _createProviderInstance(view: ViewData, def: NodeDef): any {
|
|||||||
// private services can see other private services
|
// private services can see other private services
|
||||||
const allowPrivateServices = (def.flags & NodeFlags.PrivateProvider) > 0;
|
const allowPrivateServices = (def.flags & NodeFlags.PrivateProvider) > 0;
|
||||||
const providerDef = def.provider;
|
const providerDef = def.provider;
|
||||||
let injectable: any;
|
|
||||||
switch (def.flags & NodeFlags.Types) {
|
switch (def.flags & NodeFlags.Types) {
|
||||||
case NodeFlags.TypeClassProvider:
|
case NodeFlags.TypeClassProvider:
|
||||||
injectable = createClass(
|
return createClass(
|
||||||
view, def.parent !, allowPrivateServices, providerDef !.value, providerDef !.deps);
|
view, def.parent !, allowPrivateServices, providerDef !.value, providerDef !.deps);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeFactoryProvider:
|
case NodeFlags.TypeFactoryProvider:
|
||||||
injectable = callFactory(
|
return callFactory(
|
||||||
view, def.parent !, allowPrivateServices, providerDef !.value, providerDef !.deps);
|
view, def.parent !, allowPrivateServices, providerDef !.value, providerDef !.deps);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeUseExistingProvider:
|
case NodeFlags.TypeUseExistingProvider:
|
||||||
injectable = resolveDep(view, def.parent !, allowPrivateServices, providerDef !.deps[0]);
|
return resolveDep(view, def.parent !, allowPrivateServices, providerDef !.deps[0]);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeValueProvider:
|
case NodeFlags.TypeValueProvider:
|
||||||
injectable = providerDef !.value;
|
return providerDef !.value;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return injectable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createClass(
|
function createClass(
|
||||||
view: ViewData, elDef: NodeDef, allowPrivateServices: boolean, ctor: any, deps: DepDef[]): any {
|
view: ViewData, elDef: NodeDef, allowPrivateServices: boolean, ctor: any, deps: DepDef[]): any {
|
||||||
const len = deps.length;
|
const len = deps.length;
|
||||||
let injectable: any;
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 0:
|
case 0:
|
||||||
injectable = new ctor();
|
return new ctor();
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
injectable = new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
injectable = new ctor(
|
return new ctor(
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[1]));
|
resolveDep(view, elDef, allowPrivateServices, deps[1]));
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
injectable = new ctor(
|
return new ctor(
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[1]),
|
resolveDep(view, elDef, allowPrivateServices, deps[1]),
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[2]));
|
resolveDep(view, elDef, allowPrivateServices, deps[2]));
|
||||||
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, elDef, allowPrivateServices, deps[i]);
|
depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
|
||||||
}
|
}
|
||||||
injectable = new ctor(...depValues);
|
return new ctor(...depValues);
|
||||||
}
|
}
|
||||||
return injectable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function callFactory(
|
function callFactory(
|
||||||
view: ViewData, elDef: NodeDef, allowPrivateServices: boolean, factory: any,
|
view: ViewData, elDef: NodeDef, allowPrivateServices: boolean, factory: any,
|
||||||
deps: DepDef[]): any {
|
deps: DepDef[]): any {
|
||||||
const len = deps.length;
|
const len = deps.length;
|
||||||
let injectable: any;
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 0:
|
case 0:
|
||||||
injectable = factory();
|
return factory();
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
injectable = factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
injectable = factory(
|
return factory(
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[1]));
|
resolveDep(view, elDef, allowPrivateServices, deps[1]));
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
injectable = factory(
|
return factory(
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
resolveDep(view, elDef, allowPrivateServices, deps[0]),
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[1]),
|
resolveDep(view, elDef, allowPrivateServices, deps[1]),
|
||||||
resolveDep(view, elDef, allowPrivateServices, deps[2]));
|
resolveDep(view, elDef, allowPrivateServices, deps[2]));
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
const depValues = Array(len);
|
const depValues = Array(len);
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[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.
|
// This default value is when checking the hierarchy for a token.
|
||||||
@ -372,12 +358,12 @@ export function resolveDep(
|
|||||||
return compView.renderer;
|
return compView.renderer;
|
||||||
}
|
}
|
||||||
case ElementRefTokenKey:
|
case ElementRefTokenKey:
|
||||||
return new ElementRef(asElementData(view, elDef.index).renderElement);
|
return new ElementRef(asElementData(view, elDef.nodeIndex).renderElement);
|
||||||
case ViewContainerRefTokenKey:
|
case ViewContainerRefTokenKey:
|
||||||
return asElementData(view, elDef.index).viewContainer;
|
return asElementData(view, elDef.nodeIndex).viewContainer;
|
||||||
case TemplateRefTokenKey: {
|
case TemplateRefTokenKey: {
|
||||||
if (elDef.element !.template) {
|
if (elDef.element !.template) {
|
||||||
return asElementData(view, elDef.index).template;
|
return asElementData(view, elDef.nodeIndex).template;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -392,7 +378,7 @@ export function resolveDep(
|
|||||||
(allowPrivateServices ? elDef.element !.allProviders :
|
(allowPrivateServices ? elDef.element !.allProviders :
|
||||||
elDef.element !.publicProviders) ![tokenKey];
|
elDef.element !.publicProviders) ![tokenKey];
|
||||||
if (providerDef) {
|
if (providerDef) {
|
||||||
const providerData = asProviderData(view, providerDef.index);
|
const providerData = asProviderData(view, providerDef.nodeIndex);
|
||||||
if (providerData.instance === NOT_CREATED) {
|
if (providerData.instance === NOT_CREATED) {
|
||||||
providerData.instance = _createProviderInstance(view, providerDef);
|
providerData.instance = _createProviderInstance(view, providerDef);
|
||||||
}
|
}
|
||||||
@ -423,7 +409,7 @@ export function resolveDep(
|
|||||||
function findCompView(view: ViewData, elDef: NodeDef, allowPrivateServices: boolean) {
|
function findCompView(view: ViewData, elDef: NodeDef, allowPrivateServices: boolean) {
|
||||||
let compView: ViewData;
|
let compView: ViewData;
|
||||||
if (allowPrivateServices) {
|
if (allowPrivateServices) {
|
||||||
compView = asElementData(view, elDef.index).componentView;
|
compView = asElementData(view, elDef.nodeIndex).componentView;
|
||||||
} else {
|
} else {
|
||||||
compView = view;
|
compView = view;
|
||||||
while (compView.parent && !isComponentView(compView)) {
|
while (compView.parent && !isComponentView(compView)) {
|
||||||
@ -437,7 +423,7 @@ function updateProp(
|
|||||||
view: ViewData, providerData: ProviderData, def: NodeDef, bindingIdx: number, value: any,
|
view: ViewData, providerData: ProviderData, def: NodeDef, bindingIdx: number, value: any,
|
||||||
changes: SimpleChanges): SimpleChanges {
|
changes: SimpleChanges): SimpleChanges {
|
||||||
if (def.flags & NodeFlags.Component) {
|
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) {
|
if (compView.def.flags & ViewFlags.OnPush) {
|
||||||
compView.state |= ViewState.ChecksEnabled;
|
compView.state |= ViewState.ChecksEnabled;
|
||||||
}
|
}
|
||||||
@ -479,7 +465,7 @@ export function callLifecycleHooksChildrenFirst(view: ViewData, lifecycles: Node
|
|||||||
i += nodeDef.childCount;
|
i += nodeDef.childCount;
|
||||||
}
|
}
|
||||||
while (parent && (parent.flags & NodeFlags.TypeElement) &&
|
while (parent && (parent.flags & NodeFlags.TypeElement) &&
|
||||||
i === parent.index + parent.childCount) {
|
i === parent.nodeIndex + parent.childCount) {
|
||||||
// last child of an element
|
// last child of an element
|
||||||
if (parent.directChildFlags & lifecycles) {
|
if (parent.directChildFlags & lifecycles) {
|
||||||
callElementProvidersLifecycles(view, parent, lifecycles);
|
callElementProvidersLifecycles(view, parent, lifecycles);
|
||||||
@ -490,7 +476,7 @@ export function callLifecycleHooksChildrenFirst(view: ViewData, lifecycles: Node
|
|||||||
}
|
}
|
||||||
|
|
||||||
function callElementProvidersLifecycles(view: ViewData, elDef: NodeDef, lifecycles: NodeFlags) {
|
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];
|
const nodeDef = view.def.nodes[i];
|
||||||
if (nodeDef.flags & lifecycles) {
|
if (nodeDef.flags & lifecycles) {
|
||||||
callProviderLifecycles(view, i, nodeDef.flags & lifecycles);
|
callProviderLifecycles(view, i, nodeDef.flags & lifecycles);
|
||||||
|
@ -9,16 +9,16 @@
|
|||||||
import {BindingDef, BindingFlags, NodeDef, NodeFlags, PureExpressionData, ViewData, asPureExpressionData} from './types';
|
import {BindingDef, BindingFlags, NodeDef, NodeFlags, PureExpressionData, ViewData, asPureExpressionData} from './types';
|
||||||
import {calcBindingFlags, checkAndUpdateBinding} from './util';
|
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
|
// 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 {
|
export function pureArrayDef(checkIndex: number, argCount: number): NodeDef {
|
||||||
return _pureExpressionDef(NodeFlags.TypePureArray, new Array(argCount));
|
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 keys = Object.keys(propToIndex);
|
||||||
const nbKeys = keys.length;
|
const nbKeys = keys.length;
|
||||||
const propertyNames = new Array(nbKeys);
|
const propertyNames = new Array(nbKeys);
|
||||||
@ -28,10 +28,11 @@ export function pureObjectDef(propToIndex: {[p: string]: number}): NodeDef {
|
|||||||
propertyNames[index] = key;
|
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);
|
const bindings: BindingDef[] = new Array(propertyNames.length);
|
||||||
for (let i = 0; i < propertyNames.length; i++) {
|
for (let i = 0; i < propertyNames.length; i++) {
|
||||||
const prop = propertyNames[i];
|
const prop = propertyNames[i];
|
||||||
@ -46,12 +47,13 @@ function _pureExpressionDef(flags: NodeFlags, propertyNames: string[]): NodeDef
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
// will bet set by the view definition
|
// will bet set by the view definition
|
||||||
index: -1,
|
nodeIndex: -1,
|
||||||
parent: null,
|
parent: null,
|
||||||
renderParent: null,
|
renderParent: null,
|
||||||
bindingIndex: -1,
|
bindingIndex: -1,
|
||||||
outputIndex: -1,
|
outputIndex: -1,
|
||||||
// regular values
|
// regular values
|
||||||
|
checkIndex,
|
||||||
flags,
|
flags,
|
||||||
childFlags: 0,
|
childFlags: 0,
|
||||||
directChildFlags: 0,
|
directChildFlags: 0,
|
||||||
@ -93,7 +95,7 @@ export function checkAndUpdatePureExpressionInline(
|
|||||||
if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9)) changed = true;
|
if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9)) changed = true;
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
const data = asPureExpressionData(view, def.index);
|
const data = asPureExpressionData(view, def.nodeIndex);
|
||||||
let value: any;
|
let value: any;
|
||||||
switch (def.flags & NodeFlags.Types) {
|
switch (def.flags & NodeFlags.Types) {
|
||||||
case NodeFlags.TypePureArray:
|
case NodeFlags.TypePureArray:
|
||||||
@ -175,7 +177,7 @@ export function checkAndUpdatePureExpressionDynamic(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
const data = asPureExpressionData(view, def.index);
|
const data = asPureExpressionData(view, def.nodeIndex);
|
||||||
let value: any;
|
let value: any;
|
||||||
switch (def.flags & NodeFlags.Types) {
|
switch (def.flags & NodeFlags.Types) {
|
||||||
case NodeFlags.TypePureArray:
|
case NodeFlags.TypePureArray:
|
||||||
|
@ -22,13 +22,14 @@ export function queryDef(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
// will bet set by the view definition
|
// will bet set by the view definition
|
||||||
index: -1,
|
nodeIndex: -1,
|
||||||
parent: null,
|
parent: null,
|
||||||
renderParent: null,
|
renderParent: null,
|
||||||
bindingIndex: -1,
|
bindingIndex: -1,
|
||||||
outputIndex: -1,
|
outputIndex: -1,
|
||||||
// regular values
|
// regular values
|
||||||
flags,
|
// TODO(vicb): check
|
||||||
|
checkIndex: -1, flags,
|
||||||
childFlags: 0,
|
childFlags: 0,
|
||||||
directChildFlags: 0,
|
directChildFlags: 0,
|
||||||
childMatchedQueries: 0,
|
childMatchedQueries: 0,
|
||||||
@ -58,7 +59,7 @@ export function dirtyParentQueries(view: ViewData) {
|
|||||||
let tplDef = view.parentNodeDef !;
|
let tplDef = view.parentNodeDef !;
|
||||||
view = view.parent;
|
view = view.parent;
|
||||||
// content queries
|
// content queries
|
||||||
const end = tplDef.index + tplDef.childCount;
|
const end = tplDef.nodeIndex + tplDef.childCount;
|
||||||
for (let i = 0; i <= end; i++) {
|
for (let i = 0; i <= end; i++) {
|
||||||
const nodeDef = view.def.nodes[i];
|
const nodeDef = view.def.nodes[i];
|
||||||
if ((nodeDef.flags & NodeFlags.TypeContentQuery) &&
|
if ((nodeDef.flags & NodeFlags.TypeContentQuery) &&
|
||||||
@ -66,7 +67,7 @@ export function dirtyParentQueries(view: ViewData) {
|
|||||||
(nodeDef.query !.filterId & queryIds) === nodeDef.query !.filterId) {
|
(nodeDef.query !.filterId & queryIds) === nodeDef.query !.filterId) {
|
||||||
asQueryList(view, i).setDirty();
|
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.TypeContentQuery) ||
|
||||||
!(nodeDef.childFlags & NodeFlags.DynamicQuery)) {
|
!(nodeDef.childFlags & NodeFlags.DynamicQuery)) {
|
||||||
// skip elements that don't contain the template element or no query.
|
// 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) {
|
export function checkAndUpdateQuery(view: ViewData, nodeDef: NodeDef) {
|
||||||
const queryList = asQueryList(view, nodeDef.index);
|
const queryList = asQueryList(view, nodeDef.nodeIndex);
|
||||||
if (!queryList.dirty) {
|
if (!queryList.dirty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -98,8 +99,9 @@ export function checkAndUpdateQuery(view: ViewData, nodeDef: NodeDef) {
|
|||||||
if (nodeDef.flags & NodeFlags.TypeContentQuery) {
|
if (nodeDef.flags & NodeFlags.TypeContentQuery) {
|
||||||
const elementDef = nodeDef.parent !.parent !;
|
const elementDef = nodeDef.parent !.parent !;
|
||||||
newValues = calcQueryValues(
|
newValues = calcQueryValues(
|
||||||
view, elementDef.index, elementDef.index + elementDef.childCount, nodeDef.query !, []);
|
view, elementDef.nodeIndex, elementDef.nodeIndex + elementDef.childCount, nodeDef.query !,
|
||||||
directiveInstance = asProviderData(view, nodeDef.parent !.index).instance;
|
[]);
|
||||||
|
directiveInstance = asProviderData(view, nodeDef.parent !.nodeIndex).instance;
|
||||||
} else if (nodeDef.flags & NodeFlags.TypeViewQuery) {
|
} else if (nodeDef.flags & NodeFlags.TypeViewQuery) {
|
||||||
newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, nodeDef.query !, []);
|
newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, nodeDef.query !, []);
|
||||||
directiveInstance = view.component;
|
directiveInstance = view.component;
|
||||||
@ -175,24 +177,17 @@ export function getQueryValue(
|
|||||||
view: ViewData, nodeDef: NodeDef, queryValueType: QueryValueType): any {
|
view: ViewData, nodeDef: NodeDef, queryValueType: QueryValueType): any {
|
||||||
if (queryValueType != null) {
|
if (queryValueType != null) {
|
||||||
// a match
|
// a match
|
||||||
let value: any;
|
|
||||||
switch (queryValueType) {
|
switch (queryValueType) {
|
||||||
case QueryValueType.RenderElement:
|
case QueryValueType.RenderElement:
|
||||||
value = asElementData(view, nodeDef.index).renderElement;
|
return asElementData(view, nodeDef.nodeIndex).renderElement;
|
||||||
break;
|
|
||||||
case QueryValueType.ElementRef:
|
case QueryValueType.ElementRef:
|
||||||
value = new ElementRef(asElementData(view, nodeDef.index).renderElement);
|
return new ElementRef(asElementData(view, nodeDef.nodeIndex).renderElement);
|
||||||
break;
|
|
||||||
case QueryValueType.TemplateRef:
|
case QueryValueType.TemplateRef:
|
||||||
value = asElementData(view, nodeDef.index).template;
|
return asElementData(view, nodeDef.nodeIndex).template;
|
||||||
break;
|
|
||||||
case QueryValueType.ViewContainerRef:
|
case QueryValueType.ViewContainerRef:
|
||||||
value = asElementData(view, nodeDef.index).viewContainer;
|
return asElementData(view, nodeDef.nodeIndex).viewContainer;
|
||||||
break;
|
|
||||||
case QueryValueType.Provider:
|
case QueryValueType.Provider:
|
||||||
value = asProviderData(view, nodeDef.index).instance;
|
return asProviderData(view, nodeDef.nodeIndex).instance;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ class ComponentFactory_ extends ComponentFactory<any> {
|
|||||||
throw new Error('ngModule should be provided');
|
throw new Error('ngModule should be provided');
|
||||||
}
|
}
|
||||||
const viewDef = resolveDefinition(this.viewDefFactory);
|
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(
|
const view = Services.createRootView(
|
||||||
injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
|
injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
|
||||||
const component = asProviderData(view, componentNodeIndex).instance;
|
const component = asProviderData(view, componentNodeIndex).instance;
|
||||||
@ -113,7 +113,7 @@ class ComponentRef_ extends ComponentRef<any> {
|
|||||||
this.instance = _component;
|
this.instance = _component;
|
||||||
}
|
}
|
||||||
get location(): ElementRef {
|
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 injector(): Injector { return new Injector_(this._view, this._elDef); }
|
||||||
get componentType(): Type<any> { return <any>this._component.constructor; }
|
get componentType(): Type<any> { return <any>this._component.constructor; }
|
||||||
@ -318,7 +318,7 @@ class TemplateRef_ extends TemplateRef<any> implements TemplateData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get elementRef(): ElementRef {
|
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 {
|
export function nodeValue(view: ViewData, index: number): any {
|
||||||
const def = view.def.nodes[index];
|
const def = view.def.nodes[index];
|
||||||
if (def.flags & NodeFlags.TypeElement) {
|
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;
|
return def.element !.template ? elData.template : elData.renderElement;
|
||||||
} else if (def.flags & NodeFlags.TypeText) {
|
} 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)) {
|
} 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}`);
|
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 &&
|
if (lastElementDef && nodeDef.flags & NodeFlags.CatProviderNoDirective &&
|
||||||
providerOverrides.has(nodeDef.provider !.token)) {
|
providerOverrides.has(nodeDef.provider !.token)) {
|
||||||
elIndicesWithOverwrittenProviders.push(lastElementDef !.index);
|
elIndicesWithOverwrittenProviders.push(lastElementDef !.nodeIndex);
|
||||||
lastElementDef = null;
|
lastElementDef = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,22 +260,22 @@ function applyProviderOverridesToNgModule(def: NgModuleDefinition): NgModuleDefi
|
|||||||
}
|
}
|
||||||
|
|
||||||
function prodCheckAndUpdateNode(
|
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 {
|
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);
|
checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||||
asPureExpressionData(view, nodeIndex).value :
|
asPureExpressionData(view, checkIndex).value :
|
||||||
undefined;
|
undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function prodCheckNoChangesNode(
|
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 {
|
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);
|
checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||||
asPureExpressionData(view, nodeIndex).value :
|
asPureExpressionData(view, checkIndex).value :
|
||||||
undefined;
|
undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ function debugUpdateDirectives(view: ViewData, checkType: CheckType) {
|
|||||||
debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
|
debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
|
||||||
}
|
}
|
||||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||||
asPureExpressionData(view, nodeDef.index).value :
|
asPureExpressionData(view, nodeDef.nodeIndex).value :
|
||||||
undefined;
|
undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,7 +357,7 @@ function debugUpdateRenderer(view: ViewData, checkType: CheckType) {
|
|||||||
debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
|
debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
|
||||||
}
|
}
|
||||||
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
return (nodeDef.flags & NodeFlags.CatPureExpression) ?
|
||||||
asPureExpressionData(view, nodeDef.index).value :
|
asPureExpressionData(view, nodeDef.nodeIndex).value :
|
||||||
undefined;
|
undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ function debugCheckAndUpdateNode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const elDef = nodeDef.parent !;
|
const elDef = nodeDef.parent !;
|
||||||
const el = asElementData(view, elDef.index).renderElement;
|
const el = asElementData(view, elDef.nodeIndex).renderElement;
|
||||||
if (!elDef.element !.name) {
|
if (!elDef.element !.name) {
|
||||||
// a comment.
|
// a comment.
|
||||||
view.renderer.setValue(el, `bindings=${JSON.stringify(bindingValues, null, 2)}`);
|
view.renderer.setValue(el, `bindings=${JSON.stringify(bindingValues, null, 2)}`);
|
||||||
@ -468,7 +468,7 @@ class DebugContext_ implements DebugContext {
|
|||||||
}
|
}
|
||||||
private get elOrCompView() {
|
private get elOrCompView() {
|
||||||
// Has to be done lazily as we use the DebugContext also during creation of elements...
|
// 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 injector(): Injector { return createInjector(this.elView, this.elDef); }
|
||||||
get component(): any { return this.elOrCompView.component; }
|
get component(): any { return this.elOrCompView.component; }
|
||||||
@ -476,7 +476,8 @@ class DebugContext_ implements DebugContext {
|
|||||||
get providerTokens(): any[] {
|
get providerTokens(): any[] {
|
||||||
const tokens: any[] = [];
|
const tokens: any[] = [];
|
||||||
if (this.elDef) {
|
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];
|
const childDef = this.elView.def.nodes[i];
|
||||||
if (childDef.flags & NodeFlags.CatProvider) {
|
if (childDef.flags & NodeFlags.CatProvider) {
|
||||||
tokens.push(childDef.provider !.token);
|
tokens.push(childDef.provider !.token);
|
||||||
@ -491,7 +492,8 @@ class DebugContext_ implements DebugContext {
|
|||||||
if (this.elDef) {
|
if (this.elDef) {
|
||||||
collectReferences(this.elView, this.elDef, references);
|
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];
|
const childDef = this.elView.def.nodes[i];
|
||||||
if (childDef.flags & NodeFlags.CatProvider) {
|
if (childDef.flags & NodeFlags.CatProvider) {
|
||||||
collectReferences(this.elView, childDef, references);
|
collectReferences(this.elView, childDef, references);
|
||||||
@ -514,10 +516,10 @@ class DebugContext_ implements DebugContext {
|
|||||||
let logNodeIndex: number;
|
let logNodeIndex: number;
|
||||||
if (this.nodeDef.flags & NodeFlags.TypeText) {
|
if (this.nodeDef.flags & NodeFlags.TypeText) {
|
||||||
logViewDef = this.view.def;
|
logViewDef = this.view.def;
|
||||||
logNodeIndex = this.nodeDef.index;
|
logNodeIndex = this.nodeDef.nodeIndex;
|
||||||
} else {
|
} else {
|
||||||
logViewDef = this.elView.def;
|
logViewDef = this.elView.def;
|
||||||
logNodeIndex = this.elDef.index;
|
logNodeIndex = this.elDef.nodeIndex;
|
||||||
}
|
}
|
||||||
// Note: we only generate a log function for text and element nodes
|
// Note: we only generate a log function for text and element nodes
|
||||||
// to make the generated code as small as possible.
|
// to make the generated code as small as possible.
|
||||||
@ -555,7 +557,7 @@ function findHostElement(view: ViewData): ElementData|null {
|
|||||||
view = view.parent !;
|
view = view.parent !;
|
||||||
}
|
}
|
||||||
if (view.parent) {
|
if (view.parent) {
|
||||||
return asElementData(view.parent, viewParentEl(view) !.index);
|
return asElementData(view.parent, viewParentEl(view) !.nodeIndex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
import {BindingDef, BindingFlags, NodeDef, NodeFlags, TextData, ViewData, asTextData} from './types';
|
import {BindingDef, BindingFlags, NodeDef, NodeFlags, TextData, ViewData, asTextData} from './types';
|
||||||
import {checkAndUpdateBinding, getParentRenderElement} from './util';
|
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);
|
const bindings: BindingDef[] = new Array(staticText.length - 1);
|
||||||
for (let i = 1; i < staticText.length; i++) {
|
for (let i = 1; i < staticText.length; i++) {
|
||||||
bindings[i - 1] = {
|
bindings[i - 1] = {
|
||||||
@ -24,12 +25,13 @@ export function textDef(ngContentIndex: number, staticText: string[]): NodeDef {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
// will bet set by the view definition
|
// will bet set by the view definition
|
||||||
index: -1,
|
nodeIndex: -1,
|
||||||
parent: null,
|
parent: null,
|
||||||
renderParent: null,
|
renderParent: null,
|
||||||
bindingIndex: -1,
|
bindingIndex: -1,
|
||||||
outputIndex: -1,
|
outputIndex: -1,
|
||||||
// regular values
|
// regular values
|
||||||
|
checkIndex,
|
||||||
flags: NodeFlags.TypeText,
|
flags: NodeFlags.TypeText,
|
||||||
childFlags: 0,
|
childFlags: 0,
|
||||||
directChildFlags: 0,
|
directChildFlags: 0,
|
||||||
@ -88,7 +90,7 @@ export function checkAndUpdateTextInline(
|
|||||||
if (bindLen > 7) value += _addInterpolationPart(v7, bindings[7]);
|
if (bindLen > 7) value += _addInterpolationPart(v7, bindings[7]);
|
||||||
if (bindLen > 8) value += _addInterpolationPart(v8, bindings[8]);
|
if (bindLen > 8) value += _addInterpolationPart(v8, bindings[8]);
|
||||||
if (bindLen > 9) value += _addInterpolationPart(v9, bindings[9]);
|
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);
|
view.renderer.setValue(renderNode, value);
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
@ -110,7 +112,7 @@ export function checkAndUpdateTextDynamic(view: ViewData, def: NodeDef, values:
|
|||||||
value = value + _addInterpolationPart(values[i], bindings[i]);
|
value = value + _addInterpolationPart(values[i], bindings[i]);
|
||||||
}
|
}
|
||||||
value = def.text !.prefix + value;
|
value = def.text !.prefix + value;
|
||||||
const renderNode = asTextData(view, def.index).renderText;
|
const renderNode = asTextData(view, def.nodeIndex).renderText;
|
||||||
view.renderer.setValue(renderNode, value);
|
view.renderer.setValue(renderNode, value);
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
|
@ -103,11 +103,15 @@ export const enum ViewFlags {
|
|||||||
*/
|
*/
|
||||||
export interface NodeDef {
|
export interface NodeDef {
|
||||||
flags: NodeFlags;
|
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;
|
parent: NodeDef|null;
|
||||||
renderParent: NodeDef|null;
|
renderParent: NodeDef|null;
|
||||||
/** this is checked against NgContentDef.index to find matched nodes */
|
/** this is checked against NgContentDef.index to find matched nodes */
|
||||||
ngContentIndex: number;
|
ngContentIndex: number|null;
|
||||||
/** number of transitive children */
|
/** number of transitive children */
|
||||||
childCount: number;
|
childCount: number;
|
||||||
/** aggregated NodeFlags for all transitive children (does not include self) **/
|
/** aggregated NodeFlags for all transitive children (does not include self) **/
|
||||||
|
@ -102,7 +102,7 @@ export function checkBindingNoChanges(
|
|||||||
const oldValue = view.oldValues[def.bindingIndex + bindingIdx];
|
const oldValue = view.oldValues[def.bindingIndex + bindingIdx];
|
||||||
if ((view.state & ViewState.BeforeFirstCheck) || !devModeEqual(oldValue, value)) {
|
if ((view.state & ViewState.BeforeFirstCheck) || !devModeEqual(oldValue, value)) {
|
||||||
throw expressionChangedAfterItHasBeenCheckedError(
|
throw expressionChangedAfterItHasBeenCheckedError(
|
||||||
Services.createDebugContext(view, def.index), oldValue, value,
|
Services.createDebugContext(view, def.nodeIndex), oldValue, value,
|
||||||
(view.state & ViewState.BeforeFirstCheck) !== 0);
|
(view.state & ViewState.BeforeFirstCheck) !== 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ export function dispatchEvent(
|
|||||||
export function declaredViewContainer(view: ViewData): ElementData|null {
|
export function declaredViewContainer(view: ViewData): ElementData|null {
|
||||||
if (view.parent) {
|
if (view.parent) {
|
||||||
const parentView = view.parent;
|
const parentView = view.parent;
|
||||||
return asElementData(parentView, view.parentNodeDef !.index);
|
return asElementData(parentView, view.parentNodeDef !.nodeIndex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -165,9 +165,9 @@ export function viewParentEl(view: ViewData): NodeDef|null {
|
|||||||
export function renderNode(view: ViewData, def: NodeDef): any {
|
export function renderNode(view: ViewData, def: NodeDef): any {
|
||||||
switch (def.flags & NodeFlags.Types) {
|
switch (def.flags & NodeFlags.Types) {
|
||||||
case NodeFlags.TypeElement:
|
case NodeFlags.TypeElement:
|
||||||
return asElementData(view, def.index).renderElement;
|
return asElementData(view, def.nodeIndex).renderElement;
|
||||||
case NodeFlags.TypeText:
|
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)) {
|
ViewEncapsulation.Native)) {
|
||||||
// only children of non components, or children of components with native encapsulation should
|
// only children of non components, or children of components with native encapsulation should
|
||||||
// be attached.
|
// be attached.
|
||||||
return asElementData(view, def.renderParent !.index).renderElement;
|
return asElementData(view, def.renderParent !.nodeIndex).renderElement;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return renderHost;
|
return renderHost;
|
||||||
@ -292,8 +292,8 @@ export function visitProjectedRenderNodes(
|
|||||||
}
|
}
|
||||||
const hostView = compView !.parent;
|
const hostView = compView !.parent;
|
||||||
const hostElDef = viewParentEl(compView !);
|
const hostElDef = viewParentEl(compView !);
|
||||||
const startIndex = hostElDef !.index + 1;
|
const startIndex = hostElDef !.nodeIndex + 1;
|
||||||
const endIndex = hostElDef !.index + hostElDef !.childCount;
|
const endIndex = hostElDef !.nodeIndex + hostElDef !.childCount;
|
||||||
for (let i = startIndex; i <= endIndex; i++) {
|
for (let i = startIndex; i <= endIndex; i++) {
|
||||||
const nodeDef = hostView !.def.nodes[i];
|
const nodeDef = hostView !.def.nodes[i];
|
||||||
if (nodeDef.ngContentIndex === ngContentIndex) {
|
if (nodeDef.ngContentIndex === ngContentIndex) {
|
||||||
@ -328,21 +328,21 @@ function visitRenderNode(
|
|||||||
execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
|
execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
|
||||||
}
|
}
|
||||||
if (nodeDef.bindingFlags & (BindingFlags.SyntheticHostProperty)) {
|
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);
|
execRenderNodeAction(compView, rn, action, parentNode, nextSibling, target);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
|
execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
|
||||||
}
|
}
|
||||||
if (nodeDef.flags & NodeFlags.EmbeddedViews) {
|
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++) {
|
for (let k = 0; k < embeddedViews.length; k++) {
|
||||||
visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
|
visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nodeDef.flags & NodeFlags.TypeElement && !nodeDef.element !.name) {
|
if (nodeDef.flags & NodeFlags.TypeElement && !nodeDef.element !.name) {
|
||||||
visitSiblingRenderNodes(
|
visitSiblingRenderNodes(
|
||||||
view, action, nodeDef.index + 1, nodeDef.index + nodeDef.childCount, parentNode,
|
view, action, nodeDef.nodeIndex + 1, nodeDef.nodeIndex + nodeDef.childCount, parentNode,
|
||||||
nextSibling, target);
|
nextSibling, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,8 @@ import {NOOP, checkBindingNoChanges, isComponentView, markParentViewsForCheckPro
|
|||||||
import {detachProjectedView} from './view_attach';
|
import {detachProjectedView} from './view_attach';
|
||||||
|
|
||||||
export function viewDef(
|
export function viewDef(
|
||||||
flags: ViewFlags, nodes: NodeDef[], updateDirectives?: ViewUpdateFn,
|
flags: ViewFlags, nodes: NodeDef[], updateDirectives?: null | ViewUpdateFn,
|
||||||
updateRenderer?: ViewUpdateFn): ViewDefinition {
|
updateRenderer?: null | ViewUpdateFn): ViewDefinition {
|
||||||
// clone nodes and set auto calculated values
|
// clone nodes and set auto calculated values
|
||||||
let viewBindingCount = 0;
|
let viewBindingCount = 0;
|
||||||
let viewDisposableCount = 0;
|
let viewDisposableCount = 0;
|
||||||
@ -36,7 +36,7 @@ export function viewDef(
|
|||||||
let lastRenderRootNode: NodeDef|null = null;
|
let lastRenderRootNode: NodeDef|null = null;
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
const node = nodes[i];
|
const node = nodes[i];
|
||||||
node.index = i;
|
node.nodeIndex = i;
|
||||||
node.parent = currentParent;
|
node.parent = currentParent;
|
||||||
node.bindingIndex = viewBindingCount;
|
node.bindingIndex = viewBindingCount;
|
||||||
node.outputIndex = viewDisposableCount;
|
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
|
// 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
|
// elements. We loop to either the root or the highest opened element (= with remaining
|
||||||
// children)
|
// children)
|
||||||
while (currentParent && i === currentParent.index + currentParent.childCount) {
|
while (currentParent && i === currentParent.nodeIndex + currentParent.childCount) {
|
||||||
const newParent: NodeDef|null = currentParent.parent;
|
const newParent: NodeDef|null = currentParent.parent;
|
||||||
if (newParent) {
|
if (newParent) {
|
||||||
newParent.childFlags |= currentParent.childFlags;
|
newParent.childFlags |= currentParent.childFlags;
|
||||||
@ -164,32 +164,32 @@ function validateNode(parent: NodeDef | null, node: NodeDef, nodeCount: number)
|
|||||||
if (template.lastRenderRootNode &&
|
if (template.lastRenderRootNode &&
|
||||||
template.lastRenderRootNode.flags & NodeFlags.EmbeddedViews) {
|
template.lastRenderRootNode.flags & NodeFlags.EmbeddedViews) {
|
||||||
throw new Error(
|
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) {
|
if (node.flags & NodeFlags.CatProvider) {
|
||||||
const parentFlags = parent ? parent.flags : 0;
|
const parentFlags = parent ? parent.flags : 0;
|
||||||
if ((parentFlags & NodeFlags.TypeElement) === 0) {
|
if ((parentFlags & NodeFlags.TypeElement) === 0) {
|
||||||
throw new Error(
|
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.query) {
|
||||||
if (node.flags & NodeFlags.TypeContentQuery &&
|
if (node.flags & NodeFlags.TypeContentQuery &&
|
||||||
(!parent || (parent.flags & NodeFlags.TypeDirective) === 0)) {
|
(!parent || (parent.flags & NodeFlags.TypeDirective) === 0)) {
|
||||||
throw new Error(
|
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) {
|
if (node.flags & NodeFlags.TypeViewQuery && parent) {
|
||||||
throw new Error(
|
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) {
|
if (node.childCount) {
|
||||||
const parentEnd = parent ? parent.index + parent.childCount : nodeCount - 1;
|
const parentEnd = parent ? parent.nodeIndex + parent.childCount : nodeCount - 1;
|
||||||
if (node.index <= parentEnd && node.index + node.childCount > parentEnd) {
|
if (node.nodeIndex <= parentEnd && node.nodeIndex + node.childCount > parentEnd) {
|
||||||
throw new Error(
|
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;
|
let renderHost: any;
|
||||||
if (isComponentView(view)) {
|
if (isComponentView(view)) {
|
||||||
const hostDef = view.parentNodeDef;
|
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 def = view.def;
|
||||||
const nodes = view.nodes;
|
const nodes = view.nodes;
|
||||||
@ -297,7 +297,7 @@ function createViewNodes(view: ViewData) {
|
|||||||
const instance = createDirectiveInstance(view, nodeDef);
|
const instance = createDirectiveInstance(view, nodeDef);
|
||||||
nodeData = <ProviderData>{instance};
|
nodeData = <ProviderData>{instance};
|
||||||
if (nodeDef.flags & NodeFlags.Component) {
|
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);
|
initView(compView, instance, instance);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -410,47 +410,38 @@ function markProjectedViewsForCheck(view: ViewData) {
|
|||||||
function checkAndUpdateNodeInline(
|
function checkAndUpdateNodeInline(
|
||||||
view: ViewData, nodeDef: NodeDef, v0?: any, v1?: any, v2?: any, v3?: any, v4?: any, v5?: any,
|
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 {
|
v6?: any, v7?: any, v8?: any, v9?: any): boolean {
|
||||||
let changed = false;
|
|
||||||
switch (nodeDef.flags & NodeFlags.Types) {
|
switch (nodeDef.flags & NodeFlags.Types) {
|
||||||
case NodeFlags.TypeElement:
|
case NodeFlags.TypeElement:
|
||||||
changed = checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
return checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeText:
|
case NodeFlags.TypeText:
|
||||||
changed = checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
return checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeDirective:
|
case NodeFlags.TypeDirective:
|
||||||
changed =
|
return checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||||
checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
|
||||||
break;
|
|
||||||
case NodeFlags.TypePureArray:
|
case NodeFlags.TypePureArray:
|
||||||
case NodeFlags.TypePureObject:
|
case NodeFlags.TypePureObject:
|
||||||
case NodeFlags.TypePurePipe:
|
case NodeFlags.TypePurePipe:
|
||||||
changed =
|
return checkAndUpdatePureExpressionInline(
|
||||||
checkAndUpdatePureExpressionInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
||||||
break;
|
default:
|
||||||
|
throw 'unreachable';
|
||||||
}
|
}
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkAndUpdateNodeDynamic(view: ViewData, nodeDef: NodeDef, values: any[]): boolean {
|
function checkAndUpdateNodeDynamic(view: ViewData, nodeDef: NodeDef, values: any[]): boolean {
|
||||||
let changed = false;
|
|
||||||
switch (nodeDef.flags & NodeFlags.Types) {
|
switch (nodeDef.flags & NodeFlags.Types) {
|
||||||
case NodeFlags.TypeElement:
|
case NodeFlags.TypeElement:
|
||||||
changed = checkAndUpdateElementDynamic(view, nodeDef, values);
|
return checkAndUpdateElementDynamic(view, nodeDef, values);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeText:
|
case NodeFlags.TypeText:
|
||||||
changed = checkAndUpdateTextDynamic(view, nodeDef, values);
|
return checkAndUpdateTextDynamic(view, nodeDef, values);
|
||||||
break;
|
|
||||||
case NodeFlags.TypeDirective:
|
case NodeFlags.TypeDirective:
|
||||||
changed = checkAndUpdateDirectiveDynamic(view, nodeDef, values);
|
return checkAndUpdateDirectiveDynamic(view, nodeDef, values);
|
||||||
break;
|
|
||||||
case NodeFlags.TypePureArray:
|
case NodeFlags.TypePureArray:
|
||||||
case NodeFlags.TypePureObject:
|
case NodeFlags.TypePureObject:
|
||||||
case NodeFlags.TypePurePipe:
|
case NodeFlags.TypePurePipe:
|
||||||
changed = checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
|
return checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
|
||||||
break;
|
default:
|
||||||
|
throw 'unreachable';
|
||||||
}
|
}
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkNoChangesNode(
|
export function checkNoChangesNode(
|
||||||
@ -492,11 +483,12 @@ function checkNoChangesNodeDynamic(view: ViewData, nodeDef: NodeDef, values: any
|
|||||||
* @suppress {misplacedTypeAnnotation}
|
* @suppress {misplacedTypeAnnotation}
|
||||||
*/
|
*/
|
||||||
function checkNoChangesQuery(view: ViewData, nodeDef: NodeDef) {
|
function checkNoChangesQuery(view: ViewData, nodeDef: NodeDef) {
|
||||||
const queryList = asQueryList(view, nodeDef.index);
|
const queryList = asQueryList(view, nodeDef.nodeIndex);
|
||||||
if (queryList.dirty) {
|
if (queryList.dirty) {
|
||||||
throw expressionChangedAfterItHasBeenCheckedError(
|
throw expressionChangedAfterItHasBeenCheckedError(
|
||||||
Services.createDebugContext(view, nodeDef.index), `Query ${nodeDef.query!.id} not dirty`,
|
Services.createDebugContext(view, nodeDef.nodeIndex),
|
||||||
`Query ${nodeDef.query!.id} dirty`, (view.state & ViewState.BeforeFirstCheck) !== 0);
|
`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++) {
|
for (let i = 0; i < nodeCount; i++) {
|
||||||
const nodeDef = view.def.nodes[i];
|
const nodeDef = view.def.nodes[i];
|
||||||
if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
|
if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
|
||||||
Services.setCurrentNode(view, nodeDef.index);
|
Services.setCurrentNode(view, nodeDef.nodeIndex);
|
||||||
switch (checkType) {
|
switch (checkType) {
|
||||||
case CheckType.CheckAndUpdate:
|
case CheckType.CheckAndUpdate:
|
||||||
checkAndUpdateQuery(view, nodeDef);
|
checkAndUpdateQuery(view, nodeDef);
|
||||||
|
@ -6,47 +6,35 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
import {getDebugNode} from '@angular/core';
|
||||||
import {DebugContext, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, elementDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {NodeFlags, anchorDef, asElementData, elementDef} from '@angular/core/src/view/index';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
import {createRootView, isBrowser} from './helper';
|
import {compViewDef, createAndGetRootNodes} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`View Anchor`, () => {
|
describe(`View Anchor`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn,
|
|
||||||
updateRenderer?: ViewUpdateFn): ViewDefinition {
|
|
||||||
return viewDef(ViewFlags.None, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(
|
|
||||||
viewDef: ViewDefinition, ctx?: any): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef, ctx);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
it('should create anchor nodes without parents', () => {
|
it('should create anchor nodes without parents', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(NodeFlags.None, null !, null !, 0)
|
anchorDef(NodeFlags.None, null, null, 0)
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(1);
|
expect(rootNodes.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create views with multiple root anchor nodes', () => {
|
it('should create views with multiple root anchor nodes', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes =
|
||||||
anchorDef(NodeFlags.None, null !, null !, 0),
|
createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(NodeFlags.None, null !, null !, 0)
|
anchorDef(NodeFlags.None, null, null, 0), anchorDef(NodeFlags.None, null, null, 0)
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(2);
|
expect(rootNodes.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create anchor nodes with parents', () => {
|
it('should create anchor nodes with parents', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
anchorDef(NodeFlags.None, null !, null !, 0),
|
anchorDef(NodeFlags.None, null, null, 0),
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(getDOM().childNodes(rootNodes[0]).length).toBe(1);
|
expect(getDOM().childNodes(rootNodes[0]).length).toBe(1);
|
||||||
});
|
});
|
||||||
@ -54,7 +42,7 @@ export function main() {
|
|||||||
it('should add debug information to the renderer', () => {
|
it('should add debug information to the renderer', () => {
|
||||||
const someContext = new Object();
|
const someContext = new Object();
|
||||||
const {view, rootNodes} = createAndGetRootNodes(
|
const {view, rootNodes} = createAndGetRootNodes(
|
||||||
compViewDef([anchorDef(NodeFlags.None, null !, null !, 0)]), someContext);
|
compViewDef([anchorDef(NodeFlags.None, null, null, 0)]), someContext);
|
||||||
expect(getDebugNode(rootNodes[0]) !.nativeNode).toBe(asElementData(view, 0).renderElement);
|
expect(getDebugNode(rootNodes[0]) !.nativeNode).toBe(asElementData(view, 0).renderElement);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
import {SecurityContext} from '@angular/core';
|
||||||
import {ArgumentType, BindingFlags, NodeCheckFn, NodeDef, NodeFlags, OutputType, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, anchorDef, asElementData, asProviderData, directiveDef, elementDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {ArgumentType, BindingFlags, NodeCheckFn, NodeFlags, Services, ViewData, ViewFlags, ViewState, asElementData, directiveDef, elementDef, rootRenderNodes} from '@angular/core/src/view/index';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
import {callMostRecentEventListenerHandler, createRootView, isBrowser, recordNodeToRemove} from './helper';
|
import {callMostRecentEventListenerHandler, compViewDef, createAndGetRootNodes, createRootView, isBrowser, recordNodeToRemove} from './helper';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,18 +22,6 @@ const addEventListener = '__zone_symbol__addEventListener';
|
|||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`Component Views`, () => {
|
describe(`Component Views`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(viewDef: ViewDefinition): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should create and attach component views', () => {
|
it('should create and attach component views', () => {
|
||||||
let instance: AComp = undefined !;
|
let instance: AComp = undefined !;
|
||||||
class AComp {
|
class AComp {
|
||||||
@ -41,11 +30,11 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 0, 'span'),
|
||||||
])),
|
])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, AComp, []),
|
directiveDef(1, NodeFlags.Component, null, 0, AComp, []),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const compView = asElementData(view, 0).componentView;
|
const compView = asElementData(view, 0).componentView;
|
||||||
@ -69,7 +58,7 @@ export function main() {
|
|||||||
it('should select root elements based on a selector', () => {
|
it('should select root elements based on a selector', () => {
|
||||||
const view = createRootView(
|
const view = createRootView(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 0, 'div'),
|
||||||
]),
|
]),
|
||||||
{}, [], 'root');
|
{}, [], 'root');
|
||||||
const rootNodes = rootRenderNodes(view);
|
const rootNodes = rootRenderNodes(view);
|
||||||
@ -79,7 +68,7 @@ export function main() {
|
|||||||
it('should select root elements based on a node', () => {
|
it('should select root elements based on a node', () => {
|
||||||
const view = createRootView(
|
const view = createRootView(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 0, 'div'),
|
||||||
]),
|
]),
|
||||||
{}, [], rootNode);
|
{}, [], rootNode);
|
||||||
const rootNodes = rootRenderNodes(view);
|
const rootNodes = rootRenderNodes(view);
|
||||||
@ -87,9 +76,9 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should set attributes on the root node', () => {
|
it('should set attributes on the root node', () => {
|
||||||
const view = createRootView(
|
createRootView(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'div', [['a', 'b']]),
|
elementDef(0, NodeFlags.None, null, null, 0, 'div', [['a', 'b']]),
|
||||||
]),
|
]),
|
||||||
{}, [], rootNode);
|
{}, [], rootNode);
|
||||||
expect(rootNode.getAttribute('a')).toBe('b');
|
expect(rootNode.getAttribute('a')).toBe('b');
|
||||||
@ -97,9 +86,9 @@ export function main() {
|
|||||||
|
|
||||||
it('should clear the content of the root node', () => {
|
it('should clear the content of the root node', () => {
|
||||||
rootNode.appendChild(document.createElement('div'));
|
rootNode.appendChild(document.createElement('div'));
|
||||||
const view = createRootView(
|
createRootView(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'div', [['a', 'b']]),
|
elementDef(0, NodeFlags.None, null, null, 0, 'div', [['a', 'b']]),
|
||||||
]),
|
]),
|
||||||
{}, [], rootNode);
|
{}, [], rootNode);
|
||||||
expect(rootNode.childNodes.length).toBe(0);
|
expect(rootNode.childNodes.length).toBe(0);
|
||||||
@ -121,12 +110,12 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(
|
const {view, rootNodes} = createAndGetRootNodes(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(NodeFlags.None, null!, null!, 1, 'div', null!, null!, null!, null!, () => compViewDef(
|
elementDef(0, NodeFlags.None, null, null, 1, 'div', null, null, null, null, () => compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null!, null!, 0, 'span', null!, [[BindingFlags.TypeElementAttribute, 'a', SecurityContext.NONE]]),
|
elementDef(0, NodeFlags.None, null, null, 0, 'span', null, [[BindingFlags.TypeElementAttribute, 'a', SecurityContext.NONE]]),
|
||||||
], null!, update
|
], null, update
|
||||||
)),
|
)),
|
||||||
directiveDef(NodeFlags.Component, null!, 0, AComp, []),
|
directiveDef(1, NodeFlags.Component, null, 0, AComp, []),
|
||||||
]));
|
]));
|
||||||
const compView = asElementData(view, 0).componentView;
|
const compView = asElementData(view, 0).componentView;
|
||||||
|
|
||||||
@ -155,13 +144,13 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => compViewDef(
|
() => compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 0, 'span'),
|
||||||
],
|
],
|
||||||
update)),
|
update)),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, AComp, [], null !, null !),
|
directiveDef(1, NodeFlags.Component, null, 0, AComp, [], null, null),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const compView = asElementData(view, 0).componentView;
|
const compView = asElementData(view, 0).componentView;
|
||||||
@ -192,17 +181,17 @@ export function main() {
|
|||||||
const {view} = createAndGetRootNodes(compViewDef(
|
const {view} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => {
|
() => {
|
||||||
return compViewDef(
|
return compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'span', null !, null !,
|
0, NodeFlags.None, null, null, 0, 'span', null, null,
|
||||||
[[null !, 'click']]),
|
[[null !, 'click']]),
|
||||||
],
|
],
|
||||||
update, null !, ViewFlags.OnPush);
|
update, null, ViewFlags.OnPush);
|
||||||
}),
|
}),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, AComp, [], {a: [0, 'a']}),
|
directiveDef(1, NodeFlags.Component, null, 0, AComp, [], {a: [0, 'a']}),
|
||||||
],
|
],
|
||||||
(check, view) => { check(view, 1, ArgumentType.Inline, compInputValue); }));
|
(check, view) => { check(view, 1, ArgumentType.Inline, compInputValue); }));
|
||||||
|
|
||||||
@ -245,18 +234,16 @@ export function main() {
|
|||||||
const update = jasmine.createSpy('updater');
|
const update = jasmine.createSpy('updater');
|
||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null!, null!, 1, 'div', null!, null!, null!, null!, () => compViewDef(
|
elementDef(
|
||||||
[
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
elementDef(NodeFlags.None, null!, null!, 0, 'span', null!, [[BindingFlags.TypeElementAttribute, 'a', SecurityContext.NONE]]),
|
() => compViewDef(
|
||||||
],
|
[elementDef(
|
||||||
null!, update)),
|
0, NodeFlags.None, null, null, 0, 'span', null,
|
||||||
directiveDef(
|
[[BindingFlags.TypeElementAttribute, 'a', SecurityContext.NONE]])],
|
||||||
NodeFlags.Component, null!, 0, AComp, [], null!, null!,
|
null, update)),
|
||||||
),
|
directiveDef(1, NodeFlags.Component, null, 0, AComp, [], null, null, ),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const compView = asElementData(view, 0).componentView;
|
|
||||||
|
|
||||||
update.and.callFake((check: NodeCheckFn, view: ViewData) => { throw new Error('Test'); });
|
update.and.callFake((check: NodeCheckFn, view: ViewData) => { throw new Error('Test'); });
|
||||||
expect(() => Services.checkAndUpdateView(view)).toThrowError('Test');
|
expect(() => Services.checkAndUpdateView(view)).toThrowError('Test');
|
||||||
expect(update).toHaveBeenCalled();
|
expect(update).toHaveBeenCalled();
|
||||||
@ -280,12 +267,12 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.OnDestroy, null !, 0, ChildProvider, [])
|
directiveDef(1, NodeFlags.OnDestroy, null, 0, ChildProvider, [])
|
||||||
])),
|
])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, AComp, [], null !, null !, ),
|
directiveDef(1, NodeFlags.Component, null, 0, AComp, [], null, null, ),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
Services.destroyView(view);
|
Services.destroyView(view);
|
||||||
@ -294,11 +281,8 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw on dirty checking destroyed views', () => {
|
it('should throw on dirty checking destroyed views', () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(
|
||||||
[
|
compViewDef([elementDef(0, NodeFlags.None, null, null, 0, 'div')]));
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'div'),
|
|
||||||
],
|
|
||||||
(view) => {}));
|
|
||||||
|
|
||||||
Services.destroyView(view);
|
Services.destroyView(view);
|
||||||
|
|
||||||
|
@ -6,13 +6,14 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ErrorHandler, Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
import {ErrorHandler, SecurityContext, getDebugNode} from '@angular/core';
|
||||||
import {getDebugContext} from '@angular/core/src/errors';
|
import {getDebugContext} from '@angular/core/src/errors';
|
||||||
import {ArgumentType, BindingFlags, DebugContext, NodeDef, NodeFlags, OutputType, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, elementDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {BindingFlags, NodeFlags, Services, ViewData, ViewDefinition, asElementData, elementDef} from '@angular/core/src/view/index';
|
||||||
import {TestBed} from '@angular/core/testing';
|
import {TestBed} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
import {ARG_TYPE_VALUES, callMostRecentEventListenerHandler, checkNodeInlineOrDynamic, createRootView, isBrowser, recordNodeToRemove} from './helper';
|
import {ARG_TYPE_VALUES, callMostRecentEventListenerHandler, checkNodeInlineOrDynamic, compViewDef, createAndGetRootNodes, isBrowser, recordNodeToRemove} from './helper';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,23 +25,11 @@ const removeEventListener = '__zone_symbol__removeEventListener';
|
|||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`View Elements`, () => {
|
describe(`View Elements`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(
|
|
||||||
viewDef: ViewDefinition, context?: any): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef, context);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
it('should create elements without parents', () => {
|
it('should create elements without parents', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span')
|
elementDef(0, NodeFlags.None, null, null, 0, 'span')
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(1);
|
expect(rootNodes.length).toBe(1);
|
||||||
expect(getDOM().nodeName(rootNodes[0]).toLowerCase()).toBe('span');
|
expect(getDOM().nodeName(rootNodes[0]).toLowerCase()).toBe('span');
|
||||||
@ -48,16 +37,16 @@ export function main() {
|
|||||||
|
|
||||||
it('should create views with multiple root elements', () => {
|
it('should create views with multiple root elements', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 0, 'span'),
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span')
|
elementDef(1, NodeFlags.None, null, null, 0, 'span'),
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(2);
|
expect(rootNodes.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create elements with parents', () => {
|
it('should create elements with parents', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span'),
|
elementDef(1, NodeFlags.None, null, null, 0, 'span'),
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(1);
|
expect(rootNodes.length).toBe(1);
|
||||||
const spanEl = getDOM().childNodes(rootNodes[0])[0];
|
const spanEl = getDOM().childNodes(rootNodes[0])[0];
|
||||||
@ -66,7 +55,7 @@ export function main() {
|
|||||||
|
|
||||||
it('should set fixed attributes', () => {
|
it('should set fixed attributes', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'div', [['title', 'a']]),
|
elementDef(0, NodeFlags.None, null, null, 0, 'div', [['title', 'a']]),
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(1);
|
expect(rootNodes.length).toBe(1);
|
||||||
expect(getDOM().getAttribute(rootNodes[0], 'title')).toBe('a');
|
expect(getDOM().getAttribute(rootNodes[0], 'title')).toBe('a');
|
||||||
@ -75,7 +64,7 @@ export function main() {
|
|||||||
it('should add debug information to the renderer', () => {
|
it('should add debug information to the renderer', () => {
|
||||||
const someContext = new Object();
|
const someContext = new Object();
|
||||||
const {view, rootNodes} = createAndGetRootNodes(
|
const {view, rootNodes} = createAndGetRootNodes(
|
||||||
compViewDef([elementDef(NodeFlags.None, null !, null !, 0, 'div')]), someContext);
|
compViewDef([elementDef(0, NodeFlags.None, null, null, 0, 'div')]), someContext);
|
||||||
expect(getDebugNode(rootNodes[0]) !.nativeNode).toBe(asElementData(view, 0).renderElement);
|
expect(getDebugNode(rootNodes[0]) !.nativeNode).toBe(asElementData(view, 0).renderElement);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -87,13 +76,13 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'input', null !,
|
0, NodeFlags.None, null, null, 0, 'input', null,
|
||||||
[
|
[
|
||||||
[BindingFlags.TypeProperty, 'title', SecurityContext.NONE],
|
[BindingFlags.TypeProperty, 'title', SecurityContext.NONE],
|
||||||
[BindingFlags.TypeProperty, 'value', SecurityContext.NONE]
|
[BindingFlags.TypeProperty, 'value', SecurityContext.NONE],
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
null !, (check, view) => {
|
null, (check, view) => {
|
||||||
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, ['v1', 'v2']);
|
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, ['v1', 'v2']);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -112,13 +101,13 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'div', null !,
|
0, NodeFlags.None, null, null, 0, 'div', null,
|
||||||
[
|
[
|
||||||
[BindingFlags.TypeElementAttribute, 'a1', SecurityContext.NONE],
|
[BindingFlags.TypeElementAttribute, 'a1', SecurityContext.NONE],
|
||||||
[BindingFlags.TypeElementAttribute, 'a2', SecurityContext.NONE]
|
[BindingFlags.TypeElementAttribute, 'a2', SecurityContext.NONE],
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
null !, (check, view) => {
|
null, (check, view) => {
|
||||||
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, ['v1', 'v2']);
|
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, ['v1', 'v2']);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -137,10 +126,10 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'div', null !,
|
0, NodeFlags.None, null, null, 0, 'div', null,
|
||||||
[
|
[
|
||||||
[BindingFlags.TypeElementClass, 'c1', null !],
|
[BindingFlags.TypeElementClass, 'c1', null],
|
||||||
[BindingFlags.TypeElementClass, 'c2', null !]
|
[BindingFlags.TypeElementClass, 'c2', null],
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
@ -162,13 +151,13 @@ export function main() {
|
|||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'div', null !,
|
0, NodeFlags.None, null, null, 0, 'div', null,
|
||||||
[
|
[
|
||||||
[BindingFlags.TypeElementStyle, 'width', 'px'],
|
[BindingFlags.TypeElementStyle, 'width', 'px'],
|
||||||
[BindingFlags.TypeElementStyle, 'color', null !]
|
[BindingFlags.TypeElementStyle, 'color', null],
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
null !, (check, view) => {
|
null, (check, view) => {
|
||||||
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, [10, 'red']);
|
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, [10, 'red']);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -200,7 +189,7 @@ export function main() {
|
|||||||
const removeListenerSpy =
|
const removeListenerSpy =
|
||||||
spyOn(HTMLElement.prototype, removeEventListener).and.callThrough();
|
spyOn(HTMLElement.prototype, removeEventListener).and.callThrough();
|
||||||
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'button', null !, null !, [[null !, 'click']],
|
0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
|
||||||
handleEventSpy)]));
|
handleEventSpy)]));
|
||||||
|
|
||||||
rootNodes[0].click();
|
rootNodes[0].click();
|
||||||
@ -221,8 +210,8 @@ export function main() {
|
|||||||
const addListenerSpy = spyOn(window, addEventListener);
|
const addListenerSpy = spyOn(window, addEventListener);
|
||||||
const removeListenerSpy = spyOn(window, removeEventListener);
|
const removeListenerSpy = spyOn(window, removeEventListener);
|
||||||
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'button', null !, null !,
|
0, NodeFlags.None, null, null, 0, 'button', null, null, [['window', 'windowClick']],
|
||||||
[['window', 'windowClick']], handleEventSpy)]));
|
handleEventSpy)]));
|
||||||
|
|
||||||
expect(addListenerSpy).toHaveBeenCalled();
|
expect(addListenerSpy).toHaveBeenCalled();
|
||||||
expect(addListenerSpy.calls.mostRecent().args[0]).toBe('windowClick');
|
expect(addListenerSpy.calls.mostRecent().args[0]).toBe('windowClick');
|
||||||
@ -244,7 +233,7 @@ export function main() {
|
|||||||
const addListenerSpy = spyOn(document, addEventListener);
|
const addListenerSpy = spyOn(document, addEventListener);
|
||||||
const removeListenerSpy = spyOn(document, removeEventListener);
|
const removeListenerSpy = spyOn(document, removeEventListener);
|
||||||
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'button', null !, null !,
|
0, NodeFlags.None, null, null, 0, 'button', null, null,
|
||||||
[['document', 'documentClick']], handleEventSpy)]));
|
[['document', 'documentClick']], handleEventSpy)]));
|
||||||
|
|
||||||
expect(addListenerSpy).toHaveBeenCalled();
|
expect(addListenerSpy).toHaveBeenCalled();
|
||||||
@ -267,7 +256,7 @@ export function main() {
|
|||||||
let preventDefaultSpy: jasmine.Spy = undefined !;
|
let preventDefaultSpy: jasmine.Spy = undefined !;
|
||||||
|
|
||||||
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'button', null !, null !, [[null !, 'click']],
|
0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
|
||||||
(view, eventName, event) => {
|
(view, eventName, event) => {
|
||||||
preventDefaultSpy = spyOn(event, 'preventDefault').and.callThrough();
|
preventDefaultSpy = spyOn(event, 'preventDefault').and.callThrough();
|
||||||
return eventHandlerResult;
|
return eventHandlerResult;
|
||||||
@ -294,7 +283,7 @@ export function main() {
|
|||||||
const handleErrorSpy = spyOn(TestBed.get(ErrorHandler), 'handleError');
|
const handleErrorSpy = spyOn(TestBed.get(ErrorHandler), 'handleError');
|
||||||
const addListenerSpy = spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
|
const addListenerSpy = spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
|
||||||
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'button', null !, null !, [[null !, 'click']],
|
0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
|
||||||
() => { throw new Error('Test'); })]));
|
() => { throw new Error('Test'); })]));
|
||||||
|
|
||||||
callMostRecentEventListenerHandler(addListenerSpy, 'SomeEvent');
|
callMostRecentEventListenerHandler(addListenerSpy, 'SomeEvent');
|
||||||
|
@ -6,31 +6,14 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation} from '@angular/core';
|
import {SecurityContext} from '@angular/core';
|
||||||
import {ArgumentType, BindingFlags, NodeCheckFn, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, attachEmbeddedView, detachEmbeddedView, directiveDef, elementDef, moveEmbeddedView, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {ArgumentType, BindingFlags, NodeCheckFn, NodeFlags, Services, ViewData, anchorDef, asElementData, attachEmbeddedView, detachEmbeddedView, directiveDef, elementDef, moveEmbeddedView, rootRenderNodes} from '@angular/core/src/view/index';
|
||||||
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';
|
||||||
|
|
||||||
import {createEmbeddedView, createRootView, isBrowser} from './helper';
|
import {compViewDef, compViewDefFactory, createAndGetRootNodes, createEmbeddedView} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`Embedded Views`, () => {
|
describe(`Embedded Views`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function embeddedViewDef(nodes: NodeDef[], update?: ViewUpdateFn): ViewDefinitionFactory {
|
|
||||||
return () => viewDef(ViewFlags.None, nodes, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(
|
|
||||||
viewDef: ViewDefinition, context: any = null): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef, context);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should create embedded views with the right context', () => {
|
it('should create embedded views with the right context', () => {
|
||||||
const parentContext = new Object();
|
const parentContext = new Object();
|
||||||
@ -38,10 +21,10 @@ export function main() {
|
|||||||
|
|
||||||
const {view: parentView} = createAndGetRootNodes(
|
const {view: parentView} = createAndGetRootNodes(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.EmbeddedViews, null !, null !, 0, null !,
|
NodeFlags.EmbeddedViews, null, null, 0, null,
|
||||||
embeddedViewDef([elementDef(NodeFlags.None, null !, null !, 0, 'span')])),
|
compViewDefFactory([elementDef(0, NodeFlags.None, null, null, 0, 'span')])),
|
||||||
]),
|
]),
|
||||||
parentContext);
|
parentContext);
|
||||||
|
|
||||||
@ -52,14 +35,13 @@ export function main() {
|
|||||||
|
|
||||||
it('should attach and detach embedded views', () => {
|
it('should attach and detach embedded views', () => {
|
||||||
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'div'),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'child0']])
|
elementDef(0, NodeFlags.None, null, null, 0, 'span', [['name', 'child0']])
|
||||||
])),
|
])),
|
||||||
anchorDef(
|
anchorDef(NodeFlags.None, null, null, 0, null, compViewDefFactory([elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, null !,
|
0, NodeFlags.None, null, null, 0, 'span',
|
||||||
embeddedViewDef(
|
[['name', 'child1']])]))
|
||||||
[elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'child1']])]))
|
|
||||||
]));
|
]));
|
||||||
const viewContainerData = asElementData(parentView, 1);
|
const viewContainerData = asElementData(parentView, 1);
|
||||||
const rf = parentView.root.rendererFactory;
|
const rf = parentView.root.rendererFactory;
|
||||||
@ -86,14 +68,13 @@ export function main() {
|
|||||||
|
|
||||||
it('should move embedded views', () => {
|
it('should move embedded views', () => {
|
||||||
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'div'),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'child0']])
|
elementDef(0, NodeFlags.None, null, null, 0, 'span', [['name', 'child0']])
|
||||||
])),
|
])),
|
||||||
anchorDef(
|
anchorDef(NodeFlags.None, null, null, 0, null, compViewDefFactory([elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, null !,
|
0, NodeFlags.None, null, null, 0, 'span',
|
||||||
embeddedViewDef(
|
[['name', 'child1']])]))
|
||||||
[elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'child1']])]))
|
|
||||||
]));
|
]));
|
||||||
const viewContainerData = asElementData(parentView, 1);
|
const viewContainerData = asElementData(parentView, 1);
|
||||||
|
|
||||||
@ -115,10 +96,10 @@ export function main() {
|
|||||||
|
|
||||||
it('should include embedded views in root nodes', () => {
|
it('should include embedded views in root nodes', () => {
|
||||||
const {view: parentView} = createAndGetRootNodes(compViewDef([
|
const {view: parentView} = createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'child0']])
|
elementDef(0, NodeFlags.None, null, null, 0, 'span', [['name', 'child0']])
|
||||||
])),
|
])),
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'after']])
|
elementDef(1, NodeFlags.None, null, null, 0, 'span', [['name', 'after']])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const childView0 = createEmbeddedView(parentView, parentView.def.nodes[0]);
|
const childView0 = createEmbeddedView(parentView, parentView.def.nodes[0]);
|
||||||
@ -138,12 +119,12 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view: parentView, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.EmbeddedViews, null !, null !, 0, null !,
|
NodeFlags.EmbeddedViews, null, null, 0, null,
|
||||||
embeddedViewDef(
|
compViewDefFactory(
|
||||||
[elementDef(
|
[elementDef(
|
||||||
NodeFlags.None, null !, null !, 0, 'span', null !,
|
0, NodeFlags.None, null, null, 0, 'span', null,
|
||||||
[[BindingFlags.TypeElementAttribute, 'name', SecurityContext.NONE]])],
|
[[BindingFlags.TypeElementAttribute, 'name', SecurityContext.NONE]])],
|
||||||
update))
|
update))
|
||||||
]));
|
]));
|
||||||
@ -175,10 +156,10 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {view: parentView} = createAndGetRootNodes(compViewDef([
|
const {view: parentView} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.OnDestroy, null !, 0, ChildProvider, [])
|
directiveDef(1, NodeFlags.OnDestroy, null, 0, ChildProvider, [])
|
||||||
]))
|
]))
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
@ -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 {Injector, NgModuleRef, RootRenderer, Sanitizer} from '@angular/core';
|
import {Injector, NgModuleRef} from '@angular/core';
|
||||||
import {ArgumentType, NodeCheckFn, NodeDef, RootData, Services, ViewData, ViewDefinition, initServicesIfNeeded} from '@angular/core/src/view/index';
|
import {ArgumentType, NodeCheckFn, NodeDef, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewUpdateFn, initServicesIfNeeded, rootRenderNodes, viewDef} from '@angular/core/src/view/index';
|
||||||
import {TestBed} from '@angular/core/testing';
|
import {TestBed} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -41,6 +41,39 @@ export function createEmbeddedView(parent: ViewData, anchorDef: NodeDef, context
|
|||||||
return Services.createEmbeddedView(parent, anchorDef, anchorDef.element !.template !, context);
|
return Services.createEmbeddedView(parent, anchorDef, anchorDef.element !.template !, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function compViewDef(
|
||||||
|
nodes: NodeDef[], updateDirectives?: null | ViewUpdateFn, updateRenderer?: null | ViewUpdateFn,
|
||||||
|
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
||||||
|
const def = viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
||||||
|
|
||||||
|
def.nodes.forEach((node, index) => {
|
||||||
|
if (node.nodeIndex !== index) {
|
||||||
|
throw new Error('nodeIndex should be the same as the index of the node');
|
||||||
|
}
|
||||||
|
|
||||||
|
// This check should be removed when we start reordering nodes at runtime
|
||||||
|
if (node.checkIndex > -1 && node.checkIndex !== node.nodeIndex) {
|
||||||
|
throw new Error(
|
||||||
|
`nodeIndex and checkIndex should be the same, got ${node.nodeIndex} !== ${node.checkIndex}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function compViewDefFactory(
|
||||||
|
nodes: NodeDef[], updateDirectives?: null | ViewUpdateFn, updateRenderer?: null | ViewUpdateFn,
|
||||||
|
viewFlags: ViewFlags = ViewFlags.None): ViewDefinitionFactory {
|
||||||
|
return () => compViewDef(nodes, updateDirectives, updateRenderer, viewFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAndGetRootNodes(
|
||||||
|
viewDef: ViewDefinition, ctx?: any): {rootNodes: any[], view: ViewData} {
|
||||||
|
const view = createRootView(viewDef, ctx);
|
||||||
|
const rootNodes = rootRenderNodes(view);
|
||||||
|
return {rootNodes, view};
|
||||||
|
}
|
||||||
|
|
||||||
let removeNodes: Node[];
|
let removeNodes: Node[];
|
||||||
|
|
||||||
beforeEach(() => { removeNodes = []; });
|
beforeEach(() => { removeNodes = []; });
|
||||||
|
@ -10,30 +10,21 @@ import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext,
|
|||||||
import {DebugContext, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, attachEmbeddedView, detachEmbeddedView, directiveDef, elementDef, ngContentDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {DebugContext, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, attachEmbeddedView, detachEmbeddedView, directiveDef, elementDef, ngContentDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
import {createEmbeddedView, createRootView, isBrowser} from './helper';
|
import {compViewDef, compViewDefFactory, createEmbeddedView, createRootView, isBrowser} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`View NgContent`, () => {
|
describe(`View NgContent`, () => {
|
||||||
function compViewDef(
|
function hostElDef(
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
checkIndex: number, contentNodes: NodeDef[], viewNodes: NodeDef[]): NodeDef[] {
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function embeddedViewDef(nodes: NodeDef[], update?: ViewUpdateFn): ViewDefinitionFactory {
|
|
||||||
return () => viewDef(ViewFlags.None, nodes, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hostElDef(contentNodes: NodeDef[], viewNodes: NodeDef[]): NodeDef[] {
|
|
||||||
class AComp {}
|
class AComp {}
|
||||||
|
|
||||||
const aCompViewDef = compViewDef(viewNodes);
|
const aCompViewDef = compViewDef(viewNodes);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1 + contentNodes.length, 'acomp', null !, null !,
|
checkIndex, NodeFlags.None, null, null, 1 + contentNodes.length, 'acomp', null, null,
|
||||||
null !, null !, () => aCompViewDef),
|
null, null, () => aCompViewDef),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, AComp, []), ...contentNodes
|
directiveDef(checkIndex + 1, NodeFlags.Component, null, 0, AComp, []), ...contentNodes
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,15 +37,15 @@ export function main() {
|
|||||||
|
|
||||||
it('should create ng-content nodes without parents', () => {
|
it('should create ng-content nodes without parents', () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(
|
const {view, rootNodes} = createAndGetRootNodes(
|
||||||
compViewDef(hostElDef([textDef(0, ['a'])], [ngContentDef(null !, 0)])));
|
compViewDef(hostElDef(0, [textDef(2, 0, ['a'])], [ngContentDef(null, 0)])));
|
||||||
|
|
||||||
expect(getDOM().firstChild(rootNodes[0])).toBe(asTextData(view, 2).renderText);
|
expect(getDOM().firstChild(rootNodes[0])).toBe(asTextData(view, 2).renderText);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create views with multiple root ng-content nodes', () => {
|
it('should create views with multiple root ng-content nodes', () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef(
|
||||||
[textDef(0, ['a']), textDef(1, ['b'])],
|
0, [textDef(2, 0, ['a']), textDef(3, 1, ['b'])],
|
||||||
[ngContentDef(null !, 0), ngContentDef(null !, 1)])));
|
[ngContentDef(null, 0), ngContentDef(null, 1)])));
|
||||||
|
|
||||||
expect(getDOM().childNodes(rootNodes[0])[0]).toBe(asTextData(view, 2).renderText);
|
expect(getDOM().childNodes(rootNodes[0])[0]).toBe(asTextData(view, 2).renderText);
|
||||||
expect(getDOM().childNodes(rootNodes[0])[1]).toBe(asTextData(view, 3).renderText);
|
expect(getDOM().childNodes(rootNodes[0])[1]).toBe(asTextData(view, 3).renderText);
|
||||||
@ -62,8 +53,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should create ng-content nodes with parents', () => {
|
it('should create ng-content nodes with parents', () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef(
|
||||||
[textDef(0, ['a'])],
|
0, [textDef(2, 0, ['a'])],
|
||||||
[elementDef(NodeFlags.None, null !, null !, 1, 'div'), ngContentDef(null !, 0)])));
|
[elementDef(0, NodeFlags.None, null, null, 1, 'div'), ngContentDef(null, 0)])));
|
||||||
|
|
||||||
expect(getDOM().firstChild(getDOM().firstChild(rootNodes[0])))
|
expect(getDOM().firstChild(getDOM().firstChild(rootNodes[0])))
|
||||||
.toBe(asTextData(view, 2).renderText);
|
.toBe(asTextData(view, 2).renderText);
|
||||||
@ -71,8 +62,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should reproject ng-content nodes', () => {
|
it('should reproject ng-content nodes', () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
hostElDef([textDef(0, ['a'])], hostElDef([ngContentDef(0, 0)], [
|
hostElDef(0, [textDef(2, 0, ['a'])], hostElDef(0, [ngContentDef(0, 0)], [
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'), ngContentDef(null !, 0)
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'), ngContentDef(null, 0)
|
||||||
]))));
|
]))));
|
||||||
expect(getDOM().firstChild(getDOM().firstChild(getDOM().firstChild(rootNodes[0]))))
|
expect(getDOM().firstChild(getDOM().firstChild(getDOM().firstChild(rootNodes[0]))))
|
||||||
.toBe(asTextData(view, 2).renderText);
|
.toBe(asTextData(view, 2).renderText);
|
||||||
@ -88,18 +79,18 @@ export function main() {
|
|||||||
const {view, rootNodes} =
|
const {view, rootNodes} =
|
||||||
createAndGetRootNodes(
|
createAndGetRootNodes(
|
||||||
compViewDef(
|
compViewDef(
|
||||||
hostElDef(
|
hostElDef(0,
|
||||||
[
|
[
|
||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.EmbeddedViews, null !, 0, 1, null !,
|
NodeFlags.EmbeddedViews, null, 0, 1, null,
|
||||||
embeddedViewDef([textDef(null !, ['a'])])),
|
compViewDefFactory([textDef(0, null, ['a'])])),
|
||||||
directiveDef(
|
directiveDef(3,
|
||||||
NodeFlags.None, null !, 0, CreateViewService,
|
NodeFlags.None, null, 0, CreateViewService,
|
||||||
[TemplateRef, ViewContainerRef])
|
[TemplateRef, ViewContainerRef]),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
ngContentDef(null !, 0)
|
ngContentDef(null, 0),
|
||||||
])));
|
])));
|
||||||
|
|
||||||
const anchor = asElementData(view, 2);
|
const anchor = asElementData(view, 2);
|
||||||
@ -111,12 +102,13 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should include projected nodes when attaching / detaching embedded views', () => {
|
it('should include projected nodes when attaching / detaching embedded views', () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef([textDef(0, ['a'])], [
|
const {view, rootNodes} =
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
createAndGetRootNodes(compViewDef(hostElDef(0, [textDef(2, 0, ['a'])], [
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, 0, 0, null !, embeddedViewDef([
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
ngContentDef(null !, 0),
|
anchorDef(NodeFlags.EmbeddedViews, null, 0, 0, null, compViewDefFactory([
|
||||||
|
ngContentDef(null, 0),
|
||||||
// The anchor would be added by the compiler after the ngContent
|
// The anchor would be added by the compiler after the ngContent
|
||||||
anchorDef(NodeFlags.None, null !, null !, 0),
|
anchorDef(NodeFlags.None, null, null, 0),
|
||||||
])),
|
])),
|
||||||
])));
|
])));
|
||||||
|
|
||||||
@ -139,7 +131,7 @@ export function main() {
|
|||||||
it('should use root projectable nodes', () => {
|
it('should use root projectable nodes', () => {
|
||||||
const projectableNodes = [[document.createTextNode('a')], [document.createTextNode('b')]];
|
const projectableNodes = [[document.createTextNode('a')], [document.createTextNode('b')]];
|
||||||
const view = createRootView(
|
const view = createRootView(
|
||||||
compViewDef(hostElDef([], [ngContentDef(null !, 0), ngContentDef(null !, 1)])), {},
|
compViewDef(hostElDef(0, [], [ngContentDef(null, 0), ngContentDef(null, 1)])), {},
|
||||||
projectableNodes);
|
projectableNodes);
|
||||||
const rootNodes = rootRenderNodes(view);
|
const rootNodes = rootRenderNodes(view);
|
||||||
|
|
||||||
|
@ -6,31 +6,16 @@
|
|||||||
* 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, ChangeDetectorRef, DoCheck, ElementRef, ErrorHandler, EventEmitter, Injector, OnChanges, OnDestroy, OnInit, RenderComponentType, Renderer, Renderer2, RootRenderer, Sanitizer, SecurityContext, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectorRef, DoCheck, ElementRef, ErrorHandler, EventEmitter, Injector, OnChanges, OnDestroy, OnInit, Renderer, Renderer2, SimpleChange, TemplateRef, ViewContainerRef,} from '@angular/core';
|
||||||
import {getDebugContext} from '@angular/core/src/errors';
|
import {getDebugContext} from '@angular/core/src/errors';
|
||||||
import {ArgumentType, BindingFlags, DebugContext, DepFlags, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, directiveDef, elementDef, providerDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {ArgumentType, DepFlags, NodeFlags, Services, anchorDef, asElementData, directiveDef, elementDef, providerDef, textDef} from '@angular/core/src/view/index';
|
||||||
import {TestBed, inject, withModule} from '@angular/core/testing';
|
import {TestBed, withModule} from '@angular/core/testing';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
|
|
||||||
import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, createRootView, isBrowser} from './helper';
|
import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, createRootView, createAndGetRootNodes, compViewDef, compViewDefFactory} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`View Providers`, () => {
|
describe(`View Providers`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function embeddedViewDef(nodes: NodeDef[], update?: ViewUpdateFn): ViewDefinitionFactory {
|
|
||||||
return () => viewDef(ViewFlags.None, nodes, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(viewDef: ViewDefinition): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef, {});
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
let instance: SomeService;
|
let instance: SomeService;
|
||||||
@ -43,8 +28,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should create providers eagerly', () => {
|
it('should create providers eagerly', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, [])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance instanceof SomeService).toBe(true);
|
expect(instance instanceof SomeService).toBe(true);
|
||||||
@ -57,11 +42,11 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(
|
providerDef(
|
||||||
NodeFlags.TypeClassProvider | NodeFlags.LazyProvider, null !, LazyService,
|
NodeFlags.TypeClassProvider | NodeFlags.LazyProvider, null, LazyService, LazyService,
|
||||||
LazyService, []),
|
[]),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [Injector])
|
directiveDef(2, NodeFlags.None, null, 0, SomeService, [Injector])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(lazy).toBeUndefined();
|
expect(lazy).toBeUndefined();
|
||||||
@ -71,9 +56,9 @@ export function main() {
|
|||||||
|
|
||||||
it('should create value providers', () => {
|
it('should create value providers', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.TypeValueProvider, null !, 'someToken', 'someValue', []),
|
providerDef(NodeFlags.TypeValueProvider, null, 'someToken', 'someValue', []),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, ['someToken']),
|
directiveDef(2, NodeFlags.None, null, 0, SomeService, ['someToken']),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep).toBe('someValue');
|
expect(instance.dep).toBe('someValue');
|
||||||
@ -83,9 +68,9 @@ export function main() {
|
|||||||
function someFactory() { return 'someValue'; }
|
function someFactory() { return 'someValue'; }
|
||||||
|
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.TypeFactoryProvider, null !, 'someToken', someFactory, []),
|
providerDef(NodeFlags.TypeFactoryProvider, null, 'someToken', someFactory, []),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, ['someToken']),
|
directiveDef(2, NodeFlags.None, null, 0, SomeService, ['someToken']),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep).toBe('someValue');
|
expect(instance.dep).toBe('someValue');
|
||||||
@ -93,12 +78,11 @@ export function main() {
|
|||||||
|
|
||||||
it('should create useExisting providers', () => {
|
it('should create useExisting providers', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 3, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 3, 'span'),
|
||||||
providerDef(NodeFlags.TypeValueProvider, null !, 'someExistingToken', 'someValue', []),
|
providerDef(NodeFlags.TypeValueProvider, null, 'someExistingToken', 'someValue', []),
|
||||||
providerDef(
|
providerDef(
|
||||||
NodeFlags.TypeUseExistingProvider, null !, 'someToken', null !,
|
NodeFlags.TypeUseExistingProvider, null, 'someToken', null, ['someExistingToken']),
|
||||||
['someExistingToken']),
|
directiveDef(3, NodeFlags.None, null, 0, SomeService, ['someToken']),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, ['someToken']),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep).toBe('someValue');
|
expect(instance.dep).toBe('someValue');
|
||||||
@ -114,9 +98,9 @@ export function main() {
|
|||||||
createRootView(
|
createRootView(
|
||||||
compViewDef([
|
compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => compViewDef([textDef(null !, ['a'])])),
|
() => compViewDef([textDef(0, null, ['a'])])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, SomeService, [])
|
directiveDef(1, NodeFlags.Component, null, 0, SomeService, [])
|
||||||
]),
|
]),
|
||||||
TestBed.get(Injector), [], getDOM().createElement('div'));
|
TestBed.get(Injector), [], getDOM().createElement('div'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -134,9 +118,9 @@ export function main() {
|
|||||||
|
|
||||||
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(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, Dep, []),
|
directiveDef(1, NodeFlags.None, null, 0, Dep, []),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [Dep])
|
directiveDef(2, NodeFlags.None, null, 0, SomeService, [Dep])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep instanceof Dep).toBeTruthy();
|
expect(instance.dep instanceof Dep).toBeTruthy();
|
||||||
@ -144,34 +128,38 @@ export function main() {
|
|||||||
|
|
||||||
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(0, NodeFlags.None, null, null, 3, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, Dep, []),
|
directiveDef(1, NodeFlags.None, null, 0, Dep, []),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(2, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [Dep])
|
directiveDef(3, NodeFlags.None, null, 0, SomeService, [Dep])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep instanceof Dep).toBeTruthy();
|
expect(instance.dep instanceof Dep).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not inject deps from sibling root elements', () => {
|
it('should not inject deps from sibling root elements', () => {
|
||||||
const nodes = [
|
const rootElNodes = [
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, Dep, []),
|
directiveDef(1, NodeFlags.None, null, 0, Dep, []),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(2, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [Dep])
|
directiveDef(3, NodeFlags.None, null, 0, SomeService, [Dep]),
|
||||||
];
|
];
|
||||||
|
|
||||||
// root elements
|
expect(() => createAndGetRootNodes(compViewDef(rootElNodes)))
|
||||||
expect(() => createAndGetRootNodes(compViewDef(nodes)))
|
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
'StaticInjectorError[Dep]: \n' +
|
'StaticInjectorError[Dep]: \n' +
|
||||||
' StaticInjectorError[Dep]: \n' +
|
' StaticInjectorError[Dep]: \n' +
|
||||||
' NullInjectorError: No provider for Dep!');
|
' NullInjectorError: No provider for Dep!');
|
||||||
|
|
||||||
// non root elements
|
const nonRootElNodes = [
|
||||||
expect(
|
elementDef(0, NodeFlags.None, null, null, 4, 'span'),
|
||||||
() => createAndGetRootNodes(compViewDef(
|
elementDef(1, NodeFlags.None, null, null, 1, 'span'),
|
||||||
[elementDef(NodeFlags.None, null !, null !, 4, 'span')].concat(nodes))))
|
directiveDef(2, NodeFlags.None, null, 0, Dep, []),
|
||||||
|
elementDef(3, NodeFlags.None, null, null, 1, 'span'),
|
||||||
|
directiveDef(4, NodeFlags.None, null, 0, SomeService, [Dep]),
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(() => createAndGetRootNodes(compViewDef(nonRootElNodes)))
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
'StaticInjectorError[Dep]: \n' +
|
'StaticInjectorError[Dep]: \n' +
|
||||||
' StaticInjectorError[Dep]: \n' +
|
' StaticInjectorError[Dep]: \n' +
|
||||||
@ -181,12 +169,12 @@ export function main() {
|
|||||||
it('should inject from a parent element in a parent view', () => {
|
it('should inject from a parent element in a parent view', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [Dep])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, [Dep])
|
||||||
])),
|
])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, Dep, []),
|
directiveDef(1, NodeFlags.Component, null, 0, Dep, []),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep instanceof Dep).toBeTruthy();
|
expect(instance.dep instanceof Dep).toBeTruthy();
|
||||||
@ -194,8 +182,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should throw for missing dependencies', () => {
|
it('should throw for missing dependencies', () => {
|
||||||
expect(() => createAndGetRootNodes(compViewDef([
|
expect(() => createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, ['nonExistingDep'])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, ['nonExistingDep'])
|
||||||
])))
|
])))
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
'StaticInjectorError[nonExistingDep]: \n' +
|
'StaticInjectorError[nonExistingDep]: \n' +
|
||||||
@ -205,21 +193,22 @@ export function main() {
|
|||||||
|
|
||||||
it('should use null for optional missing dependencies', () => {
|
it('should use null for optional missing dependencies', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.None, null !, 0, SomeService, [[DepFlags.Optional, 'nonExistingDep']])
|
1, NodeFlags.None, null, 0, SomeService,
|
||||||
|
[[DepFlags.Optional, 'nonExistingDep']])
|
||||||
]));
|
]));
|
||||||
expect(instance.dep).toBe(null);
|
expect(instance.dep).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should skip the current element when using SkipSelf', () => {
|
it('should skip the current element when using SkipSelf', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 4, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 4, 'span'),
|
||||||
providerDef(NodeFlags.TypeValueProvider, null !, 'someToken', 'someParentValue', []),
|
providerDef(NodeFlags.TypeValueProvider, null, 'someToken', 'someParentValue', []),
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(2, NodeFlags.None, null, null, 2, 'span'),
|
||||||
providerDef(NodeFlags.TypeValueProvider, null !, 'someToken', 'someValue', []),
|
providerDef(NodeFlags.TypeValueProvider, null, 'someToken', 'someValue', []),
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.None, null !, 0, SomeService, [[DepFlags.SkipSelf, 'someToken']])
|
4, NodeFlags.None, null, 0, SomeService, [[DepFlags.SkipSelf, 'someToken']])
|
||||||
]));
|
]));
|
||||||
expect(instance.dep).toBe('someParentValue');
|
expect(instance.dep).toBe('someParentValue');
|
||||||
});
|
});
|
||||||
@ -227,8 +216,8 @@ export function main() {
|
|||||||
it('should ask the root injector',
|
it('should ask the root injector',
|
||||||
withModule({providers: [{provide: 'rootDep', useValue: 'rootValue'}]}, () => {
|
withModule({providers: [{provide: 'rootDep', useValue: 'rootValue'}]}, () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, ['rootDep'])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, ['rootDep'])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep).toBe('rootValue');
|
expect(instance.dep).toBe('rootValue');
|
||||||
@ -237,8 +226,8 @@ export function main() {
|
|||||||
describe('builtin tokens', () => {
|
describe('builtin tokens', () => {
|
||||||
it('should inject ViewContainerRef', () => {
|
it('should inject ViewContainerRef', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 1),
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 1),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [ViewContainerRef])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ViewContainerRef]),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
||||||
@ -246,10 +235,9 @@ export function main() {
|
|||||||
|
|
||||||
it('should inject TemplateRef', () => {
|
it('should inject TemplateRef', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(
|
anchorDef(NodeFlags.None, null, null, 1, null, compViewDefFactory([anchorDef(
|
||||||
NodeFlags.None, null !, null !, 1, null !,
|
NodeFlags.None, null, null, 0)])),
|
||||||
embeddedViewDef([anchorDef(NodeFlags.None, null !, null !, 0)])),
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, [TemplateRef]),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [TemplateRef])
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
expect(instance.dep.createEmbeddedView).toBeTruthy();
|
||||||
@ -257,8 +245,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should inject ElementRef', () => {
|
it('should inject ElementRef', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [ElementRef])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ElementRef]),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.nativeElement).toBe(asElementData(view, 0).renderElement);
|
expect(instance.dep.nativeElement).toBe(asElementData(view, 0).renderElement);
|
||||||
@ -266,8 +254,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should inject Injector', () => {
|
it('should inject Injector', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [Injector])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, [Injector]),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.get(SomeService)).toBe(instance);
|
expect(instance.dep.get(SomeService)).toBe(instance);
|
||||||
@ -275,8 +263,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should inject ChangeDetectorRef for non component providers', () => {
|
it('should inject ChangeDetectorRef for non component providers', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, SomeService, [ChangeDetectorRef])
|
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ChangeDetectorRef])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep._view).toBe(view);
|
expect(instance.dep._view).toBe(view);
|
||||||
@ -285,11 +273,11 @@ export function main() {
|
|||||||
it('should inject ChangeDetectorRef for component providers', () => {
|
it('should inject ChangeDetectorRef for component providers', () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 0, 'span'),
|
||||||
])),
|
])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, SomeService, [ChangeDetectorRef]),
|
directiveDef(1, NodeFlags.Component, null, 0, SomeService, [ChangeDetectorRef]),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const compView = asElementData(view, 0).componentView;
|
const compView = asElementData(view, 0).componentView;
|
||||||
@ -299,9 +287,9 @@ export function main() {
|
|||||||
it('should inject RendererV1', () => {
|
it('should inject RendererV1', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'span', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'span', null, null, null, null,
|
||||||
() => compViewDef([anchorDef(NodeFlags.None, null !, null !, 0)])),
|
() => compViewDef([anchorDef(NodeFlags.None, null, null, 0)])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, SomeService, [Renderer])
|
directiveDef(1, NodeFlags.Component, null, 0, SomeService, [Renderer])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.createElement).toBeTruthy();
|
expect(instance.dep.createElement).toBeTruthy();
|
||||||
@ -310,9 +298,9 @@ export function main() {
|
|||||||
it('should inject Renderer2', () => {
|
it('should inject Renderer2', () => {
|
||||||
createAndGetRootNodes(compViewDef([
|
createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'span', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'span', null, null, null, null,
|
||||||
() => compViewDef([anchorDef(NodeFlags.None, null !, null !, 0)])),
|
() => compViewDef([anchorDef(NodeFlags.None, null, null, 0)])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, SomeService, [Renderer2])
|
directiveDef(1, NodeFlags.Component, null, 0, SomeService, [Renderer2])
|
||||||
]));
|
]));
|
||||||
|
|
||||||
expect(instance.dep.createElement).toBeTruthy();
|
expect(instance.dep.createElement).toBeTruthy();
|
||||||
@ -337,9 +325,9 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.None, null !, 0, SomeService, [], {a: [0, 'a'], b: [1, 'b']})
|
1, NodeFlags.None, null, 0, SomeService, [], {a: [0, 'a'], b: [1, 'b']})
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
checkNodeInlineOrDynamic(check, view, 1, inlineDynamic, ['v1', 'v2']);
|
checkNodeInlineOrDynamic(check, view, 1, inlineDynamic, ['v1', 'v2']);
|
||||||
@ -373,13 +361,11 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleEvent = jasmine.createSpy('handleEvent');
|
const handleEvent = jasmine.createSpy('handleEvent');
|
||||||
const subscribe = spyOn(emitter, 'subscribe').and.callThrough();
|
|
||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(0, NodeFlags.None, null, null, 1, 'span', null, null, null, handleEvent),
|
||||||
NodeFlags.None, null !, null !, 1, 'span', null !, null !, null !, handleEvent),
|
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.None, null !, 0, SomeService, [], null !, {emitter: 'someEventName'})
|
1, NodeFlags.None, null, 0, SomeService, [], null, {emitter: 'someEventName'})
|
||||||
]));
|
]));
|
||||||
|
|
||||||
emitter.emit('someEventInstance');
|
emitter.emit('someEventInstance');
|
||||||
@ -399,10 +385,10 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'span', null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'span', null, null, null,
|
||||||
() => { throw new Error('Test'); }),
|
() => { throw new Error('Test'); }),
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.None, null !, 0, SomeService, [], null !, {emitter: 'someEventName'})
|
1, NodeFlags.None, null, 0, SomeService, [], null, {emitter: 'someEventName'})
|
||||||
]));
|
]));
|
||||||
|
|
||||||
emitter.emit('someEventInstance');
|
emitter.emit('someEventInstance');
|
||||||
@ -440,10 +426,10 @@ export function main() {
|
|||||||
NodeFlags.AfterViewChecked | NodeFlags.OnDestroy;
|
NodeFlags.AfterViewChecked | NodeFlags.OnDestroy;
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 3, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 3, 'span'),
|
||||||
directiveDef(allFlags, null !, 0, SomeService, [], {a: [0, 'a']}),
|
directiveDef(1, allFlags, null, 0, SomeService, [], {a: [0, 'a']}),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(2, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(allFlags, null !, 0, SomeService, [], {a: [0, 'a']})
|
directiveDef(3, allFlags, null, 0, SomeService, [], {a: [0, 'a']})
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
check(view, 1, ArgumentType.Inline, 'someValue');
|
check(view, 1, ArgumentType.Inline, 'someValue');
|
||||||
@ -499,9 +485,9 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(
|
directiveDef(
|
||||||
NodeFlags.OnChanges, null !, 0, SomeService, [], {a: [0, 'nonMinifiedA']})
|
1, NodeFlags.OnChanges, null, 0, SomeService, [], {a: [0, 'nonMinifiedA']})
|
||||||
],
|
],
|
||||||
(check, view) => { check(view, 1, ArgumentType.Inline, currValue); }));
|
(check, view) => { check(view, 1, ArgumentType.Inline, currValue); }));
|
||||||
|
|
||||||
@ -520,8 +506,8 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.AfterContentChecked, null !, 0, SomeService, [], {a: [0, 'a']}),
|
directiveDef(1, NodeFlags.AfterContentChecked, null, 0, SomeService, [], {a: [0, 'a']}),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err: any;
|
let err: any;
|
||||||
@ -543,8 +529,8 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.OnDestroy, null !, 0, SomeService, [], {a: [0, 'a']}),
|
directiveDef(1, NodeFlags.OnDestroy, null, 0, SomeService, [], {a: [0, 'a']}),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err: any;
|
let err: any;
|
||||||
|
@ -7,23 +7,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {PipeTransform} from '@angular/core';
|
import {PipeTransform} from '@angular/core';
|
||||||
import {NodeDef, NodeFlags, Services, ViewData, ViewDefinition, ViewFlags, ViewUpdateFn, asProviderData, directiveDef, elementDef, nodeValue, pipeDef, pureArrayDef, pureObjectDef, purePipeDef, rootRenderNodes, viewDef} from '@angular/core/src/view/index';
|
import {NodeFlags, Services, asProviderData, directiveDef, elementDef, nodeValue, pipeDef, pureArrayDef, pureObjectDef, purePipeDef} from '@angular/core/src/view/index';
|
||||||
|
|
||||||
import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, createRootView} from './helper';
|
import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, compViewDef, createAndGetRootNodes} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`View Pure Expressions`, () => {
|
describe(`View Pure Expressions`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(viewDef: ViewDefinition): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
class Service {
|
class Service {
|
||||||
data: any;
|
data: any;
|
||||||
@ -37,9 +26,9 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
pureArrayDef(2),
|
pureArrayDef(1, 2),
|
||||||
directiveDef(NodeFlags.None, null !, 0, Service, [], {data: [0, 'data']}),
|
directiveDef(2, NodeFlags.None, null, 0, Service, [], {data: [0, 'data']}),
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
const pureValue = checkNodeInlineOrDynamic(check, view, 1, inlineDynamic, values);
|
const pureValue = checkNodeInlineOrDynamic(check, view, 1, inlineDynamic, values);
|
||||||
@ -75,8 +64,9 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'), pureObjectDef({a: 0, b: 1}),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
directiveDef(NodeFlags.None, null !, 0, Service, [], {data: [0, 'data']})
|
pureObjectDef(1, {a: 0, b: 1}),
|
||||||
|
directiveDef(2, NodeFlags.None, null, 0, Service, [], {data: [0, 'data']})
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
const pureValue = checkNodeInlineOrDynamic(check, view, 1, inlineDynamic, values);
|
const pureValue = checkNodeInlineOrDynamic(check, view, 1, inlineDynamic, values);
|
||||||
@ -115,10 +105,10 @@ export function main() {
|
|||||||
|
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 3, 'span'),
|
elementDef(0, NodeFlags.None, null !, null !, 3, 'span'),
|
||||||
pipeDef(NodeFlags.None, SomePipe, []),
|
pipeDef(NodeFlags.None, SomePipe, []),
|
||||||
purePipeDef(2),
|
purePipeDef(2, 2),
|
||||||
directiveDef(NodeFlags.None, null !, 0, Service, [], {data: [0, 'data']}),
|
directiveDef(3, NodeFlags.None, null, 0, Service, [], {data: [0, 'data']}),
|
||||||
],
|
],
|
||||||
(check, view) => {
|
(check, view) => {
|
||||||
const pureValue = checkNodeInlineOrDynamic(
|
const pureValue = checkNodeInlineOrDynamic(
|
||||||
|
@ -6,32 +6,14 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementRef, Injector, QueryList, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, TemplateRef, ViewContainerRef, ViewEncapsulation, getDebugNode} from '@angular/core';
|
import {ElementRef, QueryList, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||||
import {getDebugContext} from '@angular/core/src/errors';
|
import {getDebugContext} from '@angular/core/src/errors';
|
||||||
import {BindingFlags, DebugContext, NodeDef, NodeFlags, QueryBindingType, QueryValueType, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, attachEmbeddedView, detachEmbeddedView, directiveDef, elementDef, queryDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {NodeDef, NodeFlags, QueryBindingType, QueryValueType, Services, anchorDef, asElementData, asProviderData, attachEmbeddedView, detachEmbeddedView, directiveDef, elementDef, queryDef} from '@angular/core/src/view/index';
|
||||||
import {inject} from '@angular/core/testing';
|
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
|
||||||
|
|
||||||
import {createEmbeddedView, createRootView} from './helper';
|
import {compViewDef, compViewDefFactory, createAndGetRootNodes, createEmbeddedView} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`Query Views`, () => {
|
describe(`Query Views`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function embeddedViewDef(nodes: NodeDef[], update?: ViewUpdateFn): ViewDefinitionFactory {
|
|
||||||
return () => viewDef(ViewFlags.None, nodes, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(
|
|
||||||
viewDef: ViewDefinition, context: any = null): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef, context);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
const someQueryId = 1;
|
const someQueryId = 1;
|
||||||
|
|
||||||
@ -41,43 +23,50 @@ export function main() {
|
|||||||
a: QueryList<AService>;
|
a: QueryList<AService>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function contentQueryProviders() {
|
function contentQueryProviders(checkIndex: number) {
|
||||||
return [
|
return [
|
||||||
directiveDef(NodeFlags.None, null !, 1, QueryService, []),
|
directiveDef(checkIndex, NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.All})
|
{'a': QueryBindingType.All})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function compViewQueryProviders(extraChildCount: number, nodes: NodeDef[]) {
|
const cQPLength = contentQueryProviders(0).length;
|
||||||
|
|
||||||
|
// nodes first checkIndex should be 1 (to account for the `queryDef`
|
||||||
|
function compViewQueryProviders(checkIndex: number, extraChildCount: number, nodes: NodeDef[]) {
|
||||||
return [
|
return [
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1 + extraChildCount, 'div', null !, null !, null !,
|
checkIndex, NodeFlags.None, null, null, 1 + extraChildCount, 'div', null, null, null,
|
||||||
null !, () => compViewDef([
|
null, () => compViewDef([
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeViewQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeViewQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.All}),
|
{'a': QueryBindingType.All}),
|
||||||
...nodes
|
...nodes
|
||||||
])),
|
])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, QueryService, [], null !, null !, ),
|
directiveDef(
|
||||||
|
checkIndex + 1, NodeFlags.Component, null !, 0, QueryService, [], null !, null !, ),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function aServiceProvider() {
|
const cVQLength = compViewQueryProviders(0, 0, []).length;
|
||||||
|
|
||||||
|
|
||||||
|
function aServiceProvider(checkIndex: number) {
|
||||||
return directiveDef(
|
return directiveDef(
|
||||||
NodeFlags.None, [[someQueryId, QueryValueType.Provider]], 0, AService, []);
|
checkIndex, NodeFlags.None, [[someQueryId, QueryValueType.Provider]], 0, AService, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('content queries', () => {
|
describe('content queries', () => {
|
||||||
|
|
||||||
it('should query providers on the same element and child elements', () => {
|
it('should query providers on the same element and child elements', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 5, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 5, 'div'),
|
||||||
...contentQueryProviders(),
|
...contentQueryProviders(1),
|
||||||
aServiceProvider(),
|
aServiceProvider(1 + cQPLength),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(2 + cQPLength, NodeFlags.None, null, null, 1, 'div'),
|
||||||
aServiceProvider(),
|
aServiceProvider(3 + cQPLength),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const qs: QueryService = asProviderData(view, 1).instance;
|
const qs: QueryService = asProviderData(view, 1).instance;
|
||||||
@ -92,13 +81,14 @@ export function main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not query providers on sibling or parent elements', () => {
|
it('should not query providers on sibling or parent elements', () => {
|
||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 6, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 6, 'div'),
|
||||||
aServiceProvider(),
|
aServiceProvider(1),
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'div'),
|
elementDef(2, NodeFlags.None, null, null, 2, 'div'),
|
||||||
...contentQueryProviders(),
|
...contentQueryProviders(3),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(3 + cQPLength, NodeFlags.None, null, null, 1, 'div'),
|
||||||
aServiceProvider(),
|
aServiceProvider(4 + cQPLength),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
Services.checkAndUpdateView(view);
|
Services.checkAndUpdateView(view);
|
||||||
@ -112,10 +102,10 @@ export function main() {
|
|||||||
it('should query providers in the view', () => {
|
it('should query providers in the view', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
...compViewQueryProviders(
|
...compViewQueryProviders(
|
||||||
0,
|
0, 0,
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(1, NodeFlags.None, null, null, 1, 'span'),
|
||||||
aServiceProvider(),
|
aServiceProvider(2),
|
||||||
]),
|
]),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
@ -129,12 +119,8 @@ export function main() {
|
|||||||
|
|
||||||
it('should not query providers on the host element', () => {
|
it('should not query providers on the host element', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
...compViewQueryProviders(
|
...compViewQueryProviders(0, 1, [elementDef(1, NodeFlags.None, null, null, 0, 'span')]),
|
||||||
1,
|
aServiceProvider(cVQLength),
|
||||||
[
|
|
||||||
elementDef(NodeFlags.None, null !, null !, 0, 'span'),
|
|
||||||
]),
|
|
||||||
aServiceProvider(),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
Services.checkAndUpdateView(view);
|
Services.checkAndUpdateView(view);
|
||||||
@ -146,13 +132,13 @@ export function main() {
|
|||||||
describe('embedded views', () => {
|
describe('embedded views', () => {
|
||||||
it('should query providers in embedded views', () => {
|
it('should query providers in embedded views', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 5, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 5, 'div'),
|
||||||
...contentQueryProviders(),
|
...contentQueryProviders(1),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 2, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 2, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
aServiceProvider(),
|
aServiceProvider(1),
|
||||||
])),
|
])),
|
||||||
...contentQueryProviders(),
|
...contentQueryProviders(2 + cQPLength),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const childView = createEmbeddedView(view, view.def.nodes[3]);
|
const childView = createEmbeddedView(view, view.def.nodes[3]);
|
||||||
@ -172,15 +158,15 @@ export function main() {
|
|||||||
|
|
||||||
it('should query providers in embedded views only at the template declaration', () => {
|
it('should query providers in embedded views only at the template declaration', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 3, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 3, 'div'),
|
||||||
...contentQueryProviders(),
|
...contentQueryProviders(1),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
aServiceProvider(),
|
aServiceProvider(1),
|
||||||
])),
|
])),
|
||||||
elementDef(NodeFlags.None, null !, null !, 3, 'div'),
|
elementDef(2 + cQPLength, NodeFlags.None, null, null, 3, 'div'),
|
||||||
...contentQueryProviders(),
|
...contentQueryProviders(3 + cQPLength),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0),
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
const childView = createEmbeddedView(view, view.def.nodes[3]);
|
const childView = createEmbeddedView(view, view.def.nodes[3]);
|
||||||
@ -201,11 +187,11 @@ export function main() {
|
|||||||
|
|
||||||
it('should update content queries if embedded views are added or removed', () => {
|
it('should update content queries if embedded views are added or removed', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 3, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 3, 'div'),
|
||||||
...contentQueryProviders(),
|
...contentQueryProviders(1),
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
aServiceProvider(),
|
aServiceProvider(1),
|
||||||
])),
|
])),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
@ -230,11 +216,11 @@ export function main() {
|
|||||||
it('should update view queries if embedded views are added or removed', () => {
|
it('should update view queries if embedded views are added or removed', () => {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
...compViewQueryProviders(
|
...compViewQueryProviders(
|
||||||
0,
|
0, 0,
|
||||||
[
|
[
|
||||||
anchorDef(NodeFlags.EmbeddedViews, null !, null !, 0, null !, embeddedViewDef([
|
anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, compViewDefFactory([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
aServiceProvider(),
|
aServiceProvider(1),
|
||||||
])),
|
])),
|
||||||
]),
|
]),
|
||||||
]));
|
]));
|
||||||
@ -265,13 +251,13 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 4, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 4, 'div'),
|
||||||
directiveDef(NodeFlags.None, null !, 1, QueryService, []),
|
directiveDef(1, NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.All}),
|
{'a': QueryBindingType.All}),
|
||||||
aServiceProvider(),
|
aServiceProvider(3),
|
||||||
aServiceProvider(),
|
aServiceProvider(4),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
Services.checkAndUpdateView(view);
|
Services.checkAndUpdateView(view);
|
||||||
@ -290,13 +276,13 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 4, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 4, 'div'),
|
||||||
directiveDef(NodeFlags.None, null !, 1, QueryService, []),
|
directiveDef(1, NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.First}),
|
{'a': QueryBindingType.First}),
|
||||||
aServiceProvider(),
|
aServiceProvider(3),
|
||||||
aServiceProvider(),
|
aServiceProvider(4),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
Services.checkAndUpdateView(view);
|
Services.checkAndUpdateView(view);
|
||||||
@ -313,8 +299,8 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, [[someQueryId, QueryValueType.ElementRef]], null !, 2, 'div'),
|
elementDef(0, NodeFlags.None, [[someQueryId, QueryValueType.ElementRef]], null, 2, 'div'),
|
||||||
directiveDef(NodeFlags.None, null !, 1, QueryService, []),
|
directiveDef(1, NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.First}),
|
{'a': QueryBindingType.First}),
|
||||||
@ -333,9 +319,9 @@ export function main() {
|
|||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.None, [[someQueryId, QueryValueType.TemplateRef]], null !, 2, null !,
|
NodeFlags.None, [[someQueryId, QueryValueType.TemplateRef]], null, 2, null,
|
||||||
embeddedViewDef([anchorDef(NodeFlags.None, null !, null !, 0)])),
|
compViewDefFactory([anchorDef(NodeFlags.None, null, null, 0)])),
|
||||||
directiveDef(NodeFlags.None, null !, 1, QueryService, []),
|
directiveDef(1, NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.First}),
|
{'a': QueryBindingType.First}),
|
||||||
@ -354,8 +340,8 @@ export function main() {
|
|||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.EmbeddedViews, [[someQueryId, QueryValueType.ViewContainerRef]], null !, 2),
|
NodeFlags.EmbeddedViews, [[someQueryId, QueryValueType.ViewContainerRef]], null, 2),
|
||||||
directiveDef(NodeFlags.None, null !, 1, QueryService, []),
|
directiveDef(1, NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.First}),
|
{'a': QueryBindingType.First}),
|
||||||
@ -375,12 +361,12 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 3, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 3, 'div'),
|
||||||
directiveDef(NodeFlags.None, null !, 1, QueryService, []),
|
directiveDef(1, NodeFlags.None, null, 1, QueryService, []),
|
||||||
queryDef(
|
queryDef(
|
||||||
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
|
||||||
{'a': QueryBindingType.All}),
|
{'a': QueryBindingType.All}),
|
||||||
aServiceProvider(),
|
aServiceProvider(3),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,27 +6,12 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, getDebugNode} from '@angular/core';
|
import {DebugContext, NodeFlags, QueryValueType, Services, asElementData, asTextData, directiveDef, elementDef, textDef} from '@angular/core/src/view/index';
|
||||||
import {DebugContext, NodeDef, NodeFlags, QueryValueType, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asElementData, asProviderData, asTextData, directiveDef, elementDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
|
||||||
import {inject} from '@angular/core/testing';
|
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
|
||||||
|
|
||||||
import {createRootView, isBrowser} from './helper';
|
import {compViewDef, createAndGetRootNodes} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('View Services', () => {
|
describe('View Services', () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(
|
|
||||||
viewDef: ViewDefinition, context: any = null): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef, context);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('DebugContext', () => {
|
describe('DebugContext', () => {
|
||||||
class AComp {}
|
class AComp {}
|
||||||
@ -36,12 +21,13 @@ export function main() {
|
|||||||
function createViewWithData() {
|
function createViewWithData() {
|
||||||
const {view} = createAndGetRootNodes(compViewDef([
|
const {view} = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(
|
elementDef(
|
||||||
NodeFlags.None, null !, null !, 1, 'div', null !, null !, null !, null !,
|
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
|
||||||
() => compViewDef([
|
() => compViewDef([
|
||||||
elementDef(NodeFlags.None, [['ref', QueryValueType.ElementRef]], null !, 2, 'span'),
|
elementDef(
|
||||||
directiveDef(NodeFlags.None, null !, 0, AService, []), textDef(null !, ['a'])
|
0, NodeFlags.None, [['ref', QueryValueType.ElementRef]], null, 2, 'span'),
|
||||||
|
directiveDef(1, NodeFlags.None, null, 0, AService, []), textDef(2, null, ['a'])
|
||||||
])),
|
])),
|
||||||
directiveDef(NodeFlags.Component, null !, 0, AComp, []),
|
directiveDef(1, NodeFlags.Component, null, 0, AComp, []),
|
||||||
]));
|
]));
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -6,46 +6,34 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector, RenderComponentType, RootRenderer, Sanitizer, SecurityContext, ViewEncapsulation, WrappedValue, getDebugNode} from '@angular/core';
|
import {getDebugNode} from '@angular/core';
|
||||||
import {ArgumentType, DebugContext, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewFlags, ViewHandleEventFn, ViewUpdateFn, anchorDef, asTextData, elementDef, rootRenderNodes, textDef, viewDef} from '@angular/core/src/view/index';
|
import {NodeFlags, Services, asTextData, elementDef, textDef} from '@angular/core/src/view/index';
|
||||||
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';
|
||||||
|
|
||||||
import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, createRootView, isBrowser} from './helper';
|
import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, compViewDef, createAndGetRootNodes} from './helper';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe(`View Text`, () => {
|
describe(`View Text`, () => {
|
||||||
function compViewDef(
|
|
||||||
nodes: NodeDef[], updateDirectives?: ViewUpdateFn, updateRenderer?: ViewUpdateFn,
|
|
||||||
viewFlags: ViewFlags = ViewFlags.None): ViewDefinition {
|
|
||||||
return viewDef(viewFlags, nodes, updateDirectives, updateRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAndGetRootNodes(
|
|
||||||
viewDef: ViewDefinition, context?: any): {rootNodes: any[], view: ViewData} {
|
|
||||||
const view = createRootView(viewDef, context);
|
|
||||||
const rootNodes = rootRenderNodes(view);
|
|
||||||
return {rootNodes, view};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
it('should create text nodes without parents', () => {
|
it('should create text nodes without parents', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([textDef(null !, ['a'])])).rootNodes;
|
const rootNodes = createAndGetRootNodes(compViewDef([textDef(0, null, ['a'])])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(1);
|
expect(rootNodes.length).toBe(1);
|
||||||
expect(getDOM().getText(rootNodes[0])).toBe('a');
|
expect(getDOM().getText(rootNodes[0])).toBe('a');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create views with multiple root text nodes', () => {
|
it('should create views with multiple root text nodes', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
textDef(null !, ['a']), textDef(null !, ['b'])
|
textDef(0, null, ['a']),
|
||||||
|
textDef(1, null, ['b']),
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(2);
|
expect(rootNodes.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create text nodes with parents', () => {
|
it('should create text nodes with parents', () => {
|
||||||
const rootNodes = createAndGetRootNodes(compViewDef([
|
const rootNodes = createAndGetRootNodes(compViewDef([
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'div'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'div'),
|
||||||
textDef(null !, ['a']),
|
textDef(1, null, ['a']),
|
||||||
])).rootNodes;
|
])).rootNodes;
|
||||||
expect(rootNodes.length).toBe(1);
|
expect(rootNodes.length).toBe(1);
|
||||||
const textNode = getDOM().firstChild(rootNodes[0]);
|
const textNode = getDOM().firstChild(rootNodes[0]);
|
||||||
@ -55,7 +43,7 @@ export function main() {
|
|||||||
it('should add debug information to the renderer', () => {
|
it('should add debug information to the renderer', () => {
|
||||||
const someContext = new Object();
|
const someContext = new Object();
|
||||||
const {view, rootNodes} =
|
const {view, rootNodes} =
|
||||||
createAndGetRootNodes(compViewDef([textDef(null !, ['a'])]), someContext);
|
createAndGetRootNodes(compViewDef([textDef(0, null, ['a'])]), someContext);
|
||||||
expect(getDebugNode(rootNodes[0]) !.nativeNode).toBe(asTextData(view, 0).renderText);
|
expect(getDebugNode(rootNodes[0]) !.nativeNode).toBe(asTextData(view, 0).renderText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -65,7 +53,7 @@ export function main() {
|
|||||||
it(`should update via strategy ${inlineDynamic}`, () => {
|
it(`should update via strategy ${inlineDynamic}`, () => {
|
||||||
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
const {view, rootNodes} = createAndGetRootNodes(compViewDef(
|
||||||
[
|
[
|
||||||
textDef(null !, ['0', '1', '2']),
|
textDef(0, null, ['0', '1', '2']),
|
||||||
],
|
],
|
||||||
null !, (check, view) => {
|
null !, (check, view) => {
|
||||||
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, ['a', 'b']);
|
checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, ['a', 'b']);
|
||||||
@ -73,7 +61,6 @@ export function main() {
|
|||||||
|
|
||||||
Services.checkAndUpdateView(view);
|
Services.checkAndUpdateView(view);
|
||||||
|
|
||||||
const node = rootNodes[0];
|
|
||||||
expect(getDOM().getText(rootNodes[0])).toBe('0a1b2');
|
expect(getDOM().getText(rootNodes[0])).toBe('0a1b2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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, directiveDef, elementDef, textDef, viewDef} from '@angular/core/src/view/index';
|
import {NodeFlags, QueryValueType, ViewDefinition, ViewFlags, anchorDef, directiveDef, elementDef, textDef, viewDef} from '@angular/core/src/view/index';
|
||||||
import {filterQueryId} from '@angular/core/src/view/util';
|
import {filterQueryId} from '@angular/core/src/view/util';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
@ -14,14 +14,14 @@ export function main() {
|
|||||||
|
|
||||||
describe('parent', () => {
|
describe('parent', () => {
|
||||||
function parents(viewDef: ViewDefinition): (number | null)[] {
|
function parents(viewDef: ViewDefinition): (number | null)[] {
|
||||||
return viewDef.nodes.map(node => node.parent ? node.parent.index : null);
|
return viewDef.nodes.map(node => node.parent ? node.parent.nodeIndex : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should calculate parents for one level', () => {
|
it('should calculate parents for one level', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
textDef(null !, ['a']),
|
textDef(1, null, ['a']),
|
||||||
textDef(null !, ['a']),
|
textDef(2, null, ['a']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(parents(vd)).toEqual([null, 0, 0]);
|
expect(parents(vd)).toEqual([null, 0, 0]);
|
||||||
@ -29,11 +29,11 @@ export function main() {
|
|||||||
|
|
||||||
it('should calculate parents for one level, multiple roots', () => {
|
it('should calculate parents for one level, multiple roots', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
textDef(null !, ['a']),
|
textDef(1, null, ['a']),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(2, NodeFlags.None, null, null, 1, 'span'),
|
||||||
textDef(null !, ['a']),
|
textDef(3, null, ['a']),
|
||||||
textDef(null !, ['a']),
|
textDef(4, null, ['a']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(parents(vd)).toEqual([null, 0, null, 2, null]);
|
expect(parents(vd)).toEqual([null, 0, null, 2, null]);
|
||||||
@ -41,12 +41,12 @@ export function main() {
|
|||||||
|
|
||||||
it('should calculate parents for multiple levels', () => {
|
it('should calculate parents for multiple levels', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(1, NodeFlags.None, null, null, 1, 'span'),
|
||||||
textDef(null !, ['a']),
|
textDef(2, null, ['a']),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(3, NodeFlags.None, null, null, 1, 'span'),
|
||||||
textDef(null !, ['a']),
|
textDef(4, null, ['a']),
|
||||||
textDef(null !, ['a']),
|
textDef(5, null, ['a']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(parents(vd)).toEqual([null, 0, 1, null, 3, null]);
|
expect(parents(vd)).toEqual([null, 0, 1, null, 3, null]);
|
||||||
@ -65,8 +65,8 @@ 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(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.AfterContentChecked, null !, 0, AService, [])
|
directiveDef(1, NodeFlags.AfterContentChecked, null, 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([
|
expect(childFlags(vd)).toEqual([
|
||||||
@ -80,9 +80,9 @@ export function main() {
|
|||||||
|
|
||||||
it('should calculate childFlags for two levels', () => {
|
it('should calculate childFlags for two levels', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(1, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.AfterContentChecked, null !, 0, AService, [])
|
directiveDef(2, NodeFlags.AfterContentChecked, null, 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([
|
expect(childFlags(vd)).toEqual([
|
||||||
@ -98,11 +98,11 @@ 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(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.AfterContentChecked, null !, 0, AService, []),
|
directiveDef(1, NodeFlags.AfterContentChecked, null, 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(2, NodeFlags.None, null, null, 2, 'span'),
|
||||||
directiveDef(NodeFlags.AfterContentInit, null !, 0, AService, []),
|
directiveDef(3, NodeFlags.AfterContentInit, null, 0, AService, []),
|
||||||
directiveDef(NodeFlags.AfterViewChecked, null !, 0, AService, []),
|
directiveDef(4, NodeFlags.AfterViewChecked, null, 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([
|
expect(childFlags(vd)).toEqual([
|
||||||
@ -120,12 +120,12 @@ export function main() {
|
|||||||
|
|
||||||
it('should calculate childFlags for multiple levels', () => {
|
it('should calculate childFlags for multiple levels', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(1, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.AfterContentChecked, null !, 0, AService, []),
|
directiveDef(2, NodeFlags.AfterContentChecked, null !, 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(3, NodeFlags.None, null, null, 2, 'span'),
|
||||||
directiveDef(NodeFlags.AfterContentInit, null !, 0, AService, []),
|
directiveDef(4, NodeFlags.AfterContentInit, null, 0, AService, []),
|
||||||
directiveDef(NodeFlags.AfterViewInit, null !, 0, AService, []),
|
directiveDef(5, NodeFlags.AfterViewInit, null, 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childFlags(vd)).toEqual([
|
expect(childFlags(vd)).toEqual([
|
||||||
@ -151,8 +151,8 @@ 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(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, [])
|
directiveDef(1, NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([filterQueryId(1), 0]);
|
expect(childMatchedQueries(vd)).toEqual([filterQueryId(1), 0]);
|
||||||
@ -160,9 +160,9 @@ export function main() {
|
|||||||
|
|
||||||
it('should calculate childMatchedQueries for two levels', () => {
|
it('should calculate childMatchedQueries for two levels', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(1, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, [])
|
directiveDef(2, NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([filterQueryId(1), filterQueryId(1), 0]);
|
expect(childMatchedQueries(vd)).toEqual([filterQueryId(1), filterQueryId(1), 0]);
|
||||||
@ -170,11 +170,11 @@ 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(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, []),
|
directiveDef(1, NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(2, NodeFlags.None, null, null, 2, 'span'),
|
||||||
directiveDef(NodeFlags.None, [[2, QueryValueType.Provider]], 0, AService, []),
|
directiveDef(3, NodeFlags.None, [[2, QueryValueType.Provider]], 0, AService, []),
|
||||||
directiveDef(NodeFlags.None, [[3, QueryValueType.Provider]], 0, AService, []),
|
directiveDef(4, NodeFlags.None, [[3, QueryValueType.Provider]], 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([
|
expect(childMatchedQueries(vd)).toEqual([
|
||||||
@ -184,12 +184,12 @@ export function main() {
|
|||||||
|
|
||||||
it('should calculate childMatchedQueries for multiple levels', () => {
|
it('should calculate childMatchedQueries for multiple levels', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 2, 'span'),
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(1, NodeFlags.None, null, null, 1, 'span'),
|
||||||
directiveDef(NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, []),
|
directiveDef(2, NodeFlags.None, [[1, QueryValueType.Provider]], 0, AService, []),
|
||||||
elementDef(NodeFlags.None, null !, null !, 2, 'span'),
|
elementDef(3, NodeFlags.None, null, null, 2, 'span'),
|
||||||
directiveDef(NodeFlags.None, [[2, QueryValueType.Provider]], 0, AService, []),
|
directiveDef(4, NodeFlags.None, [[2, QueryValueType.Provider]], 0, AService, []),
|
||||||
directiveDef(NodeFlags.None, [[3, QueryValueType.Provider]], 0, AService, []),
|
directiveDef(5, NodeFlags.None, [[3, QueryValueType.Provider]], 0, AService, []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(childMatchedQueries(vd)).toEqual([
|
expect(childMatchedQueries(vd)).toEqual([
|
||||||
@ -199,13 +199,13 @@ export function main() {
|
|||||||
|
|
||||||
it('should included embedded views into childMatchedQueries', () => {
|
it('should included embedded views into childMatchedQueries', () => {
|
||||||
const vd = viewDef(ViewFlags.None, [
|
const vd = viewDef(ViewFlags.None, [
|
||||||
elementDef(NodeFlags.None, null !, null !, 1, 'span'),
|
elementDef(0, NodeFlags.None, null, null, 1, 'span'),
|
||||||
anchorDef(
|
anchorDef(
|
||||||
NodeFlags.None, null !, null !, 0, null !,
|
NodeFlags.None, null, null, 0, null,
|
||||||
() => viewDef(
|
() => viewDef(
|
||||||
ViewFlags.None,
|
ViewFlags.None,
|
||||||
[
|
[
|
||||||
elementDef(NodeFlags.None, [[1, QueryValueType.Provider]], null !, 0, 'span'),
|
elementDef(0, NodeFlags.None, [[1, QueryValueType.Provider]], null, 0, 'span'),
|
||||||
]))
|
]))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user