From de3ca567690e11833d2b17fc4c751a128cfe986d Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Tue, 10 Apr 2018 20:57:09 -0700 Subject: [PATCH] fix(ivy): support separate creation mode and update mode execution in runtime (#23292) PR Close #23292 --- .../src/largetable/render3/table.ts | 58 +- modules/benchmarks/src/tree/render3/tree.ts | 106 +- .../core/src/core_render3_private_export.ts | 1 + packages/core/src/render3/index.ts | 1 + packages/core/src/render3/instructions.ts | 65 +- .../core/src/render3/interfaces/definition.ts | 22 +- .../core/src/render3/node_manipulation.ts | 14 +- .../hello_world/bundle.golden_symbols.json | 6 + .../bundling/todo/bundle.golden_symbols.json | 6 + packages/core/test/render3/basic_perf.ts | 30 +- .../test/render3/change_detection_spec.ts | 217 ++-- .../test/render3/common_integration_spec.ts | 36 +- .../component_directives_spec.ts | 194 +-- .../content_projection_spec.ts | 15 +- .../compiler_canonical/elements_spec.ts | 81 +- .../compiler_canonical/injection_spec.ts | 28 +- .../compiler_canonical/life_cycle_spec.ts | 14 +- .../local_reference_spec.ts | 13 +- .../render3/compiler_canonical/pipes_spec.ts | 34 +- .../render3/compiler_canonical/query_spec.ts | 24 +- .../compiler_canonical/sanitize_spec.ts | 19 +- .../compiler_canonical/small_app_spec.ts | 28 +- .../template_variables_spec.ts | 65 +- packages/core/test/render3/component_spec.ts | 135 +- packages/core/test/render3/content_spec.ts | 364 +++--- .../core/test/render3/control_flow_spec.ts | 603 +++++---- packages/core/test/render3/di_spec.ts | 198 +-- packages/core/test/render3/directive_spec.ts | 6 +- packages/core/test/render3/exports_spec.ts | 146 ++- .../core/test/render3/integration_spec.ts | 387 +++--- packages/core/test/render3/lifecycle_spec.ts | 1141 ++++++++++------- packages/core/test/render3/listeners_spec.ts | 214 ++-- packages/core/test/render3/outputs_spec.ts | 195 +-- packages/core/test/render3/pipe_spec.ts | 142 +- packages/core/test/render3/properties_spec.ts | 224 ++-- .../core/test/render3/pure_function_spec.ts | 136 +- packages/core/test/render3/query_spec.ts | 361 +++--- packages/core/test/render3/render_util.ts | 10 +- .../test/render3/renderer_factory_spec.ts | 27 +- .../test/render3/view_container_ref_spec.ts | 108 +- 40 files changed, 3121 insertions(+), 2353 deletions(-) diff --git a/modules/benchmarks/src/largetable/render3/table.ts b/modules/benchmarks/src/largetable/render3/table.ts index 71d62c8a06..85b43102ce 100644 --- a/modules/benchmarks/src/largetable/render3/table.ts +++ b/modules/benchmarks/src/largetable/render3/table.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as detectChanges, ɵe as e, ɵsn as sn, ɵt as t, ɵv as v} from '@angular/core'; +import {ɵC as C, ɵE as E, ɵRenderFlags as RenderFlags, ɵT as T, ɵV as V, ɵb as b, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as detectChanges, ɵe as e, ɵsn as sn, ɵt as t, ɵv as v} from '@angular/core'; import {ComponentDef} from '@angular/core/src/render3/interfaces/definition'; import {TableCell, buildTable, emptyTable} from '../util'; @@ -18,8 +18,8 @@ export class LargeTableComponent { static ngComponentDef: ComponentDef = defineComponent({ type: LargeTableComponent, selectors: [['largetable']], - template: function(ctx: LargeTableComponent, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: LargeTableComponent) { + if (rf & RenderFlags.Create) { E(0, 'table'); { E(1, 'tbody'); @@ -28,38 +28,44 @@ export class LargeTableComponent { } e(); } - cR(2); - { - for (let row of ctx.data) { - let cm1 = V(1); - { - if (cm1) { - E(0, 'tr'); - C(1); - e(); - } - cR(1); + if (rf & RenderFlags.Update) { + cR(2); + { + for (let row of ctx.data) { + let rf1 = V(1); { - for (let cell of row) { - let cm2 = V(2); + if (rf1 & RenderFlags.Create) { + E(0, 'tr'); + C(1); + e(); + } + if (rf1 & RenderFlags.Update) { + cR(1); { - if (cm2) { - E(0, 'td'); - { T(1); } - e(); + for (let cell of row) { + let rf2 = V(2); + { + if (rf2 & RenderFlags.Create) { + E(0, 'td'); + { T(1); } + e(); + } + if (rf2 & RenderFlags.Update) { + sn(0, 'background-color', b(cell.row % 2 ? '' : 'grey')); + t(1, b(cell.value)); + } + } + v(); } - sn(0, 'background-color', b(cell.row % 2 ? '' : 'grey')); - t(1, b(cell.value)); } - v(); + cr(); } } - cr(); + v(); } - v(); } + cr(); } - cr(); }, factory: () => new LargeTableComponent(), inputs: {data: 'data'} diff --git a/modules/benchmarks/src/tree/render3/tree.ts b/modules/benchmarks/src/tree/render3/tree.ts index d05db539b4..61bd0955e0 100644 --- a/modules/benchmarks/src/tree/render3/tree.ts +++ b/modules/benchmarks/src/tree/render3/tree.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵi1 as i1, ɵp as p, ɵsn as sn, ɵt as t, ɵv as v} from '@angular/core'; +import {ɵC as C, ɵE as E, ɵRenderFlags as RenderFlags, ɵT as T, ɵV as V, ɵb as b, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵi1 as i1, ɵp as p, ɵsn as sn, ɵt as t, ɵv as v} from '@angular/core'; import {ComponentDef} from '@angular/core/src/render3/interfaces/definition'; import {TreeNode, buildTree, emptyTree} from '../util'; @@ -38,46 +38,52 @@ export class TreeComponent { static ngComponentDef: ComponentDef = defineComponent({ type: TreeComponent, selectors: [['tree']], - template: function(ctx: TreeComponent, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: TreeComponent) { + if (rf & RenderFlags.Create) { E(0, 'span'); { T(1); } e(); C(2); C(3); } - sn(0, 'background-color', b(ctx.data.depth % 2 ? '' : 'grey')); - t(1, i1(' ', ctx.data.value, ' ')); - cR(2); - { - if (ctx.data.left != null) { - let cm0 = V(0); - { - if (cm0) { - E(0, 'tree'); - e(); + if (rf & RenderFlags.Update) { + sn(0, 'background-color', b(ctx.data.depth % 2 ? '' : 'grey')); + t(1, i1(' ', ctx.data.value, ' ')); + cR(2); + { + if (ctx.data.left != null) { + let rf0 = V(0); + { + if (rf0 & RenderFlags.Create) { + E(0, 'tree'); + e(); + } + if (rf0 & RenderFlags.Update) { + p(0, 'data', b(ctx.data.left)); + } } - p(0, 'data', b(ctx.data.left)); + v(); } - v(); } - } - cr(); - cR(3); - { - if (ctx.data.right != null) { - let cm0 = V(0); - { - if (cm0) { - E(0, 'tree'); - e(); + cr(); + cR(3); + { + if (ctx.data.right != null) { + let rf0 = V(0); + { + if (rf0 & RenderFlags.Create) { + E(0, 'tree'); + e(); + } + if (rf0 & RenderFlags.Update) { + p(0, 'data', b(ctx.data.right)); + } } - p(0, 'data', b(ctx.data.right)); + v(); } - v(); } + cr(); } - cr(); }, factory: () => new TreeComponent, inputs: {data: 'data'}, @@ -92,17 +98,17 @@ export class TreeFunction { static ngComponentDef: ComponentDef = defineComponent({ type: TreeFunction, selectors: [['tree']], - template: function(ctx: TreeFunction, cm: boolean) { + template: function(rf: RenderFlags, ctx: TreeFunction) { // bit of a hack - TreeTpl(ctx.data, cm); + TreeTpl(rf, ctx.data); }, factory: () => new TreeFunction, inputs: {data: 'data'} }); } -export function TreeTpl(ctx: TreeNode, cm: boolean) { - if (cm) { +export function TreeTpl(rf: RenderFlags, ctx: TreeNode) { + if (rf & RenderFlags.Create) { E(0, 'tree'); { E(1, 'span'); @@ -113,24 +119,26 @@ export function TreeTpl(ctx: TreeNode, cm: boolean) { } e(); } - sn(1, 'background-color', b(ctx.depth % 2 ? '' : 'grey')); - t(2, i1(' ', ctx.value, ' ')); - cR(3); - { - if (ctx.left != null) { - let cm0 = V(0); - { TreeTpl(ctx.left, cm0); } - v(); + if (rf & RenderFlags.Update) { + sn(1, 'background-color', b(ctx.depth % 2 ? '' : 'grey')); + t(2, i1(' ', ctx.value, ' ')); + cR(3); + { + if (ctx.left != null) { + let rf0 = V(0); + { TreeTpl(rf0, ctx.left); } + v(); + } } - } - cr(); - cR(4); - { - if (ctx.right != null) { - let cm0 = V(0); - { TreeTpl(ctx.right, cm0); } - v(); + cr(); + cR(4); + { + if (ctx.right != null) { + let rf0 = V(0); + { TreeTpl(rf0, ctx.right); } + v(); + } } + cr(); } - cr(); } diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 319c0a3d95..3674945ed8 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -15,6 +15,7 @@ export { renderComponent as ɵrenderComponent, ComponentType as ɵComponentType, DirectiveType as ɵDirectiveType, + RenderFlags as ɵRenderFlags, directiveInject as ɵdirectiveInject, injectTemplateRef as ɵinjectTemplateRef, injectViewContainerRef as ɵinjectViewContainerRef, diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index fa8ec31994..44365e3773 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -12,6 +12,7 @@ import {InjectFlags} from './di'; import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType, PipeDef} from './interfaces/definition'; export {InjectFlags, QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, directiveInject, injectAttribute, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from './di'; +export {RenderFlags} from './interfaces/definition'; export {CssSelectorList} from './interfaces/projection'; diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index b1ff51a1ed..50e1fcb519 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -17,9 +17,9 @@ import {CurrentMatchesList, LView, LViewFlags, LifecycleStage, RootContext, TDat import {LContainerNode, LElementNode, LNode, LNodeType, TNodeFlags, LProjectionNode, LTextNode, LViewNode, TNode, TContainerNode, InitialInputData, InitialInputs, PropertyAliases, PropertyAliasValue,} from './interfaces/node'; import {assertNodeType} from './node_assert'; -import {appendChild, insertChild, insertView, appendProjectedNode, removeView, canInsertNativeNode} from './node_manipulation'; +import {appendChild, insertChild, insertView, appendProjectedNode, removeView, canInsertNativeNode, createTextNode} from './node_manipulation'; import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher'; -import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefList, DirectiveDefListOrFactory, DirectiveType, PipeDef, PipeDefListOrFactory} from './interfaces/definition'; +import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefList, DirectiveDefListOrFactory, DirectiveType, PipeDef, PipeDefListOrFactory, RenderFlags} from './interfaces/definition'; import {RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer'; import {isDifferent, stringify} from './util'; import {executeHooks, queueLifecycleHooks, queueInitHooks, executeInitHooks} from './hooks'; @@ -458,7 +458,7 @@ export function renderEmbeddedTemplate( try { isParent = true; previousOrParentNode = null !; - let cm: boolean = false; + let rf: RenderFlags = RenderFlags.Update; if (viewNode == null) { // TODO: revisit setting currentView when re-writing view containers const directives = currentView && currentView.tView.directiveRegistry; @@ -468,11 +468,11 @@ export function renderEmbeddedTemplate( const lView = createLView(-1, renderer, tView, template, context, LViewFlags.CheckAlways); viewNode = createLNode(null, LNodeType.View, null, lView); - cm = true; + rf = RenderFlags.Create; } oldView = enterView(viewNode.data, viewNode); - template(context, cm); + template(rf, context); refreshDirectives(); refreshDynamicChildren(); @@ -492,7 +492,8 @@ export function renderComponentOrTemplate( rendererFactory.begin(); } if (template) { - template(componentOrContext !, creationMode); + template(getRenderFlags(hostView), componentOrContext !); + refreshDynamicChildren(); refreshDirectives(); } else { executeInitAndContentHooks(); @@ -510,6 +511,20 @@ export function renderComponentOrTemplate( } } +/** + * This function returns the default configuration of rendering flags depending on when the + * template is in creation mode or update mode. By default, the update block is run with the + * creation block when the view is in creation mode. Otherwise, the update block is run + * alone. + * + * Dynamically created views do NOT use this configuration (update block and create block are + * always run separately). + */ +function getRenderFlags(view: LView): RenderFlags { + return view.flags & LViewFlags.CreationMode ? RenderFlags.Create | RenderFlags.Update : + RenderFlags.Update; +} + ////////////////////////// //// Element ////////////////////////// @@ -1146,10 +1161,7 @@ export function elementStyle( export function text(index: number, value?: any): void { ngDevMode && assertNull(currentView.bindingStartIndex, 'text nodes should be created before bindings'); - const textNode = value != null ? - (isProceduralRenderer(renderer) ? renderer.createText(stringify(value)) : - renderer.createTextNode(stringify(value))) : - null; + const textNode = value != null ? createTextNode(value, renderer) : null; const node = createLNode(index, LNodeType.Element, textNode); // Text nodes are self closing. isParent = false; @@ -1174,14 +1186,11 @@ export function textBinding(index: number, value: T | NO_CHANGE): void { existingNode.native.textContent = stringify(value)); } else { // Node was created but DOM node creation was delayed. Create and append now. - existingNode.native = isProceduralRenderer(renderer) ? - renderer.createText(stringify(value)) : - renderer.createTextNode(stringify(value)); + existingNode.native = createTextNode(value, renderer); insertChild(existingNode, currentView); } } - ////////////////////////// //// Directive ////////////////////////// @@ -1491,18 +1500,18 @@ function scanForView( * @param viewBlockId The ID of this view * @return boolean Whether or not this view is in creation mode */ -export function embeddedViewStart(viewBlockId: number): boolean { +export function embeddedViewStart(viewBlockId: number): RenderFlags { const container = (isParent ? previousOrParentNode : previousOrParentNode.parent !) as LContainerNode; ngDevMode && assertNodeType(container, LNodeType.Container); const lContainer = container.data; - const existingViewNode = scanForView(container, lContainer.nextIndex, viewBlockId); + let viewNode: LViewNode|null = scanForView(container, lContainer.nextIndex, viewBlockId); - if (existingViewNode) { - previousOrParentNode = existingViewNode; + if (viewNode) { + previousOrParentNode = viewNode; ngDevMode && assertNodeType(previousOrParentNode, LNodeType.View); isParent = true; - enterView((existingViewNode as LViewNode).data, existingViewNode as LViewNode); + enterView(viewNode.data, viewNode); } else { // When we create a new LView, we always reset the state of the instructions. const newView = createLView( @@ -1512,9 +1521,9 @@ export function embeddedViewStart(viewBlockId: number): boolean { newView.queries = lContainer.queries.enterView(lContainer.nextIndex); } - enterView(newView, createLNode(null, LNodeType.View, null, newView)); + enterView(newView, viewNode = createLNode(null, LNodeType.View, null, newView)); } - return !existingViewNode; + return getRenderFlags(viewNode.data); } /** @@ -1919,7 +1928,7 @@ export function detectChangesInternal( const template = def.template; try { - template(component, creationMode); + template(getRenderFlags(hostView), component); refreshDirectives(); refreshDynamicChildren(); } finally { @@ -1967,13 +1976,7 @@ export const NO_CHANGE = {} as NO_CHANGE; * (ie `bind()`, `interpolationX()`, `pureFunctionX()`) */ function initBindings() { - // `bindingIndex` is initialized when the view is first entered when not in creation mode - ngDevMode && - assertEqual( - creationMode, true, 'should only be called in creationMode for performance reasons'); - if (currentView.bindingStartIndex == null) { - bindingIndex = currentView.bindingStartIndex = data.length; - } + bindingIndex = currentView.bindingStartIndex = data.length; } /** @@ -1982,7 +1985,7 @@ function initBindings() { * @param value Value to diff */ export function bind(value: T | NO_CHANGE): T|NO_CHANGE { - if (creationMode) { + if (currentView.bindingStartIndex == null) { initBindings(); return data[bindingIndex++] = value; } @@ -2166,7 +2169,7 @@ export function consumeBinding(): any { export function bindingUpdated(value: any): boolean { ngDevMode && assertNotEqual(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.'); - if (creationMode) { + if (currentView.bindingStartIndex == null) { initBindings(); } else if (isDifferent(data[bindingIndex], value)) { throwErrorIfNoChangesMode(creationMode, checkNoChangesMode, data[bindingIndex], value); diff --git a/packages/core/src/render3/interfaces/definition.ts b/packages/core/src/render3/interfaces/definition.ts index ccf9efb369..beb1804d73 100644 --- a/packages/core/src/render3/interfaces/definition.ts +++ b/packages/core/src/render3/interfaces/definition.ts @@ -6,22 +6,34 @@ * found in the LICENSE file at https://angular.io/license */ -import {ChangeDetectionStrategy} from '../../change_detection/constants'; -import {PipeTransform} from '../../change_detection/pipe_transform'; import {Provider} from '../../core'; import {RendererType2} from '../../render/api'; import {Type} from '../../type'; -import {resolveRendererType2} from '../../view/util'; import {CssSelectorList} from './projection'; - /** * Definition of what a template rendering function should look like. */ export type ComponentTemplate = { - (ctx: T, creationMode: boolean): void; ngPrivateData?: never; + (rf: RenderFlags, ctx: T): void; ngPrivateData?: never; }; +/** + * Flags passed into template functions to determine which blocks (i.e. creation, update) + * should be executed. + * + * Typically, a template runs both the creation block and the update block on initialization and + * subsequent runs only execute the update block. However, dynamically created views require that + * the creation block be executed separately from the update block (for backwards compat). + */ +export const enum RenderFlags { + /* Whether to run the creation block (e.g. create elements and directives) */ + Create = 0b01, + + /* Whether to run the update block (e.g. refresh bindings) */ + Update = 0b10 +} + /** * A subclass of `Type` which has a static `ngComponentDef`:`ComponentDef` field making it * consumable for rendering. diff --git a/packages/core/src/render3/node_manipulation.ts b/packages/core/src/render3/node_manipulation.ts index 4aaa93d12e..5da3dfc750 100644 --- a/packages/core/src/render3/node_manipulation.ts +++ b/packages/core/src/render3/node_manipulation.ts @@ -11,9 +11,10 @@ import {callHooks} from './hooks'; import {LContainer, unusedValueExportToPlacateAjd as unused1} from './interfaces/container'; import {LContainerNode, LElementNode, LNode, LNodeType, LProjectionNode, LTextNode, LViewNode, unusedValueExportToPlacateAjd as unused2} from './interfaces/node'; import {unusedValueExportToPlacateAjd as unused3} from './interfaces/projection'; -import {ProceduralRenderer3, RElement, RNode, RText, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer'; +import {ProceduralRenderer3, RElement, RNode, RText, Renderer3, isProceduralRenderer, unusedValueExportToPlacateAjd as unused4} from './interfaces/renderer'; import {HookData, LView, LViewOrLContainer, TView, unusedValueExportToPlacateAjd as unused5} from './interfaces/view'; import {assertNodeType} from './node_assert'; +import {stringify} from './util'; const unusedValueToPlacateAjd = unused1 + unused2 + unused3 + unused4 + unused5; @@ -143,6 +144,11 @@ function findFirstRNode(rootNode: LNode): RElement|RText|null { return null; } +export function createTextNode(value: any, renderer: Renderer3): RText { + return isProceduralRenderer(renderer) ? renderer.createText(stringify(value)) : + renderer.createTextNode(stringify(value)); +} + /** * Adds or removes all DOM elements associated with a view. * @@ -174,6 +180,12 @@ export function addRemoveViewFromContainer( const renderer = container.view.renderer; if (node.type === LNodeType.Element) { if (insertMode) { + if (!node.native) { + // If the native element doesn't exist, this is a bound text node that hasn't yet been + // created because update mode has not run (occurs when a bound text node is a root + // node of a dynamically created view). See textBinding() in instructions for ctx. + (node as LTextNode).native = createTextNode('', renderer); + } isProceduralRenderer(renderer) ? renderer.insertBefore(parent, node.native !, beforeNode as RNode | null) : parent.insertBefore(node.native !, beforeNode as RNode | null, true); diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index 97f2e4852e..5ee8c67c0d 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -62,6 +62,9 @@ { "name": "createTView" }, + { + "name": "createTextNode" + }, { "name": "currentView" }, @@ -104,6 +107,9 @@ { "name": "getOrCreateTView" }, + { + "name": "getRenderFlags" + }, { "name": "hostElement" }, diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index 62c9287b50..3b1857f9d1 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -269,6 +269,9 @@ { "name": "createTView" }, + { + "name": "createTextNode" + }, { "name": "currentView" }, @@ -398,6 +401,9 @@ { "name": "getPreviousOrParentNode" }, + { + "name": "getRenderFlags" + }, { "name": "getRenderer" }, diff --git a/packages/core/test/render3/basic_perf.ts b/packages/core/test/render3/basic_perf.ts index 7f2613981c..b809ef7a4a 100644 --- a/packages/core/test/render3/basic_perf.ts +++ b/packages/core/test/render3/basic_perf.ts @@ -8,7 +8,7 @@ import {defineComponent} from '../../src/render3/index'; import {container, containerRefreshEnd, containerRefreshStart, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, text} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {document, renderComponent} from './render_util'; describe('iv perf test', () => { @@ -35,25 +35,27 @@ describe('iv perf test', () => { static ngComponentDef = defineComponent({ type: Component, selectors: [['div']], - template: function Template(ctx: any, cm: any) { - if (cm) { + template: function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - for (let i = 0; i < count; i++) { - let cm0 = embeddedViewStart(0); - { - if (cm0) { - elementStart(0, 'div'); - text(1, '-'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + for (let i = 0; i < count; i++) { + let rf0 = embeddedViewStart(0); + { + if (rf0 & RenderFlags.Create) { + elementStart(0, 'div'); + text(1, '-'); + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, factory: () => new Component }); diff --git a/packages/core/test/render3/change_detection_spec.ts b/packages/core/test/render3/change_detection_spec.ts index 32bf11c086..5fcbc3c016 100644 --- a/packages/core/test/render3/change_detection_spec.ts +++ b/packages/core/test/render3/change_detection_spec.ts @@ -12,7 +12,7 @@ import {ChangeDetectionStrategy, ChangeDetectorRef, DoCheck} from '../../src/cor import {getRenderedText, whenRendered} from '../../src/render3/component'; import {LifecycleHooksFeature, defineComponent, defineDirective, injectChangeDetectorRef} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, detectChanges, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation2, listener, markDirty, text, textBinding, tick} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {containerEl, createComponent, renderComponent, requestAnimationFrame} from './render_util'; describe('change detection', () => { @@ -27,13 +27,15 @@ describe('change detection', () => { type: MyComponent, selectors: [['my-comp']], factory: () => new MyComponent(), - template: (ctx: MyComponent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: MyComponent) => { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); text(1); elementEnd(); } - textBinding(1, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(1, bind(ctx.value)); + } } }); } @@ -102,8 +104,8 @@ describe('change detection', () => { * {{ doCheckCount }} - {{ name }} * */ - template: (ctx: MyComponent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: MyComponent) => { + if (rf & RenderFlags.Create) { text(0); elementStart(1, 'button'); { @@ -126,12 +128,14 @@ describe('change detection', () => { selectors: [['my-app']], factory: () => new MyApp(), /** */ - template: (ctx: MyApp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); elementEnd(); } - elementProperty(0, 'name', bind(ctx.name)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'name', bind(ctx.name)); + } }, directives: () => [MyComponent] }); @@ -195,8 +199,8 @@ describe('change detection', () => { it('should not check OnPush components in update mode when parent events occur', () => { function noop() {} - const ButtonParent = createComponent('button-parent', function(ctx: any, cm: boolean) { - if (cm) { + const ButtonParent = createComponent('button-parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); elementEnd(); elementStart(1, 'button', ['id', 'parent']); @@ -226,21 +230,23 @@ describe('change detection', () => { selectors: [['button-parent']], factory: () => parent = new ButtonParent(), /** {{ doCheckCount }} - */ - template: (ctx: ButtonParent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: ButtonParent) => { + if (rf & RenderFlags.Create) { text(0); elementStart(1, 'my-comp'); elementEnd(); } - textBinding(0, interpolation1('', ctx.doCheckCount, ' - ')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', ctx.doCheckCount, ' - ')); + } }, directives: () => [MyComponent], changeDetection: ChangeDetectionStrategy.OnPush }); } - const MyButtonApp = createComponent('my-button-app', function(ctx: any, cm: boolean) { - if (cm) { + const MyButtonApp = createComponent('my-button-app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button-parent'); elementEnd(); } @@ -285,11 +291,13 @@ describe('change detection', () => { selectors: [['my-comp']], factory: () => myComp = new MyComp(injectChangeDetectorRef()), /** {{ name }} */ - template: (ctx: MyComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: MyComp) => { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.name)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.name)); + } }, changeDetection: ChangeDetectionStrategy.OnPush }); @@ -310,13 +318,15 @@ describe('change detection', () => { * {{ doCheckCount}} - * */ - template: (ctx: ParentComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: ParentComp) => { + if (rf & RenderFlags.Create) { text(0); elementStart(1, 'my-comp'); elementEnd(); } - textBinding(0, interpolation1('', ctx.doCheckCount, ' - ')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', ctx.doCheckCount, ' - ')); + } }, directives: () => [MyComp] }); @@ -388,8 +398,8 @@ describe('change detection', () => { it('should check component view when called by directive on component node', () => { /** */ - const MyApp = createComponent('my-app', function(ctx: any, cm: boolean) { - if (cm) { + const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp', ['dir', '']); elementEnd(); } @@ -408,13 +418,15 @@ describe('change detection', () => { * {{ name }} *
*/ - const MyApp = createComponent('my-app', function(ctx: any, cm: boolean) { - if (cm) { + const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0); elementStart(1, 'div', ['dir', '']); elementEnd(); } - textBinding(1, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(1, bind(ctx.value)); + } }, [Dir]); const app = renderComponent(MyApp); @@ -444,23 +456,26 @@ describe('change detection', () => { *
* % } */ - template: function(ctx: MyApp, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: MyApp) { + if (rf & RenderFlags.Create) { text(0); container(1); } - textBinding(0, bind(ctx.name)); - containerRefreshStart(1); - { - if (ctx.showing) { - if (embeddedViewStart(0)) { - elementStart(0, 'div', ['dir', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.name)); + containerRefreshStart(1); + { + if (ctx.showing) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + elementStart(0, 'div', ['dir', '']); + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); + containerRefreshEnd(); } - containerRefreshEnd(); }, directives: [Dir] }); @@ -490,11 +505,13 @@ describe('change detection', () => { selectors: [['detect-changes-comp']], factory: () => new DetectChangesComp(injectChangeDetectorRef()), /** {{ value }} */ - template: (ctx: DetectChangesComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: DetectChangesComp) => { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.value)); + } } }); } @@ -519,11 +536,13 @@ describe('change detection', () => { selectors: [['detect-changes-comp']], factory: () => new DetectChangesComp(injectChangeDetectorRef()), /** {{ doCheckCount }} */ - template: (ctx: DetectChangesComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: DetectChangesComp) => { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.doCheckCount)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.doCheckCount)); + } } }); } @@ -545,8 +564,8 @@ describe('change detection', () => { selectors: [['my-app']], factory: () => new MyApp(injectChangeDetectorRef()), /** */ - template: (ctx: MyApp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { elementStart(0, 'detached-comp'); elementEnd(); } @@ -568,11 +587,13 @@ describe('change detection', () => { selectors: [['detached-comp']], factory: () => comp = new DetachedComp(injectChangeDetectorRef()), /** {{ value }} */ - template: (ctx: DetachedComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: DetachedComp) => { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.value)); + } } }); } @@ -664,11 +685,13 @@ describe('change detection', () => { selectors: [['on-push-comp']], factory: () => onPushComp = new OnPushComp(injectChangeDetectorRef()), /** {{ value }} */ - template: (ctx: OnPushComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.value)); + } }, changeDetection: ChangeDetectionStrategy.OnPush, inputs: {value: 'value'} @@ -676,12 +699,14 @@ describe('change detection', () => { } /** */ - const OnPushApp = createComponent('on-push-app', function(ctx: any, cm: boolean) { - if (cm) { + const OnPushApp = createComponent('on-push-app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'on-push-comp'); elementEnd(); } - elementProperty(0, 'value', bind(ctx.value)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'value', bind(ctx.value)); + } }, [OnPushComp]); const app = renderComponent(OnPushApp); @@ -720,11 +745,13 @@ describe('change detection', () => { selectors: [['on-push-comp']], factory: () => comp = new OnPushComp(injectChangeDetectorRef()), /** {{ value }} */ - template: (ctx: OnPushComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: OnPushComp) => { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.value)); + } }, changeDetection: ChangeDetectionStrategy.OnPush }); @@ -741,13 +768,15 @@ describe('change detection', () => { * {{ value }} - * */ - template: (ctx: OnPushParent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: OnPushParent) => { + if (rf & RenderFlags.Create) { text(0); elementStart(1, 'on-push-comp'); elementEnd(); } - textBinding(0, interpolation1('', ctx.value, ' - ')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', ctx.value, ' - ')); + } }, directives: () => [OnPushComp], changeDetection: ChangeDetectionStrategy.OnPush @@ -810,23 +839,26 @@ describe('change detection', () => { * * % } */ - template: (ctx: EmbeddedViewParent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { text(0); container(1); } - textBinding(0, interpolation1('', ctx.value, ' - ')); - containerRefreshStart(1); - { - if (ctx.showing) { - if (embeddedViewStart(0)) { - elementStart(0, 'on-push-comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', ctx.value, ' - ')); + containerRefreshStart(1); + { + if (ctx.showing) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + elementStart(0, 'on-push-comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, directives: () => [OnPushComp], changeDetection: ChangeDetectionStrategy.OnPush @@ -877,11 +909,13 @@ describe('change detection', () => { type: NoChangesComp, selectors: [['no-changes-comp']], factory: () => comp = new NoChangesComp(injectChangeDetectorRef()), - template: (ctx: NoChangesComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: NoChangesComp) => { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.value)); + } } }); } @@ -899,13 +933,15 @@ describe('change detection', () => { * {{ value }} - * */ - template: (ctx: AppComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: AppComp) => { + if (rf & RenderFlags.Create) { text(0); elementStart(1, 'no-changes-comp'); elementEnd(); } - textBinding(0, interpolation1('', ctx.value, ' - ')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', ctx.value, ' - ')); + } }, directives: () => [NoChangesComp] }); @@ -960,21 +996,26 @@ describe('change detection', () => { * {{ value }} * %} */ - template: (ctx: EmbeddedViewApp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: EmbeddedViewApp) => { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.showing) { - if (embeddedViewStart(0)) { - text(0); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.showing) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + text(0); + } + if (rf0 & RenderFlags.Update) { + textBinding(0, bind(ctx.value)); + } + embeddedViewEnd(); } - textBinding(0, bind(ctx.value)); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } }); } diff --git a/packages/core/test/render3/common_integration_spec.ts b/packages/core/test/render3/common_integration_spec.ts index 12e30404b4..511dd1f938 100644 --- a/packages/core/test/render3/common_integration_spec.ts +++ b/packages/core/test/render3/common_integration_spec.ts @@ -10,7 +10,7 @@ import {NgForOfContext} from '@angular/common'; import {defineComponent} from '../../src/render3/index'; import {bind, container, elementEnd, elementProperty, elementStart, interpolation3, text, textBinding, tick} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {NgForOf} from './common_with_def'; import {ComponentFixture} from './render_util'; @@ -28,21 +28,25 @@ describe('@angular/common integration', () => { //
    //
  • {{item}}
  • //
- template: (myApp: MyApp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, myApp: MyApp) => { + if (rf & RenderFlags.Create) { elementStart(0, 'ul'); { container(1, liTemplate, undefined, ['ngForOf', '']); } elementEnd(); } - elementProperty(1, 'ngForOf', bind(myApp.items)); + if (rf & RenderFlags.Update) { + elementProperty(1, 'ngForOf', bind(myApp.items)); + } - function liTemplate(row: NgForOfContext, cm: boolean) { - if (cm) { + function liTemplate(rf1: RenderFlags, row: NgForOfContext) { + if (rf1 & RenderFlags.Create) { elementStart(0, 'li'); { text(1); } elementEnd(); } - textBinding(1, bind(row.$implicit)); + if (rf1 & RenderFlags.Update) { + textBinding(1, bind(row.$implicit)); + } } }, directives: () => [NgForOf] @@ -84,22 +88,26 @@ describe('@angular/common integration', () => { //
    //
  • {{index}} of {{count}}: {{item}}
  • //
- template: (myApp: MyApp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, myApp: MyApp) => { + if (rf & RenderFlags.Create) { elementStart(0, 'ul'); { container(1, liTemplate, undefined, ['ngForOf', '']); } elementEnd(); } - elementProperty(1, 'ngForOf', bind(myApp.items)); + if (rf & RenderFlags.Update) { + elementProperty(1, 'ngForOf', bind(myApp.items)); + } - function liTemplate(row: NgForOfContext, cm: boolean) { - if (cm) { + function liTemplate(rf1: RenderFlags, row: NgForOfContext) { + if (rf1 & RenderFlags.Create) { elementStart(0, 'li'); { text(1); } elementEnd(); } - textBinding( - 1, interpolation3('', row.index, ' of ', row.count, ': ', row.$implicit, '')); + if (rf1 & RenderFlags.Update) { + textBinding( + 1, interpolation3('', row.index, ' of ', row.count, ': ', row.$implicit, '')); + } } }, directives: () => [NgForOf] diff --git a/packages/core/test/render3/compiler_canonical/component_directives_spec.ts b/packages/core/test/render3/compiler_canonical/component_directives_spec.ts index 104d0af439..70fa2abbcf 100644 --- a/packages/core/test/render3/compiler_canonical/component_directives_spec.ts +++ b/packages/core/test/render3/compiler_canonical/component_directives_spec.ts @@ -12,11 +12,10 @@ import {renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('components & directives', () => { - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; type $any$ = any; type $number$ = number; - it('should instantiate directives', () => { type $ChildComponent$ = ChildComponent; type $MyComponent$ = MyComponent; @@ -29,9 +28,9 @@ describe('components & directives', () => { static ngComponentDef = $r3$.ɵdefineComponent({ type: ChildComponent, selectors: [['child']], - factory: () => new ChildComponent(), - template: function(ctx: $ChildComponent$, cm: $boolean$) { - if (cm) { + factory: function ChildComponent_Factory() { return new ChildComponent(); }, + template: function ChildComponent_Template(rf: $RenderFlags$, ctx: $ChildComponent$) { + if (rf & 1) { $r3$.ɵT(0, 'child-view'); } } @@ -65,8 +64,8 @@ describe('components & directives', () => { type: MyComponent, selectors: [['my-component']], factory: () => new MyComponent(), - template: function(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'child', $e0_attrs$); $r3$.ɵe(); $r3$.ɵT(1, '!'); @@ -117,8 +116,8 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'div', $e0_attrs$); $r3$.ɵe(); } @@ -167,8 +166,8 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'button', $e0_attrs$); $r3$.ɵT(1, 'Click'); $r3$.ɵe(); @@ -213,8 +212,8 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'div', $e0_attrs$); $r3$.ɵe(); } @@ -261,8 +260,8 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'div', $e0_attrs$); $r3$.ɵe(); } @@ -296,8 +295,8 @@ describe('components & directives', () => { type: MyComp, selectors: [['my-comp']], factory: function MyComp_Factory() { return new MyComp(); }, - template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) { - if (cm) { + template: function MyComp_Template(rf: $RenderFlags$, ctx: $MyComp$) { + if (rf & 1) { $r3$.ɵT(0); } $r3$.ɵt(0, $r3$.ɵb(ctx.name)); @@ -321,12 +320,14 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'my-comp'); $r3$.ɵe(); } - $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name)); + if (rf & 2) { + $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name)); + } } }); } @@ -370,23 +371,27 @@ describe('components & directives', () => { type: MyComponent, selectors: [['my-component']], factory: () => new MyComponent(), - template: function(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'ul', null, $e0_locals$); $r3$.ɵC(2, C1, '', ['if', '']); $r3$.ɵe(); } let $foo$ = $r3$.ɵld(1); - $r3$.ɵcR(2); - $r3$.ɵcr(); + if (rf & 2) { + $r3$.ɵcR(2); + $r3$.ɵcr(); + } - function C1(ctx1: $any$, cm: $boolean$) { - if (cm) { + function C1(rf1: $RenderFlags$, ctx1: $any$) { + if (rf1 & 1) { $r3$.ɵE(0, 'li'); $r3$.ɵT(1); $r3$.ɵe(); } - $r3$.ɵt(1, $r3$.ɵi2('', ctx.salutation, ' ', $foo$, '')); + if (rf1 & 2) { + $r3$.ɵt(1, $r3$.ɵi2('', ctx.salutation, ' ', $foo$, '')); + } } } }); @@ -413,11 +418,13 @@ describe('components & directives', () => { type: MyArrayComp, selectors: [['my-array-comp']], factory: function MyArrayComp_Factory() { return new MyArrayComp(); }, - template: function MyArrayComp_Template(ctx: $MyArrayComp$, cm: $boolean$) { - if (cm) { + template: function MyArrayComp_Template(rf: $RenderFlags$, ctx: $MyArrayComp$) { + if (rf & 1) { $r3$.ɵT(0); } - $r3$.ɵt(0, $r3$.ɵi2('', ctx.names[0], ' ', ctx.names[1], '')); + if (rf & 2) { + $r3$.ɵt(0, $r3$.ɵi2('', ctx.names[0], ' ', ctx.names[1], '')); + } }, inputs: {names: 'names'} }); @@ -442,12 +449,14 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'my-array-comp'); $r3$.ɵe(); } - $r3$.ɵp(0, 'names', cm ? $e0_arr$ : $r3$.ɵNC); + if (rf & 2) { + $r3$.ɵp(0, 'names', rf & 1 ? $e0_arr$ : $r3$.ɵNC); + } } }); // /NORMATIVE @@ -484,12 +493,14 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'my-array-comp'); $r3$.ɵe(); } - $r3$.ɵp(0, 'names', $r3$.ɵb(ctx.someFn($r3$.ɵf0($e0_ff$)))); + if (rf & 2) { + $r3$.ɵp(0, 'names', $r3$.ɵb(ctx.someFn($r3$.ɵf0($e0_ff$)))); + } } }); // /NORMATIVE @@ -514,11 +525,13 @@ describe('components & directives', () => { type: MyComp, selectors: [['my-comp']], factory: function MyComp_Factory() { return new MyComp(); }, - template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) { - if (cm) { + template: function MyComp_Template(rf: $RenderFlags$, ctx: $MyComp$) { + if (rf & 1) { $r3$.ɵT(0); } - $r3$.ɵt(0, $r3$.ɵb(ctx.num)); + if (rf & 2) { + $r3$.ɵt(0, $r3$.ɵb(ctx.num)); + } }, inputs: {num: 'num'} }); @@ -540,12 +553,14 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'my-comp'); $r3$.ɵe(); } - $r3$.ɵp(0, 'num', $r3$.ɵb($r3$.ɵf0($e0_ff$).length + 1)); + if (rf & 2) { + $r3$.ɵp(0, 'num', $r3$.ɵb($r3$.ɵf0($e0_ff$).length + 1)); + } } }); // /NORMATIVE @@ -580,12 +595,14 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'my-array-comp'); $r3$.ɵe(); } - $r3$.ɵp(0, 'names', $r3$.ɵb($r3$.ɵf1($e0_ff$, ctx.customName))); + if (rf & 2) { + $r3$.ɵp(0, 'names', $r3$.ɵb($r3$.ɵf1($e0_ff$, ctx.customName))); + } } }); // /NORMATIVE @@ -624,8 +641,8 @@ describe('components & directives', () => { type: MyComp, selectors: [['my-comp']], factory: function MyComp_Factory() { return new MyComp(); }, - template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) { - if (cm) { + template: function MyComp_Template(rf: $RenderFlags$, ctx: $MyComp$) { + if (rf & 1) { $r3$.ɵT(0); $r3$.ɵT(1); $r3$.ɵT(2); @@ -639,18 +656,20 @@ describe('components & directives', () => { $r3$.ɵT(10); $r3$.ɵT(11); } - $r3$.ɵt(0, $r3$.ɵb(ctx.names[0])); - $r3$.ɵt(1, $r3$.ɵb(ctx.names[1])); - $r3$.ɵt(2, $r3$.ɵb(ctx.names[2])); - $r3$.ɵt(3, $r3$.ɵb(ctx.names[3])); - $r3$.ɵt(4, $r3$.ɵb(ctx.names[4])); - $r3$.ɵt(5, $r3$.ɵb(ctx.names[5])); - $r3$.ɵt(6, $r3$.ɵb(ctx.names[6])); - $r3$.ɵt(7, $r3$.ɵb(ctx.names[7])); - $r3$.ɵt(8, $r3$.ɵb(ctx.names[8])); - $r3$.ɵt(9, $r3$.ɵb(ctx.names[9])); - $r3$.ɵt(10, $r3$.ɵb(ctx.names[10])); - $r3$.ɵt(11, $r3$.ɵb(ctx.names[11])); + if (rf & 2) { + $r3$.ɵt(0, $r3$.ɵb(ctx.names[0])); + $r3$.ɵt(1, $r3$.ɵb(ctx.names[1])); + $r3$.ɵt(2, $r3$.ɵb(ctx.names[2])); + $r3$.ɵt(3, $r3$.ɵb(ctx.names[3])); + $r3$.ɵt(4, $r3$.ɵb(ctx.names[4])); + $r3$.ɵt(5, $r3$.ɵb(ctx.names[5])); + $r3$.ɵt(6, $r3$.ɵb(ctx.names[6])); + $r3$.ɵt(7, $r3$.ɵb(ctx.names[7])); + $r3$.ɵt(8, $r3$.ɵb(ctx.names[8])); + $r3$.ɵt(9, $r3$.ɵb(ctx.names[9])); + $r3$.ɵt(10, $r3$.ɵb(ctx.names[10])); + $r3$.ɵt(11, $r3$.ɵb(ctx.names[11])); + } }, inputs: {names: 'names'} }); @@ -685,14 +704,17 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(c: MyApp, cm: boolean) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, c: $any$) { + if (rf & 1) { $r3$.ɵE(0, 'my-comp'); $r3$.ɵe(); } - $r3$.ɵp( - 0, 'names', - $r3$.ɵb($r3$.ɵfV($e0_ff$, [c.n0, c.n1, c.n2, c.n3, c.n4, c.n5, c.n6, c.n7, c.n8]))); + if (rf & 2) { + $r3$.ɵp( + 0, 'names', + $r3$.ɵb( + $r3$.ɵfV($e0_ff$, [c.n0, c.n1, c.n2, c.n3, c.n4, c.n5, c.n6, c.n7, c.n8]))); + } } }); // /NORMATIVE @@ -723,8 +745,8 @@ describe('components & directives', () => { type: ObjectComp, selectors: [['object-comp']], factory: function ObjectComp_Factory() { return new ObjectComp(); }, - template: function ObjectComp_Template(ctx: $ObjectComp$, cm: $boolean$) { - if (cm) { + template: function ObjectComp_Template(rf: $RenderFlags$, ctx: $ObjectComp$) { + if (rf & 1) { $r3$.ɵE(0, 'p'); $r3$.ɵT(1); $r3$.ɵe(); @@ -732,8 +754,10 @@ describe('components & directives', () => { $r3$.ɵT(3); $r3$.ɵe(); } - $r3$.ɵt(1, $r3$.ɵb(ctx.config['duration'])); - $r3$.ɵt(3, $r3$.ɵb(ctx.config.animation)); + if (rf & 2) { + $r3$.ɵt(1, $r3$.ɵb(ctx.config['duration'])); + $r3$.ɵt(3, $r3$.ɵb(ctx.config.animation)); + } }, inputs: {config: 'config'} }); @@ -757,12 +781,14 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'object-comp'); $r3$.ɵe(); } - $r3$.ɵp(0, 'config', $r3$.ɵb($r3$.ɵf1($e0_ff$, ctx.name))); + if (rf & 2) { + $r3$.ɵp(0, 'config', $r3$.ɵb($r3$.ɵf1($e0_ff$, ctx.name))); + } } }); // /NORMATIVE @@ -794,8 +820,8 @@ describe('components & directives', () => { type: NestedComp, selectors: [['nested-comp']], factory: function NestedComp_Factory() { return new NestedComp(); }, - template: function NestedComp_Template(ctx: $NestedComp$, cm: $boolean$) { - if (cm) { + template: function NestedComp_Template(rf: $RenderFlags$, ctx: $NestedComp$) { + if (rf & 1) { $r3$.ɵE(0, 'p'); $r3$.ɵT(1); $r3$.ɵe(); @@ -806,9 +832,11 @@ describe('components & directives', () => { $r3$.ɵT(5); $r3$.ɵe(); } - $r3$.ɵt(1, $r3$.ɵb(ctx.config.animation)); - $r3$.ɵt(3, $r3$.ɵb(ctx.config.actions[0].opacity)); - $r3$.ɵt(5, $r3$.ɵb(ctx.config.actions[1].duration)); + if (rf & 2) { + $r3$.ɵt(1, $r3$.ɵb(ctx.config.animation)); + $r3$.ɵt(3, $r3$.ɵb(ctx.config.actions[0].opacity)); + $r3$.ɵt(5, $r3$.ɵb(ctx.config.actions[1].duration)); + } }, inputs: {config: 'config'} }); @@ -837,15 +865,17 @@ describe('components & directives', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'nested-comp'); $r3$.ɵe(); } - $r3$.ɵp( - 0, 'config', $r3$.ɵf2( - $e0_ff_2$, ctx.name, - $r3$.ɵb($r3$.ɵf1($e0_ff_1$, $r3$.ɵf1($e0_ff$, ctx.duration))))); + if (rf & 2) { + $r3$.ɵp( + 0, 'config', $r3$.ɵf2( + $e0_ff_2$, ctx.name, + $r3$.ɵb($r3$.ɵf1($e0_ff_1$, $r3$.ɵf1($e0_ff$, ctx.duration))))); + } } }); // /NORMATIVE diff --git a/packages/core/test/render3/compiler_canonical/content_projection_spec.ts b/packages/core/test/render3/compiler_canonical/content_projection_spec.ts index c93eb10296..12171ea99a 100644 --- a/packages/core/test/render3/compiler_canonical/content_projection_spec.ts +++ b/packages/core/test/render3/compiler_canonical/content_projection_spec.ts @@ -8,11 +8,10 @@ import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core'; import * as $r3$ from '../../../src/core_render3_private_export'; -import {renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('content projection', () => { - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; it('should support content projection', () => { type $SimpleComponent$ = SimpleComponent; @@ -26,8 +25,8 @@ describe('content projection', () => { type: SimpleComponent, selectors: [['simple']], factory: () => new SimpleComponent(), - template: function(ctx: $SimpleComponent$, cm: $boolean$) { - if (cm) { + template: function(rf: $RenderFlags$, ctx: $SimpleComponent$) { + if (rf & 1) { $r3$.ɵpD(0); $r3$.ɵE(1, 'div'); $r3$.ɵP(2, 0); @@ -56,8 +55,8 @@ describe('content projection', () => { type: ComplexComponent, selectors: [['complex']], factory: () => new ComplexComponent(), - template: function(ctx: $ComplexComponent$, cm: $boolean$) { - if (cm) { + template: function(rf: $RenderFlags$, ctx: $ComplexComponent$) { + if (rf & 1) { $r3$.ɵpD(0, $pD_0P$, $pD_0R$); $r3$.ɵE(1, 'div', ['id', 'first']); $r3$.ɵP(2, 0, 1); @@ -81,8 +80,8 @@ describe('content projection', () => { type: MyApp, selectors: [['my-app']], factory: () => new MyApp(), - template: function(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'simple'); $r3$.ɵT(1, 'content'); $r3$.ɵe(); diff --git a/packages/core/test/render3/compiler_canonical/elements_spec.ts b/packages/core/test/render3/compiler_canonical/elements_spec.ts index bf54e09ddd..46f2f4489d 100644 --- a/packages/core/test/render3/compiler_canonical/elements_spec.ts +++ b/packages/core/test/render3/compiler_canonical/elements_spec.ts @@ -13,10 +13,9 @@ import {ComponentFixture, renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('elements', () => { - // Saving type as $boolean$, etc to simplify testing for compiler, as types aren't saved - type $boolean$ = boolean; + // Saving type as $any$, etc to simplify testing for compiler, as types aren't saved type $any$ = any; - type $number$ = number; + type $RenderFlags$ = $r3$.ɵRenderFlags; it('should translate DOM structure', () => { type $MyComponent$ = MyComponent; @@ -34,8 +33,8 @@ describe('elements', () => { type: MyComponent, selectors: [['my-component']], factory: () => new MyComponent(), - template: function(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div', $e0_attrs$); $r3$.ɵT(1, 'Hello '); $r3$.ɵE(2, 'b'); @@ -85,15 +84,19 @@ describe('elements', () => { type: LocalRefComp, selectors: [['local-ref-comp']], factory: function LocalRefComp_Factory() { return new LocalRefComp(); }, - template: function LocalRefComp_Template(ctx: $LocalRefComp$, cm: $boolean$) { - if (cm) { + template: function LocalRefComp_Template(rf: $RenderFlags$, ctx: $LocalRefComp$) { + let $tmp$: any; + let $tmp_2$: any; + if (rf & 1) { $r3$.ɵE(0, 'div', $e0_attrs$, $e0_locals$); $r3$.ɵe(); $r3$.ɵT(3); } - const $tmp$ = $r3$.ɵld(1) as any; - const $tmp_2$ = $r3$.ɵld(2) as any; - $r3$.ɵt(3, $r3$.ɵi2(' ', $tmp$.value, ' - ', $tmp_2$.tagName, '')); + if (rf & 2) { + $tmp$ = $r3$.ɵld(1); + $tmp_2$ = $r3$.ɵld(2); + $r3$.ɵt(3, $r3$.ɵi2(' ', $tmp$.value, ' - ', $tmp_2$.tagName, '')); + } } }); // /NORMATIVE @@ -125,8 +128,8 @@ describe('elements', () => { type: ListenerComp, selectors: [['listener-comp']], factory: function ListenerComp_Factory() { return new ListenerComp(); }, - template: function ListenerComp_Template(ctx: $ListenerComp$, cm: $boolean$) { - if (cm) { + template: function ListenerComp_Template(rf: $RenderFlags$, ctx: $ListenerComp$) { + if (rf & 1) { $r3$.ɵE(0, 'button'); $r3$.ɵL('click', function ListenerComp_click_Handler() { return ctx.onClick(); }); $r3$.ɵL('keypress', function ListenerComp_keypress_Handler($event: $any$) { @@ -157,12 +160,14 @@ describe('elements', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div'); $r3$.ɵe(); } - $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someProperty)); + if (rf & 2) { + $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someProperty)); + } } }); // /NORMATIVE @@ -187,12 +192,14 @@ describe('elements', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div'); $r3$.ɵe(); } - $r3$.ɵa(0, 'title', $r3$.ɵb(ctx.someAttribute)); + if (rf & 2) { + $r3$.ɵa(0, 'title', $r3$.ɵb(ctx.someAttribute)); + } } }); // /NORMATIVE @@ -217,12 +224,14 @@ describe('elements', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div'); $r3$.ɵe(); } - $r3$.ɵkn(0, 'foo', $r3$.ɵb(ctx.someFlag)); + if (rf & 2) { + $r3$.ɵkn(0, 'foo', $r3$.ɵb(ctx.someFlag)); + } } }); // /NORMATIVE @@ -251,13 +260,15 @@ describe('elements', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div'); $r3$.ɵe(); } - $r3$.ɵsn(0, 'color', $r3$.ɵb(ctx.someColor)); - $r3$.ɵsn(0, 'width', $r3$.ɵb(ctx.someWidth), 'px'); + if (rf & 2) { + $r3$.ɵsn(0, 'color', $r3$.ɵb(ctx.someColor)); + $r3$.ɵsn(0, 'width', $r3$.ɵb(ctx.someWidth), 'px'); + } } }); // /NORMATIVE @@ -299,13 +310,15 @@ describe('elements', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div', $e0_attrs$); $r3$.ɵe(); } - $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someString + 1)); - $r3$.ɵkn(0, 'foo', $r3$.ɵb(ctx.someString == 'initial')); + if (rf & 2) { + $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someString + 1)); + $r3$.ɵkn(0, 'foo', $r3$.ɵb(ctx.someString == 'initial')); + } } }); // /NORMATIVE @@ -333,13 +346,15 @@ describe('elements', () => { type: StyleComponent, selectors: [['style-comp']], factory: function StyleComponent_Factory() { return new StyleComponent(); }, - template: function StyleComponent_Template(ctx: $StyleComponent$, cm: $boolean$) { - if (cm) { + template: function StyleComponent_Template(rf: $RenderFlags$, ctx: $StyleComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div'); $r3$.ɵe(); } - $r3$.ɵk(0, $r3$.ɵb(ctx.classExp)); - $r3$.ɵs(0, $r3$.ɵb(ctx.styleExp)); + if (rf & 2) { + $r3$.ɵk(0, $r3$.ɵb(ctx.classExp)); + $r3$.ɵs(0, $r3$.ɵb(ctx.styleExp)); + } } }); // /NORMATIVE diff --git a/packages/core/test/render3/compiler_canonical/injection_spec.ts b/packages/core/test/render3/compiler_canonical/injection_spec.ts index 0c0ae36537..4c08f69e9e 100644 --- a/packages/core/test/render3/compiler_canonical/injection_spec.ts +++ b/packages/core/test/render3/compiler_canonical/injection_spec.ts @@ -14,7 +14,7 @@ import {renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('injection', () => { - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; describe('directives', () => { // Directives (and Components) should use `directiveInject` @@ -34,11 +34,13 @@ describe('injection', () => { factory: function MyComp_Factory() { return new MyComp($r3$.ɵinjectChangeDetectorRef()); }, - template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) { - if (cm) { + template: function MyComp_Template(rf: $RenderFlags$, ctx: $MyComp$) { + if (rf & 1) { $r3$.ɵT(0); } - $r3$.ɵt(0, $r3$.ɵb(ctx.value)); + if (rf & 2) { + $r3$.ɵt(0, $r3$.ɵb(ctx.value)); + } } }); // /NORMATIVE @@ -50,8 +52,8 @@ describe('injection', () => { selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, /** */ - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'my-comp'); $r3$.ɵe(); } @@ -79,11 +81,13 @@ describe('injection', () => { type: MyComp, selectors: [['my-comp']], factory: function MyComp_Factory() { return new MyComp($r3$.ɵinjectAttribute('title')); }, - template: function MyComp_Template(ctx: $MyComp$, cm: $boolean$) { - if (cm) { + template: function MyComp_Template(rf: $RenderFlags$, ctx: $MyComp$) { + if (rf & 1) { $r3$.ɵT(0); } - $r3$.ɵt(0, $r3$.ɵb(ctx.title)); + if (rf & 2) { + $r3$.ɵt(0, $r3$.ɵb(ctx.title)); + } } }); // /NORMATIVE @@ -95,8 +99,8 @@ describe('injection', () => { selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, /** */ - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'my-comp', e0_attrs); $r3$.ɵe(); } @@ -148,7 +152,7 @@ describe('injection', () => { $r3$.ɵdirectiveInject(ServiceA), $r3$.ɵdirectiveInject(ServiceB), inject(INJECTOR)); }, /** */ - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) {}, + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {}, providers: [ServiceA], viewProviders: [ServiceB], }); diff --git a/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts b/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts index 23272df9af..c3e2a4dbb2 100644 --- a/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts +++ b/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts @@ -15,7 +15,7 @@ describe('lifecycle hooks', () => { let events: string[] = []; let simpleLayout: SimpleLayout; - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; type $LifecycleComp$ = LifecycleComp; type $SimpleLayout$ = SimpleLayout; @@ -43,7 +43,7 @@ describe('lifecycle hooks', () => { type: LifecycleComp, selectors: [['lifecycle-comp']], factory: function LifecycleComp_Factory() { return new LifecycleComp(); }, - template: function LifecycleComp_Template(ctx: $LifecycleComp$, cm: $boolean$) {}, + template: function LifecycleComp_Template(rf: $RenderFlags$, ctx: $LifecycleComp$) {}, inputs: {nameMin: 'name'}, features: [$r3$.ɵNgOnChangesFeature({nameMin: 'nameMin'})] }); @@ -66,15 +66,17 @@ describe('lifecycle hooks', () => { type: SimpleLayout, selectors: [['simple-layout']], factory: function SimpleLayout_Factory() { return simpleLayout = new SimpleLayout(); }, - template: function SimpleLayout_Template(ctx: $SimpleLayout$, cm: $boolean$) { - if (cm) { + template: function SimpleLayout_Template(rf: $RenderFlags$, ctx: $SimpleLayout$) { + if (rf & 1) { $r3$.ɵE(0, 'lifecycle-comp'); $r3$.ɵe(); $r3$.ɵE(1, 'lifecycle-comp'); $r3$.ɵe(); } - $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1)); - $r3$.ɵp(1, 'name', $r3$.ɵb(ctx.name2)); + if (rf & 2) { + $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1)); + $r3$.ɵp(1, 'name', $r3$.ɵb(ctx.name2)); + } } }); // /NORMATIVE diff --git a/packages/core/test/render3/compiler_canonical/local_reference_spec.ts b/packages/core/test/render3/compiler_canonical/local_reference_spec.ts index 7f60b95517..99b6c6ecbf 100644 --- a/packages/core/test/render3/compiler_canonical/local_reference_spec.ts +++ b/packages/core/test/render3/compiler_canonical/local_reference_spec.ts @@ -12,7 +12,7 @@ import {renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('local references', () => { - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; // TODO(misko): currently disabled until local refs are working xit('should translate DOM structure', () => { @@ -25,14 +25,17 @@ describe('local references', () => { type: MyComponent, selectors: [['my-component']], factory: () => new MyComponent, - template: function(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function(rf: $RenderFlags$, ctx: $MyComponent$) { + let l1_user: any; + if (rf & 1) { $r3$.ɵE(0, 'input', null, ['user', '']); $r3$.ɵe(); $r3$.ɵT(2); } - const l1_user = $r3$.ɵld(1); - $r3$.ɵt(2, $r3$.ɵi1('Hello ', l1_user.value, '!')); + if (rf & 2) { + l1_user = $r3$.ɵld(1); + $r3$.ɵt(2, $r3$.ɵi1('Hello ', l1_user.value, '!')); + } } }); // NORMATIVE diff --git a/packages/core/test/render3/compiler_canonical/pipes_spec.ts b/packages/core/test/render3/compiler_canonical/pipes_spec.ts index 9221efce35..e8a526e83e 100644 --- a/packages/core/test/render3/compiler_canonical/pipes_spec.ts +++ b/packages/core/test/render3/compiler_canonical/pipes_spec.ts @@ -13,7 +13,7 @@ import {containerEl, renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('pipes', () => { type $any$ = any; - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; let myPipeTransformCalls = 0; let myPurePipeTransformCalls = 0; @@ -81,13 +81,15 @@ describe('pipes', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵT(0); $r3$.ɵPp(1, 'myPipe'); $r3$.ɵPp(2, 'myPurePipe'); } - $r3$.ɵt(0, $r3$.ɵi1('', $r3$.ɵpb2(1, $r3$.ɵpb2(2, ctx.name, ctx.size), ctx.size), '')); + if (rf & 2) { + $r3$.ɵt(0, $r3$.ɵi1('', $r3$.ɵpb2(1, $r3$.ɵpb2(2, ctx.name, ctx.size), ctx.size), '')); + } } }); // /NORMATIVE @@ -154,28 +156,32 @@ describe('pipes', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵT(0); $r3$.ɵPp(1, 'myPurePipe'); $r3$.ɵT(2); $r3$.ɵPp(3, 'myPurePipe'); $r3$.ɵC(4, C4, '', ['oneTimeIf', '']); } - $r3$.ɵt(0, $r3$.ɵi1('', $r3$.ɵpb2(1, ctx.name, ctx.size), '')); - $r3$.ɵt(2, $r3$.ɵi1('', $r3$.ɵpb2(3, ctx.name, ctx.size), '')); - $r3$.ɵp(4, 'oneTimeIf', $r3$.ɵb(ctx.more)); - $r3$.ɵcR(4); - $r3$.ɵcr(); + if (rf & 2) { + $r3$.ɵt(0, $r3$.ɵi1('', $r3$.ɵpb2(1, ctx.name, ctx.size), '')); + $r3$.ɵt(2, $r3$.ɵi1('', $r3$.ɵpb2(3, ctx.name, ctx.size), '')); + $r3$.ɵp(4, 'oneTimeIf', $r3$.ɵb(ctx.more)); + $r3$.ɵcR(4); + $r3$.ɵcr(); + } - function C4(ctx1: $any$, cm: $boolean$) { - if (cm) { + function C4(rf: $RenderFlags$, ctx1: $any$) { + if (rf & 1) { $r3$.ɵE(0, 'div'); $r3$.ɵT(1); $r3$.ɵPp(2, 'myPurePipe'); $r3$.ɵe(); } - $r3$.ɵt(1, $r3$.ɵi1('', $r3$.ɵpb2(2, ctx.name, ctx.size), '')); + if (rf & 2) { + $r3$.ɵt(1, $r3$.ɵi1('', $r3$.ɵpb2(2, ctx.name, ctx.size), '')); + } } } }); diff --git a/packages/core/test/render3/compiler_canonical/query_spec.ts b/packages/core/test/render3/compiler_canonical/query_spec.ts index 10c333ccb6..ebe310a4d2 100644 --- a/packages/core/test/render3/compiler_canonical/query_spec.ts +++ b/packages/core/test/render3/compiler_canonical/query_spec.ts @@ -12,7 +12,7 @@ import {renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('queries', () => { - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; type $number$ = number; let someDir: SomeDirective; @@ -50,18 +50,20 @@ describe('queries', () => { type: ViewQueryComponent, selectors: [['view-query-component']], factory: function ViewQueryComponent_Factory() { return new ViewQueryComponent(); }, - template: function ViewQueryComponent_Template(ctx: $ViewQueryComponent$, cm: $boolean$) { + template: function ViewQueryComponent_Template( + rf: $RenderFlags$, ctx: $ViewQueryComponent$) { let $tmp$: any; - if (cm) { + if (rf & 1) { $r3$.ɵQ(0, SomeDirective, false); $r3$.ɵQ(1, SomeDirective, false); $r3$.ɵE(2, 'div', $e1_attrs$); $r3$.ɵe(); } - - $r3$.ɵqR($tmp$ = $r3$.ɵld>(0)) && (ctx.someDir = $tmp$.first); - $r3$.ɵqR($tmp$ = $r3$.ɵld>(1)) && - (ctx.someDirList = $tmp$ as QueryList); + if (rf & 2) { + $r3$.ɵqR($tmp$ = $r3$.ɵld>(0)) && (ctx.someDir = $tmp$.first); + $r3$.ɵqR($tmp$ = $r3$.ɵld>(1)) && + (ctx.someDirList = $tmp$ as QueryList); + } } }); // /NORMATIVE @@ -110,8 +112,8 @@ describe('queries', () => { $r3$.ɵqR($tmp$ = $r3$.ɵd(dirIndex)[2]) && ($instance$.someDirList = $tmp$); }, template: function ContentQueryComponent_Template( - ctx: $ContentQueryComponent$, cm: $boolean$) { - if (cm) { + rf: $number$, ctx: $ContentQueryComponent$) { + if (rf & 1) { $r3$.ɵpD(0); $r3$.ɵE(1, 'div'); $r3$.ɵP(2, 0); @@ -138,8 +140,8 @@ describe('queries', () => { type: MyApp, selectors: [['my-app']], factory: function MyApp_Factory() { return new MyApp(); }, - template: function MyApp_Template(ctx: $MyApp$, cm: $boolean$) { - if (cm) { + template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { + if (rf & 1) { $r3$.ɵE(0, 'content-query-component'); contentQueryComp = $r3$.ɵd(0)[0]; $r3$.ɵE(1, 'div', $e2_attrs$); diff --git a/packages/core/test/render3/compiler_canonical/sanitize_spec.ts b/packages/core/test/render3/compiler_canonical/sanitize_spec.ts index 78f5792707..8137445076 100644 --- a/packages/core/test/render3/compiler_canonical/sanitize_spec.ts +++ b/packages/core/test/render3/compiler_canonical/sanitize_spec.ts @@ -19,7 +19,8 @@ import {renderComponent, toHtml} from '../render_util'; */ describe('compiler sanitization', () => { - type $boolean$ = boolean; + type $RenderFlags$ = $r3$.ɵRenderFlags; + it('should translate DOM structure', () => { type $MyComponent$ = MyComponent; @@ -40,18 +41,20 @@ describe('compiler sanitization', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'div'); $r3$.ɵe(); $r3$.ɵE(1, 'img'); $r3$.ɵe(); } - $r3$.ɵp(0, 'innerHTML', $r3$.ɵb(ctx.innerHTML), $r3$.ɵsanitizeHtml); - $r3$.ɵp(0, 'hidden', $r3$.ɵb(ctx.hidden)); - $r3$.ɵsn(1, 'background-image', $r3$.ɵb(ctx.style), $r3$.ɵsanitizeStyle); - $r3$.ɵp(1, 'src', $r3$.ɵb(ctx.url), $r3$.ɵsanitizeUrl); - $r3$.ɵa(1, 'srcset', $r3$.ɵb(ctx.url), $r3$.ɵsanitizeUrl); + if (rf & 2) { + $r3$.ɵp(0, 'innerHTML', $r3$.ɵb(ctx.innerHTML), $r3$.ɵsanitizeHtml); + $r3$.ɵp(0, 'hidden', $r3$.ɵb(ctx.hidden)); + $r3$.ɵsn(1, 'background-image', $r3$.ɵb(ctx.style), $r3$.ɵsanitizeStyle); + $r3$.ɵp(1, 'src', $r3$.ɵb(ctx.url), $r3$.ɵsanitizeUrl); + $r3$.ɵa(1, 'srcset', $r3$.ɵb(ctx.url), $r3$.ɵsanitizeUrl); + } } }); // /NORMATIVE diff --git a/packages/core/test/render3/compiler_canonical/small_app_spec.ts b/packages/core/test/render3/compiler_canonical/small_app_spec.ts index 69b98adf0d..25807caeb0 100644 --- a/packages/core/test/render3/compiler_canonical/small_app_spec.ts +++ b/packages/core/test/render3/compiler_canonical/small_app_spec.ts @@ -21,6 +21,8 @@ interface ToDo { done: boolean; } +type $RenderFlags$ = r3.RenderFlags; + @Injectable() class AppState { todos: ToDo[] = [ @@ -62,16 +64,18 @@ class ToDoAppComponent { factory: function ToDoAppComponent_Factory() { return new ToDoAppComponent(r3.directiveInject(AppState)); }, - template: function ToDoAppComponent_Template(ctx: ToDoAppComponent, cm: boolean) { - if (cm) { + template: function ToDoAppComponent_Template(rf: $RenderFlags$, ctx: ToDoAppComponent) { + if (rf & 1) { const ToDoAppComponent_NgForOf_Template = function ToDoAppComponent_NgForOf_Template( - ctx1: NgForOfContext, cm: boolean) { - if (cm) { + rf: $RenderFlags$, ctx1: NgForOfContext) { + if (rf & 1) { r3.E(0, 'todo'); r3.L('archive', ctx.onArchive.bind(ctx)); r3.e(); } - r3.p(0, 'todo', r3.b(ctx1.$implicit)); + if (rf & 2) { + r3.p(0, 'todo', r3.b(ctx1.$implicit)); + } }; r3.E(0, 'h1'); r3.T(1, 'ToDo Application'); @@ -83,7 +87,9 @@ class ToDoAppComponent { r3.T(5); r3.e(); } - r3.t(5, r3.i1('count: ', ctx.appState.todos.length, '')); + if (rf & 2) { + r3.t(5, r3.i1('count: ', ctx.appState.todos.length, '')); + } } }); // /NORMATIVE @@ -125,8 +131,8 @@ class ToDoItemComponent { type: ToDoItemComponent, selectors: [['todo']], factory: function ToDoItemComponent_Factory() { return new ToDoItemComponent(); }, - template: function ToDoItemComponent_Template(ctx: ToDoItemComponent, cm: boolean) { - if (cm) { + template: function ToDoItemComponent_Template(rf: $RenderFlags$, ctx: ToDoItemComponent) { + if (rf & 1) { r3.E(0, 'div'); r3.E(1, 'input', e1_attrs); r3.L('click', ctx.onCheckboxClick.bind(ctx)); @@ -140,8 +146,10 @@ class ToDoItemComponent { r3.e(); r3.e(); } - r3.p(1, 'value', r3.b(ctx.todo.done)); - r3.t(3, r3.b(ctx.todo.text)); + if (rf & 2) { + r3.p(1, 'value', r3.b(ctx.todo.done)); + r3.t(3, r3.b(ctx.todo.text)); + } }, inputs: {todo: 'todo'}, }); diff --git a/packages/core/test/render3/compiler_canonical/template_variables_spec.ts b/packages/core/test/render3/compiler_canonical/template_variables_spec.ts index ba1ebe7f67..6cf32e38f2 100644 --- a/packages/core/test/render3/compiler_canonical/template_variables_spec.ts +++ b/packages/core/test/render3/compiler_canonical/template_variables_spec.ts @@ -12,9 +12,9 @@ import {renderComponent, toHtml} from '../render_util'; /// See: `normative.md` describe('template variables', () => { - type $boolean$ = boolean; type $any$ = any; type $number$ = number; + type $RenderFlags$ = $r3$.ɵRenderFlags; interface ForOfContext { $implicit: any; @@ -93,24 +93,29 @@ describe('template variables', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'ul'); $r3$.ɵC(1, MyComponent_ForOfDirective_Template_1, '', ['forOf', '']); $r3$.ɵe(); } - $r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); - $r3$.ɵcR(1); - $r3$.ɵcr(); + if (rf & 2) { + $r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); + $r3$.ɵcR(1); + $r3$.ɵcr(); + } - function MyComponent_ForOfDirective_Template_1(ctx1: $any$, cm: $boolean$) { - if (cm) { + function MyComponent_ForOfDirective_Template_1(rf: $RenderFlags$, ctx1: $any$) { + if (rf & 1) { $r3$.ɵE(0, 'li'); $r3$.ɵT(1); $r3$.ɵe(); } - const $l0_item$ = ctx1.$implicit; - $r3$.ɵt(1, $r3$.ɵi1('', $l0_item$.name, '')); + let $l0_item$: any; + if (rf & 2) { + $l0_item$ = ctx1.$implicit; + $r3$.ɵt(1, $r3$.ɵi1('', $l0_item$.name, '')); + } } } }); @@ -161,18 +166,20 @@ describe('template variables', () => { type: MyComponent, selectors: [['my-component']], factory: function MyComponent_Factory() { return new MyComponent(); }, - template: function MyComponent_Template(ctx: $MyComponent$, cm: $boolean$) { - if (cm) { + template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { + if (rf & 1) { $r3$.ɵE(0, 'ul'); $r3$.ɵC(1, MyComponent_ForOfDirective_Template_1, '', ['forOf', '']); $r3$.ɵe(); } - $r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); - $r3$.ɵcR(1); - $r3$.ɵcr(); + if (rf & 2) { + $r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); + $r3$.ɵcR(1); + $r3$.ɵcr(); + } - function MyComponent_ForOfDirective_Template_1(ctx1: $any$, cm: $boolean$) { - if (cm) { + function MyComponent_ForOfDirective_Template_1(rf1: $RenderFlags$, ctx1: $any$) { + if (rf & 1) { $r3$.ɵE(0, 'li'); $r3$.ɵE(1, 'div'); $r3$.ɵT(2); @@ -182,21 +189,27 @@ describe('template variables', () => { $r3$.ɵe(); $r3$.ɵe(); } - const $l0_item$ = ctx1.$implicit; - $r3$.ɵp(4, 'forOf', $r3$.ɵb($l0_item$.infos)); - $r3$.ɵt(2, $r3$.ɵi1('', $l0_item$.name, '')); - $r3$.ɵcR(4); - $r3$.ɵcr(); + let $l0_item$: any; + if (rf & 2) { + $l0_item$ = ctx1.$implicit; + $r3$.ɵp(4, 'forOf', $r3$.ɵb($l0_item$.infos)); + $r3$.ɵt(2, $r3$.ɵi1('', $l0_item$.name, '')); + $r3$.ɵcR(4); + $r3$.ɵcr(); + } function MyComponent_ForOfDirective_ForOfDirective_Template_3( - ctx2: $any$, cm: $boolean$) { - if (cm) { + rf2: $number$, ctx2: $any$) { + if (rf & 1) { $r3$.ɵE(0, 'li'); $r3$.ɵT(1); $r3$.ɵe(); } - const $l0_info$ = ctx2.$implicit; - $r3$.ɵt(1, $r3$.ɵi2(' ', $l0_item$.name, ': ', $l0_info$.description, ' ')); + let $l0_info$: any; + if (rf & 2) { + $l0_info$ = ctx2.$implicit; + $r3$.ɵt(1, $r3$.ɵi2(' ', $l0_item$.name, ': ', $l0_info$.description, ' ')); + } } } } diff --git a/packages/core/test/render3/component_spec.ts b/packages/core/test/render3/component_spec.ts index d2e423c327..0194667b3a 100644 --- a/packages/core/test/render3/component_spec.ts +++ b/packages/core/test/render3/component_spec.ts @@ -11,6 +11,7 @@ import {DoCheck, ViewEncapsulation} from '../../src/core'; import {getRenderedText} from '../../src/render3/component'; import {LifecycleHooksFeature, defineComponent, markDirty} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, text, textBinding, tick} from '../../src/render3/instructions'; +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {createRendererType2} from '../../src/view/index'; import {getRendererFactory2} from './imported_renderer2'; @@ -25,11 +26,13 @@ describe('component', () => { static ngComponentDef = defineComponent({ type: CounterComponent, selectors: [['counter']], - template: function(ctx: CounterComponent, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: CounterComponent) { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.count)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.count)); + } }, factory: () => new CounterComponent, inputs: {count: 'count'}, @@ -63,24 +66,28 @@ describe('component', () => { describe('component with a container', () => { - function showItems(ctx: {items: string[]}, cm: boolean) { - if (cm) { + function showItems(rf: RenderFlags, ctx: {items: string[]}) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - for (const item of ctx.items) { - const cm0 = embeddedViewStart(0); - { - if (cm0) { - text(0); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + for (const item of ctx.items) { + const rf0 = embeddedViewStart(0); + { + if (rf0 & RenderFlags.Create) { + text(0); + } + if (rf0 & RenderFlags.Update) { + textBinding(0, bind(item)); + } } - textBinding(0, bind(item)); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } class WrapperComponent { @@ -88,29 +95,33 @@ describe('component with a container', () => { static ngComponentDef = defineComponent({ type: WrapperComponent, selectors: [['wrapper']], - template: function ChildComponentTemplate(ctx: {items: string[]}, cm: boolean) { - if (cm) { + template: function ChildComponentTemplate(rf: RenderFlags, ctx: {items: string[]}) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - const cm0 = embeddedViewStart(0); - { showItems({items: ctx.items}, cm0); } - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + const rf0 = embeddedViewStart(0); + { showItems(rf0, {items: ctx.items}); } + embeddedViewEnd(); + } + containerRefreshEnd(); } - containerRefreshEnd(); }, factory: () => new WrapperComponent, inputs: {items: 'items'} }); } - function template(ctx: {items: string[]}, cm: boolean) { - if (cm) { + function template(rf: RenderFlags, ctx: {items: string[]}) { + if (rf & RenderFlags.Create) { elementStart(0, 'wrapper'); elementEnd(); } - elementProperty(0, 'items', bind(ctx.items)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'items', bind(ctx.items)); + } } const defs = [WrapperComponent]; @@ -132,8 +143,8 @@ describe('encapsulation', () => { static ngComponentDef = defineComponent({ type: WrapperComponent, selectors: [['wrapper']], - template: function(ctx: WrapperComponent, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: WrapperComponent) { + if (rf & RenderFlags.Create) { elementStart(0, 'encapsulated'); elementEnd(); } @@ -147,8 +158,8 @@ describe('encapsulation', () => { static ngComponentDef = defineComponent({ type: EncapsulatedComponent, selectors: [['encapsulated']], - template: function(ctx: EncapsulatedComponent, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: EncapsulatedComponent) { + if (rf & RenderFlags.Create) { text(0, 'foo'); elementStart(1, 'leaf'); elementEnd(); @@ -165,8 +176,8 @@ describe('encapsulation', () => { static ngComponentDef = defineComponent({ type: LeafComponent, selectors: [['leaf']], - template: function(ctx: LeafComponent, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: LeafComponent) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); { text(1, 'bar'); } elementEnd(); @@ -195,8 +206,8 @@ describe('encapsulation', () => { static ngComponentDef = defineComponent({ type: WrapperComponentWith, selectors: [['wrapper']], - template: function(ctx: WrapperComponentWith, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: WrapperComponentWith) { + if (rf & RenderFlags.Create) { elementStart(0, 'leaf'); elementEnd(); } @@ -212,8 +223,8 @@ describe('encapsulation', () => { static ngComponentDef = defineComponent({ type: LeafComponentwith, selectors: [['leaf']], - template: function(ctx: LeafComponentwith, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: LeafComponentwith) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); { text(1, 'bar'); } elementEnd(); @@ -252,37 +263,45 @@ describe('recursive components', () => { type: TreeComponent, selectors: [['tree-comp']], factory: () => new TreeComponent(), - template: (ctx: TreeComponent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: TreeComponent) => { + if (rf & RenderFlags.Create) { text(0); container(1); container(2); } - textBinding(0, bind(ctx.data.value)); - containerRefreshStart(1); - { - if (ctx.data.left != null) { - if (embeddedViewStart(0)) { - elementStart(0, 'tree-comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.data.value)); + containerRefreshStart(1); + { + if (ctx.data.left != null) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + elementStart(0, 'tree-comp'); + elementEnd(); + } + if (rf0 & RenderFlags.Update) { + elementProperty(0, 'data', bind(ctx.data.left)); + } + embeddedViewEnd(); } - elementProperty(0, 'data', bind(ctx.data.left)); - embeddedViewEnd(); } - } - containerRefreshEnd(); - containerRefreshStart(2); - { - if (ctx.data.right != null) { - if (embeddedViewStart(0)) { - elementStart(0, 'tree-comp'); - elementEnd(); + containerRefreshEnd(); + containerRefreshStart(2); + { + if (ctx.data.right != null) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + elementStart(0, 'tree-comp'); + elementEnd(); + } + if (rf0 & RenderFlags.Update) { + elementProperty(0, 'data', bind(ctx.data.right)); + } + embeddedViewEnd(); } - elementProperty(0, 'data', bind(ctx.data.right)); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, inputs: {data: 'data'} }); diff --git a/packages/core/test/render3/content_spec.ts b/packages/core/test/render3/content_spec.ts index 41b71b1796..45469996af 100644 --- a/packages/core/test/render3/content_spec.ts +++ b/packages/core/test/render3/content_spec.ts @@ -10,7 +10,7 @@ import {SelectorFlags} from '@angular/core/src/render3/interfaces/projection'; import {detectChanges} from '../../src/render3/index'; import {container, containerRefreshEnd, containerRefreshStart, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective, projection, projectionDef, text} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {createComponent, renderComponent, toHtml} from './render_util'; describe('content projection', () => { @@ -19,8 +19,8 @@ describe('content projection', () => { /** *
*/ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } @@ -31,8 +31,8 @@ describe('content projection', () => { /** * content */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { text(1, 'content'); } elementEnd(); @@ -44,14 +44,14 @@ describe('content projection', () => { }); it('should project content when root.', () => { - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); projection(1, 0); } }); - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { text(1, 'content'); } elementEnd(); @@ -63,24 +63,24 @@ describe('content projection', () => { }); it('should re-project content when root.', () => { - const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) { - if (cm) { + const GrandChild = createComponent('grand-child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } elementEnd(); } }); - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'grand-child'); { projection(2, 0); } elementEnd(); } }, [GrandChild]); - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'b'); @@ -100,8 +100,8 @@ describe('content projection', () => { it('should project components', () => { /**
*/ - const Child = createComponent('child', (ctx: any, cm: boolean) => { - if (cm) { + const Child = createComponent('child', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } @@ -109,8 +109,8 @@ describe('content projection', () => { } }); - const ProjectedComp = createComponent('projected-comp', (ctx: any, cm: boolean) => { - if (cm) { + const ProjectedComp = createComponent('projected-comp', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { text(0, 'content'); } }); @@ -120,8 +120,8 @@ describe('content projection', () => { * * */ - const Parent = createComponent('parent', (ctx: any, cm: boolean) => { - if (cm) { + const Parent = createComponent('parent', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'projected-comp'); @@ -137,16 +137,16 @@ describe('content projection', () => { }); it('should project content with container.', () => { - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } elementEnd(); } }); - const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: {value: any}) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { text(1, '('); @@ -155,16 +155,19 @@ describe('content projection', () => { } elementEnd(); } - containerRefreshStart(2); - { - if (ctx.value) { - if (embeddedViewStart(0)) { - text(0, 'content'); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (ctx.value) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + text(0, 'content'); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, [Child]); const parent = renderComponent(Parent); @@ -178,28 +181,31 @@ describe('content projection', () => { }); it('should project content with container into root', () => { - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); projection(1, 0); } }); - const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: {value: any}) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - if (ctx.value) { - if (embeddedViewStart(0)) { - text(0, 'content'); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.value) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + text(0, 'content'); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, [Child]); const parent = renderComponent(Parent); @@ -215,16 +221,16 @@ describe('content projection', () => { }); it('should project content with container and if-else.', () => { - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } elementEnd(); } }); - const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: {value: any}) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { text(1, '('); @@ -233,21 +239,24 @@ describe('content projection', () => { } elementEnd(); } - containerRefreshStart(2); - { - if (ctx.value) { - if (embeddedViewStart(0)) { - text(0, 'content'); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (ctx.value) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + text(0, 'content'); + } + embeddedViewEnd(); + } else { + if (embeddedViewStart(1)) { + text(0, 'else'); + } + embeddedViewEnd(); } - embeddedViewEnd(); - } else { - if (embeddedViewStart(1)) { - text(0, 'else'); - } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, [Child]); const parent = renderComponent(Parent); @@ -272,32 +281,35 @@ describe('content projection', () => { * % } * */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { container(2); } elementEnd(); } - containerRefreshStart(2); - { - if (!ctx.skipContent) { - if (embeddedViewStart(0)) { - elementStart(0, 'span'); - projection(1, 0); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (!ctx.skipContent) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + elementStart(0, 'span'); + projection(1, 0); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }); /** * content */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { childCmptInstance = loadDirective(0); @@ -326,30 +338,33 @@ describe('content projection', () => { * % } * */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { container(2); } elementEnd(); } - containerRefreshStart(2); - { - if (!ctx.skipContent) { - if (embeddedViewStart(0)) { - projection(0, 0); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (!ctx.skipContent) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + projection(0, 0); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }); /** * content */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { childCmptInstance = loadDirective(0); @@ -378,32 +393,35 @@ describe('content projection', () => { * % } * */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { container(2); } elementEnd(); } - containerRefreshStart(2); - { - if (!ctx.skipContent) { - if (embeddedViewStart(0)) { - text(0, 'before-'); - projection(1, 0); - text(2, '-after'); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (!ctx.skipContent) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + text(0, 'before-'); + projection(1, 0); + text(2, '-after'); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }); /** * content */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { childCmptInstance = loadDirective(0); @@ -426,8 +444,8 @@ describe('content projection', () => { *
* */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } @@ -441,8 +459,8 @@ describe('content projection', () => { /** * content */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { text(1, 'content'); } elementEnd(); @@ -472,31 +490,34 @@ describe('content projection', () => { * % } * */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); projection(1, 0); elementStart(2, 'div'); { container(3); } elementEnd(); } - containerRefreshStart(3); - { - if (ctx.show) { - if (embeddedViewStart(0)) { - projection(0, 0); + if (rf & RenderFlags.Update) { + containerRefreshStart(3); + { + if (ctx.show) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + projection(0, 0); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }); /** * content */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { childCmptInstance = loadDirective(0); @@ -521,8 +542,8 @@ describe('content projection', () => { *
*
*/ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef( 0, [[['span', 'title', 'toFirst']], [['span', 'title', 'toSecond']]], ['span[title=toFirst]', 'span[title=toSecond]']); @@ -541,8 +562,8 @@ describe('content projection', () => { * 2 * */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'span', ['title', 'toFirst']); @@ -567,8 +588,8 @@ describe('content projection', () => { *
*
*/ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef( 0, [ @@ -591,8 +612,8 @@ describe('content projection', () => { * 2 * */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'span', ['class', 'toFirst']); @@ -617,8 +638,8 @@ describe('content projection', () => { *
*
*/ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef( 0, [ @@ -641,8 +662,8 @@ describe('content projection', () => { * 2 * */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'span', ['class', 'other toFirst']); @@ -667,8 +688,8 @@ describe('content projection', () => { *
*
*/ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef( 0, [[['span']], [['span', SelectorFlags.CLASS, 'toSecond']]], ['span', 'span.toSecond']); @@ -687,8 +708,8 @@ describe('content projection', () => { * 2 * */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'span', ['class', 'toFirst']); @@ -713,8 +734,8 @@ describe('content projection', () => { *
*
*/ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0, [[['span', SelectorFlags.CLASS, 'toFirst']]], ['span.toFirst']); elementStart(1, 'div', ['id', 'first']); { projection(2, 0, 1); } @@ -731,8 +752,8 @@ describe('content projection', () => { * 2 * */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'span', ['class', 'toFirst']); @@ -758,8 +779,8 @@ describe('content projection', () => { *
*
*/ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0, [[['span', SelectorFlags.CLASS, 'toSecond']]], ['span.toSecond']); elementStart(1, 'div', ['id', 'first']); { projection(2, 0); } @@ -777,8 +798,8 @@ describe('content projection', () => { * remaining * */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'span'); @@ -810,8 +831,8 @@ describe('content projection', () => { *
* */ - const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) { - if (cm) { + const GrandChild = createComponent('grand-child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0, [[['span']]], ['span']); projection(1, 0, 1); elementStart(2, 'hr'); @@ -826,8 +847,8 @@ describe('content projection', () => { * in child template * */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'grand-child'); { @@ -847,8 +868,8 @@ describe('content projection', () => { * * */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'span'); @@ -872,8 +893,8 @@ describe('content projection', () => { *
* */ - const Card = createComponent('card', function(ctx: any, cm: boolean) { - if (cm) { + const Card = createComponent('card', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef( 0, [[['', 'card-title', '']], [['', 'card-content', '']]], ['[card-title]', '[card-content]']); @@ -890,8 +911,8 @@ describe('content projection', () => { * * */ - const CardWithTitle = createComponent('card-with-title', function(ctx: any, cm: boolean) { - if (cm) { + const CardWithTitle = createComponent('card-with-title', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'card'); { @@ -909,8 +930,8 @@ describe('content projection', () => { * content * */ - const App = createComponent('app', function(ctx: any, cm: boolean) { - if (cm) { + const App = createComponent('app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'card-with-title'); { text(1, 'content'); } elementEnd(); @@ -931,8 +952,8 @@ describe('content projection', () => { *
* */ - const Card = createComponent('card', function(ctx: any, cm: boolean) { - if (cm) { + const Card = createComponent('card', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef( 0, [[['', 'card-title', '']], [['', 'card-content', '']]], ['[card-title]', '[card-content]']); @@ -949,8 +970,8 @@ describe('content projection', () => { * * */ - const CardWithTitle = createComponent('card-with-title', function(ctx: any, cm: boolean) { - if (cm) { + const CardWithTitle = createComponent('card-with-title', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'card'); { @@ -968,8 +989,8 @@ describe('content projection', () => { * content * */ - const App = createComponent('app', function(ctx: any, cm: boolean) { - if (cm) { + const App = createComponent('app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'card-with-title'); { text(1, 'content'); } elementEnd(); @@ -987,8 +1008,8 @@ describe('content projection', () => { /** * */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0, [[['div']]], ['div']); projection(1, 0, 1); } @@ -1000,8 +1021,8 @@ describe('content projection', () => { *
should project
* */ - const Parent = createComponent('parent', function(ctx: any, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { elementStart(1, 'div', ['ngProjectAs', 'span']); @@ -1026,8 +1047,8 @@ describe('content projection', () => { * * */ - const Child = createComponent('child', function(ctx: any, cm: boolean) { - if (cm) { + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0, [[['div']]], ['div']); elementStart(1, 'span'); { projection(2, 0, 1); } @@ -1040,24 +1061,27 @@ describe('content projection', () => { *
content
* */ - const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) { - if (cm) { + const Parent = createComponent('parent', function(rf: RenderFlags, ctx: {value: any}) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { container(1, undefined, 'div'); } elementEnd(); } - containerRefreshStart(1); - { - if (true) { - if (embeddedViewStart(0)) { - elementStart(0, 'div'); - { text(1, 'content'); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (true) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + elementStart(0, 'div'); + { text(1, 'content'); } + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, [Child]); const parent = renderComponent(Parent); expect(toHtml(parent)).toEqual('
content
'); diff --git a/packages/core/test/render3/control_flow_spec.ts b/packages/core/test/render3/control_flow_spec.ts index 138fa41ddc..1a0ffabaec 100644 --- a/packages/core/test/render3/control_flow_spec.ts +++ b/packages/core/test/render3/control_flow_spec.ts @@ -8,32 +8,36 @@ import {defineComponent} from '../../src/render3/definition'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, text, textBinding} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {ComponentFixture, createComponent, renderToHtml} from './render_util'; describe('JS control flow', () => { it('should work with if block', () => { const ctx: {message: string | null, condition: boolean} = {message: 'Hello', condition: true}; - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - if (ctx.condition) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'span'); - { text(1); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + elementStart(0, 'span'); + { text(1); } + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + textBinding(1, bind(ctx.message)); + } } - textBinding(1, bind(ctx.message)); + embeddedViewEnd(); } - embeddedViewEnd(); } } containerRefreshEnd(); @@ -63,40 +67,44 @@ describe('JS control flow', () => { * % } * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - if (ctx.condition) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'span'); - { container(1); } - elementEnd(); - } - containerRefreshStart(1); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(1); { - if (ctx.condition2) { - let cm2 = embeddedViewStart(2); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'span'); + { container(1); } + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + containerRefreshStart(1); { - if (cm2) { - text(0, 'Hello'); + if (ctx.condition2) { + let rf2 = embeddedViewStart(2); + { + if (rf2 & RenderFlags.Create) { + text(0, 'Hello'); + } + } + embeddedViewEnd(); } } - embeddedViewEnd(); + containerRefreshEnd(); } } - containerRefreshEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, ctx)).toEqual('
Hello
'); @@ -139,33 +147,35 @@ describe('JS control flow', () => { * 3 * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - if (ctx.condition1) { - const cm1 = embeddedViewStart(1); - if (cm1) { - text(0, '1'); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + if (ctx.condition1) { + const rf1 = embeddedViewStart(1); + if (rf1 & RenderFlags.Create) { + text(0, '1'); + } + embeddedViewEnd(); + } // can't have ; here due linting rules + if (ctx.condition2) { + const rf2 = embeddedViewStart(2); + if (rf2 & RenderFlags.Create) { + text(0, '2'); + } + embeddedViewEnd(); + } // can't have ; here due linting rules + if (ctx.condition3) { + const rf3 = embeddedViewStart(3); + if (rf3 & RenderFlags.Create) { + text(0, '3'); + } + embeddedViewEnd(); } - embeddedViewEnd(); - } // can't have ; here due linting rules - if (ctx.condition2) { - const cm2 = embeddedViewStart(2); - if (cm2) { - text(0, '2'); - } - embeddedViewEnd(); - } // can't have ; here due linting rules - if (ctx.condition3) { - const cm3 = embeddedViewStart(3); - if (cm3) { - text(0, '3'); - } - embeddedViewEnd(); + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, ctx)).toEqual('123'); @@ -175,39 +185,43 @@ describe('JS control flow', () => { }); it('should work with containers with views as parents', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { text(1, 'hello'); } elementEnd(); container(2); } - containerRefreshStart(2); - { - if (ctx.condition1) { - let cm0 = embeddedViewStart(0); - { - if (cm0) { - container(0); - } - containerRefreshStart(0); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (ctx.condition1) { + let rf0 = embeddedViewStart(0); { - if (ctx.condition2) { - let cm0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + container(0); + } + if (rf0 & RenderFlags.Update) { + containerRefreshStart(0); { - if (cm0) { - text(0, 'world'); + if (ctx.condition2) { + let rf0 = embeddedViewStart(0); + { + if (rf0 & RenderFlags.Create) { + text(0, 'world'); + } + } + embeddedViewEnd(); } } - embeddedViewEnd(); + containerRefreshEnd(); } } - containerRefreshEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, {condition1: true, condition2: true})) @@ -220,28 +234,32 @@ describe('JS control flow', () => { it('should work with loop block', () => { const ctx: {data: string[] | null} = {data: ['a', 'b', 'c']}; - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'ul'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - for (let i = 0; i < ctx.data.length; i++) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'li'); - { text(1); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + for (let i = 0; i < ctx.data.length; i++) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + elementStart(0, 'li'); + { text(1); } + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + textBinding(1, bind(ctx.data[i])); + } } - textBinding(1, bind(ctx.data[i])); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, ctx)).toEqual('
  • a
  • b
  • c
'); @@ -266,38 +284,45 @@ describe('JS control flow', () => { it('should work with nested loop blocks', () => { const ctx: {data: string[][] | null} = {data: [['a', 'b', 'c'], ['m', 'n']]}; - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'ul'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - for (let i = 0; i < ctx.data[0].length; i++) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'li'); - { container(1); } - elementEnd(); - } - containerRefreshStart(1); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + for (let i = 0; i < ctx.data[0].length; i++) { + let rf1 = embeddedViewStart(1); { - ctx.data[1].forEach((value: string, ind: number) => { - if (embeddedViewStart(2)) { - text(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'li'); + { container(1); } + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + containerRefreshStart(1); + { + ctx.data[1].forEach((value: string, ind: number) => { + let rf2 = embeddedViewStart(2); + if (rf2 & RenderFlags.Create) { + text(0); + } + if (rf2 & RenderFlags.Update) { + textBinding(0, bind(ctx.data[0][i] + value)); + } + embeddedViewEnd(); + }); } - textBinding(0, bind(ctx.data[0][i] + value)); - embeddedViewEnd(); - }); + containerRefreshEnd(); + } } - containerRefreshEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, ctx)).toEqual('
  • aman
  • bmbn
  • cmcn
'); @@ -321,8 +346,8 @@ describe('JS control flow', () => { * After *
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { text(1, 'Before'); @@ -331,35 +356,42 @@ describe('JS control flow', () => { } elementEnd(); } - containerRefreshStart(2); - { - for (let i = 0; i < ctx.cafes.length; i++) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'h2'); - { text(1); } - elementEnd(); - container(2); - text(3, '-'); - } - textBinding(1, bind(ctx.cafes[i].name)); - containerRefreshStart(2); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + for (let i = 0; i < ctx.cafes.length; i++) { + let rf1 = embeddedViewStart(1); { - for (let j = 0; j < ctx.cafes[i].entrees.length; j++) { - if (embeddedViewStart(1)) { - text(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'h2'); + { text(1); } + elementEnd(); + container(2); + text(3, '-'); + } + if (rf1 & RenderFlags.Update) { + textBinding(1, bind(ctx.cafes[i].name)); + containerRefreshStart(2); + { + for (let j = 0; j < ctx.cafes[i].entrees.length; j++) { + let rf2 = embeddedViewStart(2); + if (rf2 & RenderFlags.Create) { + text(0); + } + if (rf2 & RenderFlags.Update) { + textBinding(0, bind(ctx.cafes[i].entrees[j])); + } + embeddedViewEnd(); + } } - textBinding(0, bind(ctx.cafes[i].entrees[j])); - embeddedViewEnd(); + containerRefreshEnd(); } } - containerRefreshEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const ctx = { @@ -401,8 +433,8 @@ describe('JS control flow', () => { * After *
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { text(1, 'Before'); @@ -411,52 +443,61 @@ describe('JS control flow', () => { } elementEnd(); } - containerRefreshStart(2); - { - for (let i = 0; i < ctx.cafes.length; i++) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'h2'); - { text(1); } - elementEnd(); - container(2); - text(3, '-'); - } - textBinding(1, bind(ctx.cafes[i].name)); - containerRefreshStart(2); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + for (let i = 0; i < ctx.cafes.length; i++) { + let rf1 = embeddedViewStart(1); { - for (let j = 0; j < ctx.cafes[i].entrees.length; j++) { - let cm1 = embeddedViewStart(1); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'h2'); + { text(1); } + elementEnd(); + container(2); + text(3, '-'); + } + if (rf1 & RenderFlags.Update) { + textBinding(1, bind(ctx.cafes[i].name)); + containerRefreshStart(2); { - if (cm1) { - elementStart(0, 'h3'); - { text(1); } - elementEnd(); - container(2); - } - textBinding(1, bind(ctx.cafes[i].entrees[j].name)); - containerRefreshStart(2); - { - for (let k = 0; k < ctx.cafes[i].entrees[j].foods.length; k++) { - if (embeddedViewStart(1)) { - text(0); + for (let j = 0; j < ctx.cafes[i].entrees.length; j++) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + elementStart(0, 'h3'); + { text(1); } + elementEnd(); + container(2); + } + if (rf1 & RenderFlags.Update) { + textBinding(1, bind(ctx.cafes[i].entrees[j].name)); + containerRefreshStart(2); + { + for (let k = 0; k < ctx.cafes[i].entrees[j].foods.length; k++) { + let rf2 = embeddedViewStart(1); + if (rf2 & RenderFlags.Create) { + text(0); + } + if (rf2 & RenderFlags.Update) { + textBinding(0, bind(ctx.cafes[i].entrees[j].foods[k])); + } + embeddedViewEnd(); + } + } + containerRefreshEnd(); } - textBinding(0, bind(ctx.cafes[i].entrees[j].foods[k])); - embeddedViewEnd(); } + embeddedViewEnd(); } - containerRefreshEnd(); } - embeddedViewEnd(); + containerRefreshEnd(); } } - containerRefreshEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const ctx = { @@ -491,37 +532,39 @@ describe('JS control flow', () => { it('should work with if/else blocks', () => { const ctx: {message: string | null, condition: boolean} = {message: 'Hello', condition: true}; - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - if (ctx.condition) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'span'); - { text(1, 'Hello'); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + elementStart(0, 'span'); + { text(1, 'Hello'); } + elementEnd(); + } } - } - embeddedViewEnd(); - } else { - let cm2 = embeddedViewStart(2); - { - if (cm2) { - elementStart(0, 'div'); - { text(1, 'Goodbye'); } - elementEnd(); + embeddedViewEnd(); + } else { + let rf2 = embeddedViewStart(2); + { + if (rf2) { + elementStart(0, 'div'); + { text(1, 'Goodbye'); } + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, ctx)).toEqual('
Hello
'); @@ -546,7 +589,7 @@ describe('JS control flow', () => { log.push('comp!'); return new Comp(); }, - template: function(ctx: Comp, cm: boolean) {} + template: function(rf: RenderFlags, ctx: Comp) {} }); } @@ -558,35 +601,39 @@ describe('JS control flow', () => { type: App, selectors: [['app']], factory: () => new App(), - template: function(ctx: any, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); elementEnd(); container(1); container(2); } - containerRefreshStart(1); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } - } - containerRefreshEnd(); - containerRefreshStart(2); - { - if (ctx.condition2) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + containerRefreshEnd(); + containerRefreshStart(2); + { + if (ctx.condition2) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, directives: () => [Comp] }); @@ -609,7 +656,7 @@ describe('JS control flow', () => { log.push('comp!'); return new Comp(); }, - template: function(ctx: Comp, cm: boolean) {} + template: function(rf: RenderFlags, ctx: Comp) {} }); } @@ -621,35 +668,39 @@ describe('JS control flow', () => { type: App, selectors: [['app']], factory: () => new App(), - template: function(ctx: any, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); elementEnd(); container(1); container(2); } - containerRefreshStart(1); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } - } - containerRefreshEnd(); - containerRefreshStart(2); - { - if (ctx.condition2) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + containerRefreshEnd(); + containerRefreshStart(2); + { + if (ctx.condition2) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, directives: () => [Comp] }); @@ -678,30 +729,38 @@ describe('JS for loop', () => { * % } *
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - for (let i = 0; i < ctx.data1.length; i++) { - if (embeddedViewStart(1)) { - text(0); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + for (let i = 0; i < ctx.data1.length; i++) { + let rf2 = embeddedViewStart(1); + if (rf2 & RenderFlags.Create) { + text(0); + } + if (rf2 & RenderFlags.Update) { + textBinding(0, bind(ctx.data1[i])); + } + embeddedViewEnd(); } - textBinding(0, bind(ctx.data1[i])); - embeddedViewEnd(); - } - for (let j = 0; j < ctx.data2.length; j++) { - if (embeddedViewStart(2)) { - text(0); + for (let j = 0; j < ctx.data2.length; j++) { + let rf2 = embeddedViewStart(1); + if (rf2 & RenderFlags.Create) { + text(0); + } + if (rf2 & RenderFlags.Update) { + textBinding(0, bind(ctx.data2[j])); + } + embeddedViewEnd(); } - textBinding(0, bind(ctx.data2[j])); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, ctx)).toEqual('
abc12
'); @@ -721,18 +780,20 @@ describe('function calls', () => { it('should work', () => { const ctx: {data: string[]} = {data: ['foo', 'bar']}; - function spanify(ctx: {message: string | null}, cm: boolean) { + function spanify(rf: RenderFlags, ctx: {message: string | null}) { const message = ctx.message; - if (cm) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); { text(1); } elementEnd(); } - textBinding(1, bind(message)); + if (rf & RenderFlags.Update) { + textBinding(1, bind(message)); + } } - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { text(1, 'Before'); @@ -742,20 +803,22 @@ describe('function calls', () => { } elementEnd(); } - containerRefreshStart(2); - { - let cm0 = embeddedViewStart(0); - { spanify({message: ctx.data[0]}, cm0); } - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + let rf0 = embeddedViewStart(0); + { spanify(rf0, {message: ctx.data[0]}); } + embeddedViewEnd(); + } + containerRefreshEnd(); + containerRefreshStart(3); + { + let rf0 = embeddedViewStart(0); + { spanify(rf0, {message: ctx.data[1]}); } + embeddedViewEnd(); + } + containerRefreshEnd(); } - containerRefreshEnd(); - containerRefreshStart(3); - { - let cm0 = embeddedViewStart(0); - { spanify({message: ctx.data[1]}, cm0); } - embeddedViewEnd(); - } - containerRefreshEnd(); } expect(renderToHtml(Template, ctx)) diff --git a/packages/core/test/render3/di_spec.ts b/packages/core/test/render3/di_spec.ts index 16fe380374..1128e67ece 100644 --- a/packages/core/test/render3/di_spec.ts +++ b/packages/core/test/render3/di_spec.ts @@ -7,6 +7,7 @@ */ import {ChangeDetectorRef, ElementRef, TemplateRef, ViewContainerRef} from '@angular/core'; +import {RenderFlags} from '@angular/core/src/render3/interfaces/definition'; import {defineComponent} from '../../src/render3/definition'; import {InjectFlags, bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di'; @@ -33,14 +34,17 @@ describe('di', () => { } /**
{{ dir.value }}
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', ''], ['dir', 'dir']); { text(2); } elementEnd(); } - const tmp = load(1) as any; - textBinding(2, bind(tmp.value)); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(1); + textBinding(2, bind(tmp.value)); + } } expect(renderToHtml(Template, {}, [Directive])).toEqual('
Created
'); @@ -91,8 +95,8 @@ describe('di', () => { * {{ dir.value }} *
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dirA', '']); { elementStart(1, 'span', ['dirB', '', 'dirC', ''], ['dir', 'dirC']); @@ -101,8 +105,11 @@ describe('di', () => { } elementEnd(); } - const tmp = load(2) as any; - textBinding(3, bind(tmp.value)); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(2); + textBinding(3, bind(tmp.value)); + } } const defs = [DirA, DirB, DirC]; @@ -326,8 +333,8 @@ describe('di', () => { type: App, factory: () => new App(), /**
*/ - template: (ctx: any, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dirA', '', 'dirB', '', 'dirC', 'dirC']); elementEnd(); } @@ -516,16 +523,20 @@ describe('di', () => { * {{ dir.value }} - {{ dirSame.value }} * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dirSame', 'dirSame', 'dir', 'dir']); { text(3); } elementEnd(); } - const tmp1 = load(1) as any; - const tmp2 = load(2) as any; - textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, '')); + let tmp1: any; + let tmp2: any; + if (rf & RenderFlags.Update) { + tmp1 = load(1); + tmp2 = load(2); + textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, '')); + } } const defs = [Directive, DirectiveSameInstance]; @@ -568,15 +579,19 @@ describe('di', () => { * {{ dir.value }} - {{ dirSame.value }} * */ - function Template(ctx: any, cm: any) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0, function() { }, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']); text(3); } - const tmp1 = load(1) as any; - const tmp2 = load(2) as any; - textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); + let tmp1: any; + let tmp2: any; + if (rf & RenderFlags.Update) { + tmp1 = load(1); + tmp2 = load(2); + textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); + } } const defs = [Directive, DirectiveSameInstance]; @@ -619,16 +634,19 @@ describe('di', () => { * {{ dir.value }} - {{ dirSame.value }} * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']); { text(3); } elementEnd(); } - - const tmp1 = load(1) as any; - const tmp2 = load(2) as any; - textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); + let tmp1: any; + let tmp2: any; + if (rf & RenderFlags.Update) { + tmp1 = load(1); + tmp2 = load(2); + textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); + } } const defs = [Directive, DirectiveSameInstance]; @@ -649,8 +667,8 @@ describe('di', () => { type: MyComp, selectors: [['my-comp']], factory: () => comp = new MyComp(injectChangeDetectorRef()), - template: function(ctx: MyComp, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: MyComp) { + if (rf & RenderFlags.Create) { projectionDef(0); projection(1, 0); } @@ -708,14 +726,17 @@ describe('di', () => { it('should inject current component ChangeDetectorRef into directives on components', () => { /** {{ dir.value }} */ - const MyApp = createComponent('my-app', function(ctx: any, cm: boolean) { - if (cm) { + const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp', ['dir', '', 'dirSame', ''], ['dir', 'dir']); elementEnd(); text(2); } - const tmp = load(1) as any; - textBinding(2, bind(tmp.value)); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(1); + textBinding(2, bind(tmp.value)); + } }, directives); const app = renderComponent(MyApp); @@ -737,14 +758,17 @@ describe('di', () => { selectors: [['my-app']], factory: () => new MyApp(injectChangeDetectorRef()), /**
{{ dir.value }}
*/ - template: function(ctx: any, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); { text(2); } elementEnd(); } - const tmp = load(1) as any; - textBinding(2, bind(tmp.value)); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(1); + textBinding(2, bind(tmp.value)); + } }, directives: directives }); @@ -772,8 +796,8 @@ describe('di', () => { * * {{ dir.value }} */ - template: function(ctx: any, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); { elementStart(1, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); @@ -783,7 +807,9 @@ describe('di', () => { text(3); } const tmp = load(2) as any; - textBinding(3, bind(tmp.value)); + if (rf & RenderFlags.Update) { + textBinding(3, bind(tmp.value)); + } }, directives: directives }); @@ -813,24 +839,30 @@ describe('di', () => { *
{{ dir.value }}
* % } */ - template: function(ctx: MyApp, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: MyApp) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.showing) { - if (embeddedViewStart(0)) { - elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); - { text(2); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.showing) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); + { text(2); } + elementEnd(); + } + let tmp: any; + if (rf1 & RenderFlags.Update) { + tmp = load(1); + textBinding(2, bind(tmp.value)); + } } - const tmp = load(1) as any; - textBinding(2, bind(tmp.value)); + embeddedViewEnd(); } - embeddedViewEnd(); + containerRefreshEnd(); } - containerRefreshEnd(); }, directives: directives }); @@ -855,21 +887,26 @@ describe('di', () => { selectors: [['my-app']], factory: () => new MyApp(injectChangeDetectorRef()), /**
{{ dir.value }}
*/ - template: function(ctx: MyApp, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: MyApp) { + if (rf & RenderFlags.Create) { container(0, C1, undefined, ['myIf', 'showing']); } - containerRefreshStart(0); - containerRefreshEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + containerRefreshEnd(); + } - function C1(ctx1: any, cm1: boolean) { - if (cm1) { + function C1(rf1: RenderFlags, ctx1: any) { + if (rf1 & RenderFlags.Create) { elementStart(0, 'div', ['dir', '', 'dirSame', ''], ['dir', 'dir']); { text(2); } elementEnd(); } - const tmp = load(1) as any; - textBinding(2, bind(tmp.value)); + let tmp: any; + if (rf1 & RenderFlags.Update) { + tmp = load(1); + textBinding(2, bind(tmp.value)); + } } }, directives: directives @@ -889,8 +926,8 @@ describe('di', () => { let exist: string|undefined = 'wrong'; let nonExist: string|undefined = 'wrong'; - const MyApp = createComponent('my-app', function(ctx: any, cm: boolean) { - if (cm) { + const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['exist', 'existValue', 'other', 'ignore']); exist = injectAttribute('exist'); nonExist = injectAttribute('nonExist'); @@ -1025,27 +1062,34 @@ describe('di', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['parentDir', '']); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - if (embeddedViewStart(0)) { - elementStart( - 0, 'span', ['childDir', '', 'child2Dir', ''], - ['child1', 'childDir', 'child2', 'child2Dir']); - { text(3); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart( + 0, 'span', ['childDir', '', 'child2Dir', ''], + ['child1', 'childDir', 'child2', 'child2Dir']); + { text(3); } + elementEnd(); + } + let tmp1: any; + let tmp2: any; + if (rf & RenderFlags.Update) { + tmp1 = load(1); + tmp2 = load(2); + textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); + } + embeddedViewEnd(); } - const tmp1 = load(1) as any; - const tmp2 = load(2) as any; - textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, '')); - embeddedViewEnd(); + containerRefreshEnd(); } - containerRefreshEnd(); } const defs = [ChildDirective, Child2Directive, ParentDirective]; diff --git a/packages/core/test/render3/directive_spec.ts b/packages/core/test/render3/directive_spec.ts index 4e63490a5d..d088989ea1 100644 --- a/packages/core/test/render3/directive_spec.ts +++ b/packages/core/test/render3/directive_spec.ts @@ -8,7 +8,7 @@ import {defineDirective} from '../../src/render3/index'; import {bind, elementEnd, elementProperty, elementStart, loadDirective} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {renderToHtml} from './render_util'; describe('directive', () => { @@ -31,8 +31,8 @@ describe('directive', () => { }); } - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span', ['dir', '']); elementEnd(); } diff --git a/packages/core/test/render3/exports_spec.ts b/packages/core/test/render3/exports_spec.ts index fcda7ce7c1..0ff071c707 100644 --- a/packages/core/test/render3/exports_spec.ts +++ b/packages/core/test/render3/exports_spec.ts @@ -8,21 +8,24 @@ import {defineComponent, defineDirective} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementAttribute, elementClassNamed, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, text, textBinding} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {ComponentFixture, createComponent, renderToHtml} from './render_util'; describe('exports', () => { it('should support export of DOM element', () => { /** {{ myInput.value }} */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'input', ['value', 'one'], ['myInput', '']); elementEnd(); text(2); } - const tmp = load(1) as any; - textBinding(2, tmp.value); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(1); + textBinding(2, tmp.value); + } } expect(renderToHtml(Template, {})).toEqual('one'); @@ -31,14 +34,17 @@ describe('exports', () => { it('should support basic export of component', () => { /** {{ myComp.name }} */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp', null, ['myComp', '']); elementEnd(); text(2); } - const tmp = load(1) as any; - textBinding(2, tmp.name); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(1); + textBinding(2, tmp.name); + } } class MyComponent { @@ -83,15 +89,18 @@ describe('exports', () => { const defs = [MyComponent, MyDir]; /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp', null, ['myComp', '']); elementEnd(); elementStart(2, 'div', ['myDir', '']); elementEnd(); } - const tmp = load(1) as any; - elementProperty(2, 'myDir', bind(tmp)); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(1); + elementProperty(2, 'myDir', bind(tmp)); + } } renderToHtml(Template, {}, defs); @@ -101,14 +110,17 @@ describe('exports', () => { it('should work with directives with exportAs set', () => { /**
{{ myDir.name }} */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['someDir', ''], ['myDir', 'someDir']); elementEnd(); text(2); } - const tmp = load(1) as any; - textBinding(2, tmp.name); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(1); + textBinding(2, tmp.name); + } } class SomeDir { @@ -127,8 +139,8 @@ describe('exports', () => { it('should throw if export name is not found', () => { /**
*/ - const App = createComponent('app', function(ctx: any, cm: boolean) { - if (cm) { + const App = createComponent('app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', null, ['myDir', 'someDir']); elementEnd(); } @@ -142,14 +154,16 @@ describe('exports', () => { describe('forward refs', () => { it('should work with basic text bindings', () => { /** {{ myInput.value}} */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0); elementStart(1, 'input', ['value', 'one'], ['myInput', '']); elementEnd(); } const tmp = load(2) as any; - textBinding(0, bind(tmp.value)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(tmp.value)); + } } expect(renderToHtml(Template, {})).toEqual('one'); @@ -158,15 +172,17 @@ describe('exports', () => { it('should work with element properties', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); elementEnd(); elementStart(1, 'input', ['value', 'one'], ['myInput', '']); elementEnd(); } const tmp = load(2) as any; - elementProperty(0, 'title', bind(tmp.value)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'title', bind(tmp.value)); + } } expect(renderToHtml(Template, {})).toEqual('
'); @@ -174,15 +190,17 @@ describe('exports', () => { it('should work with element attrs', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); elementEnd(); elementStart(1, 'input', ['value', 'one'], ['myInput', '']); elementEnd(); } const tmp = load(2) as any; - elementAttribute(0, 'aria-label', bind(tmp.value)); + if (rf & RenderFlags.Update) { + elementAttribute(0, 'aria-label', bind(tmp.value)); + } } expect(renderToHtml(Template, {})).toEqual('
'); @@ -190,15 +208,17 @@ describe('exports', () => { it('should work with element classes', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); elementEnd(); elementStart(1, 'input', ['type', 'checkbox', 'checked', 'true'], ['myInput', '']); elementEnd(); } const tmp = load(2) as any; - elementClassNamed(0, 'red', bind(tmp.checked)); + if (rf & RenderFlags.Update) { + elementClassNamed(0, 'red', bind(tmp.checked)); + } } expect(renderToHtml(Template, {})) @@ -216,7 +236,7 @@ describe('exports', () => { static ngComponentDef = defineComponent({ type: MyComponent, selectors: [['comp']], - template: function(ctx: MyComponent, cm: boolean) {}, + template: function(rf: RenderFlags, ctx: MyComponent) {}, factory: () => new MyComponent }); } @@ -235,15 +255,18 @@ describe('exports', () => { } /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['myDir', '']); elementEnd(); elementStart(1, 'comp', null, ['myComp', '']); elementEnd(); } - const tmp = load(2) as any; - elementProperty(0, 'myDir', bind(tmp)); + let tmp: any; + if (rf & RenderFlags.Update) { + tmp = load(2) as any; + elementProperty(0, 'myDir', bind(tmp)); + } } renderToHtml(Template, {}, [MyComponent, MyDir]); @@ -253,8 +276,8 @@ describe('exports', () => { it('should work with multiple forward refs', () => { /** {{ myInput.value }} {{ myComp.name }} */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0); text(1); elementStart(2, 'comp', null, ['myComp', '']); @@ -262,10 +285,14 @@ describe('exports', () => { elementStart(4, 'input', ['value', 'one'], ['myInput', '']); elementEnd(); } - const tmp1 = load(3) as any; - const tmp2 = load(5) as any; - textBinding(0, bind(tmp2.value)); - textBinding(1, bind(tmp1.name)); + let tmp1: any; + let tmp2: any; + if (rf & RenderFlags.Update) { + tmp1 = load(3) as any; + tmp2 = load(5) as any; + textBinding(0, bind(tmp2.value)); + textBinding(1, bind(tmp1.name)); + } } let myComponent: MyComponent; @@ -287,29 +314,34 @@ describe('exports', () => { }); it('should work inside a view container', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { container(1); } elementEnd(); } - containerRefreshStart(1); - { - if (ctx.condition) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - text(0); - elementStart(1, 'input', ['value', 'one'], ['myInput', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(1); + { + let tmp: any; + if (rf1 & RenderFlags.Create) { + text(0); + elementStart(1, 'input', ['value', 'one'], ['myInput', '']); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + tmp = load(2); + textBinding(0, bind(tmp.value)); + } } - const tmp = load(2) as any; - textBinding(0, bind(tmp.value)); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, { diff --git a/packages/core/test/render3/integration_spec.ts b/packages/core/test/render3/integration_spec.ts index 476aec6a51..deb02afc3e 100644 --- a/packages/core/test/render3/integration_spec.ts +++ b/packages/core/test/render3/integration_spec.ts @@ -6,8 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ +import {RenderFlags} from '@angular/core/src/render3'; + import {defineComponent, defineDirective} from '../../src/render3/index'; import {NO_CHANGE, bind, container, containerRefreshEnd, containerRefreshStart, elementAttribute, elementClassNamed, elementEnd, elementProperty, elementStart, elementStyleNamed, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation2, interpolation3, interpolation4, interpolation5, interpolation6, interpolation7, interpolation8, interpolationV, load, loadDirective, projection, projectionDef, text, textBinding} from '../../src/render3/instructions'; +import {LViewFlags} from '../../src/render3/interfaces/view'; import {ComponentFixture, containerEl, renderToHtml} from './render_util'; @@ -18,8 +21,8 @@ describe('render3 integration test', () => { it('should render basic template', () => { expect(renderToHtml(Template, {})).toEqual('Greetings'); - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span', ['title', 'Hello']); { text(1, 'Greetings'); } elementEnd(); @@ -31,24 +34,28 @@ describe('render3 integration test', () => { expect(renderToHtml(Template, 'World')).toEqual('

Hello, World!

'); expect(renderToHtml(Template, 'New World')).toEqual('

Hello, New World!

'); - function Template(name: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'h1'); { text(1); } elementEnd(); } - textBinding(1, interpolation1('Hello, ', name, '!')); + if (rf & RenderFlags.Update) { + textBinding(1, interpolation1('Hello, ', ctx, '!')); + } } }); }); describe('text bindings', () => { it('should render "undefined" as "" when used with `bind()`', () => { - function Template(name: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, name: string) { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(name)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(name)); + } } expect(renderToHtml(Template, 'benoit')).toEqual('benoit'); @@ -56,11 +63,13 @@ describe('render3 integration test', () => { }); it('should render "null" as "" when used with `bind()`', () => { - function Template(name: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, name: string) { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(name)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(name)); + } } expect(renderToHtml(Template, 'benoit')).toEqual('benoit'); @@ -68,11 +77,13 @@ describe('render3 integration test', () => { }); it('should support creation-time values in text nodes', () => { - function Template(value: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, value: string) { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, cm ? value : NO_CHANGE); + if (rf & RenderFlags.Update) { + textBinding(0, rf & RenderFlags.Create ? value : NO_CHANGE); + } } expect(renderToHtml(Template, 'once')).toEqual('once'); expect(renderToHtml(Template, 'twice')).toEqual('once'); @@ -82,21 +93,23 @@ describe('render3 integration test', () => { describe('Siblings update', () => { it('should handle a flat list of static/bound text nodes', () => { - function Template(name: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, name: string) { + if (rf & RenderFlags.Create) { text(0, 'Hello '); text(1); text(2, '!'); } - textBinding(1, bind(name)); + if (rf & RenderFlags.Update) { + textBinding(1, bind(name)); + } } expect(renderToHtml(Template, 'world')).toEqual('Hello world!'); expect(renderToHtml(Template, 'monde')).toEqual('Hello monde!'); }); it('should handle a list of static/bound text nodes as element children', () => { - function Template(name: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, name: string) { + if (rf & RenderFlags.Create) { elementStart(0, 'b'); { text(1, 'Hello '); @@ -105,15 +118,17 @@ describe('render3 integration test', () => { } elementEnd(); } - textBinding(2, bind(name)); + if (rf & RenderFlags.Update) { + textBinding(2, bind(name)); + } } expect(renderToHtml(Template, 'world')).toEqual('Hello world!'); expect(renderToHtml(Template, 'mundo')).toEqual('Hello mundo!'); }); it('should render/update text node as a child of a deep list of elements', () => { - function Template(name: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, name: string) { + if (rf & RenderFlags.Create) { elementStart(0, 'b'); { elementStart(1, 'b'); @@ -130,15 +145,17 @@ describe('render3 integration test', () => { } elementEnd(); } - textBinding(4, interpolation1('Hello ', name, '!')); + if (rf & RenderFlags.Update) { + textBinding(4, interpolation1('Hello ', name, '!')); + } } expect(renderToHtml(Template, 'world')).toEqual('Hello world!'); expect(renderToHtml(Template, 'mundo')).toEqual('Hello mundo!'); }); it('should update 2 sibling elements', () => { - function Template(id: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, id: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'b'); { elementStart(1, 'span'); @@ -149,7 +166,9 @@ describe('render3 integration test', () => { } elementEnd(); } - elementAttribute(2, 'id', bind(id)); + if (rf & RenderFlags.Update) { + elementAttribute(2, 'id', bind(id)); + } } expect(renderToHtml(Template, 'foo')) .toEqual(''); @@ -158,8 +177,8 @@ describe('render3 integration test', () => { }); it('should handle sibling text node after element with child text node', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'p'); { text(1, 'hello'); } elementEnd(); @@ -179,8 +198,8 @@ describe('render3 integration test', () => { static ngComponentDef = defineComponent({ type: TodoComponent, selectors: [['todo']], - template: function TodoTemplate(ctx: any, cm: boolean) { - if (cm) { + template: function TodoTemplate(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'p'); { text(1, 'Todo'); @@ -188,7 +207,9 @@ describe('render3 integration test', () => { } elementEnd(); } - textBinding(2, bind(ctx.value)); + if (rf & RenderFlags.Update) { + textBinding(2, bind(ctx.value)); + } }, factory: () => new TodoComponent }); @@ -197,8 +218,8 @@ describe('render3 integration test', () => { const defs = [TodoComponent]; it('should support a basic component template', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'todo'); elementEnd(); } @@ -208,8 +229,8 @@ describe('render3 integration test', () => { }); it('should support a component template with sibling', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'todo'); elementEnd(); text(1, 'two'); @@ -223,8 +244,8 @@ describe('render3 integration test', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'todo'); elementEnd(); elementStart(1, 'todo'); @@ -244,11 +265,13 @@ describe('render3 integration test', () => { type: TodoComponentHostBinding, selectors: [['todo']], template: function TodoComponentHostBindingTemplate( - ctx: TodoComponentHostBinding, cm: boolean) { - if (cm) { + rf: RenderFlags, ctx: TodoComponentHostBinding) { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, bind(ctx.title)); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.title)); + } }, factory: () => cmptInstance = new TodoComponentHostBinding, hostBindings: function(directiveIndex: number, elementIndex: number): void { @@ -260,8 +283,8 @@ describe('render3 integration test', () => { }); } - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'todo'); elementEnd(); } @@ -279,7 +302,7 @@ describe('render3 integration test', () => { type: HostAttributeComp, selectors: [['host-attr-comp']], factory: () => new HostAttributeComp(), - template: (ctx: HostAttributeComp, cm: boolean) => {}, + template: (rf: RenderFlags, ctx: HostAttributeComp) => {}, attributes: ['role', 'button'] }); } @@ -295,20 +318,22 @@ describe('render3 integration test', () => { static ngComponentDef = defineComponent({ type: MyComp, selectors: [['comp']], - template: function MyCompTemplate(ctx: any, cm: boolean) { - if (cm) { + template: function MyCompTemplate(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'p'); { text(1); } elementEnd(); } - textBinding(1, bind(ctx.name)); + if (rf & RenderFlags.Update) { + textBinding(1, bind(ctx.name)); + } }, factory: () => new MyComp }); } - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } @@ -328,22 +353,25 @@ describe('render3 integration test', () => { static ngComponentDef = defineComponent({ type: MyComp, selectors: [['comp']], - template: function MyCompTemplate(ctx: any, cm: boolean) { - if (cm) { + template: function MyCompTemplate(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'div'); - { text(1, 'text'); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'div'); + { text(1, 'text'); } + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, factory: () => new MyComp, inputs: {condition: 'condition'} @@ -351,12 +379,14 @@ describe('render3 integration test', () => { } /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } - elementProperty(0, 'condition', bind(ctx.condition)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'condition', bind(ctx.condition)); + } } const defs = [MyComp]; @@ -381,49 +411,54 @@ describe('render3 integration test', () => { afterTree: Tree; } - function showLabel(ctx: {label: string | undefined}, cm: boolean) { - if (cm) { + function showLabel(rf: RenderFlags, ctx: {label: string | undefined}) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.label != null) { - if (embeddedViewStart(0)) { - text(0); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.label != null) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + text(0); + } + if (rf1 & RenderFlags.Update) { + textBinding(0, bind(ctx.label)); + } + embeddedViewEnd(); } - textBinding(0, bind(ctx.label)); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } - function showTree(ctx: {tree: Tree}, cm: boolean) { - if (cm) { + function showTree(rf: RenderFlags, ctx: {tree: Tree}) { + if (rf & RenderFlags.Create) { container(0); container(1); container(2); } containerRefreshStart(0); { - const cm0 = embeddedViewStart(0); - { showLabel({label: ctx.tree.beforeLabel}, cm0); } + const rf0 = embeddedViewStart(0); + { showLabel(rf0, {label: ctx.tree.beforeLabel}); } embeddedViewEnd(); } containerRefreshEnd(); containerRefreshStart(1); { for (let subTree of ctx.tree.subTrees || []) { - const cm0 = embeddedViewStart(0); - { showTree({tree: subTree}, cm0); } + const rf0 = embeddedViewStart(0); + { showTree(rf0, {tree: subTree}); } embeddedViewEnd(); } } containerRefreshEnd(); containerRefreshStart(2); { - const cm0 = embeddedViewStart(0); - { showLabel({label: ctx.tree.afterLabel}, cm0); } + const rf0 = embeddedViewStart(0); + { showLabel(rf0, {label: ctx.tree.afterLabel}); } embeddedViewEnd(); } containerRefreshEnd(); @@ -436,8 +471,8 @@ describe('render3 integration test', () => { selectors: [['child']], type: ChildComponent, template: function ChildComponentTemplate( - ctx: {beforeTree: Tree, afterTree: Tree}, cm: boolean) { - if (cm) { + rf: RenderFlags, ctx: {beforeTree: Tree, afterTree: Tree}) { + if (rf & RenderFlags.Create) { projectionDef(0); container(1); projection(2, 0); @@ -445,15 +480,15 @@ describe('render3 integration test', () => { } containerRefreshStart(1); { - const cm0 = embeddedViewStart(0); - { showTree({tree: ctx.beforeTree}, cm0); } + const rf0 = embeddedViewStart(0); + { showTree(rf0, {tree: ctx.beforeTree}); } embeddedViewEnd(); } containerRefreshEnd(); containerRefreshStart(3); { - const cm0 = embeddedViewStart(0); - { showTree({tree: ctx.afterTree}, cm0); } + const rf0 = embeddedViewStart(0); + { showTree(rf0, {tree: ctx.afterTree}); } embeddedViewEnd(); } containerRefreshEnd(); @@ -463,21 +498,23 @@ describe('render3 integration test', () => { }); } - function parentTemplate(ctx: ParentCtx, cm: boolean) { - if (cm) { + function parentTemplate(rf: RenderFlags, ctx: ParentCtx) { + if (rf & RenderFlags.Create) { elementStart(0, 'child'); { container(1); } elementEnd(); } - elementProperty(0, 'beforeTree', bind(ctx.beforeTree)); - elementProperty(0, 'afterTree', bind(ctx.afterTree)); - containerRefreshStart(1); - { - const cm0 = embeddedViewStart(0); - { showTree({tree: ctx.projectedTree}, cm0); } - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'beforeTree', bind(ctx.beforeTree)); + elementProperty(0, 'afterTree', bind(ctx.afterTree)); + containerRefreshStart(1); + { + const rf0 = embeddedViewStart(0); + { showTree(rf0, {tree: ctx.projectedTree}); } + embeddedViewEnd(); + } + containerRefreshEnd(); } - containerRefreshEnd(); } it('should work with a tree', () => { @@ -509,12 +546,14 @@ describe('render3 integration test', () => { it('should support attribute bindings', () => { const ctx: {title: string | null} = {title: 'Hello'}; - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementAttribute(0, 'title', bind(ctx.title)); + if (rf & RenderFlags.Update) { + elementAttribute(0, 'title', bind(ctx.title)); + } } // initial binding @@ -532,12 +571,14 @@ describe('render3 integration test', () => { it('should stringify values used attribute bindings', () => { const ctx: {title: any} = {title: NaN}; - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementAttribute(0, 'title', bind(ctx.title)); + if (rf & RenderFlags.Update) { + elementAttribute(0, 'title', bind(ctx.title)); + } } expect(renderToHtml(Template, ctx)).toEqual(''); @@ -547,33 +588,35 @@ describe('render3 integration test', () => { }); it('should update bindings', () => { - function Template(c: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, c: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'b'); elementEnd(); } - elementAttribute(0, 'a', interpolationV(c)); - elementAttribute(0, 'a0', bind(c[1])); - elementAttribute(0, 'a1', interpolation1(c[0], c[1], c[16])); - elementAttribute(0, 'a2', interpolation2(c[0], c[1], c[2], c[3], c[16])); - elementAttribute(0, 'a3', interpolation3(c[0], c[1], c[2], c[3], c[4], c[5], c[16])); - elementAttribute( - 0, 'a4', interpolation4(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[16])); - elementAttribute( - 0, 'a5', - interpolation5(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[16])); - elementAttribute( - 0, 'a6', - interpolation6( - c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], c[11], c[16])); - elementAttribute( - 0, 'a7', interpolation7( - c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], c[11], - c[12], c[13], c[16])); - elementAttribute( - 0, 'a8', interpolation8( - c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], c[11], - c[12], c[13], c[14], c[15], c[16])); + if (rf & RenderFlags.Update) { + elementAttribute(0, 'a', interpolationV(c)); + elementAttribute(0, 'a0', bind(c[1])); + elementAttribute(0, 'a1', interpolation1(c[0], c[1], c[16])); + elementAttribute(0, 'a2', interpolation2(c[0], c[1], c[2], c[3], c[16])); + elementAttribute(0, 'a3', interpolation3(c[0], c[1], c[2], c[3], c[4], c[5], c[16])); + elementAttribute( + 0, 'a4', interpolation4(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[16])); + elementAttribute( + 0, 'a5', + interpolation5(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[16])); + elementAttribute( + 0, 'a6', interpolation6( + c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], + c[11], c[16])); + elementAttribute( + 0, 'a7', interpolation7( + c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], + c[11], c[12], c[13], c[16])); + elementAttribute( + 0, 'a8', interpolation8( + c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], + c[11], c[12], c[13], c[14], c[15], c[16])); + } } let args = ['(', 0, 'a', 1, 'b', 2, 'c', 3, 'd', 4, 'e', 5, 'f', 6, 'g', 7, ')']; expect(renderToHtml(Template, args)) @@ -592,29 +635,31 @@ describe('render3 integration test', () => { it('should not update DOM if context has not changed', () => { const ctx: {title: string | null} = {title: 'Hello'}; - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); container(1); elementEnd(); } - elementAttribute(0, 'title', bind(ctx.title)); - containerRefreshStart(1); - { - if (true) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'b'); - {} - elementEnd(); + if (rf & RenderFlags.Update) { + elementAttribute(0, 'title', bind(ctx.title)); + containerRefreshStart(1); + { + if (true) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + elementStart(0, 'b'); + {} + elementEnd(); + } + elementAttribute(0, 'title', bind(ctx.title)); } - elementAttribute(0, 'title', bind(ctx.title)); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } // initial binding @@ -650,8 +695,8 @@ describe('render3 integration test', () => { }); } - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['hostBindingDir', '']); elementEnd(); } @@ -670,12 +715,14 @@ describe('render3 integration test', () => { describe('elementStyle', () => { it('should support binding to styles', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementStyleNamed(0, 'border-color', bind(ctx)); + if (rf & RenderFlags.Update) { + elementStyleNamed(0, 'border-color', bind(ctx)); + } } expect(renderToHtml(Template, 'red')).toEqual(''); @@ -685,12 +732,14 @@ describe('render3 integration test', () => { }); it('should support binding to styles with suffix', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementStyleNamed(0, 'font-size', bind(ctx), 'px'); + if (rf & RenderFlags.Update) { + elementStyleNamed(0, 'font-size', bind(ctx), 'px'); + } } expect(renderToHtml(Template, '100')).toEqual(''); @@ -702,12 +751,14 @@ describe('render3 integration test', () => { describe('elementClass', () => { it('should support CSS class toggle', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementClassNamed(0, 'active', bind(ctx)); + if (rf & RenderFlags.Update) { + elementClassNamed(0, 'active', bind(ctx)); + } } expect(renderToHtml(Template, true)).toEqual(''); @@ -723,12 +774,14 @@ describe('render3 integration test', () => { }); it('should work correctly with existing static classes', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span', ['class', 'existing']); elementEnd(); } - elementClassNamed(0, 'active', bind(ctx)); + if (rf & RenderFlags.Update) { + elementClassNamed(0, 'active', bind(ctx)); + } } expect(renderToHtml(Template, true)).toEqual(''); @@ -745,22 +798,24 @@ describe('render3 integration test', () => { *
* % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'div'); - {} - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'div'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect((Template as any).ngPrivateData).toBeUndefined(); diff --git a/packages/core/test/render3/lifecycle_spec.ts b/packages/core/test/render3/lifecycle_spec.ts index 8e2975868e..3ac61cf785 100644 --- a/packages/core/test/render3/lifecycle_spec.ts +++ b/packages/core/test/render3/lifecycle_spec.ts @@ -9,18 +9,20 @@ import {SimpleChanges} from '../../src/core'; import {ComponentTemplate, LifecycleHooksFeature, NgOnChangesFeature, defineComponent, defineDirective} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, listener, markDirty, projection, projectionDef, store, text} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {containerEl, renderComponent, renderToHtml, requestAnimationFrame} from './render_util'; describe('lifecycles', () => { function getParentTemplate(name: string) { - return (ctx: any, cm: boolean) => { - if (cm) { + return (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { elementStart(0, name); elementEnd(); } - elementProperty(0, 'val', bind(ctx.val)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', bind(ctx.val)); + } }; } @@ -29,8 +31,8 @@ describe('lifecycles', () => { beforeEach(() => { events = []; }); - let Comp = createOnInitComponent('comp', (ctx: any, cm: boolean) => { - if (cm) { + let Comp = createOnInitComponent('comp', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } @@ -38,8 +40,8 @@ describe('lifecycles', () => { } }); let Parent = createOnInitComponent('parent', getParentTemplate('comp'), [Comp]); - let ProjectedComp = createOnInitComponent('projected', (ctx: any, cm: boolean) => { - if (cm) { + let ProjectedComp = createOnInitComponent('projected', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { text(0, 'content'); } }); @@ -72,12 +74,14 @@ describe('lifecycles', () => { it('should call onInit method after inputs are set in creation mode (and not in update mode)', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } - elementProperty(0, 'val', bind(ctx.val)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', bind(ctx.val)); + } } renderToHtml(Template, {val: '1'}, directives); @@ -102,8 +106,8 @@ describe('lifecycles', () => { * parent temp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); } @@ -121,15 +125,17 @@ describe('lifecycles', () => { * parent temp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); elementStart(1, 'parent'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 2); + } } renderToHtml(Template, {}, directives); @@ -144,21 +150,24 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, directives); @@ -177,8 +186,8 @@ describe('lifecycles', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { elementStart(1, 'projected'); } elementEnd(); @@ -198,8 +207,8 @@ describe('lifecycles', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { elementStart(1, 'projected'); } elementEnd(); @@ -207,10 +216,12 @@ describe('lifecycles', () => { { elementStart(3, 'projected'); } elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 1); - elementProperty(2, 'val', 2); - elementProperty(3, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 1); + elementProperty(2, 'val', 2); + elementProperty(3, 'val', 2); + } } renderToHtml(Template, {}, directives); @@ -219,8 +230,8 @@ describe('lifecycles', () => { it('should be called on directives after component', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp', ['dir', '']); elementEnd(); } @@ -236,8 +247,8 @@ describe('lifecycles', () => { it('should be called on directives on an element', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '']); elementEnd(); } @@ -259,28 +270,33 @@ describe('lifecycles', () => { * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); container(1); elementStart(2, 'comp'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(2, 'val', 5); - containerRefreshStart(1); - { - for (let j = 2; j < 5; j++) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(2, 'val', 5); + containerRefreshStart(1); + { + for (let j = 2; j < 5; j++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', j); + } + embeddedViewEnd(); } - elementProperty(0, 'val', j); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, directives); @@ -299,28 +315,33 @@ describe('lifecycles', () => { * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); container(1); elementStart(2, 'parent'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(2, 'val', 5); - containerRefreshStart(1); - { - for (let j = 2; j < 5; j++) { - if (embeddedViewStart(0)) { - elementStart(0, 'parent'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(2, 'val', 5); + containerRefreshStart(1); + { + for (let j = 2; j < 5; j++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'parent'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', j); + } + embeddedViewEnd(); } - elementProperty(0, 'val', j); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, directives); @@ -344,7 +365,7 @@ describe('lifecycles', () => { allEvents = []; }); - let Comp = createDoCheckComponent('comp', (ctx: any, cm: boolean) => {}); + let Comp = createDoCheckComponent('comp', (rf: RenderFlags, ctx: any) => {}); let Parent = createDoCheckComponent('parent', getParentTemplate('comp'), [Comp]); function createDoCheckComponent( @@ -377,8 +398,8 @@ describe('lifecycles', () => { it('should call doCheck on every refresh', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } @@ -406,8 +427,8 @@ describe('lifecycles', () => { * parent temp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); } @@ -419,8 +440,8 @@ describe('lifecycles', () => { it('should call ngOnInit before ngDoCheck if creation mode', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } @@ -435,8 +456,8 @@ describe('lifecycles', () => { it('should be called on directives after component', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp', ['dir', '']); elementEnd(); } @@ -452,8 +473,8 @@ describe('lifecycles', () => { it('should be called on directives on an element', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '']); elementEnd(); } @@ -477,25 +498,27 @@ describe('lifecycles', () => { allEvents = []; }); - let Comp = createAfterContentInitComp('comp', function(ctx: any, cm: boolean) { - if (cm) { + let Comp = createAfterContentInitComp('comp', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); projection(1, 0); } }); - let Parent = createAfterContentInitComp('parent', function(ctx: any, cm: boolean) { - if (cm) { + let Parent = createAfterContentInitComp('parent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'comp'); { projection(2, 0); } elementEnd(); } - elementProperty(1, 'val', bind(ctx.val)); + if (rf & RenderFlags.Update) { + elementProperty(1, 'val', bind(ctx.val)); + } }, [Comp]); - let ProjectedComp = createAfterContentInitComp('projected', (ctx: any, cm: boolean) => { - if (cm) { + let ProjectedComp = createAfterContentInitComp('projected', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { projectionDef(0); projection(1, 0); } @@ -530,8 +553,8 @@ describe('lifecycles', () => { {type: Directive, selectors: [['', 'dir', '']], factory: () => new Directive()}); } - function ForLoopWithChildrenTemplate(ctx: any, cm: boolean) { - if (cm) { + function ForLoopWithChildrenTemplate(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); { text(1, 'content'); } elementEnd(); @@ -540,29 +563,34 @@ describe('lifecycles', () => { { text(4, 'content'); } elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(3, 'val', 4); - containerRefreshStart(2); - { - for (let i = 2; i < 4; i++) { - if (embeddedViewStart(0)) { - elementStart(0, 'parent'); - { text(1, 'content'); } - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(3, 'val', 4); + containerRefreshStart(2); + { + for (let i = 2; i < 4; i++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'parent'); + { text(1, 'content'); } + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', i); + } + embeddedViewEnd(); } - elementProperty(0, 'val', i); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const directives = [Comp, Parent, ProjectedComp, Directive]; it('should be called only in creation mode', () => { /** content */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { text(1, 'content'); } elementEnd(); @@ -591,22 +619,25 @@ describe('lifecycles', () => { * content * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - { text(1, 'content'); } - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + { text(1, 'content'); } + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, directives); @@ -625,8 +656,8 @@ describe('lifecycles', () => { * * parent template: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); { text(1, 'content'); } elementEnd(); @@ -644,8 +675,8 @@ describe('lifecycles', () => { * * parent template: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); { text(1, 'content'); } elementEnd(); @@ -653,8 +684,10 @@ describe('lifecycles', () => { { text(3, 'content'); } elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(2, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(2, 'val', 2); + } } renderToHtml(Template, {}, directives); @@ -672,8 +705,8 @@ describe('lifecycles', () => { * * projected comp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); { elementStart(1, 'projected'); @@ -702,8 +735,8 @@ describe('lifecycles', () => { * * projected comp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); { elementStart(1, 'projected'); @@ -719,10 +752,12 @@ describe('lifecycles', () => { } elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 1); - elementProperty(3, 'val', 2); - elementProperty(4, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 1); + elementProperty(3, 'val', 2); + elementProperty(4, 'val', 2); + } } renderToHtml(Template, {}, directives); @@ -737,8 +772,8 @@ describe('lifecycles', () => { * % } * content */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { text(1, 'content'); } elementEnd(); @@ -747,21 +782,26 @@ describe('lifecycles', () => { { text(4, 'content'); } elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(3, 'val', 4); - containerRefreshStart(2); - { - for (let i = 2; i < 4; i++) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - { text(1, 'content'); } - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(3, 'val', 4); + containerRefreshStart(2); + { + for (let i = 2; i < 4; i++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + { text(1, 'content'); } + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', i); + } + embeddedViewEnd(); } - elementProperty(0, 'val', i); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, directives); @@ -786,8 +826,8 @@ describe('lifecycles', () => { it('should be called every change detection run after afterContentInit', () => { /** content */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { text(1, 'content'); } elementEnd(); @@ -816,8 +856,8 @@ describe('lifecycles', () => { describe('directives', () => { it('should be called on directives after component', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp', ['dir', '']); elementEnd(); } @@ -829,8 +869,8 @@ describe('lifecycles', () => { it('should be called on directives on an element', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '']); elementEnd(); } @@ -851,8 +891,8 @@ describe('lifecycles', () => { allEvents = []; }); - let Comp = createAfterViewInitComponent('comp', (ctx: any, cm: boolean) => { - if (cm) { + let Comp = createAfterViewInitComponent('comp', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } @@ -861,8 +901,8 @@ describe('lifecycles', () => { }); let Parent = createAfterViewInitComponent('parent', getParentTemplate('comp'), [Comp]); - let ProjectedComp = createAfterViewInitComponent('projected', (ctx: any, cm: boolean) => { - if (cm) { + let ProjectedComp = createAfterViewInitComponent('projected', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { text(0, 'content'); } }); @@ -900,8 +940,8 @@ describe('lifecycles', () => { it('should be called on init and not in update mode', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } @@ -929,21 +969,24 @@ describe('lifecycles', () => { * * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -963,8 +1006,8 @@ describe('lifecycles', () => { * * parent temp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); } @@ -982,15 +1025,17 @@ describe('lifecycles', () => { * * parent temp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); elementStart(1, 'parent'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 2); + } } renderToHtml(Template, {}, defs); expect(events).toEqual(['comp1', 'comp2', 'parent1', 'parent2']); @@ -1003,8 +1048,8 @@ describe('lifecycles', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { elementStart(1, 'projected'); @@ -1027,8 +1072,8 @@ describe('lifecycles', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { elementStart(1, 'projected'); @@ -1042,10 +1087,12 @@ describe('lifecycles', () => { } elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 1); - elementProperty(2, 'val', 2); - elementProperty(3, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 1); + elementProperty(2, 'val', 2); + elementProperty(3, 'val', 2); + } } renderToHtml(Template, {}, defs); @@ -1058,8 +1105,8 @@ describe('lifecycles', () => { * * */ - const ParentComp = createAfterViewInitComponent('parent', (ctx: any, cm: boolean) => { - if (cm) { + const ParentComp = createAfterViewInitComponent('parent', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { elementStart(1, 'projected'); @@ -1067,23 +1114,27 @@ describe('lifecycles', () => { } elementEnd(); } - elementProperty(0, 'val', bind(ctx.val)); - elementProperty(1, 'val', bind(ctx.val)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', bind(ctx.val)); + elementProperty(1, 'val', bind(ctx.val)); + } }, [Comp, ProjectedComp]); /** * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); elementStart(1, 'parent'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 2); + } } renderToHtml(Template, {}, [ParentComp]); @@ -1098,28 +1149,33 @@ describe('lifecycles', () => { * % } * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); container(1); elementStart(2, 'comp'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(2, 'val', 4); - containerRefreshStart(1); - { - for (let i = 2; i < 4; i++) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(2, 'val', 4); + containerRefreshStart(1); + { + for (let i = 2; i < 4; i++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', i); + } + embeddedViewEnd(); } - elementProperty(0, 'val', i); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, defs); @@ -1135,28 +1191,33 @@ describe('lifecycles', () => { * % } * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); container(1); elementStart(2, 'parent'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(2, 'val', 4); - containerRefreshStart(1); - { - for (let i = 2; i < 4; i++) { - if (embeddedViewStart(0)) { - elementStart(0, 'parent'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(2, 'val', 4); + containerRefreshStart(1); + { + for (let i = 2; i < 4; i++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'parent'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', i); + } + embeddedViewEnd(); } - elementProperty(0, 'val', i); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, defs); @@ -1169,8 +1230,8 @@ describe('lifecycles', () => { it('should call ngAfterViewChecked every update', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } @@ -1194,12 +1255,14 @@ describe('lifecycles', () => { it('should call ngAfterViewChecked with bindings', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } - elementProperty(0, 'val', bind(ctx.myVal)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', bind(ctx.myVal)); + } } renderToHtml(Template, {myVal: 5}, defs); @@ -1217,28 +1280,33 @@ describe('lifecycles', () => { * % } * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); container(1); elementStart(2, 'parent'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(2, 'val', 4); - containerRefreshStart(1); - { - for (let i = 2; i < 4; i++) { - if (embeddedViewStart(0)) { - elementStart(0, 'parent'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(2, 'val', 4); + containerRefreshStart(1); + { + for (let i = 2; i < 4; i++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'parent'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', i); + } + embeddedViewEnd(); } - elementProperty(0, 'val', i); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, defs); @@ -1255,8 +1323,8 @@ describe('lifecycles', () => { describe('directives', () => { it('should be called on directives after component', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp', ['dir', '']); elementEnd(); } @@ -1268,8 +1336,8 @@ describe('lifecycles', () => { it('should be called on directives on an element', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '']); elementEnd(); } @@ -1286,8 +1354,8 @@ describe('lifecycles', () => { beforeEach(() => { events = []; }); - let Comp = createOnDestroyComponent('comp', (ctx: any, cm: boolean) => { - if (cm) { + let Comp = createOnDestroyComponent('comp', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { projectionDef(0); projection(1, 0); } @@ -1311,14 +1379,14 @@ describe('lifecycles', () => { }; } - let Grandparent = createOnDestroyComponent('grandparent', function(ctx: any, cm: boolean) { - if (cm) { + let Grandparent = createOnDestroyComponent('grandparent', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); } }, [Parent]); - const ProjectedComp = createOnDestroyComponent('projected', (ctx: any, cm: boolean) => {}); + const ProjectedComp = createOnDestroyComponent('projected', (rf: RenderFlags, ctx: any) => {}); class Directive { ngOnDestroy() { events.push('dir'); } @@ -1336,21 +1404,24 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -1366,25 +1437,30 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); - elementStart(1, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + elementStart(1, 'comp'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', bind('1')); + elementProperty(1, 'val', bind('2')); + } + embeddedViewEnd(); } - elementProperty(0, 'val', bind('1')); - elementProperty(1, 'val', bind('2')); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -1401,21 +1477,24 @@ describe('lifecycles', () => { * parent template: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'parent'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'parent'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -1433,21 +1512,24 @@ describe('lifecycles', () => { * parent template: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'grandparent'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'grandparent'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -1466,35 +1548,40 @@ describe('lifecycles', () => { * * } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.showing) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - { - elementStart(1, 'projected'); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.showing) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + { + elementStart(1, 'projected'); + elementEnd(); + } + elementEnd(); + elementStart(2, 'comp'); + { + elementStart(3, 'projected'); + elementEnd(); + } elementEnd(); } - elementEnd(); - elementStart(2, 'comp'); - { - elementStart(3, 'projected'); - elementEnd(); + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 1); + elementProperty(2, 'val', 2); + elementProperty(3, 'val', 2); } - elementEnd(); + embeddedViewEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 1); - elementProperty(2, 'val', 2); - elementProperty(3, 'val', 2); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {showing: true}, defs); @@ -1515,38 +1602,46 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); - container(1); - elementStart(2, 'comp'); - elementEnd(); - } - elementProperty(0, 'val', bind('1')); - elementProperty(2, 'val', bind('3')); - containerRefreshStart(1); - { - if (ctx.condition2) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); - } - elementProperty(0, 'val', bind('2')); - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + container(1); + elementStart(2, 'comp'); + elementEnd(); } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', bind('1')); + elementProperty(2, 'val', bind('3')); + containerRefreshStart(1); + { + if (ctx.condition2) { + let rf2 = embeddedViewStart(0); + if (rf2 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + if (rf2 & RenderFlags.Update) { + elementProperty(0, 'val', bind('2')); + } + embeddedViewEnd(); + } + } + containerRefreshEnd(); + } + embeddedViewEnd(); } - containerRefreshEnd(); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true, condition2: true}, defs); @@ -1585,38 +1680,46 @@ describe('lifecycles', () => { * * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); - container(1); - elementStart(2, 'comp'); - elementEnd(); - } - elementProperty(0, 'val', bind('1')); - elementProperty(2, 'val', bind('5')); - containerRefreshStart(1); - { - for (let j = 2; j < ctx.len; j++) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); - } - elementProperty(0, 'val', bind(j)); - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + container(1); + elementStart(2, 'comp'); + elementEnd(); } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val', bind('1')); + elementProperty(2, 'val', bind('5')); + containerRefreshStart(1); + { + for (let j = 2; j < ctx.len; j++) { + let rf2 = embeddedViewStart(0); + if (rf2 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + if (rf2 & RenderFlags.Update) { + elementProperty(0, 'val', bind(j)); + } + embeddedViewEnd(); + } + } + containerRefreshEnd(); + } + embeddedViewEnd(); } - containerRefreshEnd(); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } /** @@ -1657,33 +1760,36 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'button'); - { - listener('click', ctx.onClick.bind(ctx)); - text(1, 'Click me'); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button'); + { + listener('click', ctx.onClick.bind(ctx)); + text(1, 'Click me'); + } + elementEnd(); + elementStart(2, 'comp'); + elementEnd(); + elementStart(3, 'button'); + { + listener('click', ctx.onClick.bind(ctx)); + text(4, 'Click me'); + } + elementEnd(); } - elementEnd(); - elementStart(2, 'comp'); - elementEnd(); - elementStart(3, 'button'); - { - listener('click', ctx.onClick.bind(ctx)); - text(4, 'Click me'); - } - elementEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } class App { @@ -1716,21 +1822,24 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp', ['dir', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp', ['dir', '']); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -1748,21 +1857,24 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'div', ['dir', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'div', ['dir', '']); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -1779,24 +1891,26 @@ describe('lifecycles', () => { beforeEach(() => { events = []; }); - const Comp = createOnChangesComponent('comp', (ctx: any, cm: boolean) => { - if (cm) { + const Comp = createOnChangesComponent('comp', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } elementEnd(); } }); - const Parent = createOnChangesComponent('parent', (ctx: any, cm: boolean) => { - if (cm) { + const Parent = createOnChangesComponent('parent', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } - elementProperty(0, 'val1', bind(ctx.a)); - elementProperty(0, 'publicName', bind(ctx.b)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(ctx.a)); + elementProperty(0, 'publicName', bind(ctx.b)); + } }, [Comp]); - const ProjectedComp = createOnChangesComponent('projected', (ctx: any, cm: boolean) => { - if (cm) { + const ProjectedComp = createOnChangesComponent('projected', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { text(0, 'content'); } }); @@ -1848,13 +1962,15 @@ describe('lifecycles', () => { it('should call onChanges method after inputs are set in creation and update mode', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } - elementProperty(0, 'val1', bind(ctx.val1)); - elementProperty(0, 'publicName', bind(ctx.val2)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(ctx.val1)); + elementProperty(0, 'publicName', bind(ctx.val2)); + } } renderToHtml(Template, {val1: '1', val2: 'a'}, defs); @@ -1873,13 +1989,15 @@ describe('lifecycles', () => { * parent temp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); } - elementProperty(0, 'val1', bind(ctx.val1)); - elementProperty(0, 'publicName', bind(ctx.val2)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(ctx.val1)); + elementProperty(0, 'publicName', bind(ctx.val2)); + } } renderToHtml(Template, {val1: '1', val2: 'a'}, defs); @@ -1897,17 +2015,19 @@ describe('lifecycles', () => { * parent temp: */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); elementStart(1, 'parent'); elementEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); - elementProperty(1, 'val1', bind(2)); - elementProperty(1, 'publicName', bind(2)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + elementProperty(1, 'val1', bind(2)); + elementProperty(1, 'publicName', bind(2)); + } } renderToHtml(Template, {}, defs); @@ -1927,23 +2047,28 @@ describe('lifecycles', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + } + embeddedViewEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {condition: true}, defs); @@ -1965,16 +2090,18 @@ describe('lifecycles', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { elementStart(1, 'projected'); } elementEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); - elementProperty(1, 'val1', bind(2)); - elementProperty(1, 'publicName', bind(2)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + elementProperty(1, 'val1', bind(2)); + elementProperty(1, 'publicName', bind(2)); + } } renderToHtml(Template, {}, defs); @@ -1993,8 +2120,8 @@ describe('lifecycles', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); { elementStart(1, 'projected'); } elementEnd(); @@ -2002,14 +2129,16 @@ describe('lifecycles', () => { { elementStart(3, 'projected'); } elementEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); - elementProperty(1, 'val1', bind(2)); - elementProperty(1, 'publicName', bind(2)); - elementProperty(2, 'val1', bind(3)); - elementProperty(2, 'publicName', bind(3)); - elementProperty(3, 'val1', bind(4)); - elementProperty(3, 'publicName', bind(4)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + elementProperty(1, 'val1', bind(2)); + elementProperty(1, 'publicName', bind(2)); + elementProperty(2, 'val1', bind(3)); + elementProperty(2, 'publicName', bind(3)); + elementProperty(3, 'val1', bind(4)); + elementProperty(3, 'publicName', bind(4)); + } } renderToHtml(Template, {}, defs); @@ -2023,13 +2152,15 @@ describe('lifecycles', () => { it('should be called on directives after component', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp', ['dir', '']); elementEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + } } renderToHtml(Template, {}, defs); @@ -2046,13 +2177,15 @@ describe('lifecycles', () => { it('should be called on directives on an element', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dir', '']); elementEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + } } renderToHtml(Template, {}, defs); @@ -2071,31 +2204,36 @@ describe('lifecycles', () => { * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); container(1); elementStart(2, 'comp'); elementEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); - elementProperty(2, 'val1', bind(5)); - elementProperty(2, 'publicName', bind(5)); - containerRefreshStart(1); - { - for (let j = 2; j < 5; j++) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + elementProperty(2, 'val1', bind(5)); + elementProperty(2, 'publicName', bind(5)); + containerRefreshStart(1); + { + for (let j = 2; j < 5; j++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val1', bind(j)); + elementProperty(0, 'publicName', bind(j)); + } + embeddedViewEnd(); } - elementProperty(0, 'val1', bind(j)); - elementProperty(0, 'publicName', bind(j)); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, defs); @@ -2120,31 +2258,36 @@ describe('lifecycles', () => { * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); container(1); elementStart(2, 'parent'); elementEnd(); } - elementProperty(0, 'val1', bind(1)); - elementProperty(0, 'publicName', bind(1)); - elementProperty(2, 'val1', bind(5)); - elementProperty(2, 'publicName', bind(5)); - containerRefreshStart(1); - { - for (let j = 2; j < 5; j++) { - if (embeddedViewStart(0)) { - elementStart(0, 'parent'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val1', bind(1)); + elementProperty(0, 'publicName', bind(1)); + elementProperty(2, 'val1', bind(5)); + elementProperty(2, 'publicName', bind(5)); + containerRefreshStart(1); + { + for (let j = 2; j < 5; j++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'parent'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'val1', bind(j)); + elementProperty(0, 'publicName', bind(j)); + } + embeddedViewEnd(); } - elementProperty(0, 'val1', bind(j)); - elementProperty(0, 'publicName', bind(j)); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } renderToHtml(Template, {}, defs); @@ -2200,22 +2343,24 @@ describe('lifecycles', () => { } it('should call all hooks in correct order', () => { - const Comp = createAllHooksComponent('comp', (ctx: any, cm: boolean) => {}); + const Comp = createAllHooksComponent('comp', (rf: RenderFlags, ctx: any) => {}); /** * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); elementStart(1, 'comp'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 2); + } } const defs = [Comp]; @@ -2235,30 +2380,34 @@ describe('lifecycles', () => { }); it('should call all hooks in correct order with children', () => { - const Comp = createAllHooksComponent('comp', (ctx: any, cm: boolean) => {}); + const Comp = createAllHooksComponent('comp', (rf: RenderFlags, ctx: any) => {}); /** */ - const Parent = createAllHooksComponent('parent', (ctx: any, cm: boolean) => { - if (cm) { + const Parent = createAllHooksComponent('parent', (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } - elementProperty(0, 'val', bind(ctx.val)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', bind(ctx.val)); + } }, [Comp]); /** * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent'); elementEnd(); elementStart(1, 'parent'); elementEnd(); } - elementProperty(0, 'val', 1); - elementProperty(1, 'val', 2); + if (rf & RenderFlags.Update) { + elementProperty(0, 'val', 1); + elementProperty(1, 'val', 2); + } } const defs = [Parent]; diff --git a/packages/core/test/render3/listeners_spec.ts b/packages/core/test/render3/listeners_spec.ts index 9c8c92a1e2..d3a6cc9c00 100644 --- a/packages/core/test/render3/listeners_spec.ts +++ b/packages/core/test/render3/listeners_spec.ts @@ -8,7 +8,7 @@ import {defineComponent, defineDirective} from '../../src/render3/index'; import {container, containerRefreshEnd, containerRefreshStart, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, listener, text} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {getRendererFactory2} from './imported_renderer2'; import {containerEl, renderComponent, renderToHtml} from './render_util'; @@ -26,8 +26,8 @@ describe('event listeners', () => { type: MyComp, selectors: [['comp']], /** */ - template: function CompTemplate(ctx: any, cm: boolean) { - if (cm) { + template: function CompTemplate(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button'); { listener('click', function() { return ctx.onClick(); }); @@ -64,8 +64,8 @@ describe('event listeners', () => { selectors: [['prevent-default-comp']], factory: () => new PreventDefaultComp(), /** */ - template: (ctx: PreventDefaultComp, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, ctx: PreventDefaultComp) => { + if (rf & RenderFlags.Create) { elementStart(0, 'button'); { listener('click', function($event: any) { return ctx.onClick($event); }); @@ -124,8 +124,8 @@ describe('event listeners', () => { it('should call function chain on event emit', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button'); { listener('click', function() { @@ -159,8 +159,8 @@ describe('event listeners', () => { it('should evaluate expression on event emit', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button'); { listener('click', function() { return ctx.showing = !ctx.showing; }); @@ -188,25 +188,27 @@ describe('event listeners', () => { * * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.showing) { - if (embeddedViewStart(1)) { - elementStart(0, 'button'); - { - listener('click', function() { return ctx.onClick(); }); - text(1, 'Click me'); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.showing) { + if (embeddedViewStart(1)) { + elementStart(0, 'button'); + { + listener('click', function() { return ctx.onClick(); }); + text(1, 'Click me'); + } + elementEnd(); } - elementEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } let comp = new MyComp(); @@ -244,8 +246,8 @@ describe('event listeners', () => { }); } - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button', ['hostListenerDir', '']); text(1, 'Click'); elementEnd(); @@ -271,36 +273,42 @@ describe('event listeners', () => { * % } * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.showing) { - if (embeddedViewStart(0)) { - text(0, 'Hello'); - container(1); - } - containerRefreshStart(1); - { - if (ctx.button) { - if (embeddedViewStart(0)) { - elementStart(0, 'button'); - { - listener('click', function() { return ctx.onClick(); }); - text(1, 'Click'); - } - elementEnd(); - } - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.showing) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + text(0, 'Hello'); + container(1); } + if (rf1 & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.button) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button'); + { + listener('click', function() { return ctx.onClick(); }); + text(1, 'Click'); + } + elementEnd(); + } + embeddedViewEnd(); + } + } + containerRefreshEnd(); + } + embeddedViewEnd(); } - containerRefreshEnd(); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const comp = {showing: true, counter: 0, button: true, onClick: function() { this.counter++; }}; @@ -329,24 +337,27 @@ describe('event listeners', () => { * comp: * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.showing) { - if (embeddedViewStart(0)) { - text(0, 'Hello'); - elementStart(1, 'comp'); - elementEnd(); - elementStart(2, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.showing) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + text(0, 'Hello'); + elementStart(1, 'comp'); + elementEnd(); + elementStart(2, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const ctx = {showing: true}; @@ -381,52 +392,59 @@ describe('event listeners', () => { * % } * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - text(0, 'Hello'); - container(1); - container(2); - } - containerRefreshStart(1); - { - if (ctx.sub1) { - if (embeddedViewStart(0)) { - elementStart(0, 'button'); - { - listener('click', function() { return ctx.counter1++; }); - text(1, 'Click'); - } - elementEnd(); - } - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + text(0, 'Hello'); + container(1); + container(2); } - } - containerRefreshEnd(); - containerRefreshStart(2); - { - if (ctx.sub2) { - if (embeddedViewStart(0)) { - elementStart(0, 'button'); - { - listener('click', function() { return ctx.counter2++; }); - text(1, 'Click'); + if (rf1 & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.sub1) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button'); + { + listener('click', function() { return ctx.counter1++; }); + text(1, 'Click'); + } + elementEnd(); + } + embeddedViewEnd(); } - elementEnd(); } - embeddedViewEnd(); + containerRefreshEnd(); + containerRefreshStart(2); + { + if (ctx.sub2) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button'); + { + listener('click', function() { return ctx.counter2++; }); + text(1, 'Click'); + } + elementEnd(); + } + embeddedViewEnd(); + } + } + containerRefreshEnd(); } + embeddedViewEnd(); } - containerRefreshEnd(); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const ctx = {condition: true, counter1: 0, counter2: 0, sub1: true, sub2: true}; diff --git a/packages/core/test/render3/outputs_spec.ts b/packages/core/test/render3/outputs_spec.ts index 82b7e22558..f08cb0827b 100644 --- a/packages/core/test/render3/outputs_spec.ts +++ b/packages/core/test/render3/outputs_spec.ts @@ -10,7 +10,7 @@ import {EventEmitter} from '@angular/core'; import {defineComponent, defineDirective} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, listener, text} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {containerEl, renderToHtml} from './render_util'; describe('outputs', () => { @@ -25,7 +25,7 @@ describe('outputs', () => { static ngComponentDef = defineComponent({ type: ButtonToggle, selectors: [['button-toggle']], - template: function(ctx: any, cm: boolean) {}, + template: function(rf: RenderFlags, ctx: any) {}, factory: () => buttonToggle = new ButtonToggle(), outputs: {change: 'change', resetStream: 'reset'} }); @@ -51,7 +51,7 @@ describe('outputs', () => { static ngComponentDef = defineComponent({ type: DestroyComp, selectors: [['destroy-comp']], - template: function(ctx: any, cm: boolean) {}, + template: function(rf: RenderFlags, ctx: any) {}, factory: () => destroyComp = new DestroyComp() }); } @@ -73,8 +73,8 @@ describe('outputs', () => { it('should call component output function when event is emitted', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button-toggle'); { listener('change', function() { return ctx.onChange(); }); @@ -96,8 +96,8 @@ describe('outputs', () => { it('should support more than 1 output function on the same node', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button-toggle'); { listener('change', function() { return ctx.onChange(); }); @@ -121,8 +121,8 @@ describe('outputs', () => { it('should eval component output expression when event is emitted', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button-toggle'); { listener('change', function() { return ctx.counter++; }); @@ -149,24 +149,27 @@ describe('outputs', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'button-toggle'); - { - listener('change', function() { return ctx.onChange(); }); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button-toggle'); + { + listener('change', function() { return ctx.onChange(); }); + } + elementEnd(); } - elementEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } let counter = 0; @@ -193,34 +196,38 @@ describe('outputs', () => { * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - container(0); - } - containerRefreshStart(0); - { - if (ctx.condition2) { - if (embeddedViewStart(0)) { - elementStart(0, 'button-toggle'); - { - listener('change', function() { return ctx.onChange(); }); - } - elementEnd(); - } - embeddedViewEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + container(0); } + containerRefreshStart(0); + { + if (ctx.condition2) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button-toggle'); + { + listener('change', function() { return ctx.onChange(); }); + } + elementEnd(); + } + embeddedViewEnd(); + } + } + containerRefreshEnd(); + embeddedViewEnd(); } - containerRefreshEnd(); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } let counter = 0; @@ -245,32 +252,35 @@ describe('outputs', () => { * * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'button'); - { - listener('click', function() { return ctx.onClick(); }); - text(1, 'Click me'); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button'); + { + listener('click', function() { return ctx.onClick(); }); + text(1, 'Click me'); + } + elementEnd(); + elementStart(2, 'button-toggle'); + { + listener('change', function() { return ctx.onChange(); }); + } + elementEnd(); + elementStart(3, 'destroy-comp'); + elementEnd(); } - elementEnd(); - elementStart(2, 'button-toggle'); - { - listener('change', function() { return ctx.onChange(); }); - } - elementEnd(); - elementStart(3, 'destroy-comp'); - elementEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } let clickCounter = 0; @@ -299,8 +309,8 @@ describe('outputs', () => { }); it('should fire event listeners along with outputs if they match', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button', ['myButton', '']); { listener('click', function() { return ctx.onClick(); }); @@ -324,8 +334,8 @@ describe('outputs', () => { it('should work with two outputs of the same name', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button-toggle', ['otherDir', '']); { listener('change', function() { return ctx.onChange(); }); @@ -359,15 +369,17 @@ describe('outputs', () => { } /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button-toggle', ['otherChangeDir', '']); { listener('change', function() { return ctx.onChange(); }); } elementEnd(); } - elementProperty(0, 'change', bind(ctx.change)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'change', bind(ctx.change)); + } } let counter = 0; @@ -392,8 +404,8 @@ describe('outputs', () => { * 'changeStream']} * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button'); { listener('click', function() { return ctx.onClick(); }); @@ -402,29 +414,32 @@ describe('outputs', () => { elementEnd(); container(2); } - containerRefreshStart(2); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'button-toggle'); - { - listener('change', function() { return ctx.onChange(); }); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button-toggle'); + { + listener('change', function() { return ctx.onChange(); }); + } + elementEnd(); } - elementEnd(); - } - embeddedViewEnd(); - } else { - if (embeddedViewStart(1)) { - elementStart(0, 'div', ['otherDir', '']); - { - listener('change', function() { return ctx.onChange(); }); + embeddedViewEnd(); + } else { + if (embeddedViewStart(1)) { + elementStart(0, 'div', ['otherDir', '']); + { + listener('change', function() { return ctx.onChange(); }); + } + elementEnd(); } - elementEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } let counter = 0; diff --git a/packages/core/test/render3/pipe_spec.ts b/packages/core/test/render3/pipe_spec.ts index 6f65d458ab..2a49d26b4e 100644 --- a/packages/core/test/render3/pipe_spec.ts +++ b/packages/core/test/render3/pipe_spec.ts @@ -11,6 +11,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; import {defineDirective, definePipe} from '../../src/render3/definition'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, load, loadDirective, text, textBinding} from '../../src/render3/instructions'; +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {pipe, pipeBind1, pipeBind3, pipeBind4, pipeBindV} from '../../src/render3/pipe'; import {RenderLog, getRendererFactory2, patchLoggingRenderer2} from './imported_renderer2'; @@ -33,12 +34,14 @@ describe('pipe', () => { const pipes = () => [CountingPipe, MultiArgPipe, CountingImpurePipe]; it('should support interpolation', () => { - function Template(person: Person, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { text(0); pipe(1, 'countingPipe'); } - textBinding(0, interpolation1('', pipeBind1(1, person.name), '')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', pipeBind1(1, person.name), '')); + } } person.init('bob', null); @@ -46,12 +49,14 @@ describe('pipe', () => { }); it('should throw if pipe is not found', () => { - const App = createComponent('app', function(ctx: any, cm: boolean) { - if (cm) { + const App = createComponent('app', function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0); pipe(1, 'randomPipeName'); } - textBinding(0, interpolation1('', pipeBind1(1, ctx.value), '')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', pipeBind1(1, ctx.value), '')); + } }, [], pipes); expect(() => { @@ -87,27 +92,31 @@ describe('pipe', () => { }); } - function Template(ctx: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: string) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['myDir', '']); pipe(1, 'double'); elementEnd(); } - elementProperty(0, 'elprop', bind(pipeBind1(1, ctx))); - directive = loadDirective(0); + if (rf & RenderFlags.Update) { + elementProperty(0, 'elprop', bind(pipeBind1(1, ctx))); + directive = loadDirective(0); + } } renderToHtml(Template, 'a', [MyDir], [DoublePipe]); expect(directive !.dirProp).toEqual('aa'); }); it('should support arguments in pipes', () => { - function Template(person: Person, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { text(0); pipe(1, 'multiArgPipe'); } - textBinding( - 0, interpolation1('', pipeBind3(1, person.name, 'one', person.address !.city), '')); + if (rf & RenderFlags.Update) { + textBinding( + 0, interpolation1('', pipeBind3(1, person.name, 'one', person.address !.city), '')); + } } person.init('value', new Address('two')); @@ -115,14 +124,17 @@ describe('pipe', () => { }); it('should support calling pipes with different number of arguments', () => { - function Template(person: Person, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { text(0); pipe(1, 'multiArgPipe'); pipe(2, 'multiArgPipe'); } - textBinding( - 0, interpolation1('', pipeBind4(2, pipeBindV(1, [person.name, 'a', 'b']), 0, 1, 2), '')); + if (rf & RenderFlags.Update) { + textBinding( + 0, + interpolation1('', pipeBind4(2, pipeBindV(1, [person.name, 'a', 'b']), 0, 1, 2), '')); + } } person.init('value', null); @@ -141,13 +153,15 @@ describe('pipe', () => { }); } - function Template(person: Person, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); pipe(1, 'identityPipe'); elementEnd(); } - elementProperty(0, 'someProp', bind(pipeBind1(1, 'Megatron'))); + if (rf & RenderFlags.Update) { + elementProperty(0, 'someProp', bind(pipeBind1(1, 'Megatron'))); + } } renderToHtml(Template, person, null, [IdentityPipe], rendererFactory2); @@ -160,12 +174,14 @@ describe('pipe', () => { describe('pure', () => { it('should call pure pipes only if the arguments change', () => { - function Template(person: Person, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { text(0); pipe(1, 'countingPipe'); } - textBinding(0, interpolation1('', pipeBind1(1, person.name), '')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', pipeBind1(1, person.name), '')); + } } // change from undefined -> null @@ -187,12 +203,14 @@ describe('pipe', () => { describe('impure', () => { it('should call impure pipes on each change detection run', () => { - function Template(person: Person, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { text(0); pipe(1, 'countingImpurePipe'); } - textBinding(0, interpolation1('', pipeBind1(1, person.name), '')); + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', pipeBind1(1, person.name), '')); + } } person.name = 'bob'; @@ -201,8 +219,8 @@ describe('pipe', () => { }); it('should not cache impure pipes', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); pipe(1, 'countingImpurePipe'); elementEnd(); @@ -211,26 +229,30 @@ describe('pipe', () => { elementEnd(); container(4); } - elementProperty(0, 'someProp', bind(pipeBind1(1, true))); - elementProperty(2, 'someProp', bind(pipeBind1(3, true))); - pipeInstances.push(load(1), load(3)); - containerRefreshStart(4); - { - for (let i of [1, 2]) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - elementStart(0, 'div'); - pipe(1, 'countingImpurePipe'); - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'someProp', bind(pipeBind1(1, true))); + elementProperty(2, 'someProp', bind(pipeBind1(3, true))); + pipeInstances.push(load(1), load(3)); + containerRefreshStart(4); + { + for (let i of [1, 2]) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + elementStart(0, 'div'); + pipe(1, 'countingImpurePipe'); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'someProp', bind(pipeBind1(1, true))); + pipeInstances.push(load(1)); + } } - elementProperty(0, 'someProp', bind(pipeBind1(1, true))); - pipeInstances.push(load(1)); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const pipeInstances: CountingImpurePipe[] = []; @@ -261,25 +283,29 @@ describe('pipe', () => { } it('should call ngOnDestroy on pipes', () => { - function Template(person: Person, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - if (person.age > 20) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - text(0); - pipe(1, 'pipeWithOnDestroy'); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + if (person.age > 20) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + text(0); + pipe(1, 'pipeWithOnDestroy'); + } + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', pipeBind1(1, person.age), '')); + } } - textBinding(0, interpolation1('', pipeBind1(1, person.age), '')); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const pipes = [PipeWithOnDestroy]; diff --git a/packages/core/test/render3/properties_spec.ts b/packages/core/test/render3/properties_spec.ts index 31f88b184e..5bfd9fcfcf 100644 --- a/packages/core/test/render3/properties_spec.ts +++ b/packages/core/test/render3/properties_spec.ts @@ -10,18 +10,20 @@ import {EventEmitter} from '@angular/core'; import {defineComponent, defineDirective, tick} from '../../src/render3/index'; import {NO_CHANGE, bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, listener, load, loadDirective, text, textBinding} from '../../src/render3/instructions'; - +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {ComponentFixture, renderToHtml} from './render_util'; describe('elementProperty', () => { it('should support bindings to properties', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementProperty(0, 'id', bind(ctx)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'id', bind(ctx)); + } } expect(renderToHtml(Template, 'testId')).toEqual(''); @@ -37,12 +39,14 @@ describe('elementProperty', () => { } } - function Template(ctx: string, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: string) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementProperty(0, 'id', cm ? expensive(ctx) : NO_CHANGE); + if (rf & RenderFlags.Update) { + elementProperty(0, 'id', rf & RenderFlags.Create ? expensive(ctx) : NO_CHANGE); + } } expect(renderToHtml(Template, 'cheapId')).toEqual(''); @@ -50,12 +54,14 @@ describe('elementProperty', () => { }); it('should support interpolation for properties', () => { - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); elementEnd(); } - elementProperty(0, 'id', interpolation1('_', ctx, '_')); + if (rf & RenderFlags.Update) { + elementProperty(0, 'id', interpolation1('_', ctx, '_')); + } } expect(renderToHtml(Template, 'testId')).toEqual(''); @@ -74,7 +80,7 @@ describe('elementProperty', () => { const instance = loadDirective(dirIndex) as HostBindingComp; elementProperty(elIndex, 'id', bind(instance.id)); }, - template: (ctx: HostBindingComp, cm: boolean) => {} + template: (rf: RenderFlags, ctx: HostBindingComp) => {} }); } @@ -144,15 +150,16 @@ describe('elementProperty', () => { it('should check input properties before setting (directives)', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button', ['otherDir', '', 'myButton', '']); { text(1, 'Click me'); } elementEnd(); } - - elementProperty(0, 'disabled', bind(ctx.isDisabled)); - elementProperty(0, 'id', bind(ctx.id)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'disabled', bind(ctx.isDisabled)); + elementProperty(0, 'id', bind(ctx.id)); + } } const ctx: any = {isDisabled: true, id: 0}; @@ -172,15 +179,16 @@ describe('elementProperty', () => { it('should support mixed element properties and input properties', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button', ['myButton', '']); { text(1, 'Click me'); } elementEnd(); } - - elementProperty(0, 'disabled', bind(ctx.isDisabled)); - elementProperty(0, 'id', bind(ctx.id)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'disabled', bind(ctx.isDisabled)); + elementProperty(0, 'id', bind(ctx.id)); + } } const ctx: any = {isDisabled: true, id: 0}; @@ -205,19 +213,21 @@ describe('elementProperty', () => { static ngComponentDef = defineComponent({ type: Comp, selectors: [['comp']], - template: function(ctx: any, cm: boolean) {}, + template: function(rf: RenderFlags, ctx: any) {}, factory: () => comp = new Comp(), inputs: {id: 'id'} }); } /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'comp'); elementEnd(); } - elementProperty(0, 'id', bind(ctx.id)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'id', bind(ctx.id)); + } } const deps = [Comp]; @@ -231,13 +241,15 @@ describe('elementProperty', () => { it('should support two input properties with the same name', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button', ['myButton', '', 'otherDisabledDir', '']); { text(1, 'Click me'); } elementEnd(); } - elementProperty(0, 'disabled', bind(ctx.isDisabled)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'disabled', bind(ctx.isDisabled)); + } } const ctx: any = {isDisabled: true}; @@ -255,8 +267,8 @@ describe('elementProperty', () => { it('should set input property if there is an output first', () => { /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button', ['otherDir', '']); { listener('click', ctx.onClick.bind(ctx)); @@ -264,7 +276,9 @@ describe('elementProperty', () => { } elementEnd(); } - elementProperty(0, 'id', bind(ctx.id)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'id', bind(ctx.id)); + } } let counter = 0; @@ -289,35 +303,43 @@ describe('elementProperty', () => { * // inputs: {'id': [0, 'id']} * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'button', ['idDir', '']); { text(1, 'Click me'); } elementEnd(); container(2); } - elementProperty(0, 'id', bind(ctx.id1)); - containerRefreshStart(2); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'button'); - { text(1, 'Click me too'); } - elementEnd(); + if (rf & RenderFlags.Update) { + elementProperty(0, 'id', bind(ctx.id1)); + containerRefreshStart(2); + { + if (ctx.condition) { + let rf0 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + elementStart(0, 'button'); + { text(1, 'Click me too'); } + elementEnd(); + } + if (rf0 & RenderFlags.Update) { + elementProperty(0, 'id', bind(ctx.id2)); + } + embeddedViewEnd(); + } else { + let rf1 = embeddedViewStart(1); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'button', ['otherDir', '']); + { text(1, 'Click me too'); } + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty(0, 'id', bind(ctx.id3)); + } + embeddedViewEnd(); } - elementProperty(0, 'id', bind(ctx.id2)); - embeddedViewEnd(); - } else { - if (embeddedViewStart(1)) { - elementStart(0, 'button', ['otherDir', '']); - { text(1, 'Click me too'); } - elementEnd(); - } - elementProperty(0, 'id', bind(ctx.id3)); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, {condition: true, id1: 'one', id2: 'two', id3: 'three'}, deps)) @@ -367,8 +389,8 @@ describe('elementProperty', () => { it('should set input property based on attribute if existing', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'button', 'myDir', '']); elementEnd(); } @@ -381,12 +403,14 @@ describe('elementProperty', () => { it('should set input property and attribute if both defined', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'button', 'myDir', '']); elementEnd(); } - elementProperty(0, 'role', bind(ctx.role)); + if (rf & RenderFlags.Update) { + elementProperty(0, 'role', bind(ctx.role)); + } } expect(renderToHtml(Template, {role: 'listbox'}, deps)) @@ -400,8 +424,8 @@ describe('elementProperty', () => { it('should set two directive input properties based on same attribute', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'button', 'myDir', '', 'myDirB', '']); elementEnd(); } @@ -416,8 +440,8 @@ describe('elementProperty', () => { it('should process two attributes on same directive', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'button', 'dir', 'rtl', 'myDir', '']); elementEnd(); } @@ -432,8 +456,8 @@ describe('elementProperty', () => { it('should process attributes and outputs properly together', () => { /**
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'button', 'myDir', '']); { listener('change', ctx.onChange.bind(ctx)); } elementEnd(); @@ -455,8 +479,8 @@ describe('elementProperty', () => { *
*
*/ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'button', 'dir', 'rtl', 'myDir', '']); elementEnd(); elementStart(1, 'div', ['role', 'listbox', 'myDirB', '']); @@ -482,30 +506,33 @@ describe('elementProperty', () => { *
// initialInputs: [null] * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'listbox', 'myDir', '']); elementEnd(); container(1); } - containerRefreshStart(1); - { - if (ctx.condition) { - if (embeddedViewStart(0)) { - elementStart(0, 'div', ['role', 'button', 'myDirB', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.condition) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'div', ['role', 'button', 'myDirB', '']); + elementEnd(); + } + embeddedViewEnd(); + } else { + let rf2 = embeddedViewStart(1); + if (rf2 & RenderFlags.Create) { + elementStart(0, 'div', ['role', 'menu']); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); - } else { - if (embeddedViewStart(1)) { - elementStart(0, 'div', ['role', 'menu']); - {} - elementEnd(); - } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, {condition: true}, deps)) @@ -526,14 +553,16 @@ describe('elementProperty', () => { type: Comp, selectors: [['comp']], /**
{{ dir.role }} */ - template: function(ctx: any, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'div', ['role', 'button', 'myDir', ''], ['dir', 'myDir']); elementEnd(); text(2); } - const tmp = load(1) as any; - textBinding(2, bind(tmp.role)); + if (rf & RenderFlags.Update) { + const tmp = load(1) as any; + textBinding(2, bind(tmp.role)); + } }, factory: () => new Comp(), directives: () => [MyDir] @@ -545,21 +574,24 @@ describe('elementProperty', () => { * * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - for (let i = 0; i < 2; i++) { - if (embeddedViewStart(0)) { - elementStart(0, 'comp'); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + for (let i = 0; i < 2; i++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'comp'); + elementEnd(); + } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } expect(renderToHtml(Template, {}, [Comp])) diff --git a/packages/core/test/render3/pure_function_spec.ts b/packages/core/test/render3/pure_function_spec.ts index 1515e26e7d..4cb71ae428 100644 --- a/packages/core/test/render3/pure_function_spec.ts +++ b/packages/core/test/render3/pure_function_spec.ts @@ -7,6 +7,7 @@ */ import {defineComponent} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective} from '../../src/render3/instructions'; +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {pureFunction1, pureFunction2, pureFunction3, pureFunction4, pureFunction5, pureFunction6, pureFunction7, pureFunction8, pureFunctionV} from '../../src/render3/pure_function'; import {renderToHtml} from '../../test/render3/render_util'; @@ -20,7 +21,7 @@ describe('array literals', () => { type: MyComp, selectors: [['my-comp']], factory: function MyComp_Factory() { return myComp = new MyComp(); }, - template: function MyComp_Template(ctx: MyComp, cm: boolean) {}, + template: function MyComp_Template(rf: RenderFlags, ctx: MyComp) {}, inputs: {names: 'names'} }); } @@ -31,12 +32,14 @@ describe('array literals', () => { const e0_ff = (v: any) => ['Nancy', v, 'Bess']; /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); elementEnd(); } - elementProperty(0, 'names', bind(pureFunction1(e0_ff, ctx.customName))); + if (rf & RenderFlags.Update) { + elementProperty(0, 'names', bind(pureFunction1(e0_ff, ctx.customName))); + } } renderToHtml(Template, {customName: 'Carson'}, directives); @@ -71,7 +74,7 @@ describe('array literals', () => { type: ManyPropComp, selectors: [['many-prop-comp']], factory: function ManyPropComp_Factory() { return manyPropComp = new ManyPropComp(); }, - template: function ManyPropComp_Template(ctx: ManyPropComp, cm: boolean) {}, + template: function ManyPropComp_Template(rf: RenderFlags, ctx: ManyPropComp) {}, inputs: {names1: 'names1', names2: 'names2'} }); } @@ -83,13 +86,15 @@ describe('array literals', () => { * * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'many-prop-comp'); elementEnd(); } - elementProperty(0, 'names1', bind(pureFunction1(e0_ff, ctx.customName))); - elementProperty(0, 'names2', bind(pureFunction1(e0_ff_1, ctx.customName2))); + if (rf & RenderFlags.Update) { + elementProperty(0, 'names1', bind(pureFunction1(e0_ff, ctx.customName))); + elementProperty(0, 'names2', bind(pureFunction1(e0_ff_1, ctx.customName2))); + } } const defs = [ManyPropComp]; @@ -120,20 +125,22 @@ describe('array literals', () => { type: ParentComp, selectors: [['parent-comp']], factory: () => new ParentComp(), - template: function(ctx: any, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); myComps.push(loadDirective(0)); elementEnd(); } - elementProperty(0, 'names', bind(ctx.someFn(pureFunction1(e0_ff, ctx.customName)))); + if (rf & RenderFlags.Update) { + elementProperty(0, 'names', bind(ctx.someFn(pureFunction1(e0_ff, ctx.customName)))); + } }, directives: directives }); } - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'parent-comp'); elementEnd(); elementStart(1, 'parent-comp'); @@ -159,12 +166,14 @@ describe('array literals', () => { const e0_ff = (v1: any, v2: any) => ['Nancy', v1, 'Bess', v2]; /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); elementEnd(); } - elementProperty(0, 'names', bind(pureFunction2(e0_ff, ctx.customName, ctx.customName2))); + if (rf & RenderFlags.Update) { + elementProperty(0, 'names', bind(pureFunction2(e0_ff, ctx.customName, ctx.customName2))); + } } renderToHtml(Template, {customName: 'Carson', customName2: 'Hannah'}, directives); @@ -212,8 +221,8 @@ describe('array literals', () => { (v1: any, v2: any, v3: any, v4: any, v5: any, v6: any, v7: any, v8: any) => [v1, v2, v3, v4, v5, v6, v7, v8]; - function Template(c: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, c: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); f3Comp = loadDirective(0); elementEnd(); @@ -233,14 +242,17 @@ describe('array literals', () => { f8Comp = loadDirective(5); elementEnd(); } - elementProperty(0, 'names', bind(pureFunction3(e0_ff, c[5], c[6], c[7]))); - elementProperty(1, 'names', bind(pureFunction4(e2_ff, c[4], c[5], c[6], c[7]))); - elementProperty(2, 'names', bind(pureFunction5(e4_ff, c[3], c[4], c[5], c[6], c[7]))); - elementProperty(3, 'names', bind(pureFunction6(e6_ff, c[2], c[3], c[4], c[5], c[6], c[7]))); - elementProperty( - 4, 'names', bind(pureFunction7(e8_ff, c[1], c[2], c[3], c[4], c[5], c[6], c[7]))); - elementProperty( - 5, 'names', bind(pureFunction8(e10_ff, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]))); + if (rf & RenderFlags.Update) { + elementProperty(0, 'names', bind(pureFunction3(e0_ff, c[5], c[6], c[7]))); + elementProperty(1, 'names', bind(pureFunction4(e2_ff, c[4], c[5], c[6], c[7]))); + elementProperty(2, 'names', bind(pureFunction5(e4_ff, c[3], c[4], c[5], c[6], c[7]))); + elementProperty(3, 'names', bind(pureFunction6(e6_ff, c[2], c[3], c[4], c[5], c[6], c[7]))); + elementProperty( + 4, 'names', bind(pureFunction7(e8_ff, c[1], c[2], c[3], c[4], c[5], c[6], c[7]))); + elementProperty( + 5, 'names', + bind(pureFunction8(e10_ff, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]))); + } } renderToHtml(Template, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'], directives); @@ -279,14 +291,17 @@ describe('array literals', () => { * * */ - function Template(c: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, c: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'my-comp'); elementEnd(); } - elementProperty(0, 'names', bind(pureFunctionV(e0_ff, [ - c[0], c[1], c[2], c[3], pureFunction1(e0_ff_1, c[4]), c[5], c[6], c[7], c[8] - ]))); + if (rf & RenderFlags.Update) { + elementProperty( + 0, 'names', bind(pureFunctionV(e0_ff, [ + c[0], c[1], c[2], c[3], pureFunction1(e0_ff_1, c[4]), c[5], c[6], c[7], c[8] + ]))); + } } expect(myComp !.names).toEqual([ @@ -315,7 +330,7 @@ describe('object literals', () => { type: ObjectComp, selectors: [['object-comp']], factory: function ObjectComp_Factory() { return objectComp = new ObjectComp(); }, - template: function ObjectComp_Template(ctx: ObjectComp, cm: boolean) {}, + template: function ObjectComp_Template(rf: RenderFlags, ctx: ObjectComp) {}, inputs: {config: 'config'} }); } @@ -326,12 +341,14 @@ describe('object literals', () => { const e0_ff = (v: any) => { return {duration: 500, animation: v}; }; /** */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'object-comp'); elementEnd(); } - elementProperty(0, 'config', bind(pureFunction1(e0_ff, ctx.name))); + if (rf & RenderFlags.Update) { + elementProperty(0, 'config', bind(pureFunction1(e0_ff, ctx.name))); + } } renderToHtml(Template, {name: 'slide'}, defs); @@ -359,15 +376,17 @@ describe('object literals', () => { * duration: duration }]}"> * */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'object-comp'); elementEnd(); } - elementProperty( - 0, 'config', - bind(pureFunction2( - e0_ff, ctx.name, pureFunction1(e0_ff_1, pureFunction1(e0_ff_2, ctx.duration))))); + if (rf & RenderFlags.Update) { + elementProperty( + 0, 'config', + bind(pureFunction2( + e0_ff, ctx.name, pureFunction1(e0_ff_1, pureFunction1(e0_ff_2, ctx.duration))))); + } } renderToHtml(Template, {name: 'slide', duration: 100}, defs); @@ -419,25 +438,30 @@ describe('object literals', () => { * * % } */ - function Template(ctx: any, cm: boolean) { - if (cm) { + function Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { container(0); } - containerRefreshStart(0); - { - for (let i = 0; i < 2; i++) { - if (embeddedViewStart(0)) { - elementStart(0, 'object-comp'); - objectComps.push(loadDirective(0)); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(0); + { + for (let i = 0; i < 2; i++) { + let rf1 = embeddedViewStart(0); + if (rf1 & RenderFlags.Create) { + elementStart(0, 'object-comp'); + objectComps.push(loadDirective(0)); + elementEnd(); + } + if (rf1 & RenderFlags.Update) { + elementProperty( + 0, 'config', + bind(pureFunction2(e0_ff, ctx.configs[i].opacity, ctx.configs[i].duration))); + } + embeddedViewEnd(); } - elementProperty( - 0, 'config', - bind(pureFunction2(e0_ff, ctx.configs[i].opacity, ctx.configs[i].duration))); - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); } const e0_ff = (v1: any, v2: any) => { return {opacity: v1, duration: v2}; }; diff --git a/packages/core/test/render3/query_spec.ts b/packages/core/test/render3/query_spec.ts index 451afe5a68..e31fbd02d7 100644 --- a/packages/core/test/render3/query_spec.ts +++ b/packages/core/test/render3/query_spec.ts @@ -8,6 +8,7 @@ import {QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF} from '../../src/render3/di'; import {QueryList, defineComponent, detectChanges} from '../../src/render3/index'; import {container, containerRefreshEnd, containerRefreshStart, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective} from '../../src/render3/instructions'; +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {query, queryRefresh} from '../../src/render3/query'; import {createComponent, createDirective, renderComponent} from './render_util'; @@ -43,11 +44,11 @@ function isViewContainerRef(candidate: any): boolean { describe('query', () => { it('should project query children', () => { - const Child = createComponent('child', function(ctx: any, cm: boolean) {}); + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {}); let child1 = null; let child2 = null; - const Cmp = createComponent('cmp', function(ctx: any, cm: boolean) { + const Cmp = createComponent('cmp', function(rf: RenderFlags, ctx: any) { /** * * @@ -59,7 +60,7 @@ describe('query', () => { * } */ let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, Child, false); query(1, Child, true); elementStart(2, 'child'); @@ -71,8 +72,10 @@ describe('query', () => { } elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query0 = tmp as QueryList); - queryRefresh(tmp = load>(1)) && (ctx.query1 = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query0 = tmp as QueryList); + queryRefresh(tmp = load>(1)) && (ctx.query1 = tmp as QueryList); + } }, [Child]); const parent = renderComponent(Cmp); @@ -91,14 +94,16 @@ describe('query', () => { * @ViewChildren(Child, {read: ElementRef}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, Child, false, QUERY_READ_ELEMENT_REF); elToQuery = elementStart(1, 'div', ['child', '']); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -119,15 +124,17 @@ describe('query', () => { * @ViewChildren(Child, {read: OtherChild}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, Child, false, OtherChild); elementStart(1, 'div', ['child', '', 'otherChild', '']); { otherChildInstance = loadDirective(1); } elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child, OtherChild]); const cmptInstance = renderComponent(Cmpt); @@ -145,14 +152,16 @@ describe('query', () => { * @ViewChildren(Child, {read: OtherChild}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, Child, false, OtherChild); elementStart(1, 'div', ['child', '']); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child, OtherChild]); const cmptInstance = renderComponent(Cmpt); @@ -173,16 +182,18 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, QUERY_READ_FROM_NODE); elToQuery = elementStart(1, 'div', null, ['foo', '']); elementEnd(); elementStart(3, 'div'); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -202,9 +213,9 @@ describe('query', () => { * @ViewChildren('bar') barQuery; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, QUERY_READ_FROM_NODE); query(1, ['bar'], false, QUERY_READ_FROM_NODE); elToQuery = elementStart(2, 'div', null, ['foo', '', 'bar', '']); @@ -212,8 +223,10 @@ describe('query', () => { elementStart(5, 'div'); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.fooQuery = tmp as QueryList); - queryRefresh(tmp = load>(1)) && (ctx.barQuery = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.fooQuery = tmp as QueryList); + queryRefresh(tmp = load>(1)) && (ctx.barQuery = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -239,9 +252,9 @@ describe('query', () => { * @ViewChildren('foo,bar') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE); el1ToQuery = elementStart(1, 'div', null, ['foo', '']); elementEnd(); @@ -250,7 +263,9 @@ describe('query', () => { el2ToQuery = elementStart(4, 'div', null, ['bar', '']); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -270,16 +285,18 @@ describe('query', () => { * @ViewChildren('foo', {read: ElementRef}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, QUERY_READ_ELEMENT_REF); elToQuery = elementStart(1, 'div', null, ['foo', '']); elementEnd(); elementStart(3, 'div'); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -296,14 +313,16 @@ describe('query', () => { * @ViewChildren('foo', {read: ViewContainerRef}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, QUERY_READ_CONTAINER_REF); elementStart(1, 'div', null, ['foo', '']); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -319,13 +338,15 @@ describe('query', () => { * @ViewChildren('foo', {read: ViewContainerRef}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, QUERY_READ_CONTAINER_REF); container(1, undefined, undefined, undefined, ['foo', '']); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -342,13 +363,15 @@ describe('query', () => { * @ViewChildren('foo', {read: ElementRef}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, QUERY_READ_ELEMENT_REF); container(1, undefined, undefined, undefined, ['foo', '']); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -365,13 +388,15 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], undefined, QUERY_READ_FROM_NODE); container(1, undefined, undefined, undefined, ['foo', '']); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -388,13 +413,15 @@ describe('query', () => { * @ViewChildren('foo', {read: TemplateRef}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, QUERY_READ_TEMPLATE_REF); container(1, undefined, undefined, undefined, ['foo', '']); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }); const cmptInstance = renderComponent(Cmpt); @@ -404,7 +431,7 @@ describe('query', () => { }); it('should read component instance if element queried for is a component host', () => { - const Child = createComponent('child', function(ctx: any, cm: boolean) {}); + const Child = createComponent('child', function(rf: RenderFlags, ctx: any) {}); let childInstance; /** @@ -413,15 +440,17 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); elementStart(1, 'child', null, ['foo', '']); { childInstance = loadDirective(0); } elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -438,7 +467,7 @@ describe('query', () => { type: Child, selectors: [['child']], factory: () => childInstance = new Child(), - template: (ctx: Child, cm: boolean) => {}, + template: (rf: RenderFlags, ctx: Child) => {}, exportAs: 'child' }); } @@ -449,14 +478,16 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); elementStart(1, 'child', null, ['foo', 'child']); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -476,15 +507,17 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); elementStart(1, 'div', ['child', ''], ['foo', 'child']); childInstance = loadDirective(0); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -504,9 +537,9 @@ describe('query', () => { * @ViewChildren('foo, bar') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo', 'bar'], true, QUERY_READ_FROM_NODE); elementStart(1, 'div', ['child1', '', 'child2', ''], ['foo', 'child1', 'bar', 'child2']); { @@ -515,7 +548,9 @@ describe('query', () => { } elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child1, Child2]); const cmptInstance = renderComponent(Cmpt); @@ -536,17 +571,19 @@ describe('query', () => { * @ViewChildren('bar') barQuery; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); query(1, ['bar'], true, QUERY_READ_FROM_NODE); elementStart(2, 'div', ['child', ''], ['foo', 'child', 'bar', 'child']); { childInstance = loadDirective(0); } elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.fooQuery = tmp as QueryList); - queryRefresh(tmp = load>(1)) && (ctx.barQuery = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.fooQuery = tmp as QueryList); + queryRefresh(tmp = load>(1)) && (ctx.barQuery = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -570,14 +607,16 @@ describe('query', () => { * @ViewChildren('foo', {read: ElementRef}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], undefined, QUERY_READ_ELEMENT_REF); div = elementStart(1, 'div', ['child', ''], ['foo', 'child']); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -596,15 +635,17 @@ describe('query', () => { * @ViewChildren('foo, bar') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo', 'bar'], undefined, QUERY_READ_FROM_NODE); div = elementStart(1, 'div', ['child', ''], ['foo', '', 'bar', 'child']); { childInstance = loadDirective(0); } elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -623,14 +664,16 @@ describe('query', () => { * @ViewChildren('foo', {read: Child}) query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], false, Child); elementStart(1, 'div', ['foo', '']); elementEnd(); } - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + if (rf & RenderFlags.Update) { + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + } }, [Child]); const cmptInstance = renderComponent(Cmpt); @@ -652,27 +695,29 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); container(1); } - containerRefreshStart(1); - { - if (ctx.exp) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - firstEl = elementStart(0, 'div', null, ['foo', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.exp) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + firstEl = elementStart(0, 'div', null, ['foo', '']); + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); } - containerRefreshEnd(); - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); }); const cmptInstance = renderComponent(Cmpt); @@ -702,9 +747,9 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); firstEl = elementStart(1, 'span', null, ['foo', '']); elementEnd(); @@ -712,21 +757,23 @@ describe('query', () => { lastEl = elementStart(4, 'span', null, ['foo', '']); elementEnd(); } - containerRefreshStart(3); - { - if (ctx.exp) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - viewEl = elementStart(0, 'div', null, ['foo', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(3); + { + if (ctx.exp) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + viewEl = elementStart(0, 'div', null, ['foo', '']); + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); } - containerRefreshEnd(); - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); }); const cmptInstance = renderComponent(Cmpt); @@ -762,37 +809,39 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); container(1); } - containerRefreshStart(1); - { - if (ctx.exp1) { - let cm1 = embeddedViewStart(0); - { - if (cm1) { - firstEl = elementStart(0, 'div', null, ['foo', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.exp1) { + let rf0 = embeddedViewStart(0); + { + if (rf0 & RenderFlags.Create) { + firstEl = elementStart(0, 'div', null, ['foo', '']); + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); - } - if (ctx.exp2) { - let cm1 = embeddedViewStart(1); - { - if (cm1) { - lastEl = elementStart(0, 'span', null, ['foo', '']); - elementEnd(); + if (ctx.exp2) { + let rf1 = embeddedViewStart(1); + { + if (rf1 & RenderFlags.Create) { + lastEl = elementStart(0, 'span', null, ['foo', '']); + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); } - containerRefreshEnd(); - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); }); const cmptInstance = renderComponent(Cmpt); @@ -824,42 +873,46 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); container(1); } - containerRefreshStart(1); - { - if (ctx.exp1) { - let cm1 = embeddedViewStart(0); - { - if (cm1) { - firstEl = elementStart(0, 'div', null, ['foo', '']); - elementEnd(); - container(2); - } - containerRefreshStart(2); + if (rf & RenderFlags.Update) { + containerRefreshStart(1); + { + if (ctx.exp1) { + let rf0 = embeddedViewStart(0); { - if (ctx.exp2) { - let cm2 = embeddedViewStart(0); + if (rf0 & RenderFlags.Create) { + firstEl = elementStart(0, 'div', null, ['foo', '']); + elementEnd(); + container(2); + } + if (rf0 & RenderFlags.Update) { + containerRefreshStart(2); { - if (cm2) { - lastEl = elementStart(0, 'span', null, ['foo', '']); - elementEnd(); + if (ctx.exp2) { + let rf2 = embeddedViewStart(0); + { + if (rf2) { + lastEl = elementStart(0, 'span', null, ['foo', '']); + elementEnd(); + } + } + embeddedViewEnd(); } } - embeddedViewEnd(); + containerRefreshEnd(); } } - containerRefreshEnd(); + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); + queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); } - containerRefreshEnd(); - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); }); const cmptInstance = renderComponent(Cmpt); @@ -888,31 +941,33 @@ describe('query', () => { * @ViewChildren('foo') query; * } */ - const Cmpt = createComponent('cmpt', function(ctx: any, cm: boolean) { + const Cmpt = createComponent('cmpt', function(rf: RenderFlags, ctx: any) { let tmp: any; - if (cm) { + if (rf & RenderFlags.Create) { query(0, ['foo'], true, QUERY_READ_FROM_NODE); query(1, ['foo'], false, QUERY_READ_FROM_NODE); container(2); elementStart(3, 'span', null, ['foo', '']); elementEnd(); } - containerRefreshStart(2); - { - if (ctx.exp) { - let cm1 = embeddedViewStart(0); - { - if (cm1) { - elementStart(0, 'div', null, ['foo', '']); - elementEnd(); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (ctx.exp) { + let rf0 = embeddedViewStart(0); + { + if (rf0 & RenderFlags.Create) { + elementStart(0, 'div', null, ['foo', '']); + elementEnd(); + } } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); + queryRefresh(tmp = load>(0)) && (ctx.deep = tmp as QueryList); + queryRefresh(tmp = load>(1)) && (ctx.shallow = tmp as QueryList); } - containerRefreshEnd(); - queryRefresh(tmp = load>(0)) && (ctx.deep = tmp as QueryList); - queryRefresh(tmp = load>(1)) && (ctx.shallow = tmp as QueryList); }); const cmptInstance = renderComponent(Cmpt); diff --git a/packages/core/test/render3/render_util.ts b/packages/core/test/render3/render_util.ts index 969fb30691..09d848aa9f 100644 --- a/packages/core/test/render3/render_util.ts +++ b/packages/core/test/render3/render_util.ts @@ -10,7 +10,7 @@ import {stringifyElement} from '@angular/platform-browser/testing/src/browser_ut import {CreateComponentOptions} from '../../src/render3/component'; import {extractDirectiveDef, extractPipeDef} from '../../src/render3/definition'; -import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, PublicFeature, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index'; +import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, PublicFeature, RenderFlags, defineComponent, defineDirective, renderComponent as _renderComponent, tick} from '../../src/render3/index'; import {NG_HOST_SYMBOL, renderTemplate} from '../../src/render3/instructions'; import {DirectiveDefList, DirectiveDefListOrFactory, DirectiveTypesOrFactory, PipeDef, PipeDefList, PipeDefListOrFactory, PipeTypesOrFactory} from '../../src/render3/interfaces/definition'; import {LElementNode} from '../../src/render3/interfaces/node'; @@ -63,11 +63,13 @@ export class TemplateFixture extends BaseFixture { super(); this._directiveDefs = toDefs(directives, extractDirectiveDef); this._pipeDefs = toDefs(pipes, extractPipeDef); - this.hostNode = renderTemplate(this.hostElement, (ctx: any, cm: boolean) => { - if (cm) { + this.hostNode = renderTemplate(this.hostElement, (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { this.createBlock(); } - this.updateBlock(); + if (rf & RenderFlags.Update) { + this.updateBlock(); + } }, null !, domRendererFactory3, null, this._directiveDefs, this._pipeDefs); } diff --git a/packages/core/test/render3/renderer_factory_spec.ts b/packages/core/test/render3/renderer_factory_spec.ts index 56d44f9561..68cbe30ba5 100644 --- a/packages/core/test/render3/renderer_factory_spec.ts +++ b/packages/core/test/render3/renderer_factory_spec.ts @@ -12,6 +12,7 @@ import {MockAnimationDriver, MockAnimationPlayer} from '@angular/animations/brow import {RendererType2, ViewEncapsulation} from '../../src/core'; import {defineComponent, detectChanges} from '../../src/render3/index'; import {bind, elementEnd, elementProperty, elementStart, listener, text, tick} from '../../src/render3/instructions'; +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {createRendererType2} from '../../src/view/index'; import {getAnimationRendererFactory2, getRendererFactory2} from './imported_renderer2'; @@ -32,9 +33,9 @@ describe('renderer factory lifecycle', () => { static ngComponentDef = defineComponent({ type: SomeComponent, selectors: [['some-component']], - template: function(ctx: SomeComponent, cm: boolean) { + template: function(rf: RenderFlags, ctx: SomeComponent) { logs.push('component'); - if (cm) { + if (rf & RenderFlags.Create) { text(0, 'foo'); } }, @@ -46,25 +47,25 @@ describe('renderer factory lifecycle', () => { static ngComponentDef = defineComponent({ type: SomeComponentWhichThrows, selectors: [['some-component-with-Error']], - template: function(ctx: SomeComponentWhichThrows, cm: boolean) { + template: function(rf: RenderFlags, ctx: SomeComponentWhichThrows) { throw(new Error('SomeComponentWhichThrows threw')); }, factory: () => new SomeComponentWhichThrows }); } - function Template(ctx: any, cm: boolean) { + function Template(rf: RenderFlags, ctx: any) { logs.push('function'); - if (cm) { + if (rf & RenderFlags.Create) { text(0, 'bar'); } } const directives = [SomeComponent, SomeComponentWhichThrows]; - function TemplateWithComponent(ctx: any, cm: boolean) { + function TemplateWithComponent(rf: RenderFlags, ctx: any) { logs.push('function_with_component'); - if (cm) { + if (rf & RenderFlags.Create) { text(0, 'bar'); elementStart(1, 'some-component'); elementEnd(); @@ -125,8 +126,8 @@ describe('animation renderer factory', () => { static ngComponentDef = defineComponent({ type: SomeComponent, selectors: [['some-component']], - template: function(ctx: SomeComponent, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: SomeComponent) { + if (rf & RenderFlags.Create) { text(0, 'foo'); } }, @@ -142,8 +143,8 @@ describe('animation renderer factory', () => { static ngComponentDef = defineComponent({ type: SomeComponentWithAnimation, selectors: [['some-component']], - template: function(ctx: SomeComponentWithAnimation, cm: boolean) { - if (cm) { + template: function(rf: RenderFlags, ctx: SomeComponentWithAnimation) { + if (rf & RenderFlags.Create) { elementStart(0, 'div'); { listener('@myAnimation.start', ctx.callback.bind(ctx)); @@ -152,7 +153,9 @@ describe('animation renderer factory', () => { } elementEnd(); } - elementProperty(0, '@myAnimation', bind(ctx.exp)); + if (rf & RenderFlags.Update) { + elementProperty(0, '@myAnimation', bind(ctx.exp)); + } }, factory: () => new SomeComponentWithAnimation, rendererType: createRendererType2({ diff --git a/packages/core/test/render3/view_container_ref_spec.ts b/packages/core/test/render3/view_container_ref_spec.ts index a1b0a0fadf..4b49204b57 100644 --- a/packages/core/test/render3/view_container_ref_spec.ts +++ b/packages/core/test/render3/view_container_ref_spec.ts @@ -10,6 +10,7 @@ import {Component, Directive, TemplateRef, ViewContainerRef} from '../../src/cor import {getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from '../../src/render3/di'; import {defineComponent, defineDirective, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, load, loadDirective, projection, projectionDef, text, textBinding} from '../../src/render3/instructions'; +import {RenderFlags} from '../../src/render3/interfaces/definition'; import {ComponentFixture, TemplateFixture} from './render_util'; @@ -34,11 +35,13 @@ describe('ViewContainerRef', () => { } describe('API', () => { - function embeddedTemplate(ctx: any, cm: boolean) { - if (cm) { + function embeddedTemplate(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0); } - textBinding(0, ctx.name); + if (rf & RenderFlags.Update) { + textBinding(0, bind(ctx.name)); + } } function createView(s: string, index?: number) { @@ -99,7 +102,7 @@ describe('ViewContainerRef', () => { type: HeaderComponent, selectors: [['header-cmp']], factory: () => new HeaderComponent(), - template: (cmp: HeaderComponent, cm: boolean) => {} + template: (rf: RenderFlags, cmp: HeaderComponent) => {} }); } @@ -143,7 +146,8 @@ describe('ViewContainerRef', () => { const tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); elementProperty(0, 'tplRef', bind(tplRef)); containerRefreshStart(0); - if (embeddedViewStart(1)) { + let rf1 = embeddedViewStart(1); + if (rf1 & RenderFlags.Create) { elementStart(0, 'header'); elementEnd(); } @@ -195,14 +199,14 @@ describe('ViewContainerRef', () => { remove(index?: number) { this._vcRef.remove(index); } } - function EmbeddedTemplateA(ctx: any, cm: boolean) { - if (cm) { + function EmbeddedTemplateA(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0, 'A'); } } - function EmbeddedTemplateB(ctx: any, cm: boolean) { - if (cm) { + function EmbeddedTemplateB(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0, 'B'); } } @@ -219,8 +223,8 @@ describe('ViewContainerRef', () => { type: TestComponent, selectors: [['test-cmp']], factory: () => new TestComponent(), - template: (cmp: TestComponent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, cmp: TestComponent) => { + if (rf & RenderFlags.Create) { text(0, 'before|'); container(1, EmbeddedTemplateA, undefined, ['testdir', '']); container(2, EmbeddedTemplateB, undefined, ['testdir', '']); @@ -261,8 +265,8 @@ describe('ViewContainerRef', () => { remove(index?: number) { this._vcRef.remove(index); } } - function EmbeddedTemplateA(ctx: any, cm: boolean) { - if (cm) { + function EmbeddedTemplateA(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { text(0, 'A'); } } @@ -282,26 +286,28 @@ describe('ViewContainerRef', () => { type: TestComponent, selectors: [['test-cmp']], factory: () => new TestComponent(), - template: (cmp: TestComponent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, cmp: TestComponent) => { + if (rf & RenderFlags.Create) { text(0, 'before|'); container(1, EmbeddedTemplateA, undefined, ['testdir', '']); container(2); text(3, '|after'); } - containerRefreshStart(2); - { - if (cmp.condition) { - let cm1 = embeddedViewStart(0); - { - if (cm1) { - text(0, 'B'); + if (rf & RenderFlags.Update) { + containerRefreshStart(2); + { + if (cmp.condition) { + let rf1 = embeddedViewStart(0); + { + if (rf1 & RenderFlags.Create) { + text(0, 'B'); + } } + embeddedViewEnd(); } - embeddedViewEnd(); } + containerRefreshEnd(); } - containerRefreshEnd(); }, directives: [TestDirective] }); @@ -456,8 +462,8 @@ describe('ViewContainerRef', () => { }); describe('projection', () => { - function embeddedTemplate(ctx: any, cm: boolean) { - if (cm) { + function embeddedTemplate(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { elementStart(0, 'span'); text(1); elementEnd(); @@ -472,8 +478,8 @@ describe('ViewContainerRef', () => { type: Child, selectors: [['child']], factory: () => new Child(), - template: (cmp: Child, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, cmp: Child) => { + if (rf & RenderFlags.Create) { projectionDef(0); elementStart(1, 'div'); { projection(2, 0); } @@ -497,8 +503,8 @@ describe('ViewContainerRef', () => { type: Parent, selectors: [['parent']], factory: () => new Parent(), - template: (cmp: Parent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, cmp: Parent) => { + if (rf & RenderFlags.Create) { container(0, embeddedTemplate); elementStart(1, 'child'); elementStart(2, 'header', ['vcref', '']); @@ -506,9 +512,12 @@ describe('ViewContainerRef', () => { elementEnd(); elementEnd(); } - const tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); - elementProperty(2, 'tplRef', bind(tplRef)); - elementProperty(2, 'name', bind(cmp.name)); + let tplRef: any; + if (rf & RenderFlags.Update) { + tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); + elementProperty(2, 'tplRef', bind(tplRef)); + elementProperty(2, 'name', bind(cmp.name)); + } }, directives: [Child, DirectiveWithVCRef] }); @@ -535,8 +544,8 @@ describe('ViewContainerRef', () => { type: ChildWithSelector, selectors: [['child-with-selector']], factory: () => new ChildWithSelector(), - template: (cmp: ChildWithSelector, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, cmp: ChildWithSelector) => { + if (rf & RenderFlags.Create) { projectionDef(0, [[['header']]], ['header']); elementStart(1, 'first'); { projection(2, 0, 1); } @@ -545,7 +554,8 @@ describe('ViewContainerRef', () => { { projection(4, 0); } elementEnd(); } - } + }, + directives: [ChildWithSelector, DirectiveWithVCRef] }); } @@ -565,8 +575,9 @@ describe('ViewContainerRef', () => { type: Parent, selectors: [['parent']], factory: () => new Parent(), - template: (cmp: Parent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, cmp: Parent) => { + let tplRef: any; + if (rf & RenderFlags.Create) { container(0, embeddedTemplate); elementStart(1, 'child-with-selector'); elementStart(2, 'header', ['vcref', '']); @@ -574,9 +585,11 @@ describe('ViewContainerRef', () => { elementEnd(); elementEnd(); } - const tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); - elementProperty(2, 'tplRef', bind(tplRef)); - elementProperty(2, 'name', bind(cmp.name)); + if (rf & RenderFlags.Update) { + tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); + elementProperty(2, 'tplRef', bind(tplRef)); + elementProperty(2, 'name', bind(cmp.name)); + } }, directives: [ChildWithSelector, DirectiveWithVCRef] }); @@ -611,8 +624,9 @@ describe('ViewContainerRef', () => { type: Parent, selectors: [['parent']], factory: () => new Parent(), - template: (cmp: Parent, cm: boolean) => { - if (cm) { + template: (rf: RenderFlags, cmp: Parent) => { + let tplRef: any; + if (rf & RenderFlags.Create) { container(0, embeddedTemplate); elementStart(1, 'child-with-selector'); elementStart(2, 'footer', ['vcref', '']); @@ -620,9 +634,11 @@ describe('ViewContainerRef', () => { elementEnd(); elementEnd(); } - const tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); - elementProperty(2, 'tplRef', bind(tplRef)); - elementProperty(2, 'name', bind(cmp.name)); + if (rf & RenderFlags.Update) { + tplRef = getOrCreateTemplateRef(getOrCreateNodeInjectorForNode(load(0))); + elementProperty(2, 'tplRef', bind(tplRef)); + elementProperty(2, 'name', bind(cmp.name)); + } }, directives: [ChildWithSelector, DirectiveWithVCRef] });