UNPKG

@angular/compiler

Version:

Angular - the compiler library

751 lines 131 kB
/** * @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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