From 9098225ff06e4bec663c0c58828b2e9e1bc4c83a Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Fri, 18 Jan 2019 18:02:32 -0800 Subject: [PATCH] fix(ivy): View Queries inheritance fix (#28309) Prior to this change `viewQuery` functions that represent @ViewQuery list were not composable, which caused problems in case one Component/Directive inherits another one and both of them contain View Queries. Due to the fact that we used indices to reference queries, resulting query set was corrupted (child component queries were overridden by super class ones). In order to avoid that we no longer use indices assigned at compile time and instead maintain current view query index while iterating through them. This allows us to compose `viewQuery` functions and make inheritance feature work with View Queries. PR Close #28309 --- .../compliance/r3_compiler_compliance_spec.ts | 52 +- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 30 +- .../compiler/src/render3/r3_identifiers.ts | 2 + .../compiler/src/render3/view/compiler.ts | 34 +- .../compiler/src/render3/view/template.ts | 18 +- .../core/src/core_render3_private_export.ts | 2 + packages/core/src/render3/index.ts | 2 + packages/core/src/render3/instructions.ts | 25 +- packages/core/src/render3/interfaces/view.ts | 11 + packages/core/src/render3/jit/environment.ts | 2 + packages/core/src/render3/query.ts | 44 +- packages/core/src/render3/state.ts | 15 + packages/core/src/render3/util.ts | 2 +- .../hello_world/bundle.golden_symbols.json | 12 +- .../bundling/todo/bundle.golden_symbols.json | 12 +- packages/core/test/render3/content_spec.ts | 6 +- .../core/test/render3/host_binding_spec.ts | 2 +- .../inherit_definition_feature_spec.ts | 82 ++- packages/core/test/render3/query_spec.ts | 564 +++++++++--------- .../core/test/render3/styling/players_spec.ts | 10 +- .../test/render3/view_container_ref_spec.ts | 7 +- 21 files changed, 550 insertions(+), 384 deletions(-) diff --git a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts index 85f5e6742e..d6126df419 100644 --- a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts @@ -1376,20 +1376,20 @@ describe('compiler compliance', () => { factory: function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); }, viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵquery(0, SomeDirective, true); - $r3$.ɵquery(1, SomeDirective, true); + $r3$.ɵviewQuery(SomeDirective, true); + $r3$.ɵviewQuery(SomeDirective, true); } if (rf & 2) { var $tmp$; - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(0))) && (ctx.someDir = $tmp$.first)); - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(1))) && (ctx.someDirs = $tmp$)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.someDir = $tmp$.first)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.someDirs = $tmp$)); } }, - consts: 3, + consts: 1, vars: 0, template: function ViewQueryComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵelement(2, "div", $e0_attrs$); + $r3$.ɵelement(0, "div", $e0_attrs$); } }, directives: function () { return [SomeDirective]; }, @@ -1434,13 +1434,13 @@ describe('compiler compliance', () => { … viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵquery(0, $e0_attrs$, true); - $r3$.ɵquery(1, $e1_attrs$, true); + $r3$.ɵviewQuery($e0_attrs$, true); + $r3$.ɵviewQuery($e1_attrs$, true); } if (rf & 2) { var $tmp$; - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(0))) && (ctx.myRef = $tmp$.first)); - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(1))) && (ctx.myRefs = $tmp$)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.myRef = $tmp$.first)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.myRefs = $tmp$)); } }, … @@ -1489,17 +1489,17 @@ describe('compiler compliance', () => { … viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵquery(0, $e0_attrs$, true, TemplateRef); - $r3$.ɵquery(1, SomeDirective, true, ElementRef); - $r3$.ɵquery(2, $e1_attrs$, true, ElementRef); - $r3$.ɵquery(3, SomeDirective, true, TemplateRef); + $r3$.ɵviewQuery($e0_attrs$, true, TemplateRef); + $r3$.ɵviewQuery(SomeDirective, true, ElementRef); + $r3$.ɵviewQuery($e1_attrs$, true, ElementRef); + $r3$.ɵviewQuery(SomeDirective, true, TemplateRef); } if (rf & 2) { var $tmp$; - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(0))) && (ctx.myRef = $tmp$.first)); - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(1))) && (ctx.someDir = $tmp$.first)); - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(2))) && (ctx.myRefs = $tmp$)); - ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵload(3))) && (ctx.someDirs = $tmp$)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.myRef = $tmp$.first)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.someDir = $tmp$.first)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.myRefs = $tmp$)); + ($r3$.ɵqueryRefresh(($tmp$ = $r3$.ɵloadViewQuery())) && (ctx.someDirs = $tmp$)); } }, … @@ -1554,8 +1554,8 @@ describe('compiler compliance', () => { return new (t || ContentQueryComponent)(); }, contentQueries: function ContentQueryComponent_ContentQueries(dirIndex) { - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, SomeDirective, true), dirIndex); - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, SomeDirective, false), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery(SomeDirective, true), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery(SomeDirective, false), dirIndex); }, contentQueriesRefresh: function ContentQueryComponent_ContentQueriesRefresh(dirIndex, queryStartIndex) { const instance = $r3$.ɵload(dirIndex); @@ -1613,8 +1613,8 @@ describe('compiler compliance', () => { ContentQueryComponent.ngComponentDef = $r3$.ɵdefineComponent({ … contentQueries: function ContentQueryComponent_ContentQueries(dirIndex) { - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, $e0_attrs$, true), dirIndex); - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, $e1_attrs$, false), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery($e0_attrs$, true), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery($e1_attrs$, false), dirIndex); }, contentQueriesRefresh: function ContentQueryComponent_ContentQueriesRefresh(dirIndex, queryStartIndex) { const instance = $r3$.ɵload(dirIndex); @@ -1666,10 +1666,10 @@ describe('compiler compliance', () => { ContentQueryComponent.ngComponentDef = $r3$.ɵdefineComponent({ … contentQueries: function ContentQueryComponent_ContentQueries(dirIndex) { - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, $e0_attrs$ , true, TemplateRef), dirIndex); - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, SomeDirective, true, ElementRef), dirIndex); - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, $e1_attrs$, false, ElementRef), dirIndex); - $r3$.ɵregisterContentQuery($r3$.ɵquery(null, SomeDirective, false, TemplateRef), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery($e0_attrs$ , true, TemplateRef), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery(SomeDirective, true, ElementRef), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery($e1_attrs$, false, ElementRef), dirIndex); + $r3$.ɵregisterContentQuery($r3$.ɵquery(SomeDirective, false, TemplateRef), dirIndex); }, contentQueriesRefresh: function ContentQueryComponent_ContentQueriesRefresh(dirIndex, queryStartIndex) { const instance = $r3$.ɵload(dirIndex); diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 02e6b1aac9..aa2f6aad38 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -709,9 +709,9 @@ describe('ngtsc behavioral tests', () => { // Helper functions to construct RegExps for output validation const varRegExp = (name: string): RegExp => new RegExp(`var \\w+ = \\[\"${name}\"\\];`); - const queryRegExp = (id: number | null, descend: boolean, ref?: string): RegExp => { + const queryRegExp = (fnName: string, descend: boolean, ref?: string | null): RegExp => { const maybeRef = ref ? `, ${ref}` : ``; - return new RegExp(`i0\\.ɵquery\\(${id}, \\w+, ${descend}${maybeRef}\\)`); + return new RegExp(`i0\\.ɵ${fnName}\\(\\w+, ${descend}${maybeRef}\\)`); }; env.tsconfig(); @@ -740,13 +740,23 @@ describe('ngtsc behavioral tests', () => { expect(jsContents).toMatch(varRegExp('test1')); expect(jsContents).toMatch(varRegExp('test2')); expect(jsContents).toMatch(varRegExp('accessor')); - expect(jsContents).toContain(`i0.ɵquery(null, TemplateRef, false)`); + expect(jsContents).toContain(`i0.ɵquery(TemplateRef, false)`); expect(jsContents) - .toMatch(queryRegExp( - null, true, 'TemplateRef')); // match `i0.ɵquery(null, _c0, true, TemplateRef)` - expect(jsContents).toMatch(queryRegExp(null, true)); // match `i0.ɵquery(null, _c0, true)` - expect(jsContents).toMatch(queryRegExp(0, true)); // match `i0.ɵquery(0, _c0, true)` - expect(jsContents).toMatch(queryRegExp(1, true)); // match `i0.ɵquery(1, _c0, true)` + .toMatch( + // match `i0.ɵquery(_c0, true, TemplateRef)` + queryRegExp('query', true, 'TemplateRef')); + expect(jsContents) + .toMatch( + // match `i0.ɵquery(_c0, true)` + queryRegExp('query', true)); + expect(jsContents) + .toMatch( + // match `i0.ɵviewQuery(_c0, true)` + queryRegExp('viewQuery', true)); + expect(jsContents) + .toMatch( + // match `i0.ɵviewQuery(_c0, true)` + queryRegExp('viewQuery', true)); }); it('should handle queries that use forwardRef', () => { @@ -767,8 +777,8 @@ describe('ngtsc behavioral tests', () => { env.driveMain(); const jsContents = env.getContents('test.js'); - expect(jsContents).toContain(`i0.ɵquery(null, TemplateRef, true)`); - expect(jsContents).toContain(`i0.ɵquery(null, ViewContainerRef, true)`); + expect(jsContents).toContain(`i0.ɵquery(TemplateRef, true)`); + expect(jsContents).toContain(`i0.ɵquery(ViewContainerRef, true)`); }); it('should generate host listeners for components', () => { diff --git a/packages/compiler/src/render3/r3_identifiers.ts b/packages/compiler/src/render3/r3_identifiers.ts index 224e05c232..7814cfc2a7 100644 --- a/packages/compiler/src/render3/r3_identifiers.ts +++ b/packages/compiler/src/render3/r3_identifiers.ts @@ -185,6 +185,8 @@ export class Identifiers { static query: o.ExternalReference = {name: 'ɵquery', moduleName: CORE}; static queryRefresh: o.ExternalReference = {name: 'ɵqueryRefresh', moduleName: CORE}; + static viewQuery: o.ExternalReference = {name: 'ɵviewQuery', moduleName: CORE}; + static loadViewQuery: o.ExternalReference = {name: 'ɵloadViewQuery', moduleName: CORE}; static registerContentQuery: o.ExternalReference = {name: 'ɵregisterContentQuery', moduleName: CORE}; diff --git a/packages/compiler/src/render3/view/compiler.ts b/packages/compiler/src/render3/view/compiler.ts index 2f1ac60ea4..df84da23ed 100644 --- a/packages/compiler/src/render3/view/compiler.ts +++ b/packages/compiler/src/render3/view/compiler.ts @@ -254,7 +254,7 @@ export function compileComponentFromMetadata( const template = meta.template; const templateBuilder = new TemplateDefinitionBuilder( constantPool, BindingScope.ROOT_SCOPE, 0, templateTypeName, null, null, templateName, - meta.viewQueries, directiveMatcher, directivesUsed, meta.pipes, pipesUsed, R3.namespaceHTML, + directiveMatcher, directivesUsed, meta.pipes, pipesUsed, R3.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds); const templateFunctionExpression = templateBuilder.buildTemplateFunction(template.nodes, []); @@ -485,22 +485,19 @@ function selectorsFromGlobalMetadata( return o.NULL_EXPR; } -function createQueryDefinition( - query: R3QueryMetadata, constantPool: ConstantPool, idx: number | null): o.Expression { - const predicate = getQueryPredicate(query, constantPool); - - // e.g. r3.query(null, somePredicate, false) or r3.query(0, ['div'], false) +function prepareQueryParams(query: R3QueryMetadata, constantPool: ConstantPool): o.Expression[] { const parameters = [ - o.literal(idx, o.INFERRED_TYPE), - predicate, + getQueryPredicate(query, constantPool), o.literal(query.descendants), ]; - if (query.read) { parameters.push(query.read); } + return parameters; +} - return o.importExpr(R3.query).callFn(parameters); +function createQueryDefinition(query: R3QueryMetadata, constantPool: ConstantPool): o.Expression { + return o.importExpr(R3.query).callFn(prepareQueryParams(query, constantPool)); } // Turn a directive selector into an R3-compatible selector for directive def @@ -522,7 +519,7 @@ function createContentQueriesFunction( meta: R3DirectiveMetadata, constantPool: ConstantPool): o.Expression|null { if (meta.queries.length) { const statements: o.Statement[] = meta.queries.map((query: R3QueryMetadata) => { - const queryDefinition = createQueryDefinition(query, constantPool, null); + const queryDefinition = createQueryDefinition(query, constantPool); return o.importExpr(R3.registerContentQuery) .callFn([queryDefinition, o.variable('dirIndex')]) .toStmt(); @@ -620,22 +617,21 @@ function createViewQueriesFunction( const updateStatements: o.Statement[] = []; const tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME); - for (let i = 0; i < meta.viewQueries.length; i++) { - const query = meta.viewQueries[i]; - - // creation, e.g. r3.Q(0, somePredicate, true); - const queryDefinition = createQueryDefinition(query, constantPool, i); + meta.viewQueries.forEach((query: R3QueryMetadata) => { + // creation, e.g. r3.viewQuery(somePredicate, true); + const queryDefinition = + o.importExpr(R3.viewQuery).callFn(prepareQueryParams(query, constantPool)); createStatements.push(queryDefinition.toStmt()); - // update, e.g. (r3.qR(tmp = r3.ɵload(0)) && (ctx.someDir = tmp)); + // update, e.g. (r3.queryRefresh(tmp = r3.loadViewQuery()) && (ctx.someDir = tmp)); const temporary = tempAllocator(); - const getQueryList = o.importExpr(R3.load).callFn([o.literal(i)]); + const getQueryList = o.importExpr(R3.loadViewQuery).callFn([]); const refresh = o.importExpr(R3.queryRefresh).callFn([temporary.set(getQueryList)]); const updateDirective = o.variable(CONTEXT_NAME) .prop(query.propertyName) .set(query.first ? temporary.prop('first') : temporary); updateStatements.push(refresh.and(updateDirective).toStmt()); - } + }); const viewQueryFnName = meta.name ? `${meta.name}_Query` : null; return o.fn( diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index 35a61ce1a6..2e399f6916 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -31,7 +31,6 @@ import {Identifiers as R3} from '../r3_identifiers'; import {htmlAstToRender3Ast} from '../r3_template_transform'; import {prepareSyntheticListenerFunctionName, prepareSyntheticListenerName, prepareSyntheticPropertyName} from '../util'; -import {R3QueryMetadata} from './api'; import {I18nContext} from './i18n/context'; import {I18nMetaVisitor} from './i18n/meta'; import {getSerializedI18nContent} from './i18n/serializer'; @@ -161,14 +160,10 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver private constantPool: ConstantPool, parentBindingScope: BindingScope, private level = 0, private contextName: string|null, private i18nContext: I18nContext|null, private templateIndex: number|null, private templateName: string|null, - private viewQueries: R3QueryMetadata[], private directiveMatcher: SelectorMatcher|null, - private directives: Set, private pipeTypeByName: Map, - private pipes: Set, private _namespace: o.ExternalReference, - private relativeContextFilePath: string, private i18nUseExternalIds: boolean) { - // view queries can take up space in data and allocation happens earlier (in the "viewQuery" - // function) - this._dataIndex = viewQueries.length; - + private directiveMatcher: SelectorMatcher|null, private directives: Set, + private pipeTypeByName: Map, private pipes: Set, + private _namespace: o.ExternalReference, private relativeContextFilePath: string, + private i18nUseExternalIds: boolean) { this._bindingScope = parentBindingScope.nestedScope(level); // Turn the relative context file path into an identifier by replacing non-alphanumeric @@ -821,9 +816,8 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver // Create the template function const templateVisitor = new TemplateDefinitionBuilder( this.constantPool, this._bindingScope, this.level + 1, contextName, this.i18n, - templateIndex, templateName, [], this.directiveMatcher, this.directives, - this.pipeTypeByName, this.pipes, this._namespace, this.fileBasedI18nSuffix, - this.i18nUseExternalIds); + templateIndex, templateName, this.directiveMatcher, this.directives, this.pipeTypeByName, + this.pipes, this._namespace, this.fileBasedI18nSuffix, this.i18nUseExternalIds); // Nested templates must not be visited until after their parent templates have completed // processing, so they are queued here until after the initial pass. Otherwise, we wouldn't diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index eb7da1d585..745031f2cd 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -81,6 +81,8 @@ export { containerRefreshStart as ɵcontainerRefreshStart, containerRefreshEnd as ɵcontainerRefreshEnd, queryRefresh as ɵqueryRefresh, + viewQuery as ɵviewQuery, + loadViewQuery as ɵloadViewQuery, loadQueryList as ɵloadQueryList, elementEnd as ɵelementEnd, elementProperty as ɵelementProperty, diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index f90eec0741..bc57381553 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -124,6 +124,8 @@ export { export { query, queryRefresh, + viewQuery, + loadViewQuery, } from './query'; export { registerContentQuery, diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index 3dc4eb0532..ea978e5120 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -36,7 +36,7 @@ import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, DECLA import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert'; import {appendChild, appendProjectedNode, createTextNode, getLViewChild, insertView, removeView} from './node_manipulation'; import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher'; -import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getElementDepthCount, getFirstTemplatePass, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setFirstTemplatePass, setIsParent, setPreviousOrParentTNode} from './state'; +import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getCurrentViewQueryIndex, getElementDepthCount, getFirstTemplatePass, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentViewQueryIndex, setFirstTemplatePass, setIsParent, setPreviousOrParentTNode} from './state'; import {getInitialClassNameValue, initializeStaticContext as initializeStaticStylingContext, patchContextWithStaticAttrs, renderInitialStylesAndClasses, renderStyling, updateClassProp as updateElementClassProp, updateContextWithBindings, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings'; import {BoundPlayerFactory} from './styling/player_factory'; import {createEmptyStylingContext, getStylingContext, hasClassInput, hasStyling, isAnimationProp} from './styling/util'; @@ -722,6 +722,7 @@ export function createTView( data: blueprint.slice(), // Fill in to match HEADER_OFFSET in LView childIndex: -1, // Children set in addToViewTree(), if any bindingStartIndex: bindingStartIndex, + viewQueryStartIndex: initialViewLength, expandoStartIndex: initialViewLength, expandoInstructions: null, firstTemplatePass: true, @@ -2690,28 +2691,24 @@ export function checkView(hostView: LView, component: T) { const hostTView = hostView[TVIEW]; const oldView = enterView(hostView, hostView[HOST_NODE]); const templateFn = hostTView.template !; - const viewQuery = hostTView.viewQuery; + const creationMode = isCreationMode(hostView); try { namespaceHTML(); - createViewQuery(viewQuery, hostView, component); + creationMode && executeViewQueryFn(hostView, hostTView, component); templateFn(getRenderFlags(hostView), component); refreshDescendantViews(hostView); - updateViewQuery(viewQuery, hostView, component); + !creationMode && executeViewQueryFn(hostView, hostTView, component); } finally { leaveView(oldView); } } -function createViewQuery(viewQuery: ComponentQuery<{}>| null, view: LView, component: T): void { - if (viewQuery && isCreationMode(view)) { - viewQuery(RenderFlags.Create, component); - } -} - -function updateViewQuery(viewQuery: ComponentQuery<{}>| null, view: LView, component: T): void { - if (viewQuery && !isCreationMode(view)) { - viewQuery(RenderFlags.Update, component); +function executeViewQueryFn(lView: LView, tView: TView, component: T): void { + const viewQuery = tView.viewQuery; + if (viewQuery) { + setCurrentViewQueryIndex(tView.viewQueryStartIndex); + viewQuery(getRenderFlags(lView), component); } } @@ -3072,4 +3069,4 @@ function getTViewCleanup(view: LView): any[] { function loadComponentRenderer(tNode: TNode, lView: LView): Renderer3 { const componentLView = lView[tNode.index] as LView; return componentLView[RENDERER]; -} +} \ No newline at end of file diff --git a/packages/core/src/render3/interfaces/view.ts b/packages/core/src/render3/interfaces/view.ts index 88ab31b085..2196950b38 100644 --- a/packages/core/src/render3/interfaces/view.ts +++ b/packages/core/src/render3/interfaces/view.ts @@ -335,6 +335,17 @@ export interface TView { */ expandoStartIndex: number; + /** + * The index where the viewQueries section of `LView` begins. This section contains + * view queries defined for a component/directive. + * + * We store this start index so we know where the list of view queries starts. + * This is required when we invoke view queries at runtime. We invoke queries one by one and + * increment query index after each iteration. This information helps us to reset index back to + * the beginning of view query list before we invoke view queries again. + */ + viewQueryStartIndex: number; + /** * Index of the host node of the first LView or LContainer beneath this LView in * the hierarchy. diff --git a/packages/core/src/render3/jit/environment.ts b/packages/core/src/render3/jit/environment.ts index 0587dfa53c..aa116cccbe 100644 --- a/packages/core/src/render3/jit/environment.ts +++ b/packages/core/src/render3/jit/environment.ts @@ -89,6 +89,8 @@ export const angularCoreEnv: {[name: string]: Function} = { 'ɵpipe': r3.pipe, 'ɵquery': r3.query, 'ɵqueryRefresh': r3.queryRefresh, + 'ɵviewQuery': r3.viewQuery, + 'ɵloadViewQuery': r3.loadViewQuery, 'ɵregisterContentQuery': r3.registerContentQuery, 'ɵreference': r3.reference, 'ɵelementStyling': r3.elementStyling, diff --git a/packages/core/src/render3/query.ts b/packages/core/src/render3/query.ts index 8189023351..747acaa573 100644 --- a/packages/core/src/render3/query.ts +++ b/packages/core/src/render3/query.ts @@ -18,13 +18,13 @@ import {assertDefined, assertEqual} from '../util/assert'; import {assertPreviousIsParent} from './assert'; import {getNodeInjectable, locateDirectiveOrProvider} from './di'; import {NG_ELEMENT_ID} from './fields'; -import {store, storeCleanupWithContext} from './instructions'; +import {load, store, storeCleanupWithContext} from './instructions'; import {unusedValueExportToPlacateAjd as unused1} from './interfaces/definition'; import {unusedValueExportToPlacateAjd as unused2} from './interfaces/injector'; import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, unusedValueExportToPlacateAjd as unused3} from './interfaces/node'; import {LQueries, unusedValueExportToPlacateAjd as unused4} from './interfaces/query'; import {LView, TVIEW} from './interfaces/view'; -import {getIsParent, getLView, getOrCreateCurrentQueries} from './state'; +import {getCurrentViewQueryIndex, getIsParent, getLView, getOrCreateCurrentQueries, setCurrentViewQueryIndex} from './state'; import {isContentQueryHost} from './util'; import {createElementRef, createTemplateRef} from './view_engine_compatibility'; @@ -357,26 +357,20 @@ type QueryList_ = QueryList& {_valuesTree: any[]}; /** * Creates and returns a QueryList. * - * @param memoryIndex The index in memory where the QueryList should be saved. If null, - * this is is a content query and the QueryList will be saved later through directiveCreate. * @param predicate The type for which the query will search * @param descend Whether or not to descend into children * @param read What to save in the query * @returns QueryList */ export function query( - memoryIndex: number | null, predicate: Type| string[], descend?: boolean, // TODO: "read" should be an AbstractType (FW-486) - read?: any): QueryList { + predicate: Type| string[], descend?: boolean, read?: any): QueryList { ngDevMode && assertPreviousIsParent(getIsParent()); const queryList = new QueryList(); const queries = getOrCreateCurrentQueries(LQueries_); (queryList as QueryList_)._valuesTree = []; queries.track(queryList, predicate, descend, read); storeCleanupWithContext(getLView(), queryList, queryList.destroy); - if (memoryIndex != null) { - store(memoryIndex, queryList); - } return queryList; } @@ -394,3 +388,35 @@ export function queryRefresh(queryList: QueryList): boolean { } return false; } + +/** + * Creates new QueryList, stores the reference in LView and returns QueryList. + * + * @param predicate The type for which the query will search + * @param descend Whether or not to descend into children + * @param read What to save in the query + * @returns QueryList + */ +export function viewQuery( + // TODO: "read" should be an AbstractType (FW-486) + predicate: Type| string[], descend?: boolean, read?: any): QueryList { + const lView = getLView(); + const tView = lView[TVIEW]; + if (tView.firstTemplatePass) { + tView.expandoStartIndex++; + } + const index = getCurrentViewQueryIndex(); + const viewQuery: QueryList = query(predicate, descend, read); + store(index, viewQuery); + setCurrentViewQueryIndex(index + 1); + return viewQuery; +} + +/** +* Loads current View Query and moves the pointer/index to the next View Query in LView. +*/ +export function loadViewQuery(): T { + const index = getCurrentViewQueryIndex(); + setCurrentViewQueryIndex(index + 1); + return load(index); +} \ No newline at end of file diff --git a/packages/core/src/render3/state.ts b/packages/core/src/render3/state.ts index b259f70035..ffcbc9c140 100644 --- a/packages/core/src/render3/state.ts +++ b/packages/core/src/render3/state.ts @@ -256,6 +256,21 @@ export function setBindingRoot(value: number) { bindingRootIndex = value; } +/** + * Current index of a View Query which needs to be processed next. + * We iterate over the list of View Queries stored in LView and increment current query index. + */ +let viewQueryIndex: number = 0; + +export function getCurrentViewQueryIndex(): number { + // top level variables should not be exported for performance reasons (PERF_NOTES.md) + return viewQueryIndex; +} + +export function setCurrentViewQueryIndex(value: number): void { + viewQueryIndex = value; +} + /** * Swap the current state with a new state. * diff --git a/packages/core/src/render3/util.ts b/packages/core/src/render3/util.ts index c2d97fb503..8376c7881f 100644 --- a/packages/core/src/render3/util.ts +++ b/packages/core/src/render3/util.ts @@ -14,7 +14,7 @@ import {LContext, MONKEY_PATCH_KEY_NAME} from './interfaces/context'; import {ComponentDef, DirectiveDef} from './interfaces/definition'; import {NO_PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags} from './interfaces/injector'; import {TContainerNode, TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node'; -import {GlobalTargetName, GlobalTargetResolver, RComment, RElement, RText} from './interfaces/renderer'; +import {RComment, RElement, RText} from './interfaces/renderer'; import {StylingContext} from './interfaces/styling'; import {CONTEXT, DECLARATION_VIEW, FLAGS, HEADER_OFFSET, HOST, HOST_NODE, LView, LViewFlags, PARENT, RootContext, TData, TVIEW, TView} from './interfaces/view'; 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 075c989328..836307a50d 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -179,9 +179,6 @@ { "name": "createViewBlueprint" }, - { - "name": "createViewQuery" - }, { "name": "defaultScheduler" }, @@ -203,6 +200,9 @@ { "name": "executeInitHooks" }, + { + "name": "executeViewQueryFn" + }, { "name": "extractDirectiveDef" }, @@ -407,6 +407,9 @@ { "name": "setCurrentDirectiveDef" }, + { + "name": "setCurrentViewQueryIndex" + }, { "name": "setFirstTemplatePass" }, @@ -437,9 +440,6 @@ { "name": "tickRootContext" }, - { - "name": "updateViewQuery" - }, { "name": "viewAttached" } diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index f93c9288a8..29bd825d2c 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -482,9 +482,6 @@ { "name": "createViewNode" }, - { - "name": "createViewQuery" - }, { "name": "decreaseElementDepthCount" }, @@ -566,6 +563,9 @@ { "name": "executeOnDestroys" }, + { + "name": "executeViewQueryFn" + }, { "name": "extendStatics" }, @@ -1127,6 +1127,9 @@ { "name": "setCurrentDirectiveDef" }, + { + "name": "setCurrentViewQueryIndex" + }, { "name": "setDirectiveDirty" }, @@ -1220,9 +1223,6 @@ { "name": "updateContextWithBindings" }, - { - "name": "updateViewQuery" - }, { "name": "valueExists" }, diff --git a/packages/core/test/render3/content_spec.ts b/packages/core/test/render3/content_spec.ts index 6180051949..5521904c46 100644 --- a/packages/core/test/render3/content_spec.ts +++ b/packages/core/test/render3/content_spec.ts @@ -8,7 +8,7 @@ import {SelectorFlags} from '@angular/core/src/render3/interfaces/projection'; -import {AttributeMarker, defineDirective, detectChanges, directiveInject, load, query, queryRefresh, reference, templateRefExtractor} from '../../src/render3/index'; +import {AttributeMarker, defineDirective, detectChanges, directiveInject, loadViewQuery, queryRefresh, reference, templateRefExtractor, viewQuery} from '../../src/render3/index'; import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, projection, projectionDef, template, text, textBinding, interpolation1} from '../../src/render3/instructions'; import {RenderFlags} from '../../src/render3/interfaces/definition'; @@ -1026,11 +1026,11 @@ describe('content projection', () => { function(rf: RenderFlags, ctx: any) { /** @ViewChild(TemplateRef) template: TemplateRef */ if (rf & RenderFlags.Create) { - query(0, TemplateRef as any, true); + viewQuery(TemplateRef as any, true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.template = tmp.first); + queryRefresh(tmp = loadViewQuery>()) && (ctx.template = tmp.first); } }); diff --git a/packages/core/test/render3/host_binding_spec.ts b/packages/core/test/render3/host_binding_spec.ts index c9108ef69f..34321f6d5a 100644 --- a/packages/core/test/render3/host_binding_spec.ts +++ b/packages/core/test/render3/host_binding_spec.ts @@ -1009,7 +1009,7 @@ describe('host bindings', () => { elementProperty(elIndex, 'id', bind(ctx.foos.length), null, true); } }, - contentQueries: (dirIndex) => { registerContentQuery(query(null, ['foo']), dirIndex); }, + contentQueries: (dirIndex) => { registerContentQuery(query(['foo']), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; const instance = load(dirIndex); diff --git a/packages/core/test/render3/inherit_definition_feature_spec.ts b/packages/core/test/render3/inherit_definition_feature_spec.ts index d51f096aa1..9e4e170e6f 100644 --- a/packages/core/test/render3/inherit_definition_feature_spec.ts +++ b/packages/core/test/render3/inherit_definition_feature_spec.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {Inject, InjectionToken} from '../../src/core'; -import {ComponentDef, DirectiveDef, InheritDefinitionFeature, NgOnChangesFeature, ProvidersFeature, RenderFlags, allocHostVars, bind, defineBase, defineComponent, defineDirective, directiveInject, element, elementProperty, load} from '../../src/render3/index'; +import {Inject, InjectionToken, QueryList} from '../../src/core'; +import {ComponentDef, DirectiveDef, InheritDefinitionFeature, NgOnChangesFeature, ProvidersFeature, RenderFlags, allocHostVars, bind, defineBase, defineComponent, defineDirective, directiveInject, element, elementProperty, loadViewQuery, queryRefresh, viewQuery} from '../../src/render3/index'; import {ComponentFixture, createComponent} from './render_util'; @@ -363,7 +363,7 @@ describe('InheritDefinitionFeature', () => { expect(divEl.title).toEqual('new-title'); }); - it('should compose viewQuery', () => { + it('should compose viewQuery (basic mechanics check)', () => { const log: Array<[string, RenderFlags, any]> = []; class SuperComponent { @@ -404,6 +404,82 @@ describe('InheritDefinitionFeature', () => { expect(log).toEqual([['super', 1, context], ['sub', 1, context]]); }); + it('should compose viewQuery (query logic check)', () => { + /* + * class SuperComponent { + * @ViewChildren('super') superQuery; + * } + */ + class SuperComponent { + superQuery?: QueryList; + static ngComponentDef = defineComponent({ + type: SuperComponent, + template: () => {}, + consts: 0, + vars: 0, + selectors: [['', 'superDir', '']], + viewQuery: (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { + viewQuery(['super'], false); + } + if (rf & RenderFlags.Update) { + let tmp: any; + queryRefresh(tmp = loadViewQuery>()) && + (ctx.superQuery = tmp as QueryList); + } + }, + factory: () => new SuperComponent(), + }); + } + + /** + *
+ *
+ * class SubComponent extends SuperComponent { + * @ViewChildren('sub') subQuery; + * } + */ + class SubComponent extends SuperComponent { + subQuery?: QueryList; + static ngComponentDef = defineComponent({ + type: SubComponent, + template: (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { + element(0, 'div', ['id', 'sub'], ['sub', '']); + element(2, 'div', ['id', 'super'], ['super', '']); + } + }, + consts: 4, + vars: 0, + selectors: [['', 'subDir', '']], + viewQuery: (rf: RenderFlags, ctx: any) => { + if (rf & RenderFlags.Create) { + viewQuery(['sub'], false); + } + if (rf & RenderFlags.Update) { + let tmp: any; + queryRefresh(tmp = loadViewQuery>()) && + (ctx.subQuery = tmp as QueryList); + } + }, + factory: () => new SubComponent(), + features: [InheritDefinitionFeature] + }); + } + + const fixture = new ComponentFixture(SubComponent); + + const check = (key: string): void => { + const qList = (fixture.component as any)[`${key}Query`] as QueryList; + expect(qList.length).toBe(1); + expect(qList.first.nativeElement).toEqual(fixture.hostElement.querySelector(`#${key}`)); + expect(qList.first.nativeElement.id).toEqual(key); + }; + + check('sub'); + check('super'); + }); + it('should compose contentQueries', () => { const log: string[] = []; diff --git a/packages/core/test/render3/query_spec.ts b/packages/core/test/render3/query_spec.ts index 4dca778d71..fa70e15733 100644 --- a/packages/core/test/render3/query_spec.ts +++ b/packages/core/test/render3/query_spec.ts @@ -15,7 +15,7 @@ import {getNativeByIndex} from '../../src/render3/util'; import {bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadQueryList, reference, registerContentQuery, template, text} from '../../src/render3/instructions'; import {RenderFlags} from '../../src/render3/interfaces/definition'; -import {query, queryRefresh} from '../../src/render3/query'; +import {query, queryRefresh, viewQuery, loadViewQuery} from '../../src/render3/query'; import {getLView} from '../../src/render3/state'; import {templateRefExtractor} from '../../src/render3/view_engine_compatibility_prebound'; @@ -71,25 +71,27 @@ describe('query', () => { * } */ if (rf & RenderFlags.Create) { - elementStart(2, 'child'); - { element(3, 'child'); } + elementStart(0, 'child'); + { element(1, 'child'); } elementEnd(); } if (rf & RenderFlags.Update) { - child1 = getDirectiveOnNode(2); - child2 = getDirectiveOnNode(3); + child1 = getDirectiveOnNode(0); + child2 = getDirectiveOnNode(1); } }, - 4, 0, [Child], [], + 2, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, Child, false); - query(1, Child, true); + viewQuery(Child, false); + viewQuery(Child, true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query0 = tmp as QueryList); - queryRefresh(tmp = load>(1)) && (ctx.query1 = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query0 = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query1 = tmp as QueryList); } }); @@ -114,18 +116,19 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', '']); - elToQuery = getNativeByIndex(1, getLView()); + element(0, 'div', ['child', '']); + elToQuery = getNativeByIndex(0, getLView()); } }, - 2, 0, [Child], [], + 1, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, Child, false, ElementRef); + viewQuery(Child, false, ElementRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -150,19 +153,20 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - elementStart(1, 'div', ['child', '', 'otherChild', '']); - { otherChildInstance = getDirectiveOnNode(1, 1); } + elementStart(0, 'div', ['child', '', 'otherChild', '']); + { otherChildInstance = getDirectiveOnNode(0, 1); } elementEnd(); } }, - 2, 0, [Child, OtherChild], [], + 1, 0, [Child, OtherChild], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, Child, false, OtherChild); + viewQuery(Child, false, OtherChild); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -185,17 +189,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', '']); + element(0, 'div', ['child', '']); } }, - 2, 0, [Child, OtherChild], [], + 1, 0, [Child, OtherChild], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, Child, false, OtherChild); + viewQuery(Child, false, OtherChild); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -246,25 +251,25 @@ describe('query', () => { static ngComponentDef = defineComponent({ type: App, selectors: [['app']], - consts: 4, + consts: 1, vars: 0, factory: function App_Factory() { return new App(); }, template: function App_Template(rf: RenderFlags, ctx: App) { if (rf & RenderFlags.Create) { - element(3, 'div', ['myDir']); + element(0, 'div', ['myDir']); } }, viewQuery: function(rf: RenderFlags, ctx: App) { - let tmp: any; if (rf & RenderFlags.Create) { - query(0, MyDirective, false); - query(1, Service, false); - query(2, Alias, false); + viewQuery(MyDirective, false); + viewQuery(Service, false); + viewQuery(Alias, false); } if (rf & RenderFlags.Update) { - queryRefresh(tmp = load>(0)) && (ctx.directive = tmp.first); - queryRefresh(tmp = load>(1)) && (ctx.service = tmp.first); - queryRefresh(tmp = load>(2)) && (ctx.alias = tmp.first); + let tmp: any; + queryRefresh(tmp = loadViewQuery>()) && (ctx.directive = tmp.first); + queryRefresh(tmp = loadViewQuery>()) && (ctx.service = tmp.first); + queryRefresh(tmp = loadViewQuery>()) && (ctx.alias = tmp.first); } }, directives: [MyDirective] @@ -291,21 +296,21 @@ describe('query', () => { static ngComponentDef = defineComponent({ type: App, selectors: [['app']], - consts: 2, + consts: 1, vars: 0, factory: function App_Factory() { return new App(); }, template: function App_Template(rf: RenderFlags, ctx: App) { if (rf & RenderFlags.Create) { - element(1, 'div', ['myDir']); + element(0, 'div', ['myDir']); } }, viewQuery: function(rf: RenderFlags, ctx: App) { let tmp: any; if (rf & RenderFlags.Create) { - query(0, MyDirective, false, Alias); + viewQuery(MyDirective, false, Alias); } if (rf & RenderFlags.Update) { - queryRefresh(tmp = load>(0)) && (ctx.service = tmp.first); + queryRefresh(tmp = loadViewQuery>()) && (ctx.service = tmp.first); } }, directives: [MyDirective] @@ -334,19 +339,20 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', null, ['foo', '']); - elToQuery = getNativeByIndex(1, getLView()); - element(3, 'div'); + element(0, 'div', null, ['foo', '']); + elToQuery = getNativeByIndex(0, getLView()); + element(2, 'div'); } }, - 4, 0, [], [], + 3, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false); + viewQuery(['foo'], false); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -371,22 +377,22 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(2, 'div', null, ['foo', '', 'bar', '']); - elToQuery = getNativeByIndex(2, getLView()); - element(5, 'div'); + element(0, 'div', null, ['foo', '', 'bar', '']); + elToQuery = getNativeByIndex(0, getLView()); + element(3, 'div'); } }, - 6, 0, [], [], + 4, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false); - query(1, ['bar'], false); + viewQuery(['foo'], false); + viewQuery(['bar'], false); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.fooQuery = tmp as QueryList); - queryRefresh(tmp = load>(1)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.barQuery = tmp as QueryList); } }); @@ -418,21 +424,22 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', null, ['foo', '']); - el1ToQuery = getNativeByIndex(1, getLView()); - element(3, 'div'); - element(4, 'div', null, ['bar', '']); - el2ToQuery = getNativeByIndex(4, getLView()); + element(0, 'div', null, ['foo', '']); + el1ToQuery = getNativeByIndex(0, getLView()); + element(2, 'div'); + element(3, 'div', null, ['bar', '']); + el2ToQuery = getNativeByIndex(3, getLView()); } }, - 6, 0, [], [], + 5, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo', 'bar'], undefined); + viewQuery(['foo', 'bar'], undefined); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -457,19 +464,20 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', null, ['foo', '']); - elToQuery = getNativeByIndex(1, getLView()); - element(3, 'div'); + element(0, 'div', null, ['foo', '']); + elToQuery = getNativeByIndex(0, getLView()); + element(2, 'div'); } }, - 4, 0, [], [], + 3, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false); + viewQuery(['foo'], false); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -493,19 +501,19 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - elementContainerStart(1, null, ['foo', '']); - elToQuery = getNativeByIndex(1, getLView()); + elementContainerStart(0, null, ['foo', '']); + elToQuery = getNativeByIndex(0, getLView()); elementContainerEnd(); } }, - 3, 0, [], [], + 2, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false, ElementRef); + viewQuery(['foo'], false, ElementRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.query = tmp as QueryList); } }); @@ -529,19 +537,20 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - elementContainerStart(1, null, ['foo', '']); - elToQuery = getNativeByIndex(1, getLView()); + elementContainerStart(0, null, ['foo', '']); + elToQuery = getNativeByIndex(0, getLView()); elementContainerEnd(); } }, - 3, 0, [], [], + 2, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -590,24 +599,25 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - elementContainerStart(2); + elementContainerStart(0); { - element(3, 'div', null, ['foo', '']); + element(1, 'div', null, ['foo', '']); elToQuery = getNativeByIndex(3, getLView()); } elementContainerEnd(); } }, - 5, 0, [], [], + 3, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true, ElementRef); - query(1, ['foo'], false, ElementRef); + viewQuery(['foo'], true, ElementRef); + viewQuery(['foo'], false, ElementRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.deep = tmp as QueryList); - queryRefresh(tmp = load>(1)) && + queryRefresh(tmp = loadViewQuery>()) && + (ctx.deep = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && (ctx.shallow = tmp as QueryList); } }); @@ -630,17 +640,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', null, ['foo', '']); + element(0, 'div', null, ['foo', '']); } }, - 3, 0, [], [], + 2, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false, ViewContainerRef); + viewQuery(['foo'], false, ViewContainerRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -661,17 +672,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, 'ng-template', null, ['foo', '']); + template(0, null, 0, 0, 'ng-template', null, ['foo', '']); } }, - 3, 0, [], [], + 2, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false, ViewContainerRef); + viewQuery(['foo'], false, ViewContainerRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -693,18 +705,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, 'ng-template', null, ['foo', '']); + template(0, null, 0, 0, 'ng-template', null, ['foo', '']); } }, - 3, 0, [], [], + 2, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false, ElementRef); + viewQuery(['foo'], false, ElementRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.query = tmp as QueryList); } }); @@ -728,17 +740,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, 'ng-template', null, ['foo', '']); + template(0, null, 0, 0, 'ng-template', null, ['foo', '']); } }, - 3, 0, [], [], + 2, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], undefined); + viewQuery(['foo'], undefined); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -760,17 +773,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, 'ng-template', null, ['foo', '']); + template(0, null, 0, 0, 'ng-template', null, ['foo', '']); } }, - 3, 0, [], [], + 2, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false, TemplateRef); + viewQuery(['foo'], false, TemplateRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -794,20 +808,21 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'child', null, ['foo', '']); + element(0, 'child', null, ['foo', '']); } if (rf & RenderFlags.Update) { - childInstance = getDirectiveOnNode(1); + childInstance = getDirectiveOnNode(0); } }, - 3, 0, [Child], [], + 2, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -842,17 +857,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'child', null, ['foo', 'child']); + element(0, 'child', null, ['foo', 'child']); } }, - 3, 0, [Child], [], + 2, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -877,20 +893,20 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', ''], ['foo', 'child']); + element(0, 'div', ['child', ''], ['foo', 'child']); } if (rf & RenderFlags.Update) { - childInstance = getDirectiveOnNode(1); + childInstance = getDirectiveOnNode(0); } }, - 3, 0, [Child], [], + 2, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.query = tmp as QueryList); } }); @@ -916,21 +932,22 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child1', '', 'child2', ''], ['foo', 'child1', 'bar', 'child2']); + element(0, 'div', ['child1', '', 'child2', ''], ['foo', 'child1', 'bar', 'child2']); } if (rf & RenderFlags.Update) { - child1Instance = getDirectiveOnNode(1, 0); - child2Instance = getDirectiveOnNode(1, 1); + child1Instance = getDirectiveOnNode(0, 0); + child2Instance = getDirectiveOnNode(0, 1); } }, - 4, 0, [Child1, Child2], [], + 3, 0, [Child1, Child2], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo', 'bar'], true); + viewQuery(['foo', 'bar'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -956,23 +973,23 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(2, 'div', ['child', ''], ['foo', 'child', 'bar', 'child']); + element(0, 'div', ['child', ''], ['foo', 'child', 'bar', 'child']); } if (rf & RenderFlags.Update) { - childInstance = getDirectiveOnNode(2); + childInstance = getDirectiveOnNode(0); } }, - 5, 0, [Child], [], + 3, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); - query(1, ['bar'], true); + viewQuery(['foo'], true); + viewQuery(['bar'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.fooQuery = tmp as QueryList); - queryRefresh(tmp = load>(1)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.barQuery = tmp as QueryList); } }); @@ -1002,18 +1019,19 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', ''], ['foo', 'child']); - div = getNativeByIndex(1, getLView()); + element(0, 'div', ['child', ''], ['foo', 'child']); + div = getNativeByIndex(0, getLView()); } }, - 3, 0, [Child], [], + 2, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], undefined, ElementRef); + viewQuery(['foo'], undefined, ElementRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1037,21 +1055,22 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', ''], ['foo', '', 'bar', 'child']); - div = getNativeByIndex(1, getLView()); + element(0, 'div', ['child', ''], ['foo', '', 'bar', 'child']); + div = getNativeByIndex(0, getLView()); } if (rf & RenderFlags.Update) { - childInstance = getDirectiveOnNode(1); + childInstance = getDirectiveOnNode(0); } }, - 4, 0, [Child], [], + 3, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo', 'bar'], undefined); + viewQuery(['foo', 'bar'], undefined); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1075,17 +1094,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['foo', '']); + element(0, 'div', ['foo', '']); } }, - 3, 0, [Child], [], + 2, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false, Child); + viewQuery(['foo'], false, Child); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1108,17 +1128,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', '']); + element(0, 'div', ['child', '']); } }, - 2, 0, [Child, OtherChild], [], + 1, 0, [Child, OtherChild], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, Child, false, OtherChild); + viewQuery(Child, false, OtherChild); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1141,17 +1162,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', '']); + element(0, 'div', ['child', '']); } }, - 2, 0, [Child, OtherChild], [], + 1, 0, [Child, OtherChild], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, OtherChild, false, Child); + viewQuery(OtherChild, false, Child); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1171,17 +1193,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div'); + element(0, 'div'); } }, - 2, 0, [], [], + 1, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, TemplateRef as any, false, ElementRef); + viewQuery(TemplateRef as any, false, ElementRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1203,17 +1226,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', ''], ['foo', '']); + element(0, 'div', ['child', ''], ['foo', '']); } }, - 3, 0, [Child], [], + 2, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false, Child); + viewQuery(['foo'], false, Child); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1236,17 +1260,18 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', ['child', '']); + element(0, 'div', ['child', '']); } }, - 2, 0, [Child], [], + 1, 0, [Child], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, TemplateRef as any, false); + viewQuery(TemplateRef as any, false); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1277,27 +1302,27 @@ describe('query', () => { function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { template( - 2, Cmpt_Template_1, 2, 0, 'ng-template', null, ['foo', ''], + 0, Cmpt_Template_1, 2, 0, 'ng-template', null, ['foo', ''], templateRefExtractor); template( - 3, Cmpt_Template_1, 2, 0, 'ng-template', null, ['bar', ''], + 1, Cmpt_Template_1, 2, 0, 'ng-template', null, ['bar', ''], templateRefExtractor); template( - 4, Cmpt_Template_1, 2, 0, 'ng-template', null, ['baz', ''], + 2, Cmpt_Template_1, 2, 0, 'ng-template', null, ['baz', ''], templateRefExtractor); } }, - 5, 0, [], [], + 3, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, TemplateRef as any, false); - query(1, TemplateRef as any, false, ElementRef); + viewQuery(TemplateRef as any, false); + viewQuery(TemplateRef as any, false, ElementRef); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.tmplQuery = tmp as QueryList); - queryRefresh(tmp = load>(1)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.elemQuery = tmp as QueryList); } }); @@ -1367,20 +1392,21 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, Cmpt_Template_1, 2, 0, 'ng-template', ['ngIf', '']); + template(0, Cmpt_Template_1, 2, 0, 'ng-template', ['ngIf', '']); } if (rf & RenderFlags.Update) { - elementProperty(1, 'ngIf', bind(ctx.value)); + elementProperty(0, 'ngIf', bind(ctx.value)); } }, - 3, 1, [NgIf], [], + 2, 1, [NgIf], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1424,23 +1450,24 @@ describe('query', () => { type: Cmpt, factory: () => new Cmpt(), selectors: [['my-app']], - consts: 3, + consts: 2, vars: 1, template: function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, Cmpt_Template_1, 2, 1, 'ng-template', ['ngForOf', '']); + template(0, Cmpt_Template_1, 2, 1, 'ng-template', ['ngForOf', '']); } if (rf & RenderFlags.Update) { - elementProperty(1, 'ngForOf', bind(ctx.value)); + elementProperty(0, 'ngForOf', bind(ctx.value)); } }, viewQuery: function(rf: RenderFlags, ctx: Cmpt) { let tmp: any; if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }, directives: () => [NgForOf] @@ -1507,29 +1534,29 @@ describe('query', () => { function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { template( - 1, Cmpt_Template_1, 2, 1, 'ng-template', null, ['tpl1', ''], + 0, Cmpt_Template_1, 2, 1, 'ng-template', null, ['tpl1', ''], templateRefExtractor); - element(3, 'div', ['id', 'middle'], ['foo', '']); + element(2, 'div', ['id', 'middle'], ['foo', '']); template( - 5, Cmpt_Template_5, 2, 1, 'ng-template', null, ['tpl2', ''], + 4, Cmpt_Template_5, 2, 1, 'ng-template', null, ['tpl2', ''], templateRefExtractor); - template(7, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); + template(6, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); } if (rf & RenderFlags.Update) { - tpl1 = reference(2); - tpl2 = reference(6); + tpl1 = reference(1); + tpl2 = reference(5); } }, - 9, 0, [ViewContainerManipulatorDirective], [], + 8, 0, [ViewContainerManipulatorDirective], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.query = tmp as QueryList); } }); @@ -1602,30 +1629,30 @@ describe('query', () => { type: Cmpt, factory: () => new Cmpt(), selectors: [['my-app']], - consts: 5, + consts: 4, vars: 0, template: function(rf: RenderFlags, ctx: any) { let tmp: any; if (rf & RenderFlags.Create) { template( - 1, Cmpt_Template_1, 2, 1, 'ng-template', [], ['tpl', ''], + 0, Cmpt_Template_1, 2, 1, 'ng-template', [], ['tpl', ''], templateRefExtractor); + template(2, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); template(3, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); - template(4, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); } if (rf & RenderFlags.Update) { - tpl = reference(2); + tpl = reference(1); } }, viewQuery: (rf: RenderFlags, cmpt: Cmpt) => { let tmp: any; if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (cmpt.query = tmp as QueryList); } }, @@ -1672,7 +1699,7 @@ describe('query', () => { type: MyApp, factory: () => new MyApp(), selectors: [['my-app']], - consts: 5, + consts: 4, vars: 1, /** * @@ -1681,24 +1708,24 @@ describe('query', () => { template: (rf: RenderFlags, myApp: MyApp) => { if (rf & RenderFlags.Create) { template( - 1, MyApp_Template_1, 2, 0, 'ng-template', undefined, ['tpl', ''], + 0, MyApp_Template_1, 2, 0, 'ng-template', undefined, ['tpl', ''], templateRefExtractor); template( - 3, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); + 2, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); } if (rf & RenderFlags.Update) { - const tplRef = reference(2); - elementProperty(3, 'ngTemplateOutlet', bind(myApp.show ? tplRef : null)); + const tplRef = reference(1); + elementProperty(2, 'ngTemplateOutlet', bind(myApp.show ? tplRef : null)); } }, directives: () => [NgTemplateOutlet], viewQuery: (rf: RenderFlags, myApp: MyApp) => { let tmp: any; if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (myApp.query = tmp as QueryList); } } @@ -1738,10 +1765,10 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - container(1); + container(0); } if (rf & RenderFlags.Update) { - containerRefreshStart(1); + containerRefreshStart(0); { if (ctx.exp) { let rf1 = embeddedViewStart(1, 2, 0); @@ -1757,14 +1784,15 @@ describe('query', () => { containerRefreshEnd(); } }, - 2, 0, [], [], + 1, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1799,14 +1827,14 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'span', null, ['foo', '']); - firstEl = getNativeByIndex(1, getLView()); - container(3); - element(4, 'span', null, ['foo', '']); - lastEl = getNativeByIndex(4, getLView()); + element(0, 'span', null, ['foo', '']); + firstEl = getNativeByIndex(0, getLView()); + container(2); + element(3, 'span', null, ['foo', '']); + lastEl = getNativeByIndex(3, getLView()); } if (rf & RenderFlags.Update) { - containerRefreshStart(3); + containerRefreshStart(2); { if (ctx.exp) { let rf1 = embeddedViewStart(1, 2, 0); @@ -1822,14 +1850,14 @@ describe('query', () => { containerRefreshEnd(); } }, - 6, 0, [], [], + 5, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.query = tmp as QueryList); } }); @@ -1870,10 +1898,10 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - container(1); + container(0); } if (rf & RenderFlags.Update) { - containerRefreshStart(1); + containerRefreshStart(0); { if (ctx.exp1) { let rf0 = embeddedViewStart(0, 2, 0); @@ -1899,14 +1927,15 @@ describe('query', () => { containerRefreshEnd(); } }, - 2, 0, [], [], + 1, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -1943,10 +1972,10 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - container(1); + container(0); } if (rf & RenderFlags.Update) { - containerRefreshStart(1); + containerRefreshStart(0); { if (ctx.exp1) { let rf0 = embeddedViewStart(0, 3, 0); @@ -1979,14 +2008,15 @@ describe('query', () => { containerRefreshEnd(); } }, - 2, 0, [], [], + 1, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -2027,11 +2057,11 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - container(2); - element(3, 'span', null, ['foo', '']); + container(0); + element(1, 'span', null, ['foo', '']); } if (rf & RenderFlags.Update) { - containerRefreshStart(2); + containerRefreshStart(0); { if (ctx.exp) { let rf0 = embeddedViewStart(0, 4, 0); @@ -2048,16 +2078,17 @@ describe('query', () => { containerRefreshEnd(); } }, - 5, 0, [], [], + 3, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); - query(1, ['foo'], false); + viewQuery(['foo'], true); + viewQuery(['foo'], false); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.deep = tmp as QueryList); - queryRefresh(tmp = load>(1)) && + queryRefresh(tmp = loadViewQuery>()) && + (ctx.deep = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && (ctx.shallow = tmp as QueryList); } }); @@ -2126,17 +2157,17 @@ describe('query', () => { 'some-component-with-query', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - element(1, 'div', null, ['foo', '']); + element(0, 'div', null, ['foo', '']); } }, - 2, 0, [], [], + 1, 0, [], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], false); + viewQuery(['foo'], false); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && + queryRefresh(tmp = loadViewQuery>()) && (ctx.query = queryInstance = tmp as QueryList); } }); @@ -2206,18 +2237,19 @@ describe('query', () => { function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { template( - 1, AppComponent_Template_1, 1, 0, 'div', [AttributeMarker.SelectOnly, 'someDir']); - element(2, 'div', null, ['foo', '']); + 0, AppComponent_Template_1, 1, 0, 'div', [AttributeMarker.SelectOnly, 'someDir']); + element(1, 'div', null, ['foo', '']); } }, - 4, 0, [SomeDir], [], + 3, 0, [SomeDir], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.query = tmp as QueryList); } }); @@ -2250,8 +2282,7 @@ describe('query', () => { type: WithContentDirective, selectors: [['', 'with-content', '']], factory: () => new WithContentDirective(), - contentQueries: - (dirIndex) => { registerContentQuery(query(null, ['foo'], true), dirIndex); }, + contentQueries: (dirIndex) => { registerContentQuery(query(['foo'], true), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; withContentInstance = load(dirIndex); @@ -2272,8 +2303,7 @@ describe('query', () => { template: function(rf: RenderFlags, ctx: any) {}, consts: 0, vars: 0, - contentQueries: - (dirIndex) => { registerContentQuery(query(null, ['foo'], false), dirIndex); }, + contentQueries: (dirIndex) => { registerContentQuery(query(['foo'], false), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; shallowCompInstance = load(dirIndex); @@ -2425,20 +2455,21 @@ describe('query', () => { 'app-component', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - elementStart(1, 'div', ['with-content', '']); - { element(2, 'div', null, ['foo', '']); } + elementStart(0, 'div', ['with-content', '']); + { element(1, 'div', null, ['foo', '']); } elementEnd(); - element(4, 'div', ['id', 'after'], ['bar', '']); + element(3, 'div', ['id', 'after'], ['bar', '']); } }, - 6, 0, [WithContentDirective], [], + 5, 0, [WithContentDirective], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo', 'bar'], true); + viewQuery(['foo', 'bar'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.foos = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.foos = tmp as QueryList); } }); @@ -2465,20 +2496,21 @@ describe('query', () => { 'app-component', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - elementStart(1, 'div', ['with-content', '']); - { element(2, 'div', ['id', 'yes'], ['foo', '']); } + elementStart(0, 'div', ['with-content', '']); + { element(1, 'div', ['id', 'yes'], ['foo', '']); } elementEnd(); - element(4, 'div', null, ['foo', '']); + element(3, 'div', null, ['foo', '']); } }, - 6, 0, [WithContentDirective], [], + 5, 0, [WithContentDirective], [], function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['bar'], true); + viewQuery(['bar'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.bars = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.bars = tmp as QueryList); } }); @@ -2498,7 +2530,7 @@ describe('query', () => { contentQueries: (dirIndex) => { // @ContentChildren('foo, bar, baz', {descendants: true}) fooBars: // QueryList; - registerContentQuery(query(null, ['foo', 'bar', 'baz'], true), dirIndex); + registerContentQuery(query(['foo', 'bar', 'baz'], true), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; @@ -2562,7 +2594,7 @@ describe('query', () => { contentQueries: (dirIndex) => { // @ContentChildren('foo, bar, baz', {descendants: true}) fooBars: // QueryList; - registerContentQuery(query(null, ['foo'], false), dirIndex); + registerContentQuery(query(['foo'], false), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; @@ -2618,7 +2650,7 @@ describe('query', () => { contentQueries: (dirIndex) => { // @ContentChildren('foo', {descendants: true}) fooBars: // QueryList; - registerContentQuery(query(null, ['foo'], false), dirIndex); + registerContentQuery(query(['foo'], false), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; @@ -2673,7 +2705,7 @@ describe('query', () => { factory: () => new ShallowQueryDirective(), contentQueries: (dirIndex) => { // @ContentChildren('foo', {descendants: false}) foos: QueryList; - registerContentQuery(query(null, ['foo'], false), dirIndex); + registerContentQuery(query(['foo'], false), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; @@ -2693,7 +2725,7 @@ describe('query', () => { factory: () => new DeepQueryDirective(), contentQueries: (dirIndex) => { // @ContentChildren('foo', {descendants: false}) foos: QueryList; - registerContentQuery(query(null, ['foo'], true), dirIndex); + registerContentQuery(query(['foo'], true), dirIndex); }, contentQueriesRefresh: (dirIndex: number, queryStartIdx: number) => { let tmp: any; diff --git a/packages/core/test/render3/styling/players_spec.ts b/packages/core/test/render3/styling/players_spec.ts index bd2b454cd0..c39541beb9 100644 --- a/packages/core/test/render3/styling/players_spec.ts +++ b/packages/core/test/render3/styling/players_spec.ts @@ -8,12 +8,12 @@ import {QueryList} from '@angular/core'; import {RenderFlags} from '@angular/core/src/render3'; -import {defineComponent, getHostElement} from '../../../src/render3/index'; -import {element, elementEnd, elementStart, elementStyling, elementStylingApply, load, markDirty} from '../../../src/render3/instructions'; +import {defineComponent, getHostElement, loadViewQuery, viewQuery} from '../../../src/render3/index'; +import {element, elementEnd, elementStart, elementStyling, elementStylingApply, markDirty} from '../../../src/render3/instructions'; import {PlayState, Player, PlayerHandler} from '../../../src/render3/interfaces/player'; import {RElement} from '../../../src/render3/interfaces/renderer'; import {addPlayer, getPlayers} from '../../../src/render3/players'; -import {query, queryRefresh} from '../../../src/render3/query'; +import {queryRefresh} from '../../../src/render3/query'; import {getOrCreatePlayerContext} from '../../../src/render3/styling/util'; import {ComponentFixture} from '../render_util'; @@ -286,11 +286,11 @@ class SuperComp { }, viewQuery: function(rf: RenderFlags, ctx: SuperComp) { if (rf & RenderFlags.Create) { - query(0, ['child'], true); + viewQuery(['child'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.query = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && (ctx.query = tmp as QueryList); } }, directives: [Comp] diff --git a/packages/core/test/render3/view_container_ref_spec.ts b/packages/core/test/render3/view_container_ref_spec.ts index 14c1dc4772..16564a8110 100644 --- a/packages/core/test/render3/view_container_ref_spec.ts +++ b/packages/core/test/render3/view_container_ref_spec.ts @@ -8,7 +8,7 @@ import {ChangeDetectorRef, Component as _Component, ComponentFactoryResolver, ElementRef, EmbeddedViewRef, NgModuleRef, Pipe, PipeTransform, QueryList, RendererFactory2, TemplateRef, ViewContainerRef, createInjector, defineInjector, ɵAPP_ROOT as APP_ROOT, ɵNgModuleDef as NgModuleDef} from '../../src/core'; import {ViewEncapsulation} from '../../src/metadata'; -import {AttributeMarker, NO_CHANGE, NgOnChangesFeature, defineComponent, defineDirective, definePipe, injectComponentFactoryResolver, load, query, queryRefresh} from '../../src/render3/index'; +import {AttributeMarker, NO_CHANGE, NgOnChangesFeature, defineComponent, defineDirective, definePipe, injectComponentFactoryResolver, loadViewQuery, queryRefresh, viewQuery} from '../../src/render3/index'; import {allocHostVars, bind, container, containerRefreshEnd, containerRefreshStart, directiveInject, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, interpolation1, interpolation3, nextContext, projection, projectionDef, reference, template, text, textBinding, elementHostAttrs} from '../../src/render3/instructions'; import {RenderFlags} from '../../src/render3/interfaces/definition'; @@ -2067,11 +2067,12 @@ describe('ViewContainerRef', () => { }, viewQuery: function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - query(0, ['foo'], true); + viewQuery(['foo'], true); } if (rf & RenderFlags.Update) { let tmp: any; - queryRefresh(tmp = load>(0)) && (ctx.foo = tmp as QueryList); + queryRefresh(tmp = loadViewQuery>()) && + (ctx.foo = tmp as QueryList); } } });