From 9cb17ecc394a478306c8815ea24bf8d763b3899c Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Fri, 21 Sep 2018 11:41:37 -0700 Subject: [PATCH] refactor(ivy): extract directive matching code into a utility function (#26203) Upcoming implementation work for template type-checking will need to reuse the code which matches directives inside a template, so this refactor commit moves the code to a shared location in preparation. This commit pulls the code needed to match directives against a template node out of the TemplateDefinitionBuilder into a utility function, in preparation for template type-checking and other TemplateDefinitionBuilder refactoring. PR Close #26203 --- .../compiler/src/render3/view/template.ts | 18 ++------------ packages/compiler/src/render3/view/util.ts | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index abaa195e12..f213c5097c 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -30,7 +30,7 @@ import {htmlAstToRender3Ast} from '../r3_template_transform'; import {R3QueryMetadata} from './api'; import {parseStyle} from './styling'; -import {CONTEXT_NAME, I18N_ATTR, I18N_ATTR_PREFIX, ID_SEPARATOR, IMPLICIT_REFERENCE, MEANING_SEPARATOR, NON_BINDABLE_ATTR, REFERENCE_PREFIX, RENDER_FLAGS, asLiteral, invalid, isI18NAttribute, mapToExpression, trimTrailingNulls, unsupported} from './util'; +import {CONTEXT_NAME, I18N_ATTR, I18N_ATTR_PREFIX, ID_SEPARATOR, IMPLICIT_REFERENCE, MEANING_SEPARATOR, NON_BINDABLE_ATTR, REFERENCE_PREFIX, RENDER_FLAGS, asLiteral, getAttrsForDirectiveMatching, invalid, isI18NAttribute, mapToExpression, trimTrailingNulls, unsupported} from './util'; function mapBindingToInstruction(type: BindingType): o.ExternalReference|undefined { switch (type) { @@ -856,26 +856,12 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver private matchDirectives(tagName: string, elOrTpl: t.Element|t.Template) { if (this.directiveMatcher) { - const selector = createCssSelector(tagName, this.getAttrsForDirectiveMatching(elOrTpl)); + const selector = createCssSelector(tagName, getAttrsForDirectiveMatching(elOrTpl)); this.directiveMatcher.match( selector, (cssSelector, staticType) => { this.directives.add(staticType); }); } } - private getAttrsForDirectiveMatching(elOrTpl: t.Element|t.Template): {[name: string]: string} { - const attributesMap: {[name: string]: string} = {}; - - elOrTpl.attributes.forEach(a => { - if (!isI18NAttribute(a.name)) { - attributesMap[a.name] = a.value; - } - }); - elOrTpl.inputs.forEach(i => { attributesMap[i.name] = ''; }); - elOrTpl.outputs.forEach(o => { attributesMap[o.name] = ''; }); - - return attributesMap; - } - private prepareSyntheticAndSelectOnlyAttrs(inputs: t.BoundAttribute[], outputs: t.BoundEvent[]): o.Expression[] { const attrExprs: o.Expression[] = []; diff --git a/packages/compiler/src/render3/view/util.ts b/packages/compiler/src/render3/view/util.ts index 2d5ff8fbeb..07db9e71da 100644 --- a/packages/compiler/src/render3/view/util.ts +++ b/packages/compiler/src/render3/view/util.ts @@ -131,3 +131,27 @@ export class DefinitionMap { toLiteralMap(): o.LiteralMapExpr { return o.literalMap(this.values); } } + +/** + * Extract a map of properties to values for a given element or template node, which can be used + * by the directive matching machinery. + * + * @param elOrTpl the element or template in question + * @return an object set up for directive matching. For attributes on the element/template, this + * object maps a property name to its (static) value. For any bindings, this map simply maps the + * property name to an empty string. + */ +export function getAttrsForDirectiveMatching(elOrTpl: t.Element | t.Template): + {[name: string]: string} { + const attributesMap: {[name: string]: string} = {}; + + elOrTpl.attributes.forEach(a => { + if (!isI18NAttribute(a.name)) { + attributesMap[a.name] = a.value; + } + }); + elOrTpl.inputs.forEach(i => { attributesMap[i.name] = ''; }); + elOrTpl.outputs.forEach(o => { attributesMap[o.name] = ''; }); + + return attributesMap; +}