UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

777 lines 144 kB
'use strict';"use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var collection_1 = require('angular2/src/facade/collection'); var lang_1 = require('angular2/src/facade/lang'); var core_1 = require('angular2/core'); var console_1 = require('angular2/src/core/console'); var exceptions_1 = require('angular2/src/facade/exceptions'); var ast_1 = require('./expression_parser/ast'); var parser_1 = require('./expression_parser/parser'); var html_parser_1 = require('./html_parser'); var html_tags_1 = require('./html_tags'); var parse_util_1 = require('./parse_util'); var view_utils_1 = require('angular2/src/core/linker/view_utils'); var template_ast_1 = require('./template_ast'); var selector_1 = require('angular2/src/compiler/selector'); var element_schema_registry_1 = require('angular2/src/compiler/schema/element_schema_registry'); var template_preparser_1 = require('./template_preparser'); var style_url_resolver_1 = require('./style_url_resolver'); var html_ast_1 = require('./html_ast'); var util_1 = require('./util'); var identifiers_1 = require('./identifiers'); var provider_parser_1 = require('./provider_parser'); // Group 1 = "bind-" // Group 2 = "var-" // Group 3 = "let-" // Group 4 = "ref-/#" // Group 5 = "on-" // Group 6 = "bindon-" // Group 7 = the identifier after "bind-", "var-/#", or "on-" // Group 8 = identifier inside [()] // Group 9 = identifier inside [] // Group 10 = identifier inside () var BIND_NAME_REGEXP = /^(?:(?:(?:(bind-)|(var-)|(let-)|(ref-|#)|(on-)|(bindon-))(.+))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/g; var TEMPLATE_ELEMENT = 'template'; var TEMPLATE_ATTR = 'template'; var TEMPLATE_ATTR_PREFIX = '*'; var CLASS_ATTR = 'class'; var PROPERTY_PARTS_SEPARATOR = '.'; var ATTRIBUTE_PREFIX = 'attr'; var CLASS_PREFIX = 'class'; var STYLE_PREFIX = 'style'; var TEXT_CSS_SELECTOR = selector_1.CssSelector.parse('*')[0]; /** * Provides an array of {@link TemplateAstVisitor}s which will be used to transform * parsed templates before compilation is invoked, allowing custom expression syntax * and other advanced transformations. * * This is currently an internal-only feature and not meant for general use. */ exports.TEMPLATE_TRANSFORMS = lang_1.CONST_EXPR(new core_1.OpaqueToken('TemplateTransforms')); var TemplateParseError = (function (_super) { __extends(TemplateParseError, _super); function TemplateParseError(message, span, level) { _super.call(this, span, message, level); } return TemplateParseError; }(parse_util_1.ParseError)); exports.TemplateParseError = TemplateParseError; var TemplateParseResult = (function () { function TemplateParseResult(templateAst, errors) { this.templateAst = templateAst; this.errors = errors; } return TemplateParseResult; }()); exports.TemplateParseResult = TemplateParseResult; var TemplateParser = (function () { function TemplateParser(_exprParser, _schemaRegistry, _htmlParser, _console, transforms) { this._exprParser = _exprParser; this._schemaRegistry = _schemaRegistry; this._htmlParser = _htmlParser; this._console = _console; this.transforms = transforms; } TemplateParser.prototype.parse = function (component, template, directives, pipes, templateUrl) { var result = this.tryParse(component, template, directives, pipes, templateUrl); var warnings = result.errors.filter(function (error) { return error.level === parse_util_1.ParseErrorLevel.WARNING; }); var errors = result.errors.filter(function (error) { return error.level === parse_util_1.ParseErrorLevel.FATAL; }); if (warnings.length > 0) { this._console.warn("Template parse warnings:\n" + warnings.join('\n')); } if (errors.length > 0) { var errorString = errors.join('\n'); throw new exceptions_1.BaseException("Template parse errors:\n" + errorString); } return result.templateAst; }; TemplateParser.prototype.tryParse = function (component, template, directives, pipes, templateUrl) { var htmlAstWithErrors = this._htmlParser.parse(template, templateUrl); var errors = htmlAstWithErrors.errors; var result; if (htmlAstWithErrors.rootNodes.length > 0) { var uniqDirectives = removeDuplicates(directives); var uniqPipes = removeDuplicates(pipes); var providerViewContext = new provider_parser_1.ProviderViewContext(component, htmlAstWithErrors.rootNodes[0].sourceSpan); var parseVisitor = new TemplateParseVisitor(providerViewContext, uniqDirectives, uniqPipes, this._exprParser, this._schemaRegistry); result = html_ast_1.htmlVisitAll(parseVisitor, htmlAstWithErrors.rootNodes, EMPTY_ELEMENT_CONTEXT); errors = errors.concat(parseVisitor.errors).concat(providerViewContext.errors); } else { result = []; } if (errors.length > 0) { return new TemplateParseResult(result, errors); } if (lang_1.isPresent(this.transforms)) { this.transforms.forEach(function (transform) { result = template_ast_1.templateVisitAll(transform, result); }); } return new TemplateParseResult(result, errors); }; TemplateParser = __decorate([ core_1.Injectable(), __param(4, core_1.Optional()), __param(4, core_1.Inject(exports.TEMPLATE_TRANSFORMS)), __metadata('design:paramtypes', [parser_1.Parser, element_schema_registry_1.ElementSchemaRegistry, html_parser_1.HtmlParser, console_1.Console, Array]) ], TemplateParser); return TemplateParser; }()); exports.TemplateParser = TemplateParser; var TemplateParseVisitor = (function () { function TemplateParseVisitor(providerViewContext, directives, pipes, _exprParser, _schemaRegistry) { var _this = this; this.providerViewContext = providerViewContext; this._exprParser = _exprParser; this._schemaRegistry = _schemaRegistry; this.errors = []; this.directivesIndex = new Map(); this.ngContentCount = 0; this.selectorMatcher = new selector_1.SelectorMatcher(); collection_1.ListWrapper.forEachWithIndex(directives, function (directive, index) { var selector = selector_1.CssSelector.parse(directive.selector); _this.selectorMatcher.addSelectables(selector, directive); _this.directivesIndex.set(directive, index); }); this.pipesByName = new Map(); pipes.forEach(function (pipe) { return _this.pipesByName.set(pipe.name, pipe); }); } TemplateParseVisitor.prototype._reportError = function (message, sourceSpan, level) { if (level === void 0) { level = parse_util_1.ParseErrorLevel.FATAL; } this.errors.push(new TemplateParseError(message, sourceSpan, level)); }; TemplateParseVisitor.prototype._parseInterpolation = function (value, sourceSpan) { var sourceInfo = sourceSpan.start.toString(); try { var ast = this._exprParser.parseInterpolation(value, sourceInfo); this._checkPipes(ast, sourceSpan); if (lang_1.isPresent(ast) && ast.ast.expressions.length > view_utils_1.MAX_INTERPOLATION_VALUES) { throw new exceptions_1.BaseException("Only support at most " + view_utils_1.MAX_INTERPOLATION_VALUES + " interpolation values!"); } return ast; } catch (e) { this._reportError("" + e, sourceSpan); return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo); } }; TemplateParseVisitor.prototype._parseAction = function (value, sourceSpan) { var sourceInfo = sourceSpan.start.toString(); try { var ast = this._exprParser.parseAction(value, sourceInfo); this._checkPipes(ast, sourceSpan); return ast; } catch (e) { this._reportError("" + e, sourceSpan); return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo); } }; TemplateParseVisitor.prototype._parseBinding = function (value, sourceSpan) { var sourceInfo = sourceSpan.start.toString(); try { var ast = this._exprParser.parseBinding(value, sourceInfo); this._checkPipes(ast, sourceSpan); return ast; } catch (e) { this._reportError("" + e, sourceSpan); return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo); } }; TemplateParseVisitor.prototype._parseTemplateBindings = function (value, sourceSpan) { var _this = this; var sourceInfo = sourceSpan.start.toString(); try { var bindingsResult = this._exprParser.parseTemplateBindings(value, sourceInfo); bindingsResult.templateBindings.forEach(function (binding) { if (lang_1.isPresent(binding.expression)) { _this._checkPipes(binding.expression, sourceSpan); } }); bindingsResult.warnings.forEach(function (warning) { _this._reportError(warning, sourceSpan, parse_util_1.ParseErrorLevel.WARNING); }); return bindingsResult.templateBindings; } catch (e) { this._reportError("" + e, sourceSpan); return []; } }; TemplateParseVisitor.prototype._checkPipes = function (ast, sourceSpan) { var _this = this; if (lang_1.isPresent(ast)) { var collector = new PipeCollector(); ast.visit(collector); collector.pipes.forEach(function (pipeName) { if (!_this.pipesByName.has(pipeName)) { _this._reportError("The pipe '" + pipeName + "' could not be found", sourceSpan); } }); } }; TemplateParseVisitor.prototype.visitExpansion = function (ast, context) { return null; }; TemplateParseVisitor.prototype.visitExpansionCase = function (ast, context) { return null; }; TemplateParseVisitor.prototype.visitText = function (ast, parent) { var ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR); var expr = this._parseInterpolation(ast.value, ast.sourceSpan); if (lang_1.isPresent(expr)) { return new template_ast_1.BoundTextAst(expr, ngContentIndex, ast.sourceSpan); } else { return new template_ast_1.TextAst(ast.value, ngContentIndex, ast.sourceSpan); } }; TemplateParseVisitor.prototype.visitAttr = function (ast, contex) { return new template_ast_1.AttrAst(ast.name, ast.value, ast.sourceSpan); }; TemplateParseVisitor.prototype.visitComment = function (ast, context) { return null; }; TemplateParseVisitor.prototype.visitElement = function (element, parent) { var _this = this; var nodeName = element.name; var preparsedElement = template_preparser_1.preparseElement(element); if (preparsedElement.type === template_preparser_1.PreparsedElementType.SCRIPT || preparsedElement.type === template_preparser_1.PreparsedElementType.STYLE) { // Skipping <script> for security reasons // Skipping <style> as we already processed them // in the StyleCompiler return null; } if (preparsedElement.type === template_preparser_1.PreparsedElementType.STYLESHEET && style_url_resolver_1.isStyleUrlResolvable(preparsedElement.hrefAttr)) { // Skipping stylesheets with either relative urls or package scheme as we already processed // them in the StyleCompiler return null; } var matchableAttrs = []; var elementOrDirectiveProps = []; var elementOrDirectiveRefs = []; var elementVars = []; var events = []; var templateElementOrDirectiveProps = []; var templateMatchableAttrs = []; var templateElementVars = []; var hasInlineTemplates = false; var attrs = []; var lcElName = html_tags_1.splitNsName(nodeName.toLowerCase())[1]; var isTemplateElement = lcElName == TEMPLATE_ELEMENT; element.attrs.forEach(function (attr) { var hasBinding = _this._parseAttr(isTemplateElement, attr, matchableAttrs, elementOrDirectiveProps, events, elementOrDirectiveRefs, elementVars); var hasTemplateBinding = _this._parseInlineTemplateBinding(attr, templateMatchableAttrs, templateElementOrDirectiveProps, templateElementVars); if (!hasBinding && !hasTemplateBinding) { // don't include the bindings as attributes as well in the AST attrs.push(_this.visitAttr(attr, null)); matchableAttrs.push([attr.name, attr.value]); } if (hasTemplateBinding) { hasInlineTemplates = true; } }); var elementCssSelector = createElementCssSelector(nodeName, matchableAttrs); var directiveMetas = this._parseDirectives(this.selectorMatcher, elementCssSelector); var references = []; var directiveAsts = this._createDirectiveAsts(isTemplateElement, element.name, directiveMetas, elementOrDirectiveProps, elementOrDirectiveRefs, element.sourceSpan, references); var elementProps = this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directiveAsts); var isViewRoot = parent.isTemplateElement || hasInlineTemplates; var providerContext = new provider_parser_1.ProviderElementContext(this.providerViewContext, parent.providerContext, isViewRoot, directiveAsts, attrs, references, element.sourceSpan); var children = html_ast_1.htmlVisitAll(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children, ElementContext.create(isTemplateElement, directiveAsts, isTemplateElement ? parent.providerContext : providerContext)); providerContext.afterElement(); // Override the actual selector when the `ngProjectAs` attribute is provided var projectionSelector = lang_1.isPresent(preparsedElement.projectAs) ? selector_1.CssSelector.parse(preparsedElement.projectAs)[0] : elementCssSelector; var ngContentIndex = parent.findNgContentIndex(projectionSelector); var parsedElement; if (preparsedElement.type === template_preparser_1.PreparsedElementType.NG_CONTENT) { if (lang_1.isPresent(element.children) && element.children.length > 0) { this._reportError("<ng-content> element cannot have content. <ng-content> must be immediately followed by </ng-content>", element.sourceSpan); } parsedElement = new template_ast_1.NgContentAst(this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan); } else if (isTemplateElement) { this._assertAllEventsPublishedByDirectives(directiveAsts, events); this._assertNoComponentsNorElementBindingsOnTemplate(directiveAsts, elementProps, element.sourceSpan); parsedElement = new template_ast_1.EmbeddedTemplateAst(attrs, events, references, elementVars, providerContext.transformedDirectiveAsts, providerContext.transformProviders, providerContext.transformedHasViewContainer, children, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan); } else { this._assertOnlyOneComponent(directiveAsts, element.sourceSpan); var ngContentIndex_1 = hasInlineTemplates ? null : parent.findNgContentIndex(projectionSelector); parsedElement = new template_ast_1.ElementAst(nodeName, attrs, elementProps, events, references, providerContext.transformedDirectiveAsts, providerContext.transformProviders, providerContext.transformedHasViewContainer, children, hasInlineTemplates ? null : ngContentIndex_1, element.sourceSpan); } if (hasInlineTemplates) { var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs); var templateDirectiveMetas = this._parseDirectives(this.selectorMatcher, templateCssSelector); var templateDirectiveAsts = this._createDirectiveAsts(true, element.name, templateDirectiveMetas, templateElementOrDirectiveProps, [], element.sourceSpan, []); var templateElementProps = this._createElementPropertyAsts(element.name, templateElementOrDirectiveProps, templateDirectiveAsts); this._assertNoComponentsNorElementBindingsOnTemplate(templateDirectiveAsts, templateElementProps, element.sourceSpan); var templateProviderContext = new provider_parser_1.ProviderElementContext(this.providerViewContext, parent.providerContext, parent.isTemplateElement, templateDirectiveAsts, [], [], element.sourceSpan); templateProviderContext.afterElement(); parsedElement = new template_ast_1.EmbeddedTemplateAst([], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts, templateProviderContext.transformProviders, templateProviderContext.transformedHasViewContainer, [parsedElement], ngContentIndex, element.sourceSpan); } return parsedElement; }; TemplateParseVisitor.prototype._parseInlineTemplateBinding = function (attr, targetMatchableAttrs, targetProps, targetVars) { var templateBindingsSource = null; if (attr.name == TEMPLATE_ATTR) { templateBindingsSource = attr.value; } else if (attr.name.startsWith(TEMPLATE_ATTR_PREFIX)) { var key = attr.name.substring(TEMPLATE_ATTR_PREFIX.length); // remove the star templateBindingsSource = (attr.value.length == 0) ? key : key + ' ' + attr.value; } if (lang_1.isPresent(templateBindingsSource)) { var bindings = this._parseTemplateBindings(templateBindingsSource, attr.sourceSpan); for (var i = 0; i < bindings.length; i++) { var binding = bindings[i]; if (binding.keyIsVar) { targetVars.push(new template_ast_1.VariableAst(binding.key, binding.name, attr.sourceSpan)); } else if (lang_1.isPresent(binding.expression)) { this._parsePropertyAst(binding.key, binding.expression, attr.sourceSpan, targetMatchableAttrs, targetProps); } else { targetMatchableAttrs.push([binding.key, '']); this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps); } } return true; } return false; }; TemplateParseVisitor.prototype._parseAttr = function (isTemplateElement, attr, targetMatchableAttrs, targetProps, targetEvents, targetRefs, targetVars) { var attrName = this._normalizeAttributeName(attr.name); var attrValue = attr.value; var bindParts = lang_1.RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName); var hasBinding = false; if (lang_1.isPresent(bindParts)) { hasBinding = true; if (lang_1.isPresent(bindParts[1])) { this._parseProperty(bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps); } else if (lang_1.isPresent(bindParts[2])) { var identifier = bindParts[7]; if (isTemplateElement) { this._reportError("\"var-\" on <template> elements is deprecated. Use \"let-\" instead!", attr.sourceSpan, parse_util_1.ParseErrorLevel.WARNING); this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars); } else { this._reportError("\"var-\" on non <template> elements is deprecated. Use \"ref-\" instead!", attr.sourceSpan, parse_util_1.ParseErrorLevel.WARNING); this._parseReference(identifier, attrValue, attr.sourceSpan, targetRefs); } } else if (lang_1.isPresent(bindParts[3])) { if (isTemplateElement) { var identifier = bindParts[7]; this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars); } else { this._reportError("\"let-\" is only supported on template elements.", attr.sourceSpan); } } else if (lang_1.isPresent(bindParts[4])) { var identifier = bindParts[7]; this._parseReference(identifier, attrValue, attr.sourceSpan, targetRefs); } else if (lang_1.isPresent(bindParts[5])) { this._parseEvent(bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents); } else if (lang_1.isPresent(bindParts[6])) { this._parseProperty(bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps); this._parseAssignmentEvent(bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents); } else if (lang_1.isPresent(bindParts[8])) { this._parseProperty(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps); this._parseAssignmentEvent(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents); } else if (lang_1.isPresent(bindParts[9])) { this._parseProperty(bindParts[9], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps); } else if (lang_1.isPresent(bindParts[10])) { this._parseEvent(bindParts[10], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents); } } else { hasBinding = this._parsePropertyInterpolation(attrName, attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps); } if (!hasBinding) { this._parseLiteralAttr(attrName, attrValue, attr.sourceSpan, targetProps); } return hasBinding; }; TemplateParseVisitor.prototype._normalizeAttributeName = function (attrName) { return attrName.toLowerCase().startsWith('data-') ? attrName.substring(5) : attrName; }; TemplateParseVisitor.prototype._parseVariable = function (identifier, value, sourceSpan, targetVars) { if (identifier.indexOf('-') > -1) { this._reportError("\"-\" is not allowed in variable names", sourceSpan); } targetVars.push(new template_ast_1.VariableAst(identifier, value, sourceSpan)); }; TemplateParseVisitor.prototype._parseReference = function (identifier, value, sourceSpan, targetRefs) { if (identifier.indexOf('-') > -1) { this._reportError("\"-\" is not allowed in reference names", sourceSpan); } targetRefs.push(new ElementOrDirectiveRef(identifier, value, sourceSpan)); }; TemplateParseVisitor.prototype._parseProperty = function (name, expression, sourceSpan, targetMatchableAttrs, targetProps) { this._parsePropertyAst(name, this._parseBinding(expression, sourceSpan), sourceSpan, targetMatchableAttrs, targetProps); }; TemplateParseVisitor.prototype._parsePropertyInterpolation = function (name, value, sourceSpan, targetMatchableAttrs, targetProps) { var expr = this._parseInterpolation(value, sourceSpan); if (lang_1.isPresent(expr)) { this._parsePropertyAst(name, expr, sourceSpan, targetMatchableAttrs, targetProps); return true; } return false; }; TemplateParseVisitor.prototype._parsePropertyAst = function (name, ast, sourceSpan, targetMatchableAttrs, targetProps) { targetMatchableAttrs.push([name, ast.source]); targetProps.push(new BoundElementOrDirectiveProperty(name, ast, false, sourceSpan)); }; TemplateParseVisitor.prototype._parseAssignmentEvent = function (name, expression, sourceSpan, targetMatchableAttrs, targetEvents) { this._parseEvent(name + "Change", expression + "=$event", sourceSpan, targetMatchableAttrs, targetEvents); }; TemplateParseVisitor.prototype._parseEvent = function (name, expression, sourceSpan, targetMatchableAttrs, targetEvents) { // long format: 'target: eventName' var parts = util_1.splitAtColon(name, [null, name]); var target = parts[0]; var eventName = parts[1]; var ast = this._parseAction(expression, sourceSpan); targetMatchableAttrs.push([name, ast.source]); targetEvents.push(new template_ast_1.BoundEventAst(eventName, target, ast, sourceSpan)); // Don't detect directives for event names for now, // so don't add the event name to the matchableAttrs }; TemplateParseVisitor.prototype._parseLiteralAttr = function (name, value, sourceSpan, targetProps) { targetProps.push(new BoundElementOrDirectiveProperty(name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan)); }; TemplateParseVisitor.prototype._parseDirectives = function (selectorMatcher, elementCssSelector) { var _this = this; // Need to sort the directives so that we get consistent results throughout, // as selectorMatcher uses Maps inside. // Also dedupe directives as they might match more than one time! var directives = collection_1.ListWrapper.createFixedSize(this.directivesIndex.size); selectorMatcher.match(elementCssSelector, function (selector, directive) { directives[_this.directivesIndex.get(directive)] = directive; }); return directives.filter(function (dir) { return lang_1.isPresent(dir); }); }; TemplateParseVisitor.prototype._createDirectiveAsts = function (isTemplateElement, elementName, directives, props, elementOrDirectiveRefs, sourceSpan, targetReferences) { var _this = this; var matchedReferences = new Set(); var component = null; var directiveAsts = directives.map(function (directive) { if (directive.isComponent) { component = directive; } var hostProperties = []; var hostEvents = []; var directiveProperties = []; _this._createDirectiveHostPropertyAsts(elementName, directive.hostProperties, sourceSpan, hostProperties); _this._createDirectiveHostEventAsts(directive.hostListeners, sourceSpan, hostEvents); _this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties); elementOrDirectiveRefs.forEach(function (elOrDirRef) { if ((elOrDirRef.value.length === 0 && directive.isComponent) || (directive.exportAs == elOrDirRef.value)) { targetReferences.push(new template_ast_1.ReferenceAst(elOrDirRef.name, identifiers_1.identifierToken(directive.type), elOrDirRef.sourceSpan)); matchedReferences.add(elOrDirRef.name); } }); return new template_ast_1.DirectiveAst(directive, directiveProperties, hostProperties, hostEvents, sourceSpan); }); elementOrDirectiveRefs.forEach(function (elOrDirRef) { if (elOrDirRef.value.length > 0) { if (!collection_1.SetWrapper.has(matchedReferences, elOrDirRef.name)) { _this._reportError("There is no directive with \"exportAs\" set to \"" + elOrDirRef.value + "\"", elOrDirRef.sourceSpan); } ; } else if (lang_1.isBlank(component)) { var refToken = null; if (isTemplateElement) { refToken = identifiers_1.identifierToken(identifiers_1.Identifiers.TemplateRef); } targetReferences.push(new template_ast_1.ReferenceAst(elOrDirRef.name, refToken, elOrDirRef.sourceSpan)); } }); return directiveAsts; }; TemplateParseVisitor.prototype._createDirectiveHostPropertyAsts = function (elementName, hostProps, sourceSpan, targetPropertyAsts) { var _this = this; if (lang_1.isPresent(hostProps)) { collection_1.StringMapWrapper.forEach(hostProps, function (expression, propName) { var exprAst = _this._parseBinding(expression, sourceSpan); targetPropertyAsts.push(_this._createElementPropertyAst(elementName, propName, exprAst, sourceSpan)); }); } }; TemplateParseVisitor.prototype._createDirectiveHostEventAsts = function (hostListeners, sourceSpan, targetEventAsts) { var _this = this; if (lang_1.isPresent(hostListeners)) { collection_1.StringMapWrapper.forEach(hostListeners, function (expression, propName) { _this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts); }); } }; TemplateParseVisitor.prototype._createDirectivePropertyAsts = function (directiveProperties, boundProps, targetBoundDirectiveProps) { if (lang_1.isPresent(directiveProperties)) { var boundPropsByName = new Map(); boundProps.forEach(function (boundProp) { var prevValue = boundPropsByName.get(boundProp.name); if (lang_1.isBlank(prevValue) || prevValue.isLiteral) { // give [a]="b" a higher precedence than a="b" on the same element boundPropsByName.set(boundProp.name, boundProp); } }); collection_1.StringMapWrapper.forEach(directiveProperties, function (elProp, dirProp) { var boundProp = boundPropsByName.get(elProp); // Bindings are optional, so this binding only needs to be set up if an expression is given. if (lang_1.isPresent(boundProp)) { targetBoundDirectiveProps.push(new template_ast_1.BoundDirectivePropertyAst(dirProp, boundProp.name, boundProp.expression, boundProp.sourceSpan)); } }); } }; TemplateParseVisitor.prototype._createElementPropertyAsts = function (elementName, props, directives) { var _this = this; var boundElementProps = []; var boundDirectivePropsIndex = new Map(); directives.forEach(function (directive) { directive.inputs.forEach(function (prop) { boundDirectivePropsIndex.set(prop.templateName, prop); }); }); props.forEach(function (prop) { if (!prop.isLiteral && lang_1.isBlank(boundDirectivePropsIndex.get(prop.name))) { boundElementProps.push(_this._createElementPropertyAst(elementName, prop.name, prop.expression, prop.sourceSpan)); } }); return boundElementProps; }; TemplateParseVisitor.prototype._createElementPropertyAst = function (elementName, name, ast, sourceSpan) { var unit = null; var bindingType; var boundPropertyName; var parts = name.split(PROPERTY_PARTS_SEPARATOR); if (parts.length === 1) { boundPropertyName = this._schemaRegistry.getMappedPropName(parts[0]); bindingType = template_ast_1.PropertyBindingType.Property; if (!this._schemaRegistry.hasProperty(elementName, boundPropertyName)) { this._reportError("Can't bind to '" + boundPropertyName + "' since it isn't a known native property", sourceSpan); } } else { if (parts[0] == ATTRIBUTE_PREFIX) { boundPropertyName = parts[1]; var nsSeparatorIdx = boundPropertyName.indexOf(':'); if (nsSeparatorIdx > -1) { var ns = boundPropertyName.substring(0, nsSeparatorIdx); var name_1 = boundPropertyName.substring(nsSeparatorIdx + 1); boundPropertyName = html_tags_1.mergeNsAndName(ns, name_1); } bindingType = template_ast_1.PropertyBindingType.Attribute; } else if (parts[0] == CLASS_PREFIX) { boundPropertyName = parts[1]; bindingType = template_ast_1.PropertyBindingType.Class; } else if (parts[0] == STYLE_PREFIX) { unit = parts.length > 2 ? parts[2] : null; boundPropertyName = parts[1]; bindingType = template_ast_1.PropertyBindingType.Style; } else { this._reportError("Invalid property name '" + name + "'", sourceSpan); bindingType = null; } } return new template_ast_1.BoundElementPropertyAst(boundPropertyName, bindingType, ast, unit, sourceSpan); }; TemplateParseVisitor.prototype._findComponentDirectiveNames = function (directives) { var componentTypeNames = []; directives.forEach(function (directive) { var typeName = directive.directive.type.name; if (directive.directive.isComponent) { componentTypeNames.push(typeName); } }); return componentTypeNames; }; TemplateParseVisitor.prototype._assertOnlyOneComponent = function (directives, sourceSpan) { var componentTypeNames = this._findComponentDirectiveNames(directives); if (componentTypeNames.length > 1) { this._reportError("More than one component: " + componentTypeNames.join(','), sourceSpan); } }; TemplateParseVisitor.prototype._assertNoComponentsNorElementBindingsOnTemplate = function (directives, elementProps, sourceSpan) { var _this = this; var componentTypeNames = this._findComponentDirectiveNames(directives); if (componentTypeNames.length > 0) { this._reportError("Components on an embedded template: " + componentTypeNames.join(','), sourceSpan); } elementProps.forEach(function (prop) { _this._reportError("Property binding " + prop.name + " not used by any directive on an embedded template", sourceSpan); }); }; TemplateParseVisitor.prototype._assertAllEventsPublishedByDirectives = function (directives, events) { var _this = this; var allDirectiveEvents = new Set(); directives.forEach(function (directive) { collection_1.StringMapWrapper.forEach(directive.directive.outputs, function (eventName, _) { allDirectiveEvents.add(eventName); }); }); events.forEach(function (event) { if (lang_1.isPresent(event.target) || !collection_1.SetWrapper.has(allDirectiveEvents, event.name)) { _this._reportError("Event binding " + event.fullName + " not emitted by any directive on an embedded template", event.sourceSpan); } }); }; return TemplateParseVisitor; }()); var NonBindableVisitor = (function () { function NonBindableVisitor() { } NonBindableVisitor.prototype.visitElement = function (ast, parent) { var preparsedElement = template_preparser_1.preparseElement(ast); if (preparsedElement.type === template_preparser_1.PreparsedElementType.SCRIPT || preparsedElement.type === template_preparser_1.PreparsedElementType.STYLE || preparsedElement.type === template_preparser_1.PreparsedElementType.STYLESHEET) { // Skipping <script> for security reasons // Skipping <style> and stylesheets as we already processed them // in the StyleCompiler return null; } var attrNameAndValues = ast.attrs.map(function (attrAst) { return [attrAst.name, attrAst.value]; }); var selector = createElementCssSelector(ast.name, attrNameAndValues); var ngContentIndex = parent.findNgContentIndex(selector); var children = html_ast_1.htmlVisitAll(this, ast.children, EMPTY_ELEMENT_CONTEXT); return new template_ast_1.ElementAst(ast.name, html_ast_1.htmlVisitAll(this, ast.attrs), [], [], [], [], [], false, children, ngContentIndex, ast.sourceSpan); }; NonBindableVisitor.prototype.visitComment = function (ast, context) { return null; }; NonBindableVisitor.prototype.visitAttr = function (ast, context) { return new template_ast_1.AttrAst(ast.name, ast.value, ast.sourceSpan); }; NonBindableVisitor.prototype.visitText = function (ast, parent) { var ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR); return new template_ast_1.TextAst(ast.value, ngContentIndex, ast.sourceSpan); }; NonBindableVisitor.prototype.visitExpansion = function (ast, context) { return ast; }; NonBindableVisitor.prototype.visitExpansionCase = function (ast, context) { return ast; }; return NonBindableVisitor; }()); var BoundElementOrDirectiveProperty = (function () { function BoundElementOrDirectiveProperty(name, expression, isLiteral, sourceSpan) { this.name = name; this.expression = expression; this.isLiteral = isLiteral; this.sourceSpan = sourceSpan; } return BoundElementOrDirectiveProperty; }()); var ElementOrDirectiveRef = (function () { function ElementOrDirectiveRef(name, value, sourceSpan) { this.name = name; this.value = value; this.sourceSpan = sourceSpan; } return ElementOrDirectiveRef; }()); function splitClasses(classAttrValue) { return lang_1.StringWrapper.split(classAttrValue.trim(), /\s+/g); } exports.splitClasses = splitClasses; var ElementContext = (function () { function ElementContext(isTemplateElement, _ngContentIndexMatcher, _wildcardNgContentIndex, providerContext) { this.isTemplateElement = isTemplateElement; this._ngContentIndexMatcher = _ngContentIndexMatcher; this._wildcardNgContentIndex = _wildcardNgContentIndex; this.providerContext = providerContext; } ElementContext.create = function (isTemplateElement, directives, providerContext) { var matcher = new selector_1.SelectorMatcher(); var wildcardNgContentIndex = null; if (directives.length > 0 && directives[0].directive.isComponent) { var ngContentSelectors = directives[0].directive.template.ngContentSelectors; for (var i = 0; i < ngContentSelectors.length; i++) { var selector = ngContentSelectors[i]; if (lang_1.StringWrapper.equals(selector, '*')) { wildcardNgContentIndex = i; } else { matcher.addSelectables(selector_1.CssSelector.parse(ngContentSelectors[i]), i); } } } return new ElementContext(isTemplateElement, matcher, wildcardNgContentIndex, providerContext); }; ElementContext.prototype.findNgContentIndex = function (selector) { var ngContentIndices = []; this._ngContentIndexMatcher.match(selector, function (selector, ngContentIndex) { ngContentIndices.push(ngContentIndex); }); collection_1.ListWrapper.sort(ngContentIndices); if (lang_1.isPresent(this._wildcardNgContentIndex)) { ngContentIndices.push(this._wildcardNgContentIndex); } return ngContentIndices.length > 0 ? ngContentIndices[0] : null; }; return ElementContext; }()); function createElementCssSelector(elementName, matchableAttrs) { var cssSelector = new selector_1.CssSelector(); var elNameNoNs = html_tags_1.splitNsName(elementName)[1]; cssSelector.setElement(elNameNoNs); for (var i = 0; i < matchableAttrs.length; i++) { var attrName = matchableAttrs[i][0]; var attrNameNoNs = html_tags_1.splitNsName(attrName)[1]; var attrValue = matchableAttrs[i][1]; cssSelector.addAttribute(attrNameNoNs, attrValue); if (attrName.toLowerCase() == CLASS_ATTR) { var classes = splitClasses(attrValue); classes.forEach(function (className) { return cssSelector.addClassName(className); }); } } return cssSelector; } var EMPTY_ELEMENT_CONTEXT = new ElementContext(true, new selector_1.SelectorMatcher(), null, null); var NON_BINDABLE_VISITOR = new NonBindableVisitor(); var PipeCollector = (function (_super) { __extends(PipeCollector, _super); function PipeCollector() { _super.apply(this, arguments); this.pipes = new Set(); } PipeCollector.prototype.visitPipe = function (ast, context) { this.pipes.add(ast.name); ast.exp.visit(this); this.visitAll(ast.args, context); return null; }; return PipeCollector; }(ast_1.RecursiveAstVisitor)); exports.PipeCollector = PipeCollector; function removeDuplicates(items) { var res = []; items.forEach(function (item) { var hasMatch = res.filter(function (r) { return r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl && r.type.runtime == item.type.runtime; }) .length > 0; if (!hasMatch) { res.push(item); } }); return res; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGVfcGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlmZmluZ19wbHVnaW5fd3JhcHBlci1vdXRwdXRfcGF0aC1CUkplcjFKOS50bXAvYW5ndWxhcjIvc3JjL2NvbXBpbGVyL3RlbXBsYXRlX3BhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQkFLTyxnQ0FBZ0MsQ0FBQyxDQUFBO0FBQ3hDLHFCQU9PLDBCQUEwQixDQUFDLENBQUE7QUFDbEMscUJBQXdELGVBQWUsQ0FBQyxDQUFBO0FBQ3hFLHdCQUFzQiwyQkFBMkIsQ0FBQyxDQUFBO0FBQ2xELDJCQUE0QixnQ0FBZ0MsQ0FBQyxDQUFBO0FBQzdELG9CQU9PLHlCQUF5QixDQUFDLENBQUE7QUFDakMsdUJBQXFCLDRCQUE0QixDQUFDLENBQUE7QUFVbEQsNEJBQXlCLGVBQWUsQ0FBQyxDQUFBO0FBQ3pDLDBCQUEwQyxhQUFhLENBQUMsQ0FBQTtBQUN4RCwyQkFBMEUsY0FBYyxDQUFDLENBQUE7QUFDekYsMkJBQXVDLHFDQUFxQyxDQUFDLENBQUE7QUFFN0UsNkJBbUJPLGdCQUFnQixDQUFDLENBQUE7QUFDeEIseUJBQTJDLGdDQUFnQyxDQUFDLENBQUE7QUFFNUUsd0NBQW9DLHNEQUFzRCxDQUFDLENBQUE7QUFDM0YsbUNBQXNFLHNCQUFzQixDQUFDLENBQUE7QUFFN0YsbUNBQW1DLHNCQUFzQixDQUFDLENBQUE7QUFFMUQseUJBVU8sWUFBWSxDQUFDLENBQUE7QUFFcEIscUJBQTJCLFFBQVEsQ0FBQyxDQUFBO0FBQ3BDLDRCQUEyQyxlQUFlLENBQUMsQ0FBQTtBQUUzRCxnQ0FBMEQsbUJBQW1CLENBQUMsQ0FBQTtBQUU5RSxvQkFBb0I7QUFDcEIsbUJBQW1CO0FBQ25CLG1CQUFtQjtBQUNuQixxQkFBcUI7QUFDckIsa0JBQWtCO0FBQ2xCLHNCQUFzQjtBQUN0Qiw2REFBNkQ7QUFDN0QsbUNBQW1DO0FBQ25DLGlDQUFpQztB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