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
This commit is contained in:
Alex Rickabaugh 2018-09-21 11:41:37 -07:00 committed by Jason Aden
parent 35936864bc
commit 9cb17ecc39
2 changed files with 26 additions and 16 deletions

View File

@ -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<void>, 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[] = [];

View File

@ -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;
}