angular2
Version:
Angular 2 - a web framework for modern web apps
150 lines (149 loc) • 7.32 kB
JavaScript
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);
};
import { CompileDirectiveMetadata, CompileTemplateMetadata } from './compile_metadata';
import { isPresent } from 'angular2/src/facade/lang';
import { BaseException } from 'angular2/src/facade/exceptions';
import { PromiseWrapper } from 'angular2/src/facade/async';
import { XHR } from 'angular2/src/compiler/xhr';
import { UrlResolver } from 'angular2/src/compiler/url_resolver';
import { extractStyleUrls, isStyleUrlResolvable } from './style_url_resolver';
import { Injectable } from 'angular2/src/core/di';
import { ViewEncapsulation } from 'angular2/src/core/metadata/view';
import { HtmlTextAst, htmlVisitAll } from './html_ast';
import { HtmlParser } from './html_parser';
import { preparseElement, PreparsedElementType } from './template_preparser';
export let DirectiveNormalizer = class DirectiveNormalizer {
constructor(_xhr, _urlResolver, _htmlParser) {
this._xhr = _xhr;
this._urlResolver = _urlResolver;
this._htmlParser = _htmlParser;
}
normalizeDirective(directive) {
if (!directive.isComponent) {
// For non components there is nothing to be normalized yet.
return PromiseWrapper.resolve(directive);
}
return this.normalizeTemplate(directive.type, directive.template)
.then((normalizedTemplate) => new CompileDirectiveMetadata({
type: directive.type,
isComponent: directive.isComponent,
selector: directive.selector,
exportAs: directive.exportAs,
changeDetection: directive.changeDetection,
inputs: directive.inputs,
outputs: directive.outputs,
hostListeners: directive.hostListeners,
hostProperties: directive.hostProperties,
hostAttributes: directive.hostAttributes,
lifecycleHooks: directive.lifecycleHooks,
providers: directive.providers,
viewProviders: directive.viewProviders,
queries: directive.queries,
viewQueries: directive.viewQueries,
template: normalizedTemplate
}));
}
normalizeTemplate(directiveType, template) {
if (isPresent(template.template)) {
return PromiseWrapper.resolve(this.normalizeLoadedTemplate(directiveType, template, template.template, directiveType.moduleUrl));
}
else if (isPresent(template.templateUrl)) {
var sourceAbsUrl = this._urlResolver.resolve(directiveType.moduleUrl, template.templateUrl);
return this._xhr.get(sourceAbsUrl)
.then(templateContent => this.normalizeLoadedTemplate(directiveType, template, templateContent, sourceAbsUrl));
}
else {
throw new BaseException(`No template specified for component ${directiveType.name}`);
}
}
normalizeLoadedTemplate(directiveType, templateMeta, template, templateAbsUrl) {
var rootNodesAndErrors = this._htmlParser.parse(template, directiveType.name);
if (rootNodesAndErrors.errors.length > 0) {
var errorString = rootNodesAndErrors.errors.join('\n');
throw new BaseException(`Template parse errors:\n${errorString}`);
}
var visitor = new TemplatePreparseVisitor();
htmlVisitAll(visitor, rootNodesAndErrors.rootNodes);
var allStyles = templateMeta.styles.concat(visitor.styles);
var allStyleAbsUrls = visitor.styleUrls.filter(isStyleUrlResolvable)
.map(url => this._urlResolver.resolve(templateAbsUrl, url))
.concat(templateMeta.styleUrls.filter(isStyleUrlResolvable)
.map(url => this._urlResolver.resolve(directiveType.moduleUrl, url)));
var allResolvedStyles = allStyles.map(style => {
var styleWithImports = extractStyleUrls(this._urlResolver, templateAbsUrl, style);
styleWithImports.styleUrls.forEach(styleUrl => allStyleAbsUrls.push(styleUrl));
return styleWithImports.style;
});
var encapsulation = templateMeta.encapsulation;
if (encapsulation === ViewEncapsulation.Emulated && allResolvedStyles.length === 0 &&
allStyleAbsUrls.length === 0) {
encapsulation = ViewEncapsulation.None;
}
return new CompileTemplateMetadata({
encapsulation: encapsulation,
template: template,
templateUrl: templateAbsUrl,
styles: allResolvedStyles,
styleUrls: allStyleAbsUrls,
ngContentSelectors: visitor.ngContentSelectors
});
}
};
DirectiveNormalizer = __decorate([
Injectable(),
__metadata('design:paramtypes', [XHR, UrlResolver, HtmlParser])
], DirectiveNormalizer);
class TemplatePreparseVisitor {
constructor() {
this.ngContentSelectors = [];
this.styles = [];
this.styleUrls = [];
this.ngNonBindableStackCount = 0;
}
visitElement(ast, context) {
var preparsedElement = preparseElement(ast);
switch (preparsedElement.type) {
case PreparsedElementType.NG_CONTENT:
if (this.ngNonBindableStackCount === 0) {
this.ngContentSelectors.push(preparsedElement.selectAttr);
}
break;
case PreparsedElementType.STYLE:
var textContent = '';
ast.children.forEach(child => {
if (child instanceof HtmlTextAst) {
textContent += child.value;
}
});
this.styles.push(textContent);
break;
case PreparsedElementType.STYLESHEET:
this.styleUrls.push(preparsedElement.hrefAttr);
break;
default:
// DDC reports this as error. See:
// https://github.com/dart-lang/dev_compiler/issues/428
break;
}
if (preparsedElement.nonBindable) {
this.ngNonBindableStackCount++;
}
htmlVisitAll(this, ast.children);
if (preparsedElement.nonBindable) {
this.ngNonBindableStackCount--;
}
return null;
}
visitComment(ast, context) { return null; }
visitAttr(ast, context) { return null; }
visitText(ast, context) { return null; }
visitExpansion(ast, context) { return null; }
visitExpansionCase(ast, context) { return null; }
}