@angular/compiler
Version:
Angular - the compiler library
751 lines • 131 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define("@angular/compiler/src/render3/view/compiler", ["require", "exports", "tslib", "@angular/compiler/src/compile_metadata", "@angular/compiler/src/compiler_util/expression_converter", "@angular/compiler/src/core", "@angular/compiler/src/ml_parser/interpolation_config", "@angular/compiler/src/output/output_ast", "@angular/compiler/src/selector", "@angular/compiler/src/shadow_css", "@angular/compiler/src/style_compiler", "@angular/compiler/src/util", "@angular/compiler/src/render3/r3_ast", "@angular/compiler/src/render3/r3_factory", "@angular/compiler/src/render3/r3_identifiers", "@angular/compiler/src/render3/util", "@angular/compiler/src/render3/view/styling_builder", "@angular/compiler/src/render3/view/template", "@angular/compiler/src/render3/view/util"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyHostBindings = exports.parseHostBindings = exports.compileComponentFromRender2 = exports.compileDirectiveFromRender2 = exports.compileComponentFromMetadata = exports.compileDirectiveFromMetadata = void 0;
var tslib_1 = require("tslib");
var compile_metadata_1 = require("@angular/compiler/src/compile_metadata");
var expression_converter_1 = require("@angular/compiler/src/compiler_util/expression_converter");
var core = require("@angular/compiler/src/core");
var interpolation_config_1 = require("@angular/compiler/src/ml_parser/interpolation_config");
var o = require("@angular/compiler/src/output/output_ast");
var selector_1 = require("@angular/compiler/src/selector");
var shadow_css_1 = require("@angular/compiler/src/shadow_css");
var style_compiler_1 = require("@angular/compiler/src/style_compiler");
var util_1 = require("@angular/compiler/src/util");
var r3_ast_1 = require("@angular/compiler/src/render3/r3_ast");
var r3_factory_1 = require("@angular/compiler/src/render3/r3_factory");
var r3_identifiers_1 = require("@angular/compiler/src/render3/r3_identifiers");
var util_2 = require("@angular/compiler/src/render3/util");
var styling_builder_1 = require("@angular/compiler/src/render3/view/styling_builder");
var template_1 = require("@angular/compiler/src/render3/view/template");
var util_3 = require("@angular/compiler/src/render3/view/util");
var EMPTY_ARRAY = [];
// This regex matches any binding names that contain the "attr." prefix, e.g. "attr.required"
// If there is a match, the first matching group will contain the attribute name to bind.
var ATTR_REGEX = /attr\.([^\]]+)/;
function baseDirectiveFields(meta, constantPool, bindingParser) {
var definitionMap = new util_3.DefinitionMap();
var selectors = core.parseSelectorToR3Selector(meta.selector);
// e.g. `type: MyDirective`
definitionMap.set('type', meta.internalType);
// e.g. `selectors: [['', 'someDir', '']]`
if (selectors.length > 0) {
definitionMap.set('selectors', util_3.asLiteral(selectors));
}
if (meta.queries.length > 0) {
// e.g. `contentQueries: (rf, ctx, dirIndex) => { ... }
definitionMap.set('contentQueries', createContentQueriesFunction(meta.queries, constantPool, meta.name));
}
if (meta.viewQueries.length) {
definitionMap.set('viewQuery', createViewQueriesFunction(meta.viewQueries, constantPool, meta.name));
}
// e.g. `hostBindings: (rf, ctx) => { ... }
definitionMap.set('hostBindings', createHostBindingsFunction(meta.host, meta.typeSourceSpan, bindingParser, constantPool, meta.selector || '', meta.name, definitionMap));
// e.g 'inputs: {a: 'a'}`
definitionMap.set('inputs', util_3.conditionallyCreateMapObjectLiteral(meta.inputs, true));
// e.g 'outputs: {a: 'a'}`
definitionMap.set('outputs', util_3.conditionallyCreateMapObjectLiteral(meta.outputs));
if (meta.exportAs !== null) {
definitionMap.set('exportAs', o.literalArr(meta.exportAs.map(function (e) { return o.literal(e); })));
}
return definitionMap;
}
/**
* Add features to the definition map.
*/
function addFeatures(definitionMap, meta) {
// e.g. `features: [NgOnChangesFeature]`
var features = [];
var providers = meta.providers;
var viewProviders = meta.viewProviders;
if (providers || viewProviders) {
var args = [providers || new o.LiteralArrayExpr([])];
if (viewProviders) {
args.push(viewProviders);
}
features.push(o.importExpr(r3_identifiers_1.Identifiers.ProvidersFeature).callFn(args));
}
if (meta.usesInheritance) {
features.push(o.importExpr(r3_identifiers_1.Identifiers.InheritDefinitionFeature));
}
if (meta.fullInheritance) {
features.push(o.importExpr(r3_identifiers_1.Identifiers.CopyDefinitionFeature));
}
if (meta.lifecycle.usesOnChanges) {
features.push(o.importExpr(r3_identifiers_1.Identifiers.NgOnChangesFeature));
}
if (features.length) {
definitionMap.set('features', o.literalArr(features));
}
}
/**
* Compile a directive for the render3 runtime as defined by the `R3DirectiveMetadata`.
*/
function compileDirectiveFromMetadata(meta, constantPool, bindingParser) {
var definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
addFeatures(definitionMap, meta);
var expression = o.importExpr(r3_identifiers_1.Identifiers.defineDirective).callFn([definitionMap.toLiteralMap()]);
var typeParams = createDirectiveTypeParams(meta);
var type = o.expressionType(o.importExpr(r3_identifiers_1.Identifiers.DirectiveDefWithMeta, typeParams));
return { expression: expression, type: type };
}
exports.compileDirectiveFromMetadata = compileDirectiveFromMetadata;
/**
* Compile a component for the render3 runtime as defined by the `R3ComponentMetadata`.
*/
function compileComponentFromMetadata(meta, constantPool, bindingParser) {
var e_1, _a;
var definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
addFeatures(definitionMap, meta);
var selector = meta.selector && selector_1.CssSelector.parse(meta.selector);
var firstSelector = selector && selector[0];
// e.g. `attr: ["class", ".my.app"]`
// This is optional an only included if the first selector of a component specifies attributes.
if (firstSelector) {
var selectorAttributes = firstSelector.getAttrs();
if (selectorAttributes.length) {
definitionMap.set('attrs', constantPool.getConstLiteral(o.literalArr(selectorAttributes.map(function (value) { return value != null ? o.literal(value) : o.literal(undefined); })),
/* forceShared */ true));
}
}
// Generate the CSS matcher that recognize directive
var directiveMatcher = null;
if (meta.directives.length > 0) {
var matcher = new selector_1.SelectorMatcher();
try {
for (var _b = tslib_1.__values(meta.directives), _c = _b.next(); !_c.done; _c = _b.next()) {
var _d = _c.value, selector_2 = _d.selector, expression_1 = _d.expression;
matcher.addSelectables(selector_1.CssSelector.parse(selector_2), expression_1);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
directiveMatcher = matcher;
}
// e.g. `template: function MyComponent_Template(_ctx, _cm) {...}`
var templateTypeName = meta.name;
var templateName = templateTypeName ? templateTypeName + "_Template" : null;
var directivesUsed = new Set();
var pipesUsed = new Set();
var changeDetection = meta.changeDetection;
var template = meta.template;
var templateBuilder = new template_1.TemplateDefinitionBuilder(constantPool, template_1.BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName, directiveMatcher, directivesUsed, meta.pipes, pipesUsed, r3_identifiers_1.Identifiers.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds);
var templateFunctionExpression = templateBuilder.buildTemplateFunction(template.nodes, []);
// We need to provide this so that dynamically generated components know what
// projected content blocks to pass through to the component when it is instantiated.
var ngContentSelectors = templateBuilder.getNgContentSelectors();
if (ngContentSelectors) {
definitionMap.set('ngContentSelectors', ngContentSelectors);
}
// e.g. `decls: 2`
definitionMap.set('decls', o.literal(templateBuilder.getConstCount()));
// e.g. `vars: 2`
definitionMap.set('vars', o.literal(templateBuilder.getVarCount()));
// Generate `consts` section of ComponentDef:
// - either as an array:
// `consts: [['one', 'two'], ['three', 'four']]`
// - or as a factory function in case additional statements are present (to support i18n):
// `consts: function() { var i18n_0; if (ngI18nClosureMode) {...} else {...} return [i18n_0]; }`
var _e = templateBuilder.getConsts(), constExpressions = _e.constExpressions, prepareStatements = _e.prepareStatements;
if (constExpressions.length > 0) {
var constsExpr = o.literalArr(constExpressions);
// Prepare statements are present - turn `consts` into a function.
if (prepareStatements.length > 0) {
constsExpr = o.fn([], tslib_1.__spread(prepareStatements, [new o.ReturnStatement(constsExpr)]));
}
definitionMap.set('consts', constsExpr);
}
definitionMap.set('template', templateFunctionExpression);
// e.g. `directives: [MyDirective]`
if (directivesUsed.size) {
var directivesExpr = o.literalArr(Array.from(directivesUsed));
if (meta.wrapDirectivesAndPipesInClosure) {
directivesExpr = o.fn([], [new o.ReturnStatement(directivesExpr)]);
}
definitionMap.set('directives', directivesExpr);
}
// e.g. `pipes: [MyPipe]`
if (pipesUsed.size) {
var pipesExpr = o.literalArr(Array.from(pipesUsed));
if (meta.wrapDirectivesAndPipesInClosure) {
pipesExpr = o.fn([], [new o.ReturnStatement(pipesExpr)]);
}
definitionMap.set('pipes', pipesExpr);
}
if (meta.encapsulation === null) {
meta.encapsulation = core.ViewEncapsulation.Emulated;
}
// e.g. `styles: [str1, str2]`
if (meta.styles && meta.styles.length) {
var styleValues = meta.encapsulation == core.ViewEncapsulation.Emulated ?
compileStyles(meta.styles, style_compiler_1.CONTENT_ATTR, style_compiler_1.HOST_ATTR) :
meta.styles;
var strings = styleValues.map(function (str) { return constantPool.getConstLiteral(o.literal(str)); });
definitionMap.set('styles', o.literalArr(strings));
}
else if (meta.encapsulation === core.ViewEncapsulation.Emulated) {
// If there is no style, don't generate css selectors on elements
meta.encapsulation = core.ViewEncapsulation.None;
}
// Only set view encapsulation if it's not the default value
if (meta.encapsulation !== core.ViewEncapsulation.Emulated) {
definitionMap.set('encapsulation', o.literal(meta.encapsulation));
}
// e.g. `animation: [trigger('123', [])]`
if (meta.animations !== null) {
definitionMap.set('data', o.literalMap([{ key: 'animation', value: meta.animations, quoted: false }]));
}
// Only set the change detection flag if it's defined and it's not the default.
if (changeDetection != null && changeDetection !== core.ChangeDetectionStrategy.Default) {
definitionMap.set('changeDetection', o.literal(changeDetection));
}
var expression = o.importExpr(r3_identifiers_1.Identifiers.defineComponent).callFn([definitionMap.toLiteralMap()]);
var typeParams = createDirectiveTypeParams(meta);
typeParams.push(stringArrayAsType(meta.template.ngContentSelectors));
var type = o.expressionType(o.importExpr(r3_identifiers_1.Identifiers.ComponentDefWithMeta, typeParams));
return { expression: expression, type: type };
}
exports.compileComponentFromMetadata = compileComponentFromMetadata;
/**
* A wrapper around `compileDirective` which depends on render2 global analysis data as its input
* instead of the `R3DirectiveMetadata`.
*
* `R3DirectiveMetadata` is computed from `CompileDirectiveMetadata` and other statically reflected
* information.
*/
function compileDirectiveFromRender2(outputCtx, directive, reflector, bindingParser) {
var name = compile_metadata_1.identifierName(directive.type);
name || util_1.error("Cannot resolver the name of " + directive.type);
var definitionField = outputCtx.constantPool.propertyNameOf(1 /* Directive */);
var meta = directiveMetadataFromGlobalMetadata(directive, outputCtx, reflector);
var res = compileDirectiveFromMetadata(meta, outputCtx.constantPool, bindingParser);
var factoryRes = r3_factory_1.compileFactoryFunction(tslib_1.__assign(tslib_1.__assign({}, meta), { injectFn: r3_identifiers_1.Identifiers.directiveInject, target: r3_factory_1.R3FactoryTarget.Directive }));
var ngFactoryDefStatement = new o.ClassStmt(name, null, [new o.ClassField('ɵfac', o.INFERRED_TYPE, [o.StmtModifier.Static], factoryRes.factory)], [], new o.ClassMethod(null, [], []), []);
var directiveDefStatement = new o.ClassStmt(name, null, [new o.ClassField(definitionField, o.INFERRED_TYPE, [o.StmtModifier.Static], res.expression)], [], new o.ClassMethod(null, [], []), []);
// Create the partial class to be merged with the actual class.
outputCtx.statements.push(ngFactoryDefStatement, directiveDefStatement);
}
exports.compileDirectiveFromRender2 = compileDirectiveFromRender2;
/**
* A wrapper around `compileComponent` which depends on render2 global analysis data as its input
* instead of the `R3DirectiveMetadata`.
*
* `R3ComponentMetadata` is computed from `CompileDirectiveMetadata` and other statically reflected
* information.
*/
function compileComponentFromRender2(outputCtx, component, render3Ast, reflector, bindingParser, directiveTypeBySel, pipeTypeByName) {
var name = compile_metadata_1.identifierName(component.type);
name || util_1.error("Cannot resolver the name of " + component.type);
var definitionField = outputCtx.constantPool.propertyNameOf(2 /* Component */);
var summary = component.toSummary();
// Compute the R3ComponentMetadata from the CompileDirectiveMetadata
var meta = tslib_1.__assign(tslib_1.__assign({}, directiveMetadataFromGlobalMetadata(component, outputCtx, reflector)), { selector: component.selector, template: { nodes: render3Ast.nodes, ngContentSelectors: render3Ast.ngContentSelectors }, directives: [], pipes: typeMapToExpressionMap(pipeTypeByName, outputCtx), viewQueries: queriesFromGlobalMetadata(component.viewQueries, outputCtx), wrapDirectivesAndPipesInClosure: false, styles: (summary.template && summary.template.styles) || EMPTY_ARRAY, encapsulation: (summary.template && summary.template.encapsulation) || core.ViewEncapsulation.Emulated, interpolation: interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG, animations: null, viewProviders: component.viewProviders.length > 0 ? new o.WrappedNodeExpr(component.viewProviders) : null, relativeContextFilePath: '', i18nUseExternalIds: true });
var res = compileComponentFromMetadata(meta, outputCtx.constantPool, bindingParser);
var factoryRes = r3_factory_1.compileFactoryFunction(tslib_1.__assign(tslib_1.__assign({}, meta), { injectFn: r3_identifiers_1.Identifiers.directiveInject, target: r3_factory_1.R3FactoryTarget.Directive }));
var ngFactoryDefStatement = new o.ClassStmt(name, null, [new o.ClassField('ɵfac', o.INFERRED_TYPE, [o.StmtModifier.Static], factoryRes.factory)], [], new o.ClassMethod(null, [], []), []);
var componentDefStatement = new o.ClassStmt(name, null, [new o.ClassField(definitionField, o.INFERRED_TYPE, [o.StmtModifier.Static], res.expression)], [], new o.ClassMethod(null, [], []), []);
// Create the partial class to be merged with the actual class.
outputCtx.statements.push(ngFactoryDefStatement, componentDefStatement);
}
exports.compileComponentFromRender2 = compileComponentFromRender2;
/**
* Compute `R3DirectiveMetadata` given `CompileDirectiveMetadata` and a `CompileReflector`.
*/
function directiveMetadataFromGlobalMetadata(directive, outputCtx, reflector) {
// The global-analysis based Ivy mode in ngc is no longer utilized/supported.
throw new Error('unsupported');
}
/**
* Convert `CompileQueryMetadata` into `R3QueryMetadata`.
*/
function queriesFromGlobalMetadata(queries, outputCtx) {
return queries.map(function (query) {
var read = null;
if (query.read && query.read.identifier) {
read = outputCtx.importExpr(query.read.identifier.reference);
}
return {
propertyName: query.propertyName,
first: query.first,
predicate: selectorsFromGlobalMetadata(query.selectors, outputCtx),
descendants: query.descendants,
read: read,
static: !!query.static
};
});
}
/**
* Convert `CompileTokenMetadata` for query selectors into either an expression for a predicate
* type, or a list of string predicates.
*/
function selectorsFromGlobalMetadata(selectors, outputCtx) {
if (selectors.length > 1 || (selectors.length == 1 && selectors[0].value)) {
var selectorStrings = selectors.map(function (value) { return value.value; });
selectorStrings.some(function (value) { return !value; }) &&
util_1.error('Found a type among the string selectors expected');
return outputCtx.constantPool.getConstLiteral(o.literalArr(selectorStrings.map(function (value) { return o.literal(value); })));
}
if (selectors.length == 1) {
var first = selectors[0];
if (first.identifier) {
return outputCtx.importExpr(first.identifier.reference);
}
}
util_1.error('Unexpected query form');
return o.NULL_EXPR;
}
function prepareQueryParams(query, constantPool) {
var parameters = [util_3.getQueryPredicate(query, constantPool), o.literal(query.descendants)];
if (query.read) {
parameters.push(query.read);
}
return parameters;
}
function convertAttributesToExpressions(attributes) {
var e_2, _a;
var values = [];
try {
for (var _b = tslib_1.__values(Object.getOwnPropertyNames(attributes)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
var value = attributes[key];
values.push(o.literal(key), value);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
return values;
}
// Define and update any content queries
function createContentQueriesFunction(queries, constantPool, name) {
var e_3, _a;
var createStatements = [];
var updateStatements = [];
var tempAllocator = util_3.temporaryAllocator(updateStatements, util_3.TEMPORARY_NAME);
try {
for (var queries_1 = tslib_1.__values(queries), queries_1_1 = queries_1.next(); !queries_1_1.done; queries_1_1 = queries_1.next()) {
var query = queries_1_1.value;
var queryInstruction = query.static ? r3_identifiers_1.Identifiers.staticContentQuery : r3_identifiers_1.Identifiers.contentQuery;
// creation, e.g. r3.contentQuery(dirIndex, somePredicate, true, null);
createStatements.push(o.importExpr(queryInstruction)
.callFn(tslib_1.__spread([o.variable('dirIndex')], prepareQueryParams(query, constantPool)))
.toStmt());
// update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
var temporary = tempAllocator();
var getQueryList = o.importExpr(r3_identifiers_1.Identifiers.loadQuery).callFn([]);
var refresh = o.importExpr(r3_identifiers_1.Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
var updateDirective = o.variable(util_3.CONTEXT_NAME)
.prop(query.propertyName)
.set(query.first ? temporary.prop('first') : temporary);
updateStatements.push(refresh.and(updateDirective).toStmt());
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (queries_1_1 && !queries_1_1.done && (_a = queries_1.return)) _a.call(queries_1);
}
finally { if (e_3) throw e_3.error; }
}
var contentQueriesFnName = name ? name + "_ContentQueries" : null;
return o.fn([
new o.FnParam(util_3.RENDER_FLAGS, o.NUMBER_TYPE), new o.FnParam(util_3.CONTEXT_NAME, null),
new o.FnParam('dirIndex', null)
], [
template_1.renderFlagCheckIfStmt(1 /* Create */, createStatements),
template_1.renderFlagCheckIfStmt(2 /* Update */, updateStatements)
], o.INFERRED_TYPE, null, contentQueriesFnName);
}
function stringAsType(str) {
return o.expressionType(o.literal(str));
}
function stringMapAsType(map) {
var mapValues = Object.keys(map).map(function (key) {
var value = Array.isArray(map[key]) ? map[key][0] : map[key];
return {
key: key,
value: o.literal(value),
quoted: true,
};
});
return o.expressionType(o.literalMap(mapValues));
}
function stringArrayAsType(arr) {
return arr.length > 0 ? o.expressionType(o.literalArr(arr.map(function (value) { return o.literal(value); }))) :
o.NONE_TYPE;
}
function createDirectiveTypeParams(meta) {
// On the type side, remove newlines from the selector as it will need to fit into a TypeScript
// string literal, which must be on one line.
var selectorForType = meta.selector !== null ? meta.selector.replace(/\n/g, '') : null;
return [
util_2.typeWithParameters(meta.type.type, meta.typeArgumentCount),
selectorForType !== null ? stringAsType(selectorForType) : o.NONE_TYPE,
meta.exportAs !== null ? stringArrayAsType(meta.exportAs) : o.NONE_TYPE,
stringMapAsType(meta.inputs),
stringMapAsType(meta.outputs),
stringArrayAsType(meta.queries.map(function (q) { return q.propertyName; })),
];
}
// Define and update any view queries
function createViewQueriesFunction(viewQueries, constantPool, name) {
var createStatements = [];
var updateStatements = [];
var tempAllocator = util_3.temporaryAllocator(updateStatements, util_3.TEMPORARY_NAME);
viewQueries.forEach(function (query) {
var queryInstruction = query.static ? r3_identifiers_1.Identifiers.staticViewQuery : r3_identifiers_1.Identifiers.viewQuery;
// creation, e.g. r3.viewQuery(somePredicate, true);
var queryDefinition = o.importExpr(queryInstruction).callFn(prepareQueryParams(query, constantPool));
createStatements.push(queryDefinition.toStmt());
// update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp));
var temporary = tempAllocator();
var getQueryList = o.importExpr(r3_identifiers_1.Identifiers.loadQuery).callFn([]);
var refresh = o.importExpr(r3_identifiers_1.Identifiers.queryRefresh).callFn([temporary.set(getQueryList)]);
var updateDirective = o.variable(util_3.CONTEXT_NAME)
.prop(query.propertyName)
.set(query.first ? temporary.prop('first') : temporary);
updateStatements.push(refresh.and(updateDirective).toStmt());
});
var viewQueryFnName = name ? name + "_Query" : null;
return o.fn([new o.FnParam(util_3.RENDER_FLAGS, o.NUMBER_TYPE), new o.FnParam(util_3.CONTEXT_NAME, null)], [
template_1.renderFlagCheckIfStmt(1 /* Create */, createStatements),
template_1.renderFlagCheckIfStmt(2 /* Update */, updateStatements)
], o.INFERRED_TYPE, null, viewQueryFnName);
}
// Return a host binding function or null if one is not necessary.
function createHostBindingsFunction(hostBindingsMetadata, typeSourceSpan, bindingParser, constantPool, selector, name, definitionMap) {
var bindingContext = o.variable(util_3.CONTEXT_NAME);
var styleBuilder = new styling_builder_1.StylingBuilder(bindingContext);
var _a = hostBindingsMetadata.specialAttributes, styleAttr = _a.styleAttr, classAttr = _a.classAttr;
if (styleAttr !== undefined) {
styleBuilder.registerStyleAttr(styleAttr);
}
if (classAttr !== undefined) {
styleBuilder.registerClassAttr(classAttr);
}
var createStatements = [];
var updateStatements = [];
var hostBindingSourceSpan = typeSourceSpan;
var directiveSummary = metadataAsSummary(hostBindingsMetadata);
// Calculate host event bindings
var eventBindings = bindingParser.createDirectiveHostEventAsts(directiveSummary, hostBindingSourceSpan);
if (eventBindings && eventBindings.length) {
var listeners = createHostListeners(eventBindings, name);
createStatements.push.apply(createStatements, tslib_1.__spread(listeners));
}
// Calculate the host property bindings
var bindings = bindingParser.createBoundHostProperties(directiveSummary, hostBindingSourceSpan);
var allOtherBindings = [];
// We need to calculate the total amount of binding slots required by
// all the instructions together before any value conversions happen.
// Value conversions may require additional slots for interpolation and
// bindings with pipes. These calculates happen after this block.
var totalHostVarsCount = 0;
bindings && bindings.forEach(function (binding) {
var stylingInputWasSet = styleBuilder.registerInputBasedOnName(binding.name, binding.expression, hostBindingSourceSpan);
if (stylingInputWasSet) {
totalHostVarsCount += styling_builder_1.MIN_STYLING_BINDING_SLOTS_REQUIRED;
}
else {
allOtherBindings.push(binding);
totalHostVarsCount++;
}
});
var valueConverter;
var getValueConverter = function () {
if (!valueConverter) {
var hostVarsCountFn = function (numSlots) {
var originalVarsCount = totalHostVarsCount;
totalHostVarsCount += numSlots;
return originalVarsCount;
};
valueConverter = new template_1.ValueConverter(constantPool, function () { return util_1.error('Unexpected node'); }, // new nodes are illegal here
hostVarsCountFn, function () { return util_1.error('Unexpected pipe'); }); // pipes are illegal here
}
return valueConverter;
};
var propertyBindings = [];
var attributeBindings = [];
var syntheticHostBindings = [];
allOtherBindings.forEach(function (binding) {
// resolve literal arrays and literal objects
var value = binding.expression.visit(getValueConverter());
var bindingExpr = bindingFn(bindingContext, value);
var _a = getBindingNameAndInstruction(binding), bindingName = _a.bindingName, instruction = _a.instruction, isAttribute = _a.isAttribute;
var securityContexts = bindingParser.calcPossibleSecurityContexts(selector, bindingName, isAttribute)
.filter(function (context) { return context !== core.SecurityContext.NONE; });
var sanitizerFn = null;
if (securityContexts.length) {
if (securityContexts.length === 2 &&
securityContexts.indexOf(core.SecurityContext.URL) > -1 &&
securityContexts.indexOf(core.SecurityContext.RESOURCE_URL) > -1) {
// Special case for some URL attributes (such as "src" and "href") that may be a part
// of different security contexts. In this case we use special santitization function and
// select the actual sanitizer at runtime based on a tag name that is provided while
// invoking sanitization function.
sanitizerFn = o.importExpr(r3_identifiers_1.Identifiers.sanitizeUrlOrResourceUrl);
}
else {
sanitizerFn = template_1.resolveSanitizationFn(securityContexts[0], isAttribute);
}
}
var instructionParams = [o.literal(bindingName), bindingExpr.currValExpr];
if (sanitizerFn) {
instructionParams.push(sanitizerFn);
}
updateStatements.push.apply(updateStatements, tslib_1.__spread(bindingExpr.stmts));
if (instruction === r3_identifiers_1.Identifiers.hostProperty) {
propertyBindings.push(instructionParams);
}
else if (instruction === r3_identifiers_1.Identifiers.attribute) {
attributeBindings.push(instructionParams);
}
else if (instruction === r3_identifiers_1.Identifiers.syntheticHostProperty) {
syntheticHostBindings.push(instructionParams);
}
else {
updateStatements.push(o.importExpr(instruction).callFn(instructionParams).toStmt());
}
});
if (propertyBindings.length > 0) {
updateStatements.push(util_3.chainedInstruction(r3_identifiers_1.Identifiers.hostProperty, propertyBindings).toStmt());
}
if (attributeBindings.length > 0) {
updateStatements.push(util_3.chainedInstruction(r3_identifiers_1.Identifiers.attribute, attributeBindings).toStmt());
}
if (syntheticHostBindings.length > 0) {
updateStatements.push(util_3.chainedInstruction(r3_identifiers_1.Identifiers.syntheticHostProperty, syntheticHostBindings).toStmt());
}
// since we're dealing with directives/components and both have hostBinding
// functions, we need to generate a special hostAttrs instruction that deals
// with both the assignment of styling as well as static attributes to the host
// element. The instruction below will instruct all initial styling (styling
// that is inside of a host binding within a directive/component) to be attached
// to the host element alongside any of the provided host attributes that were
// collected earlier.
var hostAttrs = convertAttributesToExpressions(hostBindingsMetadata.attributes);
styleBuilder.assignHostAttrs(hostAttrs, definitionMap);
if (styleBuilder.hasBindings) {
// finally each binding that was registered in the statement above will need to be added to
// the update block of a component/directive templateFn/hostBindingsFn so that the bindings
// are evaluated and updated for the element.
styleBuilder.buildUpdateLevelInstructions(getValueConverter()).forEach(function (instruction) {
if (instruction.calls.length > 0) {
var calls_1 = [];
instruction.calls.forEach(function (call) {
// we subtract a value of `1` here because the binding slot was already allocated
// at the top of this method when all the input bindings were counted.
totalHostVarsCount +=
Math.max(call.allocateBindingSlots - styling_builder_1.MIN_STYLING_BINDING_SLOTS_REQUIRED, 0);
calls_1.push(convertStylingCall(call, bindingContext, bindingFn));
});
updateStatements.push(util_3.chainedInstruction(instruction.reference, calls_1).toStmt());
}
});
}
if (totalHostVarsCount) {
definitionMap.set('hostVars', o.literal(totalHostVarsCount));
}
if (createStatements.length > 0 || updateStatements.length > 0) {
var hostBindingsFnName = name ? name + "_HostBindings" : null;
var statements = [];
if (createStatements.length > 0) {
statements.push(template_1.renderFlagCheckIfStmt(1 /* Create */, createStatements));
}
if (updateStatements.length > 0) {
statements.push(template_1.renderFlagCheckIfStmt(2 /* Update */, updateStatements));
}
return o.fn([new o.FnParam(util_3.RENDER_FLAGS, o.NUMBER_TYPE), new o.FnParam(util_3.CONTEXT_NAME, null)], statements, o.INFERRED_TYPE, null, hostBindingsFnName);
}
return null;
}
function bindingFn(implicit, value) {
return expression_converter_1.convertPropertyBinding(null, implicit, value, 'b', expression_converter_1.BindingForm.Expression, function () { return util_1.error('Unexpected interpolation'); });
}
function convertStylingCall(call, bindingContext, bindingFn) {
return call.params(function (value) { return bindingFn(bindingContext, value).currValExpr; });
}
function getBindingNameAndInstruction(binding) {
var bindingName = binding.name;
var instruction;
// Check to see if this is an attr binding or a property binding
var attrMatches = bindingName.match(ATTR_REGEX);
if (attrMatches) {
bindingName = attrMatches[1];
instruction = r3_identifiers_1.Identifiers.attribute;
}
else {
if (binding.isAnimation) {
bindingName = util_2.prepareSyntheticPropertyName(bindingName);
// host bindings that have a synthetic property (e.g. @foo) should always be rendered
// in the context of the component and not the parent. Therefore there is a special
// compatibility instruction available for this purpose.
instruction = r3_identifiers_1.Identifiers.syntheticHostProperty;
}
else {
instruction = r3_identifiers_1.Identifiers.hostProperty;
}
}
return { bindingName: bindingName, instruction: instruction, isAttribute: !!attrMatches };
}
function createHostListeners(eventBindings, name) {
var listeners = [];
var syntheticListeners = [];
var instructions = [];
eventBindings.forEach(function (binding) {
var bindingName = binding.name && compile_metadata_1.sanitizeIdentifier(binding.name);
var bindingFnName = binding.type === 1 /* Animation */ ?
util_2.prepareSyntheticListenerFunctionName(bindingName, binding.targetOrPhase) :
bindingName;
var handlerName = name && bindingName ? name + "_" + bindingFnName + "_HostBindingHandler" : null;
var params = template_1.prepareEventListenerParameters(r3_ast_1.BoundEvent.fromParsedEvent(binding), handlerName);
if (binding.type == 1 /* Animation */) {
syntheticListeners.push(params);
}
else {
listeners.push(params);
}
});
if (syntheticListeners.length > 0) {
instructions.push(util_3.chainedInstruction(r3_identifiers_1.Identifiers.syntheticHostListener, syntheticListeners).toStmt());
}
if (listeners.length > 0) {
instructions.push(util_3.chainedInstruction(r3_identifiers_1.Identifiers.listener, listeners).toStmt());
}
return instructions;
}
function metadataAsSummary(meta) {
// clang-format off
return {
// This is used by the BindingParser, which only deals with listeners and properties. There's no
// need to pass attributes to it.
hostAttributes: {},
hostListeners: meta.listeners,
hostProperties: meta.properties,
};
// clang-format on
}
function typeMapToExpressionMap(map, outputCtx) {
// Convert each map entry into another entry where the value is an expression importing the type.
var entries = Array.from(map).map(function (_a) {
var _b = tslib_1.__read(_a, 2), key = _b[0], type = _b[1];
return [key, outputCtx.importExpr(type)];
});
return new Map(entries);
}
var HOST_REG_EXP = /^(?:\[([^\]]+)\])|(?:\(([^\)]+)\))$/;
function parseHostBindings(host) {
var e_4, _a;
var attributes = {};
var listeners = {};
var properties = {};
var specialAttributes = {};
try {
for (var _b = tslib_1.__values(Object.keys(host)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
var value = host[key];
var matches = key.match(HOST_REG_EXP);
if (matches === null) {
switch (key) {
case 'class':
if (typeof value !== 'string') {
// TODO(alxhub): make this a diagnostic.
throw new Error("Class binding must be string");
}
specialAttributes.classAttr = value;
break;
case 'style':
if (typeof value !== 'string') {
// TODO(alxhub): make this a diagnostic.
throw new Error("Style binding must be string");
}
specialAttributes.styleAttr = value;
break;
default:
if (typeof value === 'string') {
attributes[key] = o.literal(value);
}
else {
attributes[key] = value;
}
}
}
else if (matches[1 /* Binding */] != null) {
if (typeof value !== 'string') {
// TODO(alxhub): make this a diagnostic.
throw new Error("Property binding must be string");
}
// synthetic properties (the ones that have a `@` as a prefix)
// are still treated the same as regular properties. Therefore
// there is no point in storing them in a separate map.
properties[matches[1 /* Binding */]] = value;
}
else if (matches[2 /* Event */] != null) {
if (typeof value !== 'string') {
// TODO(alxhub): make this a diagnostic.
throw new Error("Event binding must be string");
}
listeners[matches[2 /* Event */]] = value;
}
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_4) throw e_4.error; }
}
return { attributes: attributes, listeners: listeners, properties: properties, specialAttributes: specialAttributes };
}
exports.parseHostBindings = parseHostBindings;
/**
* Verifies host bindings and returns the list of errors (if any). Empty array indicates that a
* given set of host bindings has no errors.
*
* @param bindings set of host bindings to verify.
* @param sourceSpan source span where host bindings were defined.
* @returns array of errors associated with a given set of host bindings.
*/
function verifyHostBindings(bindings, sourceSpan) {
var summary = metadataAsSummary(bindings);
// TODO: abstract out host bindings verification logic and use it instead of
// creating events and properties ASTs to detect errors (FW-996)
var bindingParser = template_1.makeBindingParser();
bindingParser.createDirectiveHostEventAsts(summary, sourceSpan);
bindingParser.createBoundHostProperties(summary, sourceSpan);
return bindingParser.errors;
}
exports.verifyHostBindings = verifyHostBindings;
function compileStyles(styles, selector, hostSelector) {
var shadowCss = new shadow_css_1.ShadowCss();
return styles.map(function (style) {
return shadowCss.shimCssText(style, selector, hostSelector);
});
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvcmVuZGVyMy92aWV3L2NvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRzs7Ozs7Ozs7Ozs7Ozs7SUFHSCwyRUFBeUs7SUFFekssaUdBQTZGO0lBRTdGLGlEQUFtQztJQUVuQyw2RkFBa0Y7SUFDbEYsMkRBQTZDO0lBRTdDLDJEQUE0RDtJQUM1RCwrREFBMkM7SUFDM0MsdUVBQTZEO0lBRTdELG1EQUFnRDtJQUNoRCwrREFBcUM7SUFDckMsdUVBQXNIO0lBQ3RILCtFQUFvRDtJQUVwRCwyREFBK0c7SUFHL0csc0ZBQTZHO0lBQzdHLHdFQUFvTDtJQUNwTCxnRUFBNEw7SUFFNUwsSUFBTSxXQUFXLEdBQVUsRUFBRSxDQUFDO0lBRTlCLDZGQUE2RjtJQUM3Rix5RkFBeUY7SUFDekYsSUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUM7SUFFcEMsU0FBUyxtQkFBbUIsQ0FDeEIsSUFBeUIsRUFBRSxZQUEwQixFQUNyRCxhQUE0QjtRQUM5QixJQUFNLGFBQWEsR0FBRyxJQUFJLG9CQUFhLEVBQUUsQ0FBQztRQUMxQyxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWhFLDJCQUEyQjtRQUMzQixhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFN0MsMENBQTBDO1FBQzFDLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDeEIsYUFBYSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsZ0JBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1NBQ3REO1FBRUQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFD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