@ -2,34 +2,10 @@ import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
import {reflector} from 'angular2/src/core/reflection/reflection';
|
||||
|
||||
import {
|
||||
DirectiveIndex,
|
||||
BindingRecord,
|
||||
DirectiveRecord,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorDefinition,
|
||||
ChangeDetectorGenConfig,
|
||||
ASTWithSource
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {DirectiveIndex, BindingRecord, DirectiveRecord, ChangeDetectionStrategy, ChangeDetectorDefinition, ChangeDetectorGenConfig, ASTWithSource} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
import {CompileDirectiveMetadata, CompileTypeMetadata} from './directive_metadata';
|
||||
import {
|
||||
TemplateAst,
|
||||
ElementAst,
|
||||
BoundTextAst,
|
||||
PropertyBindingType,
|
||||
DirectiveAst,
|
||||
TemplateAstVisitor,
|
||||
templateVisitAll,
|
||||
NgContentAst,
|
||||
EmbeddedTemplateAst,
|
||||
VariableAst,
|
||||
BoundElementPropertyAst,
|
||||
BoundEventAst,
|
||||
BoundDirectivePropertyAst,
|
||||
AttrAst,
|
||||
TextAst
|
||||
} from './template_ast';
|
||||
import {TemplateAst, ElementAst, BoundTextAst, PropertyBindingType, DirectiveAst, TemplateAstVisitor, templateVisitAll, NgContentAst, EmbeddedTemplateAst, VariableAst, BoundElementPropertyAst, BoundEventAst, BoundDirectivePropertyAst, AttrAst, TextAst} from './template_ast';
|
||||
import {LifecycleHooks} from 'angular2/src/core/linker/interfaces';
|
||||
|
||||
export function createChangeDetectorDefinitions(
|
||||
@ -50,8 +26,9 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
||||
eventRecords: BindingRecord[] = [];
|
||||
directiveRecords: DirectiveRecord[] = [];
|
||||
|
||||
constructor(public parent: ProtoViewVisitor, public allVisitors: ProtoViewVisitor[],
|
||||
public strategy: ChangeDetectionStrategy) {
|
||||
constructor(
|
||||
public parent: ProtoViewVisitor, public allVisitors: ProtoViewVisitor[],
|
||||
public strategy: ChangeDetectionStrategy) {
|
||||
this.viewIndex = allVisitors.length;
|
||||
allVisitors.push(this);
|
||||
}
|
||||
@ -96,10 +73,9 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
||||
}
|
||||
|
||||
visitEvent(ast: BoundEventAst, directiveRecord: DirectiveRecord): any {
|
||||
var bindingRecord =
|
||||
isPresent(directiveRecord) ?
|
||||
BindingRecord.createForHostEvent(ast.handler, ast.fullName, directiveRecord) :
|
||||
BindingRecord.createForEvent(ast.handler, ast.fullName, this.boundElementCount - 1);
|
||||
var bindingRecord = isPresent(directiveRecord) ?
|
||||
BindingRecord.createForHostEvent(ast.handler, ast.fullName, directiveRecord) :
|
||||
BindingRecord.createForEvent(ast.handler, ast.fullName, this.boundElementCount - 1);
|
||||
this.eventRecords.push(bindingRecord);
|
||||
return null;
|
||||
}
|
||||
@ -109,25 +85,21 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
||||
var dirIndex = isPresent(directiveRecord) ? directiveRecord.directiveIndex : null;
|
||||
var bindingRecord;
|
||||
if (ast.type === PropertyBindingType.Property) {
|
||||
bindingRecord =
|
||||
isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostProperty(dirIndex, ast.value, ast.name) :
|
||||
BindingRecord.createForElementProperty(ast.value, boundElementIndex, ast.name);
|
||||
bindingRecord = isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostProperty(dirIndex, ast.value, ast.name) :
|
||||
BindingRecord.createForElementProperty(ast.value, boundElementIndex, ast.name);
|
||||
} else if (ast.type === PropertyBindingType.Attribute) {
|
||||
bindingRecord =
|
||||
isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostAttribute(dirIndex, ast.value, ast.name) :
|
||||
BindingRecord.createForElementAttribute(ast.value, boundElementIndex, ast.name);
|
||||
bindingRecord = isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostAttribute(dirIndex, ast.value, ast.name) :
|
||||
BindingRecord.createForElementAttribute(ast.value, boundElementIndex, ast.name);
|
||||
} else if (ast.type === PropertyBindingType.Class) {
|
||||
bindingRecord =
|
||||
isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostClass(dirIndex, ast.value, ast.name) :
|
||||
BindingRecord.createForElementClass(ast.value, boundElementIndex, ast.name);
|
||||
bindingRecord = isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostClass(dirIndex, ast.value, ast.name) :
|
||||
BindingRecord.createForElementClass(ast.value, boundElementIndex, ast.name);
|
||||
} else if (ast.type === PropertyBindingType.Style) {
|
||||
bindingRecord =
|
||||
isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostStyle(dirIndex, ast.value, ast.name, ast.unit) :
|
||||
BindingRecord.createForElementStyle(ast.value, boundElementIndex, ast.name, ast.unit);
|
||||
bindingRecord = isPresent(dirIndex) ?
|
||||
BindingRecord.createForHostStyle(dirIndex, ast.value, ast.name, ast.unit) :
|
||||
BindingRecord.createForElementStyle(ast.value, boundElementIndex, ast.name, ast.unit);
|
||||
}
|
||||
this.bindingRecords.push(bindingRecord);
|
||||
return null;
|
||||
@ -195,8 +167,9 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
||||
}
|
||||
|
||||
|
||||
function createChangeDefinitions(pvVisitors: ProtoViewVisitor[], componentType: CompileTypeMetadata,
|
||||
genConfig: ChangeDetectorGenConfig): ChangeDetectorDefinition[] {
|
||||
function createChangeDefinitions(
|
||||
pvVisitors: ProtoViewVisitor[], componentType: CompileTypeMetadata,
|
||||
genConfig: ChangeDetectorGenConfig): ChangeDetectorDefinition[] {
|
||||
var pvVariableNames = _collectNestedProtoViewsVariableNames(pvVisitors);
|
||||
return pvVisitors.map(pvVisitor => {
|
||||
var id = `${componentType.name}_${pvVisitor.viewIndex}`;
|
||||
|
@ -1,8 +1,6 @@
|
||||
import {CompileTypeMetadata} from './directive_metadata';
|
||||
import {SourceExpressions, moduleRef} from './source_module';
|
||||
import {
|
||||
ChangeDetectorJITGenerator
|
||||
} from 'angular2/src/core/change_detection/change_detection_jit_generator';
|
||||
import {ChangeDetectorJITGenerator} from 'angular2/src/core/change_detection/change_detection_jit_generator';
|
||||
import {AbstractChangeDetector} from 'angular2/src/core/change_detection/abstract_change_detector';
|
||||
import {ChangeDetectionUtil} from 'angular2/src/core/change_detection/change_detection_util';
|
||||
import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants';
|
||||
@ -10,21 +8,16 @@ import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants'
|
||||
import {createChangeDetectorDefinitions} from './change_definition_factory';
|
||||
import {IS_DART, isJsObject, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {
|
||||
ChangeDetectorGenConfig,
|
||||
ChangeDetectorDefinition,
|
||||
DynamicProtoChangeDetector,
|
||||
ChangeDetectionStrategy
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {ChangeDetectorGenConfig, ChangeDetectorDefinition, DynamicProtoChangeDetector, ChangeDetectionStrategy} from 'angular2/src/core/change_detection/change_detection';
|
||||
|
||||
import {TemplateAst} from './template_ast';
|
||||
import {Codegen} from 'angular2/src/transform/template_compiler/change_detector_codegen';
|
||||
import {MODULE_SUFFIX} from './util';
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
|
||||
const ABSTRACT_CHANGE_DETECTOR = "AbstractChangeDetector";
|
||||
const UTIL = "ChangeDetectionUtil";
|
||||
const CHANGE_DETECTOR_STATE = "ChangeDetectorState";
|
||||
const ABSTRACT_CHANGE_DETECTOR = 'AbstractChangeDetector';
|
||||
const UTIL = 'ChangeDetectionUtil';
|
||||
const CHANGE_DETECTOR_STATE = 'ChangeDetectorState';
|
||||
|
||||
export const CHANGE_DETECTION_JIT_IMPORTS = CONST_EXPR({
|
||||
'AbstractChangeDetector': AbstractChangeDetector,
|
||||
@ -45,12 +38,13 @@ var CONSTANTS_MODULE =
|
||||
export class ChangeDetectionCompiler {
|
||||
constructor(private _genConfig: ChangeDetectorGenConfig) {}
|
||||
|
||||
compileComponentRuntime(componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
||||
parsedTemplate: TemplateAst[]): Function[] {
|
||||
compileComponentRuntime(
|
||||
componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
||||
parsedTemplate: TemplateAst[]): Function[] {
|
||||
var changeDetectorDefinitions =
|
||||
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||
return changeDetectorDefinitions.map(definition =>
|
||||
this._createChangeDetectorFactory(definition));
|
||||
return changeDetectorDefinitions.map(
|
||||
definition => this._createChangeDetectorFactory(definition));
|
||||
}
|
||||
|
||||
private _createChangeDetectorFactory(definition: ChangeDetectorDefinition): Function {
|
||||
@ -58,8 +52,9 @@ export class ChangeDetectionCompiler {
|
||||
return () => proto.instantiate();
|
||||
}
|
||||
|
||||
compileComponentCodeGen(componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
||||
parsedTemplate: TemplateAst[]): SourceExpressions {
|
||||
compileComponentCodeGen(
|
||||
componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
||||
parsedTemplate: TemplateAst[]): SourceExpressions {
|
||||
var changeDetectorDefinitions =
|
||||
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||
var factories = [];
|
||||
@ -74,8 +69,8 @@ export class ChangeDetectionCompiler {
|
||||
codegen = new Codegen(PREGEN_PROTO_CHANGE_DETECTOR_MODULE);
|
||||
var className = `_${definition.id}`;
|
||||
var typeRef = (index === 0 && componentType.isHost) ?
|
||||
'dynamic' :
|
||||
`${moduleRef(componentType.moduleUrl)}${componentType.name}`;
|
||||
'dynamic' :
|
||||
`${moduleRef(componentType.moduleUrl)}${componentType.name}`;
|
||||
codegen.generate(typeRef, className, definition);
|
||||
factories.push(`${className}.newChangeDetector`);
|
||||
sourcePart = codegen.toString();
|
||||
|
@ -1,10 +1,6 @@
|
||||
import {RuntimeCompiler_} from "./runtime_compiler";
|
||||
import {RuntimeCompiler_} from './runtime_compiler';
|
||||
export {TemplateCompiler} from './template_compiler';
|
||||
export {
|
||||
CompileDirectiveMetadata,
|
||||
CompileTypeMetadata,
|
||||
CompileTemplateMetadata
|
||||
} from './directive_metadata';
|
||||
export {CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata} from './directive_metadata';
|
||||
export {SourceModule, SourceWithImports} from './source_module';
|
||||
export {PLATFORM_DIRECTIVES, PLATFORM_PIPES} from 'angular2/src/core/platform_directives_and_pipes';
|
||||
export * from 'angular2/src/compiler/template_ast';
|
||||
@ -36,23 +32,12 @@ function _createChangeDetectorGenConfig() {
|
||||
* A set of providers that provide `RuntimeCompiler` and its dependencies to use for
|
||||
* template compilation.
|
||||
*/
|
||||
export const COMPILER_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
||||
Lexer,
|
||||
Parser,
|
||||
HtmlParser,
|
||||
TemplateParser,
|
||||
TemplateNormalizer,
|
||||
RuntimeMetadataResolver,
|
||||
DEFAULT_PACKAGE_URL_PROVIDER,
|
||||
StyleCompiler,
|
||||
ProtoViewCompiler,
|
||||
ViewCompiler,
|
||||
export const COMPILER_PROVIDERS: Array<Type|Provider|any[]> = CONST_EXPR([
|
||||
Lexer, Parser, HtmlParser, TemplateParser, TemplateNormalizer, RuntimeMetadataResolver,
|
||||
DEFAULT_PACKAGE_URL_PROVIDER, StyleCompiler, ProtoViewCompiler, ViewCompiler,
|
||||
ChangeDetectionCompiler,
|
||||
new Provider(ChangeDetectorGenConfig, {useFactory: _createChangeDetectorGenConfig, deps: []}),
|
||||
TemplateCompiler,
|
||||
new Provider(RuntimeCompiler, {useClass: RuntimeCompiler_}),
|
||||
new Provider(Compiler, {useExisting: RuntimeCompiler}),
|
||||
DomElementSchemaRegistry,
|
||||
new Provider(ElementSchemaRegistry, {useExisting: DomElementSchemaRegistry}),
|
||||
UrlResolver
|
||||
TemplateCompiler, new Provider(RuntimeCompiler, {useClass: RuntimeCompiler_}),
|
||||
new Provider(Compiler, {useExisting: RuntimeCompiler}), DomElementSchemaRegistry,
|
||||
new Provider(ElementSchemaRegistry, {useExisting: DomElementSchemaRegistry}), UrlResolver
|
||||
]);
|
||||
|
@ -1,65 +1,9 @@
|
||||
import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from "angular2/src/facade/lang";
|
||||
import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
import {
|
||||
isWhitespace,
|
||||
$EOF,
|
||||
$HASH,
|
||||
$TILDA,
|
||||
$CARET,
|
||||
$PERCENT,
|
||||
$$,
|
||||
$_,
|
||||
$COLON,
|
||||
$SQ,
|
||||
$DQ,
|
||||
$EQ,
|
||||
$SLASH,
|
||||
$BACKSLASH,
|
||||
$PERIOD,
|
||||
$STAR,
|
||||
$PLUS,
|
||||
$LPAREN,
|
||||
$RPAREN,
|
||||
$LBRACE,
|
||||
$RBRACE,
|
||||
$LBRACKET,
|
||||
$RBRACKET,
|
||||
$PIPE,
|
||||
$COMMA,
|
||||
$SEMICOLON,
|
||||
$MINUS,
|
||||
$BANG,
|
||||
$QUESTION,
|
||||
$AT,
|
||||
$AMPERSAND,
|
||||
$GT,
|
||||
$a,
|
||||
$A,
|
||||
$z,
|
||||
$Z,
|
||||
$0,
|
||||
$9,
|
||||
$FF,
|
||||
$CR,
|
||||
$LF,
|
||||
$VTAB
|
||||
} from "angular2/src/compiler/chars";
|
||||
import {isWhitespace, $EOF, $HASH, $TILDA, $CARET, $PERCENT, $$, $_, $COLON, $SQ, $DQ, $EQ, $SLASH, $BACKSLASH, $PERIOD, $STAR, $PLUS, $LPAREN, $RPAREN, $LBRACE, $RBRACE, $LBRACKET, $RBRACKET, $PIPE, $COMMA, $SEMICOLON, $MINUS, $BANG, $QUESTION, $AT, $AMPERSAND, $GT, $a, $A, $z, $Z, $0, $9, $FF, $CR, $LF, $VTAB} from 'angular2/src/compiler/chars';
|
||||
|
||||
export {
|
||||
$EOF,
|
||||
$AT,
|
||||
$RBRACE,
|
||||
$LBRACE,
|
||||
$LBRACKET,
|
||||
$RBRACKET,
|
||||
$LPAREN,
|
||||
$RPAREN,
|
||||
$COMMA,
|
||||
$COLON,
|
||||
$SEMICOLON,
|
||||
isWhitespace
|
||||
} from "angular2/src/compiler/chars";
|
||||
export {$EOF, $AT, $RBRACE, $LBRACE, $LBRACKET, $RBRACKET, $LPAREN, $RPAREN, $COMMA, $COLON, $SEMICOLON, isWhitespace} from 'angular2/src/compiler/chars';
|
||||
|
||||
export enum CssTokenType {
|
||||
EOF,
|
||||
@ -94,35 +38,37 @@ export class LexedCssResult {
|
||||
constructor(public error: CssScannerError, public token: CssToken) {}
|
||||
}
|
||||
|
||||
export function generateErrorMessage(input: string, message: string, errorValue: string,
|
||||
index: number, row: number, column: number): string {
|
||||
export function generateErrorMessage(
|
||||
input: string, message: string, errorValue: string, index: number, row: number,
|
||||
column: number): string {
|
||||
return `${message} at column ${row}:${column} in expression [` +
|
||||
findProblemCode(input, errorValue, index, column) + ']';
|
||||
findProblemCode(input, errorValue, index, column) + ']';
|
||||
}
|
||||
|
||||
export function findProblemCode(input: string, errorValue: string, index: number,
|
||||
column: number): string {
|
||||
export function findProblemCode(
|
||||
input: string, errorValue: string, index: number, column: number): string {
|
||||
var endOfProblemLine = index;
|
||||
var current = charCode(input, index);
|
||||
while (current > 0 && !isNewline(current)) {
|
||||
current = charCode(input, ++endOfProblemLine);
|
||||
}
|
||||
var choppedString = input.substring(0, endOfProblemLine);
|
||||
var pointerPadding = "";
|
||||
var pointerPadding = '';
|
||||
for (var i = 0; i < column; i++) {
|
||||
pointerPadding += " ";
|
||||
pointerPadding += ' ';
|
||||
}
|
||||
var pointerString = "";
|
||||
var pointerString = '';
|
||||
for (var i = 0; i < errorValue.length; i++) {
|
||||
pointerString += "^";
|
||||
pointerString += '^';
|
||||
}
|
||||
return choppedString + "\n" + pointerPadding + pointerString + "\n";
|
||||
return choppedString + '\n' + pointerPadding + pointerString + '\n';
|
||||
}
|
||||
|
||||
export class CssToken {
|
||||
numValue: number;
|
||||
constructor(public index: number, public column: number, public line: number,
|
||||
public type: CssTokenType, public strValue: string) {
|
||||
constructor(
|
||||
public index: number, public column: number, public line: number, public type: CssTokenType,
|
||||
public strValue: string) {
|
||||
this.numValue = charCode(strValue, 0);
|
||||
}
|
||||
}
|
||||
@ -248,7 +194,7 @@ export class CssScanner {
|
||||
|
||||
var next = output.token;
|
||||
if (!isPresent(next)) {
|
||||
next = new CssToken(0, 0, 0, CssTokenType.EOF, "end of file");
|
||||
next = new CssToken(0, 0, 0, CssTokenType.EOF, 'end of file');
|
||||
}
|
||||
|
||||
var isMatchingType;
|
||||
@ -265,16 +211,17 @@ export class CssScanner {
|
||||
|
||||
var error = null;
|
||||
if (!isMatchingType || (isPresent(value) && value != next.strValue)) {
|
||||
var errorMessage = resolveEnumToken(CssTokenType, next.type) + " does not match expected " +
|
||||
resolveEnumToken(CssTokenType, type) + " value";
|
||||
var errorMessage = resolveEnumToken(CssTokenType, next.type) + ' does not match expected ' +
|
||||
resolveEnumToken(CssTokenType, type) + ' value';
|
||||
|
||||
if (isPresent(value)) {
|
||||
errorMessage += ' ("' + next.strValue + '" should match "' + value + '")';
|
||||
}
|
||||
|
||||
error = new CssScannerError(
|
||||
next, generateErrorMessage(this.input, errorMessage, next.strValue, previousIndex,
|
||||
previousLine, previousColumn));
|
||||
next, generateErrorMessage(
|
||||
this.input, errorMessage, next.strValue, previousIndex, previousLine,
|
||||
previousColumn));
|
||||
}
|
||||
|
||||
return new LexedCssResult(error, next);
|
||||
@ -354,8 +301,8 @@ export class CssScanner {
|
||||
}
|
||||
|
||||
scanComment(): CssToken {
|
||||
if (this.assertCondition(isCommentStart(this.peek, this.peekPeek),
|
||||
"Expected comment start value")) {
|
||||
if (this.assertCondition(
|
||||
isCommentStart(this.peek, this.peekPeek), 'Expected comment start value')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -392,8 +339,8 @@ export class CssScanner {
|
||||
}
|
||||
|
||||
scanString(): CssToken {
|
||||
if (this.assertCondition(isStringStart(this.peek, this.peekPeek),
|
||||
"Unexpected non-string starting value")) {
|
||||
if (this.assertCondition(
|
||||
isStringStart(this.peek, this.peekPeek), 'Unexpected non-string starting value')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -412,7 +359,7 @@ export class CssScanner {
|
||||
this.advance();
|
||||
}
|
||||
|
||||
if (this.assertCondition(this.peek == target, "Unterminated quote")) {
|
||||
if (this.assertCondition(this.peek == target, 'Unterminated quote')) {
|
||||
return null;
|
||||
}
|
||||
this.advance();
|
||||
@ -442,8 +389,8 @@ export class CssScanner {
|
||||
}
|
||||
|
||||
scanIdentifier(): CssToken {
|
||||
if (this.assertCondition(isIdentifierStart(this.peek, this.peekPeek),
|
||||
'Expected identifier starting value')) {
|
||||
if (this.assertCondition(
|
||||
isIdentifierStart(this.peek, this.peekPeek), 'Expected identifier starting value')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -469,8 +416,9 @@ export class CssScanner {
|
||||
scanCharacter(): CssToken {
|
||||
var start = this.index;
|
||||
var startingColumn = this.column;
|
||||
if (this.assertCondition(isValidCssCharacter(this.peek, this._currentMode),
|
||||
charStr(this.peek) + ' is not a valid CSS character')) {
|
||||
if (this.assertCondition(
|
||||
isValidCssCharacter(this.peek, this._currentMode),
|
||||
charStr(this.peek) + ' is not a valid CSS character')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -557,12 +505,12 @@ function isIdentifierStart(code: number, next: number): boolean {
|
||||
}
|
||||
|
||||
return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH ||
|
||||
target == $MINUS || target == $_;
|
||||
target == $MINUS || target == $_;
|
||||
}
|
||||
|
||||
function isIdentifierPart(target: number): boolean {
|
||||
return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH ||
|
||||
target == $MINUS || target == $_ || isDigit(target);
|
||||
target == $MINUS || target == $_ || isDigit(target);
|
||||
}
|
||||
|
||||
function isValidPseudoSelectorCharacter(code: number): boolean {
|
||||
|
@ -1,40 +1,10 @@
|
||||
import {
|
||||
ParseSourceSpan,
|
||||
ParseSourceFile,
|
||||
ParseLocation,
|
||||
ParseError
|
||||
} from "angular2/src/compiler/parse_util";
|
||||
import {ParseSourceSpan, ParseSourceFile, ParseLocation, ParseError} from 'angular2/src/compiler/parse_util';
|
||||
|
||||
import {
|
||||
bitWiseOr,
|
||||
bitWiseAnd,
|
||||
NumberWrapper,
|
||||
StringWrapper,
|
||||
isPresent
|
||||
} from "angular2/src/facade/lang";
|
||||
import {bitWiseOr, bitWiseAnd, NumberWrapper, StringWrapper, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {
|
||||
CssLexerMode,
|
||||
CssToken,
|
||||
CssTokenType,
|
||||
CssScanner,
|
||||
CssScannerError,
|
||||
generateErrorMessage,
|
||||
$AT,
|
||||
$EOF,
|
||||
$RBRACE,
|
||||
$LBRACE,
|
||||
$LBRACKET,
|
||||
$RBRACKET,
|
||||
$LPAREN,
|
||||
$RPAREN,
|
||||
$COMMA,
|
||||
$COLON,
|
||||
$SEMICOLON,
|
||||
isNewline
|
||||
} from "angular2/src/compiler/css/lexer";
|
||||
import {CssLexerMode, CssToken, CssTokenType, CssScanner, CssScannerError, generateErrorMessage, $AT, $EOF, $RBRACE, $LBRACE, $LBRACKET, $RBRACKET, $LPAREN, $RPAREN, $COMMA, $COLON, $SEMICOLON, isNewline} from 'angular2/src/compiler/css/lexer';
|
||||
|
||||
export {CssToken} from "angular2/src/compiler/css/lexer";
|
||||
export {CssToken} from 'angular2/src/compiler/css/lexer';
|
||||
|
||||
export enum BlockType {
|
||||
Import,
|
||||
@ -60,7 +30,7 @@ const SEMICOLON_DELIM = 32;
|
||||
const NEWLINE_DELIM = 64;
|
||||
const RPAREN_DELIM = 128;
|
||||
|
||||
function mergeTokens(tokens: CssToken[], separator: string = ""): CssToken {
|
||||
function mergeTokens(tokens: CssToken[], separator: string = ''): CssToken {
|
||||
var mainToken = tokens[0];
|
||||
var str = mainToken.strValue;
|
||||
for (var i = 1; i < tokens.length; i++) {
|
||||
@ -205,8 +175,9 @@ export class CssParser {
|
||||
|
||||
var token = this._scan();
|
||||
|
||||
this._assertCondition(token.type == CssTokenType.AtKeyword,
|
||||
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token);
|
||||
this._assertCondition(
|
||||
token.type == CssTokenType.AtKeyword,
|
||||
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token);
|
||||
|
||||
var block, type = this._resolveBlockType(token);
|
||||
switch (type) {
|
||||
@ -245,11 +216,12 @@ export class CssParser {
|
||||
default:
|
||||
var listOfTokens = [];
|
||||
this._scanner.setMode(CssLexerMode.ALL);
|
||||
this._error(generateErrorMessage(
|
||||
this._scanner.input,
|
||||
`The CSS "at" rule "${token.strValue}" is not allowed to used here`,
|
||||
token.strValue, token.index, token.line, token.column),
|
||||
token);
|
||||
this._error(
|
||||
generateErrorMessage(
|
||||
this._scanner.input,
|
||||
`The CSS "at" rule "${token.strValue}" is not allowed to used here`, token.strValue,
|
||||
token.index, token.line, token.column),
|
||||
token);
|
||||
|
||||
this._collectUntilDelim(bitWiseOr([delimiters, LBRACE_DELIM, SEMICOLON_DELIM]))
|
||||
.forEach((token) => { listOfTokens.push(token); });
|
||||
@ -403,7 +375,7 @@ export class CssParser {
|
||||
// contains an inner selector that needs to be parsed
|
||||
// in isolation
|
||||
if (this._scanner.getMode() == CssLexerMode.PSEUDO_SELECTOR && isPresent(previousToken) &&
|
||||
previousToken.numValue == $COLON && token.strValue == "not" &&
|
||||
previousToken.numValue == $COLON && token.strValue == 'not' &&
|
||||
this._scanner.peek == $LPAREN) {
|
||||
selectorCssTokens.push(token);
|
||||
selectorCssTokens.push(this._consume(CssTokenType.Character, '('));
|
||||
@ -453,7 +425,7 @@ export class CssParser {
|
||||
|
||||
this._scanner.setMode(CssLexerMode.STYLE_VALUE);
|
||||
|
||||
var strValue = "";
|
||||
var strValue = '';
|
||||
var tokens = [];
|
||||
var previous: CssToken;
|
||||
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
|
||||
@ -493,9 +465,9 @@ export class CssParser {
|
||||
this._consume(CssTokenType.Character, ';');
|
||||
} else if (code != $RBRACE) {
|
||||
this._error(
|
||||
generateErrorMessage(this._scanner.input,
|
||||
`The CSS key/value definition did not end with a semicolon`,
|
||||
previous.strValue, previous.index, previous.line, previous.column),
|
||||
generateErrorMessage(
|
||||
this._scanner.input, `The CSS key/value definition did not end with a semicolon`,
|
||||
previous.strValue, previous.index, previous.line, previous.column),
|
||||
previous);
|
||||
}
|
||||
|
||||
@ -592,7 +564,7 @@ export class CssParser {
|
||||
remainingTokens.forEach((token) => { propStr.push(token.strValue); });
|
||||
}
|
||||
|
||||
prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(" "));
|
||||
prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(' '));
|
||||
}
|
||||
|
||||
// this means we've reached the end of the definition and/or block
|
||||
@ -608,10 +580,11 @@ export class CssParser {
|
||||
if (parseValue) {
|
||||
value = this._parseValue(delimiters);
|
||||
} else {
|
||||
this._error(generateErrorMessage(this._scanner.input,
|
||||
`The CSS property was not paired with a style value`,
|
||||
prop.strValue, prop.index, prop.line, prop.column),
|
||||
prop);
|
||||
this._error(
|
||||
generateErrorMessage(
|
||||
this._scanner.input, `The CSS property was not paired with a style value`,
|
||||
prop.strValue, prop.index, prop.line, prop.column),
|
||||
prop);
|
||||
}
|
||||
|
||||
return new CssDefinitionAST(prop, value);
|
||||
@ -629,8 +602,8 @@ export class CssParser {
|
||||
/** @internal */
|
||||
_error(message: string, problemToken: CssToken) {
|
||||
var length = problemToken.strValue.length;
|
||||
var error = CssParseError.create(this._file, 0, problemToken.line, problemToken.column, length,
|
||||
message);
|
||||
var error = CssParseError.create(
|
||||
this._file, 0, problemToken.line, problemToken.column, length, message);
|
||||
this._errors.push(error);
|
||||
}
|
||||
}
|
||||
@ -657,7 +630,7 @@ export class CssKeyframeRuleAST extends CssBlockRuleAST {
|
||||
export class CssKeyframeDefinitionAST extends CssBlockRuleAST {
|
||||
public steps;
|
||||
constructor(_steps: CssToken[], block: CssBlockAST) {
|
||||
super(BlockType.Keyframes, block, mergeTokens(_steps, ","));
|
||||
super(BlockType.Keyframes, block, mergeTokens(_steps, ','));
|
||||
this.steps = _steps;
|
||||
}
|
||||
visit(visitor: CssASTVisitor, context?: any) {
|
||||
@ -669,10 +642,11 @@ export class CssBlockDefinitionRuleAST extends CssBlockRuleAST {
|
||||
public strValue: string;
|
||||
constructor(type: BlockType, public query: CssToken[], block: CssBlockAST) {
|
||||
super(type, block);
|
||||
this.strValue = query.map(token => token.strValue).join("");
|
||||
this.strValue = query.map(token => token.strValue).join('');
|
||||
var firstCssToken: CssToken = query[0];
|
||||
this.name = new CssToken(firstCssToken.index, firstCssToken.column, firstCssToken.line,
|
||||
CssTokenType.Identifier, this.strValue);
|
||||
this.name = new CssToken(
|
||||
firstCssToken.index, firstCssToken.column, firstCssToken.line, CssTokenType.Identifier,
|
||||
this.strValue);
|
||||
}
|
||||
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssBlock(this.block, context); }
|
||||
}
|
||||
@ -692,7 +666,7 @@ export class CssSelectorRuleAST extends CssBlockRuleAST {
|
||||
|
||||
constructor(public selectors: CssSelectorAST[], block: CssBlockAST) {
|
||||
super(BlockType.Selector, block);
|
||||
this.strValue = selectors.map(selector => selector.strValue).join(",");
|
||||
this.strValue = selectors.map(selector => selector.strValue).join(',');
|
||||
}
|
||||
|
||||
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelectorRule(this, context); }
|
||||
@ -707,7 +681,7 @@ export class CssSelectorAST extends CssAST {
|
||||
public strValue;
|
||||
constructor(public tokens: CssToken[], public isComplex: boolean = false) {
|
||||
super();
|
||||
this.strValue = tokens.map(token => token.strValue).join("");
|
||||
this.strValue = tokens.map(token => token.strValue).join('');
|
||||
}
|
||||
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelector(this, context); }
|
||||
}
|
||||
@ -723,12 +697,13 @@ export class CssStyleSheetAST extends CssAST {
|
||||
}
|
||||
|
||||
export class CssParseError extends ParseError {
|
||||
static create(file: ParseSourceFile, offset: number, line: number, col: number, length: number,
|
||||
errMsg: string): CssParseError {
|
||||
static create(
|
||||
file: ParseSourceFile, offset: number, line: number, col: number, length: number,
|
||||
errMsg: string): CssParseError {
|
||||
var start = new ParseLocation(file, offset, line, col);
|
||||
var end = new ParseLocation(file, offset, line, col + length);
|
||||
var span = new ParseSourceSpan(start, end);
|
||||
return new CssParseError(span, "CSS Parse Error: " + errMsg);
|
||||
return new CssParseError(span, 'CSS Parse Error: ' + errMsg);
|
||||
}
|
||||
|
||||
constructor(span: ParseSourceSpan, message: string) { super(span, message); }
|
||||
|
@ -1,23 +1,7 @@
|
||||
import {
|
||||
isPresent,
|
||||
isBlank,
|
||||
isNumber,
|
||||
isBoolean,
|
||||
normalizeBool,
|
||||
normalizeBlank,
|
||||
serializeEnum,
|
||||
Type,
|
||||
isString,
|
||||
RegExpWrapper,
|
||||
StringWrapper,
|
||||
isArray
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {isPresent, isBlank, isNumber, isBoolean, normalizeBool, normalizeBlank, serializeEnum, Type, isString, RegExpWrapper, StringWrapper, isArray} from 'angular2/src/facade/lang';
|
||||
import {unimplemented} from 'angular2/src/facade/exceptions';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
CHANGE_DETECTION_STRATEGY_VALUES
|
||||
} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {ChangeDetectionStrategy, CHANGE_DETECTION_STRATEGY_VALUES} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {ViewEncapsulation, VIEW_ENCAPSULATION_VALUES} from 'angular2/src/core/metadata/view';
|
||||
import {CssSelector} from 'angular2/src/compiler/selector';
|
||||
import {splitAtColon} from './util';
|
||||
@ -105,7 +89,7 @@ export class CompileDiDependencyMetadata {
|
||||
isOptional: boolean;
|
||||
query: CompileQueryMetadata;
|
||||
viewQuery: CompileQueryMetadata;
|
||||
token: CompileIdentifierMetadata | string;
|
||||
token: CompileIdentifierMetadata|string;
|
||||
|
||||
constructor({isAttribute, isSelf, isHost, isSkipSelf, isOptional, query, viewQuery, token}: {
|
||||
isAttribute?: boolean,
|
||||
@ -115,7 +99,7 @@ export class CompileDiDependencyMetadata {
|
||||
isOptional?: boolean,
|
||||
query?: CompileQueryMetadata,
|
||||
viewQuery?: CompileQueryMetadata,
|
||||
token?: CompileIdentifierMetadata | string
|
||||
token?: CompileIdentifierMetadata|string
|
||||
} = {}) {
|
||||
this.isAttribute = normalizeBool(isAttribute);
|
||||
this.isSelf = normalizeBool(isSelf);
|
||||
@ -156,10 +140,10 @@ export class CompileDiDependencyMetadata {
|
||||
}
|
||||
|
||||
export class CompileProviderMetadata {
|
||||
token: CompileIdentifierMetadata | string;
|
||||
token: CompileIdentifierMetadata|string;
|
||||
useClass: CompileTypeMetadata;
|
||||
useValue: any;
|
||||
useExisting: CompileIdentifierMetadata | string;
|
||||
useExisting: CompileIdentifierMetadata|string;
|
||||
useFactory: CompileFactoryMetadata;
|
||||
deps: CompileDiDependencyMetadata[];
|
||||
multi: boolean;
|
||||
@ -168,7 +152,7 @@ export class CompileProviderMetadata {
|
||||
token?: CompileIdentifierMetadata | string,
|
||||
useClass?: CompileTypeMetadata,
|
||||
useValue?: any,
|
||||
useExisting?: CompileIdentifierMetadata | string,
|
||||
useExisting?: CompileIdentifierMetadata|string,
|
||||
useFactory?: CompileFactoryMetadata,
|
||||
deps?: CompileDiDependencyMetadata[],
|
||||
multi?: boolean
|
||||
@ -323,13 +307,13 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
|
||||
}
|
||||
|
||||
export class CompileQueryMetadata {
|
||||
selectors: Array<CompileIdentifierMetadata | string>;
|
||||
selectors: Array<CompileIdentifierMetadata|string>;
|
||||
descendants: boolean;
|
||||
first: boolean;
|
||||
propertyName: string;
|
||||
|
||||
constructor({selectors, descendants, first, propertyName}: {
|
||||
selectors?: Array<CompileIdentifierMetadata | string>,
|
||||
selectors?: Array<CompileIdentifierMetadata|string>,
|
||||
descendants?: boolean,
|
||||
first?: boolean,
|
||||
propertyName?: string
|
||||
@ -389,8 +373,8 @@ export class CompileTemplateMetadata {
|
||||
static fromJson(data: {[key: string]: any}): CompileTemplateMetadata {
|
||||
return new CompileTemplateMetadata({
|
||||
encapsulation: isPresent(data['encapsulation']) ?
|
||||
VIEW_ENCAPSULATION_VALUES[data['encapsulation']] :
|
||||
data['encapsulation'],
|
||||
VIEW_ENCAPSULATION_VALUES[data['encapsulation']] :
|
||||
data['encapsulation'],
|
||||
template: data['template'],
|
||||
templateUrl: data['templateUrl'],
|
||||
styles: data['styles'],
|
||||
@ -401,8 +385,8 @@ export class CompileTemplateMetadata {
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {
|
||||
'encapsulation':
|
||||
isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) : this.encapsulation,
|
||||
'encapsulation': isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) :
|
||||
this.encapsulation,
|
||||
'template': this.template,
|
||||
'templateUrl': this.templateUrl,
|
||||
'styles': this.styles,
|
||||
@ -416,27 +400,27 @@ export class CompileTemplateMetadata {
|
||||
* Metadata regarding compilation of a directive.
|
||||
*/
|
||||
export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
||||
static create({type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs,
|
||||
outputs, host, lifecycleHooks, providers, viewProviders, queries, viewQueries,
|
||||
template}: {
|
||||
type?: CompileTypeMetadata,
|
||||
isComponent?: boolean,
|
||||
dynamicLoadable?: boolean,
|
||||
selector?: string,
|
||||
exportAs?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
inputs?: string[],
|
||||
outputs?: string[],
|
||||
host?: {[key: string]: string},
|
||||
lifecycleHooks?: LifecycleHooks[],
|
||||
providers?:
|
||||
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
|
||||
viewProviders?:
|
||||
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
|
||||
queries?: CompileQueryMetadata[],
|
||||
viewQueries?: CompileQueryMetadata[],
|
||||
template?: CompileTemplateMetadata
|
||||
} = {}): CompileDirectiveMetadata {
|
||||
static create(
|
||||
{type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, outputs,
|
||||
host, lifecycleHooks, providers, viewProviders, queries, viewQueries, template}: {
|
||||
type?: CompileTypeMetadata,
|
||||
isComponent?: boolean,
|
||||
dynamicLoadable?: boolean,
|
||||
selector?: string,
|
||||
exportAs?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
inputs?: string[],
|
||||
outputs?: string[],
|
||||
host?: {[key: string]: string},
|
||||
lifecycleHooks?: LifecycleHooks[],
|
||||
providers?:
|
||||
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
||||
viewProviders?:
|
||||
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
||||
queries?: CompileQueryMetadata[],
|
||||
viewQueries?: CompileQueryMetadata[],
|
||||
template?: CompileTemplateMetadata
|
||||
} = {}): CompileDirectiveMetadata {
|
||||
var hostListeners: {[key: string]: string} = {};
|
||||
var hostProperties: {[key: string]: string} = {};
|
||||
var hostAttributes: {[key: string]: string} = {};
|
||||
@ -503,34 +487,35 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
||||
hostProperties: {[key: string]: string};
|
||||
hostAttributes: {[key: string]: string};
|
||||
lifecycleHooks: LifecycleHooks[];
|
||||
providers: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>;
|
||||
viewProviders: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>;
|
||||
providers: Array<CompileProviderMetadata|CompileTypeMetadata|any[]>;
|
||||
viewProviders: Array<CompileProviderMetadata|CompileTypeMetadata|any[]>;
|
||||
queries: CompileQueryMetadata[];
|
||||
viewQueries: CompileQueryMetadata[];
|
||||
template: CompileTemplateMetadata;
|
||||
constructor({type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs,
|
||||
outputs, hostListeners, hostProperties, hostAttributes, lifecycleHooks, providers,
|
||||
viewProviders, queries, viewQueries, template}: {
|
||||
type?: CompileTypeMetadata,
|
||||
isComponent?: boolean,
|
||||
dynamicLoadable?: boolean,
|
||||
selector?: string,
|
||||
exportAs?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
inputs?: {[key: string]: string},
|
||||
outputs?: {[key: string]: string},
|
||||
hostListeners?: {[key: string]: string},
|
||||
hostProperties?: {[key: string]: string},
|
||||
hostAttributes?: {[key: string]: string},
|
||||
lifecycleHooks?: LifecycleHooks[],
|
||||
providers?:
|
||||
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
|
||||
viewProviders?:
|
||||
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
|
||||
queries?: CompileQueryMetadata[],
|
||||
viewQueries?: CompileQueryMetadata[],
|
||||
template?: CompileTemplateMetadata
|
||||
} = {}) {
|
||||
constructor(
|
||||
{type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, outputs,
|
||||
hostListeners, hostProperties, hostAttributes, lifecycleHooks, providers, viewProviders,
|
||||
queries, viewQueries, template}: {
|
||||
type?: CompileTypeMetadata,
|
||||
isComponent?: boolean,
|
||||
dynamicLoadable?: boolean,
|
||||
selector?: string,
|
||||
exportAs?: string,
|
||||
changeDetection?: ChangeDetectionStrategy,
|
||||
inputs?: {[key: string]: string},
|
||||
outputs?: {[key: string]: string},
|
||||
hostListeners?: {[key: string]: string},
|
||||
hostProperties?: {[key: string]: string},
|
||||
hostAttributes?: {[key: string]: string},
|
||||
lifecycleHooks?: LifecycleHooks[],
|
||||
providers?:
|
||||
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
||||
viewProviders?:
|
||||
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
||||
queries?: CompileQueryMetadata[],
|
||||
viewQueries?: CompileQueryMetadata[],
|
||||
template?: CompileTemplateMetadata
|
||||
} = {}) {
|
||||
this.type = type;
|
||||
this.isComponent = isComponent;
|
||||
this.dynamicLoadable = dynamicLoadable;
|
||||
@ -560,8 +545,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
||||
exportAs: data['exportAs'],
|
||||
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
|
||||
changeDetection: isPresent(data['changeDetection']) ?
|
||||
CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] :
|
||||
data['changeDetection'],
|
||||
CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] :
|
||||
data['changeDetection'],
|
||||
inputs: data['inputs'],
|
||||
outputs: data['outputs'],
|
||||
hostListeners: data['hostListeners'],
|
||||
@ -606,8 +591,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
||||
/**
|
||||
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
|
||||
*/
|
||||
export function createHostComponentMeta(componentType: CompileTypeMetadata,
|
||||
componentSelector: string): CompileDirectiveMetadata {
|
||||
export function createHostComponentMeta(
|
||||
componentType: CompileTypeMetadata, componentSelector: string): CompileDirectiveMetadata {
|
||||
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
|
||||
return CompileDirectiveMetadata.create({
|
||||
type: new CompileTypeMetadata({
|
||||
@ -638,8 +623,9 @@ export class CompilePipeMetadata implements CompileMetadataWithType {
|
||||
type: CompileTypeMetadata;
|
||||
name: string;
|
||||
pure: boolean;
|
||||
constructor({type, name,
|
||||
pure}: {type?: CompileTypeMetadata, name?: string, pure?: boolean} = {}) {
|
||||
constructor({type, name, pure}: {type?: CompileTypeMetadata,
|
||||
name?: string,
|
||||
pure?: boolean} = {}) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.pure = normalizeBool(pure);
|
||||
@ -677,7 +663,7 @@ function arrayFromJson(obj: any[], fn: (a: {[key: string]: any}) => any): any {
|
||||
return isBlank(obj) ? null : obj.map(o => objFromJson(o, fn));
|
||||
}
|
||||
|
||||
function arrayToJson(obj: any[]): string | {[key: string]: any} {
|
||||
function arrayToJson(obj: any[]): string|{[key: string]: any} {
|
||||
return isBlank(obj) ? null : obj.map(objToJson);
|
||||
}
|
||||
|
||||
@ -687,7 +673,7 @@ function objFromJson(obj: any, fn: (a: {[key: string]: any}) => any): any {
|
||||
return fn(obj);
|
||||
}
|
||||
|
||||
function objToJson(obj: any): string | {[key: string]: any} {
|
||||
function objToJson(obj: any): string|{[key: string]: any} {
|
||||
if (isArray(obj)) return arrayToJson(obj);
|
||||
if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj;
|
||||
return obj.toJson();
|
||||
|
@ -18,9 +18,10 @@ export class HtmlAttrAst implements HtmlAst {
|
||||
}
|
||||
|
||||
export class HtmlElementAst implements HtmlAst {
|
||||
constructor(public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[],
|
||||
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
|
||||
public endSourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[],
|
||||
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
|
||||
public endSourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: HtmlAstVisitor, context: any): any { return visitor.visitElement(this, context); }
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,4 @@
|
||||
import {
|
||||
StringWrapper,
|
||||
NumberWrapper,
|
||||
isPresent,
|
||||
isBlank,
|
||||
CONST_EXPR,
|
||||
serializeEnum
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {StringWrapper, NumberWrapper, isPresent, isBlank, CONST_EXPR, serializeEnum} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {ParseLocation, ParseError, ParseSourceFile, ParseSourceSpan} from './parse_util';
|
||||
import {getHtmlTagDefinition, HtmlTagContentType, NAMED_ENTITIES} from './html_tags';
|
||||
@ -29,8 +22,8 @@ export enum HtmlTokenType {
|
||||
}
|
||||
|
||||
export class HtmlToken {
|
||||
constructor(public type: HtmlTokenType, public parts: string[],
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public type: HtmlTokenType, public parts: string[], public sourceSpan: ParseSourceSpan) {}
|
||||
}
|
||||
|
||||
export class HtmlTokenError extends ParseError {
|
||||
@ -191,8 +184,8 @@ class _HtmlTokenizer {
|
||||
if (isBlank(end)) {
|
||||
end = this._getLocation();
|
||||
}
|
||||
var token = new HtmlToken(this.currentTokenType, parts,
|
||||
new ParseSourceSpan(this.currentTokenStart, end));
|
||||
var token = new HtmlToken(
|
||||
this.currentTokenType, parts, new ParseSourceSpan(this.currentTokenStart, end));
|
||||
this.tokens.push(token);
|
||||
this.currentTokenStart = null;
|
||||
this.currentTokenType = null;
|
||||
@ -239,8 +232,8 @@ class _HtmlTokenizer {
|
||||
private _requireCharCode(charCode: number) {
|
||||
var location = this._getLocation();
|
||||
if (!this._attemptCharCode(charCode)) {
|
||||
throw this._createError(unexpectedCharacterErrorMsg(this.peek),
|
||||
this._getSpan(location, location));
|
||||
throw this._createError(
|
||||
unexpectedCharacterErrorMsg(this.peek), this._getSpan(location, location));
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,12 +328,12 @@ class _HtmlTokenizer {
|
||||
}
|
||||
}
|
||||
|
||||
private _consumeRawText(decodeEntities: boolean, firstCharOfEnd: number,
|
||||
attemptEndRest: Function): HtmlToken {
|
||||
private _consumeRawText(
|
||||
decodeEntities: boolean, firstCharOfEnd: number, attemptEndRest: Function): HtmlToken {
|
||||
var tagCloseStart;
|
||||
var textStart = this._getLocation();
|
||||
this._beginToken(decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT,
|
||||
textStart);
|
||||
this._beginToken(
|
||||
decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT, textStart);
|
||||
var parts = [];
|
||||
while (true) {
|
||||
tagCloseStart = this._getLocation();
|
||||
@ -543,7 +536,7 @@ function isWhitespace(code: number): boolean {
|
||||
|
||||
function isNameEnd(code: number): boolean {
|
||||
return isWhitespace(code) || code === $GT || code === $SLASH || code === $SQ || code === $DQ ||
|
||||
code === $EQ;
|
||||
code === $EQ;
|
||||
}
|
||||
|
||||
function isPrefixEnd(code: number): boolean {
|
||||
|
@ -1,13 +1,4 @@
|
||||
import {
|
||||
isPresent,
|
||||
isBlank,
|
||||
StringWrapper,
|
||||
stringify,
|
||||
assertionsEnabled,
|
||||
StringJoiner,
|
||||
serializeEnum,
|
||||
CONST_EXPR
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {isPresent, isBlank, StringWrapper, stringify, assertionsEnabled, StringJoiner, serializeEnum, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
@ -35,8 +26,9 @@ export class HtmlParser {
|
||||
parse(sourceContent: string, sourceUrl: string): HtmlParseTreeResult {
|
||||
var tokensAndErrors = tokenizeHtml(sourceContent, sourceUrl);
|
||||
var treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build();
|
||||
return new HtmlParseTreeResult(treeAndErrors.rootNodes, (<ParseError[]>tokensAndErrors.errors)
|
||||
.concat(treeAndErrors.errors));
|
||||
return new HtmlParseTreeResult(
|
||||
treeAndErrors.rootNodes,
|
||||
(<ParseError[]>tokensAndErrors.errors).concat(treeAndErrors.errors));
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,9 +55,9 @@ class TreeBuilder {
|
||||
} else if (this.peek.type === HtmlTokenType.COMMENT_START) {
|
||||
this._closeVoidElement();
|
||||
this._consumeComment(this._advance());
|
||||
} else if (this.peek.type === HtmlTokenType.TEXT ||
|
||||
this.peek.type === HtmlTokenType.RAW_TEXT ||
|
||||
this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) {
|
||||
} else if (
|
||||
this.peek.type === HtmlTokenType.TEXT || this.peek.type === HtmlTokenType.RAW_TEXT ||
|
||||
this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) {
|
||||
this._closeVoidElement();
|
||||
this._consumeText(this._advance());
|
||||
} else {
|
||||
@ -174,8 +166,8 @@ class TreeBuilder {
|
||||
var tagDef = getHtmlTagDefinition(el.name);
|
||||
var parentEl = this._getParentElement();
|
||||
if (tagDef.requireExtraParent(isPresent(parentEl) ? parentEl.name : null)) {
|
||||
var newParent = new HtmlElementAst(tagDef.parentToAdd, [], [el], el.sourceSpan,
|
||||
el.startSourceSpan, el.endSourceSpan);
|
||||
var newParent = new HtmlElementAst(
|
||||
tagDef.parentToAdd, [], [el], el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
|
||||
this._addToParent(newParent);
|
||||
this.elementStack.push(newParent);
|
||||
this.elementStack.push(el);
|
||||
@ -192,12 +184,12 @@ class TreeBuilder {
|
||||
this._getParentElement().endSourceSpan = endTagToken.sourceSpan;
|
||||
|
||||
if (getHtmlTagDefinition(fullName).isVoid) {
|
||||
this.errors.push(
|
||||
HtmlTreeError.create(fullName, endTagToken.sourceSpan,
|
||||
`Void elements do not have end tags "${endTagToken.parts[1]}"`));
|
||||
this.errors.push(HtmlTreeError.create(
|
||||
fullName, endTagToken.sourceSpan,
|
||||
`Void elements do not have end tags "${endTagToken.parts[1]}"`));
|
||||
} else if (!this._popElement(fullName)) {
|
||||
this.errors.push(HtmlTreeError.create(fullName, endTagToken.sourceSpan,
|
||||
`Unexpected closing tag "${endTagToken.parts[1]}"`));
|
||||
this.errors.push(HtmlTreeError.create(
|
||||
fullName, endTagToken.sourceSpan, `Unexpected closing tag "${endTagToken.parts[1]}"`));
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,8 +234,8 @@ class TreeBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
function getElementFullName(prefix: string, localName: string,
|
||||
parentElement: HtmlElementAst): string {
|
||||
function getElementFullName(
|
||||
prefix: string, localName: string, parentElement: HtmlElementAst): string {
|
||||
if (isBlank(prefix)) {
|
||||
prefix = getHtmlTagDefinition(localName).implicitNamespacePrefix;
|
||||
if (isBlank(prefix) && isPresent(parentElement)) {
|
||||
|
@ -1,10 +1,4 @@
|
||||
import {
|
||||
isPresent,
|
||||
isBlank,
|
||||
normalizeBool,
|
||||
RegExpWrapper,
|
||||
CONST_EXPR
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {isPresent, isBlank, normalizeBool, RegExpWrapper, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
|
||||
// see https://html.spec.whatwg.org/multipage/entities.json
|
||||
@ -281,16 +275,17 @@ export class HtmlTagDefinition {
|
||||
public isVoid: boolean;
|
||||
public ignoreFirstLf: boolean;
|
||||
|
||||
constructor({closedByChildren, requiredParents, implicitNamespacePrefix, contentType,
|
||||
closedByParent, isVoid, ignoreFirstLf}: {
|
||||
closedByChildren?: string[],
|
||||
closedByParent?: boolean,
|
||||
requiredParents?: string[],
|
||||
implicitNamespacePrefix?: string,
|
||||
contentType?: HtmlTagContentType,
|
||||
isVoid?: boolean,
|
||||
ignoreFirstLf?: boolean
|
||||
} = {}) {
|
||||
constructor(
|
||||
{closedByChildren, requiredParents, implicitNamespacePrefix, contentType, closedByParent,
|
||||
isVoid, ignoreFirstLf}: {
|
||||
closedByChildren?: string[],
|
||||
closedByParent?: boolean,
|
||||
requiredParents?: string[],
|
||||
implicitNamespacePrefix?: string,
|
||||
contentType?: HtmlTagContentType,
|
||||
isVoid?: boolean,
|
||||
ignoreFirstLf?: boolean
|
||||
} = {}) {
|
||||
if (isPresent(closedByChildren) && closedByChildren.length > 0) {
|
||||
closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true);
|
||||
}
|
||||
@ -342,32 +337,9 @@ var TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = {
|
||||
'wbr': new HtmlTagDefinition({isVoid: true}),
|
||||
'p': new HtmlTagDefinition({
|
||||
closedByChildren: [
|
||||
'address',
|
||||
'article',
|
||||
'aside',
|
||||
'blockquote',
|
||||
'div',
|
||||
'dl',
|
||||
'fieldset',
|
||||
'footer',
|
||||
'form',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'header',
|
||||
'hgroup',
|
||||
'hr',
|
||||
'main',
|
||||
'nav',
|
||||
'ol',
|
||||
'p',
|
||||
'pre',
|
||||
'section',
|
||||
'table',
|
||||
'ul'
|
||||
'address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', 'footer', 'form',
|
||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr',
|
||||
'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'
|
||||
],
|
||||
closedByParent: true
|
||||
}),
|
||||
|
@ -1,21 +1,8 @@
|
||||
import {Injectable, Provider, provide} from 'angular2/src/core/di';
|
||||
|
||||
import {
|
||||
StringWrapper,
|
||||
RegExpWrapper,
|
||||
CONST_EXPR,
|
||||
isBlank,
|
||||
isPresent
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {StringWrapper, RegExpWrapper, CONST_EXPR, isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {
|
||||
HtmlAstVisitor,
|
||||
HtmlAttrAst,
|
||||
HtmlElementAst,
|
||||
HtmlTextAst,
|
||||
HtmlCommentAst,
|
||||
HtmlAst
|
||||
} from './html_ast';
|
||||
import {HtmlAstVisitor, HtmlAttrAst, HtmlElementAst, HtmlTextAst, HtmlCommentAst, HtmlAst} from './html_ast';
|
||||
import {HtmlParser, HtmlParseTreeResult} from './html_parser';
|
||||
|
||||
import {dashCaseToCamelCase, camelCaseToDashCase} from './util';
|
||||
@ -50,8 +37,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
||||
this.visitingTemplateEl = ast.name.toLowerCase() == 'template';
|
||||
let attrs = ast.attrs.map(attr => attr.visit(this, null));
|
||||
let children = ast.children.map(child => child.visit(this, null));
|
||||
return new HtmlElementAst(ast.name, attrs, children, ast.sourceSpan, ast.startSourceSpan,
|
||||
ast.endSourceSpan);
|
||||
return new HtmlElementAst(
|
||||
ast.name, attrs, children, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
|
||||
}
|
||||
|
||||
visitAttr(originalAst: HtmlAttrAst, context: any): HtmlAttrAst {
|
||||
@ -103,8 +90,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
||||
}
|
||||
|
||||
return attrName == ast.name && attrValue == ast.value ?
|
||||
ast :
|
||||
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
|
||||
ast :
|
||||
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
|
||||
}
|
||||
|
||||
private _rewriteTemplateAttribute(ast: HtmlAttrAst): HtmlAttrAst {
|
||||
@ -115,8 +102,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
||||
name = 'template';
|
||||
|
||||
// rewrite the directive selector
|
||||
value = StringWrapper.replaceAllMapped(value, TEMPLATE_SELECTOR_REGEXP,
|
||||
(m) => { return dashCaseToCamelCase(m[1]); });
|
||||
value = StringWrapper.replaceAllMapped(
|
||||
value, TEMPLATE_SELECTOR_REGEXP, (m) => { return dashCaseToCamelCase(m[1]); });
|
||||
|
||||
// rewrite the var declarations
|
||||
value = StringWrapper.replaceAllMapped(value, VARIABLE_TPL_BINDING_REGEXP, m => {
|
||||
@ -142,8 +129,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
||||
} else if (isPresent(m[2])) {
|
||||
attrName = `[(${dashCaseToCamelCase(m[2])})]`;
|
||||
} else if (isPresent(m[3])) {
|
||||
let prop = StringWrapper.replaceAllMapped(m[3], SPECIAL_PREFIXES_REGEXP,
|
||||
(m) => { return m[1].toLowerCase() + '.'; });
|
||||
let prop = StringWrapper.replaceAllMapped(
|
||||
m[3], SPECIAL_PREFIXES_REGEXP, (m) => { return m[1].toLowerCase() + '.'; });
|
||||
|
||||
if (prop.startsWith('class.') || prop.startsWith('attr.') || prop.startsWith('style.')) {
|
||||
attrName = `[${prop}]`;
|
||||
@ -157,8 +144,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
||||
}
|
||||
|
||||
return attrName == ast.name && attrValue == ast.value ?
|
||||
ast :
|
||||
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
|
||||
ast :
|
||||
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
|
||||
}
|
||||
|
||||
private _rewriteStar(ast: HtmlAttrAst): HtmlAttrAst {
|
||||
@ -174,8 +161,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
||||
}
|
||||
|
||||
return attrName == ast.name && attrValue == ast.value ?
|
||||
ast :
|
||||
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
|
||||
ast :
|
||||
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
|
||||
}
|
||||
|
||||
private _rewriteInterpolation(ast: HtmlAttrAst): HtmlAttrAst {
|
||||
@ -218,7 +205,7 @@ export class LegacyHtmlParser extends HtmlParser {
|
||||
let rootNodes = htmlParseTreeResult.rootNodes.map(node => node.visit(transformer, null));
|
||||
|
||||
return transformer.rewrittenAst.length > 0 ?
|
||||
new HtmlParseTreeResult(rootNodes, htmlParseTreeResult.errors) :
|
||||
htmlParseTreeResult;
|
||||
new HtmlParseTreeResult(rootNodes, htmlParseTreeResult.errors) :
|
||||
htmlParseTreeResult;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
export class ParseLocation {
|
||||
constructor(public file: ParseSourceFile, public offset: number, public line: number,
|
||||
public col: number) {}
|
||||
constructor(
|
||||
public file: ParseSourceFile, public offset: number, public line: number,
|
||||
public col: number) {}
|
||||
|
||||
toString(): string { return `${this.file.url}@${this.line}:${this.col}`; }
|
||||
}
|
||||
@ -33,7 +34,7 @@ export abstract class ParseError {
|
||||
while (ctxLen < 100 && ctxStart > 0) {
|
||||
ctxStart--;
|
||||
ctxLen++;
|
||||
if (source[ctxStart] == "\n") {
|
||||
if (source[ctxStart] == '\n') {
|
||||
if (++ctxLines == 3) {
|
||||
break;
|
||||
}
|
||||
@ -45,7 +46,7 @@ export abstract class ParseError {
|
||||
while (ctxLen < 100 && ctxEnd < source.length - 1) {
|
||||
ctxEnd++;
|
||||
ctxLen++;
|
||||
if (source[ctxEnd] == "\n") {
|
||||
if (source[ctxEnd] == '\n') {
|
||||
if (++ctxLines == 3) {
|
||||
break;
|
||||
}
|
||||
@ -53,7 +54,7 @@ export abstract class ParseError {
|
||||
}
|
||||
|
||||
let context = source.substring(ctxStart, this.span.start.offset) + '[ERROR ->]' +
|
||||
source.substring(this.span.start.offset, ctxEnd + 1);
|
||||
source.substring(this.span.start.offset, ctxEnd + 1);
|
||||
|
||||
return `${this.msg} ("${context}"): ${this.span.start}`;
|
||||
}
|
||||
|
@ -1,54 +1,13 @@
|
||||
import {
|
||||
isPresent,
|
||||
isBlank,
|
||||
Type,
|
||||
isString,
|
||||
StringWrapper,
|
||||
IS_DART,
|
||||
CONST_EXPR
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {
|
||||
SetWrapper,
|
||||
StringMapWrapper,
|
||||
ListWrapper,
|
||||
MapWrapper
|
||||
} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
TemplateAst,
|
||||
TemplateAstVisitor,
|
||||
NgContentAst,
|
||||
EmbeddedTemplateAst,
|
||||
ElementAst,
|
||||
VariableAst,
|
||||
BoundEventAst,
|
||||
BoundElementPropertyAst,
|
||||
AttrAst,
|
||||
BoundTextAst,
|
||||
TextAst,
|
||||
DirectiveAst,
|
||||
BoundDirectivePropertyAst,
|
||||
templateVisitAll
|
||||
} from './template_ast';
|
||||
import {
|
||||
CompileTypeMetadata,
|
||||
CompileDirectiveMetadata,
|
||||
CompilePipeMetadata
|
||||
} from './directive_metadata';
|
||||
import {isPresent, isBlank, Type, isString, StringWrapper, IS_DART, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {SetWrapper, StringMapWrapper, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
|
||||
import {CompileTypeMetadata, CompileDirectiveMetadata, CompilePipeMetadata} from './directive_metadata';
|
||||
import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
|
||||
import {AppProtoView, AppView} from 'angular2/src/core/linker/view';
|
||||
import {ViewType} from 'angular2/src/core/linker/view_type';
|
||||
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
|
||||
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
||||
import {
|
||||
escapeSingleQuoteString,
|
||||
codeGenConstConstructorCall,
|
||||
codeGenValueFn,
|
||||
codeGenFnHeader,
|
||||
MODULE_SUFFIX,
|
||||
codeGenStringMap,
|
||||
Expression,
|
||||
Statement
|
||||
} from './util';
|
||||
import {escapeSingleQuoteString, codeGenConstConstructorCall, codeGenValueFn, codeGenFnHeader, MODULE_SUFFIX, codeGenStringMap, Expression, Statement} from './util';
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
|
||||
export const PROTO_VIEW_JIT_IMPORTS = CONST_EXPR(
|
||||
@ -74,19 +33,20 @@ const STYLE_ATTR = 'style';
|
||||
export class ProtoViewCompiler {
|
||||
constructor() {}
|
||||
|
||||
compileProtoViewRuntime(metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
||||
template: TemplateAst[], pipes: CompilePipeMetadata[]):
|
||||
CompileProtoViews<AppProtoView, AppProtoElement, any> {
|
||||
compileProtoViewRuntime(
|
||||
metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
||||
template: TemplateAst[],
|
||||
pipes: CompilePipeMetadata[]): CompileProtoViews<AppProtoView, AppProtoElement, any> {
|
||||
var protoViewFactory = new RuntimeProtoViewFactory(metadataCache, component, pipes);
|
||||
var allProtoViews = [];
|
||||
protoViewFactory.createCompileProtoView(template, [], [], allProtoViews);
|
||||
return new CompileProtoViews<AppProtoView, AppProtoElement, any>([], allProtoViews);
|
||||
}
|
||||
|
||||
compileProtoViewCodeGen(resolvedMetadataCacheExpr: Expression,
|
||||
component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||
pipes: CompilePipeMetadata[]):
|
||||
CompileProtoViews<Expression, Expression, string> {
|
||||
compileProtoViewCodeGen(
|
||||
resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
|
||||
template: TemplateAst[],
|
||||
pipes: CompilePipeMetadata[]): CompileProtoViews<Expression, Expression, string> {
|
||||
var protoViewFactory = new CodeGenProtoViewFactory(resolvedMetadataCacheExpr, component, pipes);
|
||||
var allProtoViews = [];
|
||||
var allStatements = [];
|
||||
@ -97,26 +57,29 @@ export class ProtoViewCompiler {
|
||||
}
|
||||
|
||||
export class CompileProtoViews<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
||||
constructor(public declarations: STATEMENT[],
|
||||
public protoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
||||
constructor(
|
||||
public declarations: STATEMENT[],
|
||||
public protoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
||||
}
|
||||
|
||||
|
||||
export class CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
|
||||
constructor(public embeddedTemplateIndex: number,
|
||||
public protoElements: CompileProtoElement<APP_PROTO_EL>[],
|
||||
public protoView: APP_PROTO_VIEW) {}
|
||||
constructor(
|
||||
public embeddedTemplateIndex: number,
|
||||
public protoElements: CompileProtoElement<APP_PROTO_EL>[], public protoView: APP_PROTO_VIEW) {
|
||||
}
|
||||
}
|
||||
|
||||
export class CompileProtoElement<APP_PROTO_EL> {
|
||||
constructor(public boundElementIndex, public attrNameAndValues: string[][],
|
||||
public variableNameAndValues: string[][], public renderEvents: BoundEventAst[],
|
||||
public directives: CompileDirectiveMetadata[], public embeddedTemplateIndex: number,
|
||||
public appProtoEl: APP_PROTO_EL) {}
|
||||
constructor(
|
||||
public boundElementIndex, public attrNameAndValues: string[][],
|
||||
public variableNameAndValues: string[][], public renderEvents: BoundEventAst[],
|
||||
public directives: CompileDirectiveMetadata[], public embeddedTemplateIndex: number,
|
||||
public appProtoEl: APP_PROTO_EL) {}
|
||||
}
|
||||
|
||||
function visitAndReturnContext(visitor: TemplateAstVisitor, asts: TemplateAst[],
|
||||
context: any): any {
|
||||
function visitAndReturnContext(
|
||||
visitor: TemplateAstVisitor, asts: TemplateAst[], context: any): any {
|
||||
templateVisitAll(visitor, asts, context);
|
||||
return context;
|
||||
}
|
||||
@ -124,18 +87,17 @@ function visitAndReturnContext(visitor: TemplateAstVisitor, asts: TemplateAst[],
|
||||
abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
||||
constructor(public component: CompileDirectiveMetadata) {}
|
||||
|
||||
abstract createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType,
|
||||
templateVariableBindings: string[][],
|
||||
targetStatements: STATEMENT[]): APP_PROTO_VIEW;
|
||||
abstract createAppProtoView(
|
||||
embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
|
||||
targetStatements: STATEMENT[]): APP_PROTO_VIEW;
|
||||
|
||||
abstract createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][],
|
||||
variableNameAndValues: string[][],
|
||||
directives: CompileDirectiveMetadata[],
|
||||
targetStatements: STATEMENT[]): APP_PROTO_EL;
|
||||
abstract createAppProtoElement(
|
||||
boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
|
||||
directives: CompileDirectiveMetadata[], targetStatements: STATEMENT[]): APP_PROTO_EL;
|
||||
|
||||
createCompileProtoView(template: TemplateAst[], templateVariableBindings: string[][],
|
||||
targetStatements: STATEMENT[],
|
||||
targetProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]):
|
||||
createCompileProtoView(
|
||||
template: TemplateAst[], templateVariableBindings: string[][], targetStatements: STATEMENT[],
|
||||
targetProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]):
|
||||
CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
|
||||
var embeddedTemplateIndex = targetProtoViews.length;
|
||||
// Note: targetProtoViews needs to be in depth first order.
|
||||
@ -145,8 +107,8 @@ abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
||||
this, targetStatements, targetProtoViews);
|
||||
templateVisitAll(builder, template);
|
||||
var viewType = getViewType(this.component, embeddedTemplateIndex);
|
||||
var appProtoView = this.createAppProtoView(embeddedTemplateIndex, viewType,
|
||||
templateVariableBindings, targetStatements);
|
||||
var appProtoView = this.createAppProtoView(
|
||||
embeddedTemplateIndex, viewType, templateVariableBindings, targetStatements);
|
||||
var cpv = new CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>(
|
||||
embeddedTemplateIndex, builder.protoElements, appProtoView);
|
||||
targetProtoViews[embeddedTemplateIndex] = cpv;
|
||||
@ -157,8 +119,9 @@ abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
||||
class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, Statement> {
|
||||
private _nextVarId: number = 0;
|
||||
|
||||
constructor(public resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
|
||||
public pipes: CompilePipeMetadata[]) {
|
||||
constructor(
|
||||
public resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
|
||||
public pipes: CompilePipeMetadata[]) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
@ -166,23 +129,23 @@ class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, S
|
||||
return `appProtoView${this._nextVarId++}_${this.component.type.name}${embeddedTemplateIndex}`;
|
||||
}
|
||||
|
||||
createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType,
|
||||
templateVariableBindings: string[][],
|
||||
targetStatements: Statement[]): Expression {
|
||||
createAppProtoView(
|
||||
embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
|
||||
targetStatements: Statement[]): Expression {
|
||||
var protoViewVarName = this._nextProtoViewVar(embeddedTemplateIndex);
|
||||
var viewTypeExpr = codeGenViewType(viewType);
|
||||
var pipesExpr = embeddedTemplateIndex === 0 ?
|
||||
codeGenTypesArray(this.pipes.map(pipeMeta => pipeMeta.type)) :
|
||||
null;
|
||||
codeGenTypesArray(this.pipes.map(pipeMeta => pipeMeta.type)) :
|
||||
null;
|
||||
var statement =
|
||||
`var ${protoViewVarName} = ${APP_VIEW_MODULE_REF}AppProtoView.create(${this.resolvedMetadataCacheExpr.expression}, ${viewTypeExpr}, ${pipesExpr}, ${codeGenStringMap(templateVariableBindings)});`;
|
||||
targetStatements.push(new Statement(statement));
|
||||
return new Expression(protoViewVarName);
|
||||
}
|
||||
|
||||
createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][],
|
||||
variableNameAndValues: string[][], directives: CompileDirectiveMetadata[],
|
||||
targetStatements: Statement[]): Expression {
|
||||
createAppProtoElement(
|
||||
boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
|
||||
directives: CompileDirectiveMetadata[], targetStatements: Statement[]): Expression {
|
||||
var varName = `appProtoEl${this._nextVarId++}_${this.component.type.name}`;
|
||||
var value = `${APP_EL_MODULE_REF}AppProtoElement.create(
|
||||
${this.resolvedMetadataCacheExpr.expression},
|
||||
@ -198,26 +161,29 @@ class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, S
|
||||
}
|
||||
|
||||
class RuntimeProtoViewFactory extends ProtoViewFactory<AppProtoView, AppProtoElement, any> {
|
||||
constructor(public metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
||||
public pipes: CompilePipeMetadata[]) {
|
||||
constructor(
|
||||
public metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
||||
public pipes: CompilePipeMetadata[]) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType,
|
||||
templateVariableBindings: string[][], targetStatements: any[]): AppProtoView {
|
||||
createAppProtoView(
|
||||
embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
|
||||
targetStatements: any[]): AppProtoView {
|
||||
var pipes =
|
||||
embeddedTemplateIndex === 0 ? this.pipes.map(pipeMeta => pipeMeta.type.runtime) : [];
|
||||
var templateVars = keyValueArrayToStringMap(templateVariableBindings);
|
||||
return AppProtoView.create(this.metadataCache, viewType, pipes, templateVars);
|
||||
}
|
||||
|
||||
createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][],
|
||||
variableNameAndValues: string[][], directives: CompileDirectiveMetadata[],
|
||||
targetStatements: any[]): AppProtoElement {
|
||||
createAppProtoElement(
|
||||
boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
|
||||
directives: CompileDirectiveMetadata[], targetStatements: any[]): AppProtoElement {
|
||||
var attrs = keyValueArrayToStringMap(attrNameAndValues);
|
||||
return AppProtoElement.create(this.metadataCache, boundElementIndex, attrs,
|
||||
directives.map(dirMeta => dirMeta.type.runtime),
|
||||
keyValueArrayToStringMap(variableNameAndValues));
|
||||
return AppProtoElement.create(
|
||||
this.metadataCache, boundElementIndex, attrs,
|
||||
directives.map(dirMeta => dirMeta.type.runtime),
|
||||
keyValueArrayToStringMap(variableNameAndValues));
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,12 +192,13 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
||||
protoElements: CompileProtoElement<APP_PROTO_EL>[] = [];
|
||||
boundElementCount: number = 0;
|
||||
|
||||
constructor(public factory: ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT>,
|
||||
public allStatements: STATEMENT[],
|
||||
public allProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
||||
constructor(
|
||||
public factory: ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT>,
|
||||
public allStatements: STATEMENT[],
|
||||
public allProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
||||
|
||||
private _readAttrNameAndValues(directives: CompileDirectiveMetadata[],
|
||||
attrAsts: TemplateAst[]): string[][] {
|
||||
private _readAttrNameAndValues(directives: CompileDirectiveMetadata[], attrAsts: TemplateAst[]):
|
||||
string[][] {
|
||||
var attrs = visitAndReturnContext(this, attrAsts, {});
|
||||
directives.forEach(directiveMeta => {
|
||||
StringMapWrapper.forEach(directiveMeta.hostAttributes, (value: string, name: string) => {
|
||||
@ -262,15 +229,17 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
||||
var renderEvents: Map<string, BoundEventAst> =
|
||||
visitAndReturnContext(this, ast.outputs, new Map<string, BoundEventAst>());
|
||||
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
|
||||
directiveAst.visit(this, new DirectiveContext(index, boundElementIndex, renderEvents,
|
||||
variableNameAndValues, directives));
|
||||
directiveAst.visit(
|
||||
this, new DirectiveContext(
|
||||
index, boundElementIndex, renderEvents, variableNameAndValues, directives));
|
||||
});
|
||||
var renderEventArray = [];
|
||||
renderEvents.forEach((eventAst, _) => renderEventArray.push(eventAst));
|
||||
|
||||
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
|
||||
this._addProtoElement(ast.isBound(), boundElementIndex, attrNameAndValues,
|
||||
variableNameAndValues, renderEventArray, directives, null);
|
||||
this._addProtoElement(
|
||||
ast.isBound(), boundElementIndex, attrNameAndValues, variableNameAndValues,
|
||||
renderEventArray, directives, null);
|
||||
templateVisitAll(this, ast.children);
|
||||
return null;
|
||||
}
|
||||
@ -280,8 +249,8 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
||||
var directives: CompileDirectiveMetadata[] = [];
|
||||
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
|
||||
directiveAst.visit(
|
||||
this, new DirectiveContext(index, boundElementIndex, new Map<string, BoundEventAst>(), [],
|
||||
directives));
|
||||
this, new DirectiveContext(
|
||||
index, boundElementIndex, new Map<string, BoundEventAst>(), [], directives));
|
||||
});
|
||||
|
||||
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
|
||||
@ -289,19 +258,21 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
||||
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
|
||||
var nestedProtoView = this.factory.createCompileProtoView(
|
||||
ast.children, templateVariableBindings, this.allStatements, this.allProtoViews);
|
||||
this._addProtoElement(true, boundElementIndex, attrNameAndValues, [], [], directives,
|
||||
nestedProtoView.embeddedTemplateIndex);
|
||||
this._addProtoElement(
|
||||
true, boundElementIndex, attrNameAndValues, [], [], directives,
|
||||
nestedProtoView.embeddedTemplateIndex);
|
||||
return null;
|
||||
}
|
||||
|
||||
private _addProtoElement(isBound: boolean, boundElementIndex, attrNameAndValues: string[][],
|
||||
variableNameAndValues: string[][], renderEvents: BoundEventAst[],
|
||||
directives: CompileDirectiveMetadata[], embeddedTemplateIndex: number) {
|
||||
private _addProtoElement(
|
||||
isBound: boolean, boundElementIndex, attrNameAndValues: string[][],
|
||||
variableNameAndValues: string[][], renderEvents: BoundEventAst[],
|
||||
directives: CompileDirectiveMetadata[], embeddedTemplateIndex: number) {
|
||||
var appProtoEl = null;
|
||||
if (isBound) {
|
||||
appProtoEl =
|
||||
this.factory.createAppProtoElement(boundElementIndex, attrNameAndValues,
|
||||
variableNameAndValues, directives, this.allStatements);
|
||||
appProtoEl = this.factory.createAppProtoElement(
|
||||
boundElementIndex, attrNameAndValues, variableNameAndValues, directives,
|
||||
this.allStatements);
|
||||
}
|
||||
var compileProtoEl = new CompileProtoElement<APP_PROTO_EL>(
|
||||
boundElementIndex, attrNameAndValues, variableNameAndValues, renderEvents, directives,
|
||||
@ -317,8 +288,9 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
||||
visitDirective(ast: DirectiveAst, ctx: DirectiveContext): any {
|
||||
ctx.targetDirectives.push(ast.directive);
|
||||
templateVisitAll(this, ast.hostEvents, ctx.hostEventTargetAndNames);
|
||||
ast.exportAsVars.forEach(
|
||||
varAst => { ctx.targetVariableNameAndValues.push([varAst.name, ctx.index]); });
|
||||
ast.exportAsVars.forEach(varAst => {
|
||||
ctx.targetVariableNameAndValues.push([varAst.name, ctx.index]);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
visitEvent(ast: BoundEventAst, eventTargetAndNames: Map<string, BoundEventAst>): any {
|
||||
@ -331,12 +303,14 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
||||
|
||||
function mapToKeyValueArray(data: {[key: string]: string}): string[][] {
|
||||
var entryArray: string[][] = [];
|
||||
StringMapWrapper.forEach(data,
|
||||
(value: string, name: string) => { entryArray.push([name, value]); });
|
||||
StringMapWrapper.forEach(data, (value: string, name: string) => {
|
||||
entryArray.push([name, value]);
|
||||
});
|
||||
// We need to sort to get a defined output order
|
||||
// for tests and for caching generated artifacts...
|
||||
ListWrapper.sort<string[]>(entryArray, (entry1: string[], entry2: string[]) =>
|
||||
StringWrapper.compare(entry1[0], entry2[0]));
|
||||
ListWrapper.sort<string[]>(
|
||||
entryArray,
|
||||
(entry1: string[], entry2: string[]) => StringWrapper.compare(entry1[0], entry2[0]));
|
||||
var keyValueArray: string[][] = [];
|
||||
entryArray.forEach((entry) => { keyValueArray.push([entry[0], entry[1]]); });
|
||||
return keyValueArray;
|
||||
@ -351,10 +325,11 @@ function mergeAttributeValue(attrName: string, attrValue1: string, attrValue2: s
|
||||
}
|
||||
|
||||
class DirectiveContext {
|
||||
constructor(public index: number, public boundElementIndex: number,
|
||||
public hostEventTargetAndNames: Map<string, BoundEventAst>,
|
||||
public targetVariableNameAndValues: any[][],
|
||||
public targetDirectives: CompileDirectiveMetadata[]) {}
|
||||
constructor(
|
||||
public index: number, public boundElementIndex: number,
|
||||
public hostEventTargetAndNames: Map<string, BoundEventAst>,
|
||||
public targetVariableNameAndValues: any[][],
|
||||
public targetDirectives: CompileDirectiveMetadata[]) {}
|
||||
}
|
||||
|
||||
function keyValueArrayToStringMap(keyValueArray: any[][]): {[key: string]: any} {
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {resolveForwardRef} from 'angular2/src/core/di';
|
||||
import {
|
||||
Type,
|
||||
isBlank,
|
||||
isPresent,
|
||||
isArray,
|
||||
stringify,
|
||||
RegExpWrapper
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {Type, isBlank, isPresent, isArray, stringify, RegExpWrapper} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import * as cpl from './directive_metadata';
|
||||
import * as md from 'angular2/src/core/metadata/directives';
|
||||
@ -30,10 +23,11 @@ export class RuntimeMetadataResolver {
|
||||
private _anonymousTypes = new Map<Object, number>();
|
||||
private _anonymousTypeIndex = 0;
|
||||
|
||||
constructor(private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
|
||||
private _viewResolver: ViewResolver,
|
||||
@Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[],
|
||||
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[]) {}
|
||||
constructor(
|
||||
private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
|
||||
private _viewResolver: ViewResolver,
|
||||
@Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[],
|
||||
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[]) {}
|
||||
|
||||
/**
|
||||
* Wrap the stringify method to avoid naming things `function (arg1...) {`
|
||||
@ -157,7 +151,7 @@ function flattenPipes(view: ViewMetadata, platformPipes: any[]): Type[] {
|
||||
return pipes;
|
||||
}
|
||||
|
||||
function flattenArray(tree: any[], out: Array<Type | any[]>): void {
|
||||
function flattenArray(tree: any[], out: Array<Type|any[]>): void {
|
||||
for (var i = 0; i < tree.length; i++) {
|
||||
var item = resolveForwardRef(tree[i]);
|
||||
if (isArray(item)) {
|
||||
|
@ -18,8 +18,8 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
||||
if (isBlank(element)) {
|
||||
var nsAndName = splitNsName(tagName);
|
||||
element = isPresent(nsAndName[0]) ?
|
||||
DOM.createElementNS(NAMESPACE_URIS[nsAndName[0]], nsAndName[1]) :
|
||||
DOM.createElement(nsAndName[1]);
|
||||
DOM.createElementNS(NAMESPACE_URIS[nsAndName[0]], nsAndName[1]) :
|
||||
DOM.createElement(nsAndName[1]);
|
||||
this._protoElements.set(tagName, element);
|
||||
}
|
||||
return element;
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
isPresent,
|
||||
isBlank,
|
||||
RegExpWrapper,
|
||||
RegExpMatcherWrapper,
|
||||
StringWrapper
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {isPresent, isBlank, RegExpWrapper, RegExpMatcherWrapper, StringWrapper} from 'angular2/src/facade/lang';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
const _EMPTY_ATTR_VALUE = '';
|
||||
@ -36,7 +30,7 @@ export class CssSelector {
|
||||
var _addResult = (res: CssSelector[], cssSel) => {
|
||||
if (cssSel.notSelectors.length > 0 && isBlank(cssSel.element) &&
|
||||
ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) {
|
||||
cssSel.element = "*";
|
||||
cssSel.element = '*';
|
||||
}
|
||||
res.push(cssSel);
|
||||
};
|
||||
@ -81,7 +75,7 @@ export class CssSelector {
|
||||
|
||||
isElementSelector(): boolean {
|
||||
return isPresent(this.element) && ListWrapper.isEmpty(this.classNames) &&
|
||||
ListWrapper.isEmpty(this.attrs) && this.notSelectors.length === 0;
|
||||
ListWrapper.isEmpty(this.attrs) && this.notSelectors.length === 0;
|
||||
}
|
||||
|
||||
setElement(element: string = null) { this.element = element; }
|
||||
@ -174,8 +168,8 @@ export class SelectorMatcher {
|
||||
* @param cssSelector A css selector
|
||||
* @param callbackCtxt An opaque object that will be given to the callback of the `match` function
|
||||
*/
|
||||
private _addSelectable(cssSelector: CssSelector, callbackCtxt: any,
|
||||
listContext: SelectorListContext) {
|
||||
private _addSelectable(
|
||||
cssSelector: CssSelector, callbackCtxt: any, listContext: SelectorListContext) {
|
||||
var matcher: SelectorMatcher = this;
|
||||
var element = cssSelector.element;
|
||||
var classNames = cssSelector.classNames;
|
||||
@ -229,8 +223,8 @@ export class SelectorMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
private _addTerminal(map: Map<string, SelectorContext[]>, name: string,
|
||||
selectable: SelectorContext) {
|
||||
private _addTerminal(
|
||||
map: Map<string, SelectorContext[]>, name: string, selectable: SelectorContext) {
|
||||
var terminalList = map.get(name);
|
||||
if (isBlank(terminalList)) {
|
||||
terminalList = [];
|
||||
@ -267,7 +261,7 @@ export class SelectorMatcher {
|
||||
|
||||
result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result;
|
||||
result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) ||
|
||||
result;
|
||||
result;
|
||||
|
||||
if (isPresent(classNames)) {
|
||||
for (var index = 0; index < classNames.length; index++) {
|
||||
@ -287,18 +281,18 @@ export class SelectorMatcher {
|
||||
|
||||
var terminalValuesMap = this._attrValueMap.get(attrName);
|
||||
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
|
||||
result = this._matchTerminal(terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector,
|
||||
matchedCallback) ||
|
||||
result;
|
||||
result = this._matchTerminal(
|
||||
terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
|
||||
result;
|
||||
}
|
||||
result = this._matchTerminal(terminalValuesMap, attrValue, cssSelector, matchedCallback) ||
|
||||
result;
|
||||
result;
|
||||
|
||||
var partialValuesMap = this._attrValuePartialMap.get(attrName);
|
||||
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
|
||||
result = this._matchPartial(partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector,
|
||||
matchedCallback) ||
|
||||
result;
|
||||
result = this._matchPartial(
|
||||
partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
|
||||
result;
|
||||
}
|
||||
result =
|
||||
this._matchPartial(partialValuesMap, attrValue, cssSelector, matchedCallback) || result;
|
||||
@ -308,14 +302,15 @@ export class SelectorMatcher {
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_matchTerminal(map: Map<string, SelectorContext[]>, name, cssSelector: CssSelector,
|
||||
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
||||
_matchTerminal(
|
||||
map: Map<string, SelectorContext[]>, name, cssSelector: CssSelector,
|
||||
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
||||
if (isBlank(map) || isBlank(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var selectables = map.get(name);
|
||||
var starSelectables = map.get("*");
|
||||
var starSelectables = map.get('*');
|
||||
if (isPresent(starSelectables)) {
|
||||
selectables = selectables.concat(starSelectables);
|
||||
}
|
||||
@ -332,8 +327,9 @@ export class SelectorMatcher {
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_matchPartial(map: Map<string, SelectorMatcher>, name, cssSelector: CssSelector,
|
||||
matchedCallback /*: (c: CssSelector, a: any) => void*/): boolean {
|
||||
_matchPartial(
|
||||
map: Map<string, SelectorMatcher>, name, cssSelector: CssSelector,
|
||||
matchedCallback /*: (c: CssSelector, a: any) => void*/): boolean {
|
||||
if (isBlank(map) || isBlank(name)) {
|
||||
return false;
|
||||
}
|
||||
@ -359,8 +355,9 @@ export class SelectorListContext {
|
||||
export class SelectorContext {
|
||||
notSelectors: CssSelector[];
|
||||
|
||||
constructor(public selector: CssSelector, public cbContext: any,
|
||||
public listContext: SelectorListContext) {
|
||||
constructor(
|
||||
public selector: CssSelector, public cbContext: any,
|
||||
public listContext: SelectorListContext) {
|
||||
this.notSelectors = selector.notSelectors;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
StringWrapper,
|
||||
RegExp,
|
||||
RegExpWrapper,
|
||||
RegExpMatcherWrapper,
|
||||
isPresent,
|
||||
isBlank
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {StringWrapper, RegExp, RegExpWrapper, RegExpMatcherWrapper, isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
* This file is a port of shadowCSS from webcomponents.js to TypeScript.
|
||||
@ -174,8 +167,8 @@ export class ShadowCss {
|
||||
**/
|
||||
private _insertPolyfillDirectivesInCssText(cssText: string): string {
|
||||
// Difference with webcomponents.js: does not handle comments
|
||||
return StringWrapper.replaceAllMapped(cssText, _cssContentNextSelectorRe,
|
||||
function(m) { return m[1] + '{'; });
|
||||
return StringWrapper.replaceAllMapped(
|
||||
cssText, _cssContentNextSelectorRe, function(m) { return m[1] + '{'; });
|
||||
}
|
||||
|
||||
/*
|
||||
@ -279,8 +272,8 @@ export class ShadowCss {
|
||||
* scopeName.foo .bar { ... }
|
||||
*/
|
||||
private _convertColonHostContext(cssText: string): string {
|
||||
return this._convertColonRule(cssText, _cssColonHostContextRe,
|
||||
this._colonHostContextPartReplacer);
|
||||
return this._convertColonRule(
|
||||
cssText, _cssColonHostContextRe, this._colonHostContextPartReplacer);
|
||||
}
|
||||
|
||||
private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string {
|
||||
@ -339,8 +332,8 @@ export class ShadowCss {
|
||||
});
|
||||
}
|
||||
|
||||
private _scopeSelector(selector: string, scopeSelector: string, hostSelector: string,
|
||||
strict: boolean): string {
|
||||
private _scopeSelector(
|
||||
selector: string, scopeSelector: string, hostSelector: string, strict: boolean): string {
|
||||
var r = [], parts = selector.split(',');
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var p = parts[i].trim();
|
||||
@ -348,8 +341,8 @@ export class ShadowCss {
|
||||
var shallowPart = deepParts[0];
|
||||
if (this._selectorNeedsScoping(shallowPart, scopeSelector)) {
|
||||
deepParts[0] = strict && !StringWrapper.contains(shallowPart, _polyfillHostNoCombinator) ?
|
||||
this._applyStrictSelectorScope(shallowPart, scopeSelector) :
|
||||
this._applySelectorScope(shallowPart, scopeSelector, hostSelector);
|
||||
this._applyStrictSelectorScope(shallowPart, scopeSelector) :
|
||||
this._applySelectorScope(shallowPart, scopeSelector, hostSelector);
|
||||
}
|
||||
// replace /deep/ with a space for child selectors
|
||||
r.push(deepParts.join(' '));
|
||||
@ -370,15 +363,15 @@ export class ShadowCss {
|
||||
return RegExpWrapper.create('^(' + scopeSelector + ')' + _selectorReSuffix, 'm');
|
||||
}
|
||||
|
||||
private _applySelectorScope(selector: string, scopeSelector: string,
|
||||
hostSelector: string): string {
|
||||
private _applySelectorScope(selector: string, scopeSelector: string, hostSelector: string):
|
||||
string {
|
||||
// Difference from webcomponentsjs: scopeSelector could not be an array
|
||||
return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector);
|
||||
}
|
||||
|
||||
// scope via name and [is=name]
|
||||
private _applySimpleSelectorScope(selector: string, scopeSelector: string,
|
||||
hostSelector: string): string {
|
||||
private _applySimpleSelectorScope(selector: string, scopeSelector: string, hostSelector: string):
|
||||
string {
|
||||
if (isPresent(RegExpWrapper.firstMatch(_polyfillHostRe, selector))) {
|
||||
var replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector;
|
||||
selector = StringWrapper.replace(selector, _polyfillHostNoCombinator, replaceBy);
|
||||
@ -397,19 +390,20 @@ export class ShadowCss {
|
||||
for (var i = 0; i < splits.length; i++) {
|
||||
var sep = splits[i];
|
||||
var parts = scoped.split(sep);
|
||||
scoped = parts.map(p => {
|
||||
// remove :host since it should be unnecessary
|
||||
var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, '');
|
||||
if (t.length > 0 && !ListWrapper.contains(splits, t) &&
|
||||
!StringWrapper.contains(t, attrName)) {
|
||||
var re = /([^:]*)(:*)(.*)/g;
|
||||
var m = RegExpWrapper.firstMatch(re, t);
|
||||
if (isPresent(m)) {
|
||||
p = m[1] + attrName + m[2] + m[3];
|
||||
}
|
||||
}
|
||||
return p;
|
||||
})
|
||||
scoped = parts
|
||||
.map(p => {
|
||||
// remove :host since it should be unnecessary
|
||||
var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, '');
|
||||
if (t.length > 0 && !ListWrapper.contains(splits, t) &&
|
||||
!StringWrapper.contains(t, attrName)) {
|
||||
var re = /([^:]*)(:*)(.*)/g;
|
||||
var m = RegExpWrapper.firstMatch(re, t);
|
||||
if (isPresent(m)) {
|
||||
p = m[1] + attrName + m[2] + m[3];
|
||||
}
|
||||
}
|
||||
return p;
|
||||
})
|
||||
.join(sep);
|
||||
}
|
||||
return scoped;
|
||||
@ -430,14 +424,13 @@ var _polyfillHost = '-shadowcsshost';
|
||||
// note: :host-context pre-processed to -shadowcsshostcontext.
|
||||
var _polyfillHostContext = '-shadowcsscontext';
|
||||
var _parenSuffix = ')(?:\\((' +
|
||||
'(?:\\([^)(]*\\)|[^)(]*)+?' +
|
||||
')\\))?([^,{]*)';
|
||||
'(?:\\([^)(]*\\)|[^)(]*)+?' +
|
||||
')\\))?([^,{]*)';
|
||||
var _cssColonHostRe = RegExpWrapper.create('(' + _polyfillHost + _parenSuffix, 'im');
|
||||
var _cssColonHostContextRe = RegExpWrapper.create('(' + _polyfillHostContext + _parenSuffix, 'im');
|
||||
var _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
|
||||
var _shadowDOMSelectorsRe = [
|
||||
/::shadow/g,
|
||||
/::content/g,
|
||||
/::shadow/g, /::content/g,
|
||||
// Deprecated selectors
|
||||
// TODO(vicb): see https://github.com/angular/clang-format/issues/16
|
||||
// clang-format off
|
||||
|
@ -1,30 +1,6 @@
|
||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
isArray,
|
||||
isBlank,
|
||||
isNumber,
|
||||
isPresent,
|
||||
isPrimitive,
|
||||
isString,
|
||||
Type
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {
|
||||
AttributeMetadata,
|
||||
DirectiveMetadata,
|
||||
ComponentMetadata,
|
||||
ContentChildrenMetadata,
|
||||
ContentChildMetadata,
|
||||
InputMetadata,
|
||||
HostBindingMetadata,
|
||||
HostListenerMetadata,
|
||||
OutputMetadata,
|
||||
PipeMetadata,
|
||||
ViewMetadata,
|
||||
ViewChildMetadata,
|
||||
ViewChildrenMetadata,
|
||||
ViewQueryMetadata,
|
||||
QueryMetadata,
|
||||
} from 'angular2/src/core/metadata';
|
||||
import {isArray, isBlank, isNumber, isPresent, isPrimitive, isString, Type} from 'angular2/src/facade/lang';
|
||||
import {AttributeMetadata, DirectiveMetadata, ComponentMetadata, ContentChildrenMetadata, ContentChildMetadata, InputMetadata, HostBindingMetadata, HostListenerMetadata, OutputMetadata, PipeMetadata, ViewMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, QueryMetadata,} from 'angular2/src/core/metadata';
|
||||
|
||||
/**
|
||||
* The host of the static resolver is expected to be able to provide module metadata in the form of
|
||||
@ -124,60 +100,62 @@ export class StaticReflector {
|
||||
private initializeConversionMap(): any {
|
||||
let core_metadata = 'angular2/src/core/metadata';
|
||||
let conversionMap = this.conversionMap;
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'Directive'),
|
||||
(moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
if (!isPresent(p0)) {
|
||||
p0 = {};
|
||||
}
|
||||
return new DirectiveMetadata({
|
||||
selector: p0['selector'],
|
||||
inputs: p0['inputs'],
|
||||
outputs: p0['outputs'],
|
||||
events: p0['events'],
|
||||
host: p0['host'],
|
||||
bindings: p0['bindings'],
|
||||
providers: p0['providers'],
|
||||
exportAs: p0['exportAs'],
|
||||
queries: p0['queries'],
|
||||
});
|
||||
});
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'Component'),
|
||||
(moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
if (!isPresent(p0)) {
|
||||
p0 = {};
|
||||
}
|
||||
return new ComponentMetadata({
|
||||
selector: p0['selector'],
|
||||
inputs: p0['inputs'],
|
||||
outputs: p0['outputs'],
|
||||
properties: p0['properties'],
|
||||
events: p0['events'],
|
||||
host: p0['host'],
|
||||
exportAs: p0['exportAs'],
|
||||
moduleId: p0['moduleId'],
|
||||
bindings: p0['bindings'],
|
||||
providers: p0['providers'],
|
||||
viewBindings: p0['viewBindings'],
|
||||
viewProviders: p0['viewProviders'],
|
||||
changeDetection: p0['changeDetection'],
|
||||
queries: p0['queries'],
|
||||
templateUrl: p0['templateUrl'],
|
||||
template: p0['template'],
|
||||
styleUrls: p0['styleUrls'],
|
||||
styles: p0['styles'],
|
||||
directives: p0['directives'],
|
||||
pipes: p0['pipes'],
|
||||
encapsulation: p0['encapsulation']
|
||||
});
|
||||
});
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'Input'),
|
||||
(moduleContext, expression) => new InputMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'Output'),
|
||||
(moduleContext, expression) => new OutputMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'Directive'), (moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
if (!isPresent(p0)) {
|
||||
p0 = {};
|
||||
}
|
||||
return new DirectiveMetadata({
|
||||
selector: p0['selector'],
|
||||
inputs: p0['inputs'],
|
||||
outputs: p0['outputs'],
|
||||
events: p0['events'],
|
||||
host: p0['host'],
|
||||
bindings: p0['bindings'],
|
||||
providers: p0['providers'],
|
||||
exportAs: p0['exportAs'],
|
||||
queries: p0['queries'],
|
||||
});
|
||||
});
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'Component'), (moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
if (!isPresent(p0)) {
|
||||
p0 = {};
|
||||
}
|
||||
return new ComponentMetadata({
|
||||
selector: p0['selector'],
|
||||
inputs: p0['inputs'],
|
||||
outputs: p0['outputs'],
|
||||
properties: p0['properties'],
|
||||
events: p0['events'],
|
||||
host: p0['host'],
|
||||
exportAs: p0['exportAs'],
|
||||
moduleId: p0['moduleId'],
|
||||
bindings: p0['bindings'],
|
||||
providers: p0['providers'],
|
||||
viewBindings: p0['viewBindings'],
|
||||
viewProviders: p0['viewProviders'],
|
||||
changeDetection: p0['changeDetection'],
|
||||
queries: p0['queries'],
|
||||
templateUrl: p0['templateUrl'],
|
||||
template: p0['template'],
|
||||
styleUrls: p0['styleUrls'],
|
||||
styles: p0['styles'],
|
||||
directives: p0['directives'],
|
||||
pipes: p0['pipes'],
|
||||
encapsulation: p0['encapsulation']
|
||||
});
|
||||
});
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'Input'),
|
||||
(moduleContext, expression) =>
|
||||
new InputMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'Output'),
|
||||
(moduleContext, expression) =>
|
||||
new OutputMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'View'), (moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
if (!isPresent(p0)) {
|
||||
@ -192,9 +170,10 @@ export class StaticReflector {
|
||||
styles: p0['styles'],
|
||||
});
|
||||
});
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'Attribute'),
|
||||
(moduleContext, expression) => new AttributeMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'Attribute'),
|
||||
(moduleContext, expression) =>
|
||||
new AttributeMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'Query'), (moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
||||
@ -203,30 +182,34 @@ export class StaticReflector {
|
||||
}
|
||||
return new QueryMetadata(p0, {descendants: p1.descendants, first: p1.first});
|
||||
});
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'ContentChildren'),
|
||||
(moduleContext, expression) => new ContentChildrenMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'ContentChild'),
|
||||
(moduleContext, expression) => new ContentChildMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'ViewChildren'),
|
||||
(moduleContext, expression) => new ViewChildrenMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'ViewChild'),
|
||||
(moduleContext, expression) => new ViewChildMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'ViewQuery'),
|
||||
(moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
||||
if (!isPresent(p1)) {
|
||||
p1 = {};
|
||||
}
|
||||
return new ViewQueryMetadata(p0, {
|
||||
descendants: p1['descendants'],
|
||||
first: p1['first'],
|
||||
});
|
||||
});
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'ContentChildren'),
|
||||
(moduleContext, expression) =>
|
||||
new ContentChildrenMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'ContentChild'),
|
||||
(moduleContext, expression) =>
|
||||
new ContentChildMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'ViewChildren'),
|
||||
(moduleContext, expression) =>
|
||||
new ViewChildrenMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'ViewChild'),
|
||||
(moduleContext, expression) =>
|
||||
new ViewChildMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'ViewQuery'), (moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
||||
if (!isPresent(p1)) {
|
||||
p1 = {};
|
||||
}
|
||||
return new ViewQueryMetadata(p0, {
|
||||
descendants: p1['descendants'],
|
||||
first: p1['first'],
|
||||
});
|
||||
});
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'Pipe'), (moduleContext, expression) => {
|
||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||
if (!isPresent(p0)) {
|
||||
@ -237,13 +220,15 @@ export class StaticReflector {
|
||||
pure: p0['pure'],
|
||||
});
|
||||
});
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'HostBinding'),
|
||||
(moduleContext, expression) => new HostBindingMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(this.getStaticType(core_metadata, 'HostListener'),
|
||||
(moduleContext, expression) => new HostListenerMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0),
|
||||
this.getDecoratorParameter(moduleContext, expression, 1)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'HostBinding'),
|
||||
(moduleContext, expression) =>
|
||||
new HostBindingMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||
conversionMap.set(
|
||||
this.getStaticType(core_metadata, 'HostListener'),
|
||||
(moduleContext, expression) => new HostListenerMetadata(
|
||||
this.getDecoratorParameter(moduleContext, expression, 0),
|
||||
this.getDecoratorParameter(moduleContext, expression, 1)));
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -264,8 +249,8 @@ export class StaticReflector {
|
||||
return null;
|
||||
}
|
||||
|
||||
private getDecoratorParameter(moduleContext: string, expression: {[key: string]: any},
|
||||
index: number): any {
|
||||
private getDecoratorParameter(
|
||||
moduleContext: string, expression: {[key: string]: any}, index: number): any {
|
||||
if (isMetadataSymbolicCallExpression(expression) && isPresent(expression['arguments']) &&
|
||||
(<any[]>expression['arguments']).length <= index + 1) {
|
||||
return this.simplify(moduleContext, (<any[]>expression['arguments'])[index]);
|
||||
@ -273,14 +258,14 @@ export class StaticReflector {
|
||||
return null;
|
||||
}
|
||||
|
||||
private getPropertyMetadata(moduleContext: string,
|
||||
value: {[key: string]: any}): {[key: string]: any} {
|
||||
private getPropertyMetadata(moduleContext: string, value: {[key: string]: any}):
|
||||
{[key: string]: any} {
|
||||
if (isPresent(value)) {
|
||||
let result = {};
|
||||
StringMapWrapper.forEach(value, (value, name) => {
|
||||
let data = this.getMemberData(moduleContext, value);
|
||||
if (isPresent(data)) {
|
||||
let propertyData = data.filter(d => d['kind'] == "property")
|
||||
let propertyData = data.filter(d => d['kind'] == 'property')
|
||||
.map(d => d['directives'])
|
||||
.reduce((p, c) => (<any[]>p).concat(<any[]>c), []);
|
||||
if (propertyData.length != 0) {
|
||||
@ -301,12 +286,11 @@ export class StaticReflector {
|
||||
for (let item of member) {
|
||||
result.push({
|
||||
kind: item['__symbolic'],
|
||||
directives:
|
||||
isPresent(item['decorators']) ?
|
||||
(<any[]>item['decorators'])
|
||||
.map(decorator => this.convertKnownDecorator(moduleContext, decorator))
|
||||
.filter(d => isPresent(d)) :
|
||||
null
|
||||
directives: isPresent(item['decorators']) ?
|
||||
(<any[]>item['decorators'])
|
||||
.map(decorator => this.convertKnownDecorator(moduleContext, decorator))
|
||||
.filter(d => isPresent(d)) :
|
||||
null
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -323,7 +307,7 @@ export class StaticReflector {
|
||||
}
|
||||
if (isArray(expression)) {
|
||||
let result = [];
|
||||
for (let item of(<any>expression)) {
|
||||
for (let item of (<any>expression)) {
|
||||
result.push(simplify(item));
|
||||
}
|
||||
return result;
|
||||
@ -331,7 +315,7 @@ export class StaticReflector {
|
||||
if (isPresent(expression)) {
|
||||
if (isPresent(expression['__symbolic'])) {
|
||||
switch (expression['__symbolic']) {
|
||||
case "binop":
|
||||
case 'binop':
|
||||
let left = simplify(expression['left']);
|
||||
let right = simplify(expression['right']);
|
||||
switch (expression['operator']) {
|
||||
@ -377,7 +361,7 @@ export class StaticReflector {
|
||||
return left % right;
|
||||
}
|
||||
return null;
|
||||
case "pre":
|
||||
case 'pre':
|
||||
let operand = simplify(expression['operand']);
|
||||
switch (expression['operator']) {
|
||||
case '+':
|
||||
@ -390,17 +374,17 @@ export class StaticReflector {
|
||||
return ~operand;
|
||||
}
|
||||
return null;
|
||||
case "index":
|
||||
case 'index':
|
||||
let indexTarget = simplify(expression['expression']);
|
||||
let index = simplify(expression['index']);
|
||||
if (isPresent(indexTarget) && isPrimitive(index)) return indexTarget[index];
|
||||
return null;
|
||||
case "select":
|
||||
case 'select':
|
||||
let selectTarget = simplify(expression['expression']);
|
||||
let member = simplify(expression['member']);
|
||||
if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member];
|
||||
return null;
|
||||
case "reference":
|
||||
case 'reference':
|
||||
let referenceModuleName =
|
||||
_this.normalizeModuleName(moduleContext, expression['module']);
|
||||
let referenceModule = _this.getModuleMetadata(referenceModuleName);
|
||||
@ -410,7 +394,7 @@ export class StaticReflector {
|
||||
return _this.getStaticType(referenceModuleName, expression['name']);
|
||||
}
|
||||
return _this.simplify(referenceModuleName, referenceValue);
|
||||
case "call":
|
||||
case 'call':
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
@ -430,7 +414,7 @@ export class StaticReflector {
|
||||
if (!isPresent(moduleMetadata)) {
|
||||
moduleMetadata = this.host.getMetadataFor(module);
|
||||
if (!isPresent(moduleMetadata)) {
|
||||
moduleMetadata = {__symbolic: "module", module: module, metadata: {}};
|
||||
moduleMetadata = {__symbolic: 'module', module: module, metadata: {}};
|
||||
}
|
||||
this.metadataCache.set(module, moduleMetadata);
|
||||
}
|
||||
@ -441,7 +425,7 @@ export class StaticReflector {
|
||||
let moduleMetadata = this.getModuleMetadata(type.moduleId);
|
||||
let result = moduleMetadata['metadata'][type.name];
|
||||
if (!isPresent(result)) {
|
||||
result = {__symbolic: "class"};
|
||||
result = {__symbolic: 'class'};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -460,7 +444,7 @@ function isMetadataSymbolicCallExpression(expression: any): boolean {
|
||||
|
||||
function isMetadataSymbolicReferenceExpression(expression: any): boolean {
|
||||
return !isPrimitive(expression) && !isArray(expression) &&
|
||||
expression['__symbolic'] == 'reference';
|
||||
expression['__symbolic'] == 'reference';
|
||||
}
|
||||
|
||||
function isClassMetadata(expression: any): boolean {
|
||||
|
@ -7,12 +7,7 @@ import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ShadowCss} from 'angular2/src/compiler/shadow_css';
|
||||
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
|
||||
import {extractStyleUrls} from './style_url_resolver';
|
||||
import {
|
||||
escapeSingleQuoteString,
|
||||
codeGenExportVariable,
|
||||
codeGenToString,
|
||||
MODULE_SUFFIX
|
||||
} from './util';
|
||||
import {escapeSingleQuoteString, codeGenExportVariable, codeGenToString, MODULE_SUFFIX} from './util';
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
|
||||
const COMPONENT_VARIABLE = '%COMP%';
|
||||
@ -26,11 +21,11 @@ export class StyleCompiler {
|
||||
|
||||
constructor(private _xhr: XHR, private _urlResolver: UrlResolver) {}
|
||||
|
||||
compileComponentRuntime(template: CompileTemplateMetadata): Promise<Array<string | any[]>> {
|
||||
compileComponentRuntime(template: CompileTemplateMetadata): Promise<Array<string|any[]>> {
|
||||
var styles = template.styles;
|
||||
var styleAbsUrls = template.styleUrls;
|
||||
return this._loadStyles(styles, styleAbsUrls,
|
||||
template.encapsulation === ViewEncapsulation.Emulated);
|
||||
return this._loadStyles(
|
||||
styles, styleAbsUrls, template.encapsulation === ViewEncapsulation.Emulated);
|
||||
}
|
||||
|
||||
compileComponentCodeGen(template: CompileTemplateMetadata): SourceExpression {
|
||||
@ -44,30 +39,31 @@ export class StyleCompiler {
|
||||
this._styleModule(
|
||||
stylesheetUrl, false,
|
||||
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, false)),
|
||||
this._styleModule(stylesheetUrl, true, this._styleCodeGen([styleWithImports.style],
|
||||
styleWithImports.styleUrls, true))
|
||||
this._styleModule(
|
||||
stylesheetUrl, true,
|
||||
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, true))
|
||||
];
|
||||
}
|
||||
|
||||
clearCache() { this._styleCache.clear(); }
|
||||
|
||||
private _loadStyles(plainStyles: string[], absUrls: string[],
|
||||
encapsulate: boolean): Promise<Array<string | any[]>> {
|
||||
private _loadStyles(plainStyles: string[], absUrls: string[], encapsulate: boolean):
|
||||
Promise<Array<string|any[]>> {
|
||||
var promises: Promise<string[]>[] = absUrls.map((absUrl: string): Promise<string[]> => {
|
||||
var cacheKey = `${absUrl}${encapsulate ? '.shim' : ''}`;
|
||||
var result: Promise<string[]> = this._styleCache.get(cacheKey);
|
||||
if (isBlank(result)) {
|
||||
result = this._xhr.get(absUrl).then((style) => {
|
||||
var styleWithImports = extractStyleUrls(this._urlResolver, absUrl, style);
|
||||
return this._loadStyles([styleWithImports.style], styleWithImports.styleUrls,
|
||||
encapsulate);
|
||||
return this._loadStyles(
|
||||
[styleWithImports.style], styleWithImports.styleUrls, encapsulate);
|
||||
});
|
||||
this._styleCache.set(cacheKey, result);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
return PromiseWrapper.all<string[]>(promises).then((nestedStyles: string[][]) => {
|
||||
var result: Array<string | any[]> =
|
||||
var result: Array<string|any[]> =
|
||||
plainStyles.map(plainStyle => this._shimIfNeeded(plainStyle, encapsulate));
|
||||
nestedStyles.forEach(styles => result.push(styles));
|
||||
return result;
|
||||
@ -87,8 +83,8 @@ export class StyleCompiler {
|
||||
return new SourceExpression([], expressionSource);
|
||||
}
|
||||
|
||||
private _styleModule(stylesheetUrl: string, shim: boolean,
|
||||
expression: SourceExpression): SourceModule {
|
||||
private _styleModule(stylesheetUrl: string, shim: boolean, expression: SourceExpression):
|
||||
SourceModule {
|
||||
var moduleSource = `
|
||||
${expression.declarations.join('\n')}
|
||||
${codeGenExportVariable('STYLES')}${expression.expression};
|
||||
|
@ -18,8 +18,8 @@ export function isStyleUrlResolvable(url: string): boolean {
|
||||
* Rewrites stylesheets by resolving and removing the @import urls that
|
||||
* are either relative or don't have a `package:` scheme
|
||||
*/
|
||||
export function extractStyleUrls(resolver: UrlResolver, baseUrl: string,
|
||||
cssText: string): StyleWithImports {
|
||||
export function extractStyleUrls(
|
||||
resolver: UrlResolver, baseUrl: string, cssText: string): StyleWithImports {
|
||||
var foundUrls = [];
|
||||
var modifiedCssText = StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m) => {
|
||||
var url = isPresent(m[1]) ? m[1] : m[2];
|
||||
|
@ -22,8 +22,8 @@ export interface TemplateAst {
|
||||
* A segment of text within the template.
|
||||
*/
|
||||
export class TextAst implements TemplateAst {
|
||||
constructor(public value: string, public ngContentIndex: number,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public value: string, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitText(this, context); }
|
||||
}
|
||||
|
||||
@ -31,8 +31,8 @@ export class TextAst implements TemplateAst {
|
||||
* A bound expression within the text of a template.
|
||||
*/
|
||||
export class BoundTextAst implements TemplateAst {
|
||||
constructor(public value: AST, public ngContentIndex: number,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public value: AST, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitBoundText(this, context);
|
||||
}
|
||||
@ -50,8 +50,9 @@ export class AttrAst implements TemplateAst {
|
||||
* A binding for an element property (e.g. `[property]="expression"`).
|
||||
*/
|
||||
export class BoundElementPropertyAst implements TemplateAst {
|
||||
constructor(public name: string, public type: PropertyBindingType, public value: AST,
|
||||
public unit: string, public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public name: string, public type: PropertyBindingType, public value: AST, public unit: string,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitElementProperty(this, context);
|
||||
}
|
||||
@ -61,8 +62,9 @@ export class BoundElementPropertyAst implements TemplateAst {
|
||||
* A binding for an element event (e.g. `(event)="handler()"`).
|
||||
*/
|
||||
export class BoundEventAst implements TemplateAst {
|
||||
constructor(public name: string, public target: string, public handler: AST,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public name: string, public target: string, public handler: AST,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitEvent(this, context);
|
||||
}
|
||||
@ -89,11 +91,11 @@ export class VariableAst implements TemplateAst {
|
||||
* An element declaration in a template.
|
||||
*/
|
||||
export class ElementAst implements TemplateAst {
|
||||
constructor(public name: string, public attrs: AttrAst[],
|
||||
public inputs: BoundElementPropertyAst[], public outputs: BoundEventAst[],
|
||||
public exportAsVars: VariableAst[], public directives: DirectiveAst[],
|
||||
public children: TemplateAst[], public ngContentIndex: number,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public name: string, public attrs: AttrAst[], public inputs: BoundElementPropertyAst[],
|
||||
public outputs: BoundEventAst[], public exportAsVars: VariableAst[],
|
||||
public directives: DirectiveAst[], public children: TemplateAst[],
|
||||
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitElement(this, context);
|
||||
}
|
||||
@ -102,8 +104,9 @@ export class ElementAst implements TemplateAst {
|
||||
* Whether the element has any active bindings (inputs, outputs, vars, or directives).
|
||||
*/
|
||||
isBound(): boolean {
|
||||
return (this.inputs.length > 0 || this.outputs.length > 0 || this.exportAsVars.length > 0 ||
|
||||
this.directives.length > 0);
|
||||
return (
|
||||
this.inputs.length > 0 || this.outputs.length > 0 || this.exportAsVars.length > 0 ||
|
||||
this.directives.length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,8 +114,8 @@ export class ElementAst implements TemplateAst {
|
||||
*/
|
||||
getComponent(): CompileDirectiveMetadata {
|
||||
return this.directives.length > 0 && this.directives[0].directive.isComponent ?
|
||||
this.directives[0].directive :
|
||||
null;
|
||||
this.directives[0].directive :
|
||||
null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,9 +123,10 @@ export class ElementAst implements TemplateAst {
|
||||
* A `<template>` element included in an Angular template.
|
||||
*/
|
||||
export class EmbeddedTemplateAst implements TemplateAst {
|
||||
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
|
||||
public directives: DirectiveAst[], public children: TemplateAst[],
|
||||
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
|
||||
public directives: DirectiveAst[], public children: TemplateAst[],
|
||||
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitEmbeddedTemplate(this, context);
|
||||
}
|
||||
@ -132,8 +136,9 @@ export class EmbeddedTemplateAst implements TemplateAst {
|
||||
* A directive property with a bound value (e.g. `*ngIf="condition").
|
||||
*/
|
||||
export class BoundDirectivePropertyAst implements TemplateAst {
|
||||
constructor(public directiveName: string, public templateName: string, public value: AST,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public directiveName: string, public templateName: string, public value: AST,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitDirectiveProperty(this, context);
|
||||
}
|
||||
@ -143,10 +148,10 @@ export class BoundDirectivePropertyAst implements TemplateAst {
|
||||
* A directive declared on an element.
|
||||
*/
|
||||
export class DirectiveAst implements TemplateAst {
|
||||
constructor(public directive: CompileDirectiveMetadata,
|
||||
public inputs: BoundDirectivePropertyAst[],
|
||||
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
|
||||
public exportAsVars: VariableAst[], public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public directive: CompileDirectiveMetadata, public inputs: BoundDirectivePropertyAst[],
|
||||
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
|
||||
public exportAsVars: VariableAst[], public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitDirective(this, context);
|
||||
}
|
||||
@ -156,8 +161,8 @@ export class DirectiveAst implements TemplateAst {
|
||||
* Position where content is to be projected (instance of `<ng-content>` in a template).
|
||||
*/
|
||||
export class NgContentAst implements TemplateAst {
|
||||
constructor(public index: number, public ngContentIndex: number,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public index: number, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitNgContent(this, context);
|
||||
}
|
||||
@ -209,8 +214,8 @@ export interface TemplateAstVisitor {
|
||||
/**
|
||||
* Visit every node in a list of {@link TemplateAst}s with the given {@link TemplateAstVisitor}.
|
||||
*/
|
||||
export function templateVisitAll(visitor: TemplateAstVisitor, asts: TemplateAst[],
|
||||
context: any = null): any[] {
|
||||
export function templateVisitAll(
|
||||
visitor: TemplateAstVisitor, asts: TemplateAst[], context: any = null): any[] {
|
||||
var result = [];
|
||||
asts.forEach(ast => {
|
||||
var astResult = ast.visit(visitor, context);
|
||||
|
@ -1,55 +1,15 @@
|
||||
import {
|
||||
IS_DART,
|
||||
Type,
|
||||
Json,
|
||||
isBlank,
|
||||
isPresent,
|
||||
stringify,
|
||||
evalExpression
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {IS_DART, Type, Json, isBlank, isPresent, stringify, evalExpression} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {
|
||||
ListWrapper,
|
||||
SetWrapper,
|
||||
MapWrapper,
|
||||
StringMapWrapper
|
||||
} from 'angular2/src/facade/collection';
|
||||
import {ListWrapper, SetWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {
|
||||
createHostComponentMeta,
|
||||
CompileDirectiveMetadata,
|
||||
CompileTypeMetadata,
|
||||
CompileTemplateMetadata,
|
||||
CompilePipeMetadata,
|
||||
CompileMetadataWithType
|
||||
} from './directive_metadata';
|
||||
import {
|
||||
TemplateAst,
|
||||
TemplateAstVisitor,
|
||||
NgContentAst,
|
||||
EmbeddedTemplateAst,
|
||||
ElementAst,
|
||||
VariableAst,
|
||||
BoundEventAst,
|
||||
BoundElementPropertyAst,
|
||||
AttrAst,
|
||||
BoundTextAst,
|
||||
TextAst,
|
||||
DirectiveAst,
|
||||
BoundDirectivePropertyAst,
|
||||
templateVisitAll
|
||||
} from './template_ast';
|
||||
import {createHostComponentMeta, CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata, CompilePipeMetadata, CompileMetadataWithType} from './directive_metadata';
|
||||
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {SourceModule, moduleRef, SourceExpression} from './source_module';
|
||||
import {ChangeDetectionCompiler, CHANGE_DETECTION_JIT_IMPORTS} from './change_detector_compiler';
|
||||
import {StyleCompiler} from './style_compiler';
|
||||
import {ViewCompiler, VIEW_JIT_IMPORTS} from './view_compiler';
|
||||
import {
|
||||
ProtoViewCompiler,
|
||||
APP_VIEW_MODULE_REF,
|
||||
CompileProtoView,
|
||||
PROTO_VIEW_JIT_IMPORTS
|
||||
} from './proto_view_compiler';
|
||||
import {ProtoViewCompiler, APP_VIEW_MODULE_REF, CompileProtoView, PROTO_VIEW_JIT_IMPORTS} from './proto_view_compiler';
|
||||
import {TemplateParser, PipeCollector} from './template_parser';
|
||||
import {TemplateNormalizer} from './template_normalizer';
|
||||
import {RuntimeMetadataResolver} from './runtime_metadata';
|
||||
@ -57,14 +17,7 @@ import {HostViewFactory} from 'angular2/src/core/linker/view';
|
||||
import {ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
||||
|
||||
import {
|
||||
codeGenExportVariable,
|
||||
escapeSingleQuoteString,
|
||||
codeGenValueFn,
|
||||
MODULE_SUFFIX,
|
||||
addAll,
|
||||
Expression
|
||||
} from './util';
|
||||
import {codeGenExportVariable, escapeSingleQuoteString, codeGenValueFn, MODULE_SUFFIX, addAll, Expression} from './util';
|
||||
|
||||
export var METADATA_CACHE_MODULE_REF =
|
||||
moduleRef('package:angular2/src/core/linker/resolved_metadata_cache' + MODULE_SUFFIX);
|
||||
@ -80,13 +33,13 @@ export class TemplateCompiler {
|
||||
private _compiledTemplateCache = new Map<any, CompiledTemplate>();
|
||||
private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>();
|
||||
|
||||
constructor(private _runtimeMetadataResolver: RuntimeMetadataResolver,
|
||||
private _templateNormalizer: TemplateNormalizer,
|
||||
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
|
||||
private _cdCompiler: ChangeDetectionCompiler,
|
||||
private _protoViewCompiler: ProtoViewCompiler, private _viewCompiler: ViewCompiler,
|
||||
private _resolvedMetadataCache: ResolvedMetadataCache,
|
||||
private _genConfig: ChangeDetectorGenConfig) {}
|
||||
constructor(
|
||||
private _runtimeMetadataResolver: RuntimeMetadataResolver,
|
||||
private _templateNormalizer: TemplateNormalizer, private _templateParser: TemplateParser,
|
||||
private _styleCompiler: StyleCompiler, private _cdCompiler: ChangeDetectionCompiler,
|
||||
private _protoViewCompiler: ProtoViewCompiler, private _viewCompiler: ViewCompiler,
|
||||
private _resolvedMetadataCache: ResolvedMetadataCache,
|
||||
private _genConfig: ChangeDetectorGenConfig) {}
|
||||
|
||||
normalizeDirectiveMetadata(directive: CompileDirectiveMetadata):
|
||||
Promise<CompileDirectiveMetadata> {
|
||||
@ -131,8 +84,9 @@ export class TemplateCompiler {
|
||||
this._compileComponentRuntime(hostCacheKey, hostMeta, [compMeta], [], []);
|
||||
}
|
||||
return this._compiledTemplateDone.get(hostCacheKey)
|
||||
.then((compiledTemplate: CompiledTemplate) =>
|
||||
new HostViewFactory(compMeta.selector, compiledTemplate.viewFactory));
|
||||
.then(
|
||||
(compiledTemplate: CompiledTemplate) =>
|
||||
new HostViewFactory(compMeta.selector, compiledTemplate.viewFactory));
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
@ -150,8 +104,8 @@ export class TemplateCompiler {
|
||||
components.forEach(componentWithDirs => {
|
||||
var compMeta = <CompileDirectiveMetadata>componentWithDirs.component;
|
||||
assertComponent(compMeta);
|
||||
this._compileComponentCodeGen(compMeta, componentWithDirs.directives, componentWithDirs.pipes,
|
||||
declarations);
|
||||
this._compileComponentCodeGen(
|
||||
compMeta, componentWithDirs.directives, componentWithDirs.pipes, declarations);
|
||||
if (compMeta.dynamicLoadable) {
|
||||
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
|
||||
var viewFactoryExpression =
|
||||
@ -173,10 +127,9 @@ export class TemplateCompiler {
|
||||
|
||||
|
||||
|
||||
private _compileComponentRuntime(cacheKey: any, compMeta: CompileDirectiveMetadata,
|
||||
viewDirectives: CompileDirectiveMetadata[],
|
||||
pipes: CompilePipeMetadata[],
|
||||
compilingComponentsPath: any[]): CompiledTemplate {
|
||||
private _compileComponentRuntime(
|
||||
cacheKey: any, compMeta: CompileDirectiveMetadata, viewDirectives: CompileDirectiveMetadata[],
|
||||
pipes: CompilePipeMetadata[], compilingComponentsPath: any[]): CompiledTemplate {
|
||||
let uniqViewDirectives = <CompileDirectiveMetadata[]>removeDuplicates(viewDirectives);
|
||||
let uniqViewPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
||||
var compiledTemplate = this._compiledTemplateCache.get(cacheKey);
|
||||
@ -184,38 +137,37 @@ export class TemplateCompiler {
|
||||
if (isBlank(compiledTemplate)) {
|
||||
compiledTemplate = new CompiledTemplate();
|
||||
this._compiledTemplateCache.set(cacheKey, compiledTemplate);
|
||||
done = PromiseWrapper
|
||||
.all([<any>this._styleCompiler.compileComponentRuntime(compMeta.template)].concat(
|
||||
uniqViewDirectives.map(dirMeta => this.normalizeDirectiveMetadata(dirMeta))))
|
||||
.then((stylesAndNormalizedViewDirMetas: any[]) => {
|
||||
var normalizedViewDirMetas = stylesAndNormalizedViewDirMetas.slice(1);
|
||||
var styles = stylesAndNormalizedViewDirMetas[0];
|
||||
var parsedTemplate = this._templateParser.parse(
|
||||
compMeta.template.template, normalizedViewDirMetas, uniqViewPipes,
|
||||
compMeta.type.name);
|
||||
done =
|
||||
PromiseWrapper
|
||||
.all([<any>this._styleCompiler.compileComponentRuntime(compMeta.template)].concat(
|
||||
uniqViewDirectives.map(dirMeta => this.normalizeDirectiveMetadata(dirMeta))))
|
||||
.then((stylesAndNormalizedViewDirMetas: any[]) => {
|
||||
var normalizedViewDirMetas = stylesAndNormalizedViewDirMetas.slice(1);
|
||||
var styles = stylesAndNormalizedViewDirMetas[0];
|
||||
var parsedTemplate = this._templateParser.parse(
|
||||
compMeta.template.template, normalizedViewDirMetas, uniqViewPipes,
|
||||
compMeta.type.name);
|
||||
|
||||
var childPromises = [];
|
||||
var usedDirectives = DirectiveCollector.findUsedDirectives(parsedTemplate);
|
||||
usedDirectives.components.forEach(
|
||||
component => this._compileNestedComponentRuntime(
|
||||
component, compilingComponentsPath, childPromises));
|
||||
return PromiseWrapper.all(childPromises)
|
||||
.then((_) => {
|
||||
var filteredPipes = filterPipes(parsedTemplate, uniqViewPipes);
|
||||
compiledTemplate.init(this._createViewFactoryRuntime(
|
||||
compMeta, parsedTemplate, usedDirectives.directives, styles,
|
||||
filteredPipes));
|
||||
return compiledTemplate;
|
||||
});
|
||||
});
|
||||
var childPromises = [];
|
||||
var usedDirectives = DirectiveCollector.findUsedDirectives(parsedTemplate);
|
||||
usedDirectives.components.forEach(
|
||||
component => this._compileNestedComponentRuntime(
|
||||
component, compilingComponentsPath, childPromises));
|
||||
return PromiseWrapper.all(childPromises).then((_) => {
|
||||
var filteredPipes = filterPipes(parsedTemplate, uniqViewPipes);
|
||||
compiledTemplate.init(this._createViewFactoryRuntime(
|
||||
compMeta, parsedTemplate, usedDirectives.directives, styles, filteredPipes));
|
||||
return compiledTemplate;
|
||||
});
|
||||
});
|
||||
this._compiledTemplateDone.set(cacheKey, done);
|
||||
}
|
||||
return compiledTemplate;
|
||||
}
|
||||
|
||||
private _compileNestedComponentRuntime(childComponentDir: CompileDirectiveMetadata,
|
||||
parentCompilingComponentsPath: any[],
|
||||
childPromises: Promise<any>[]) {
|
||||
private _compileNestedComponentRuntime(
|
||||
childComponentDir: CompileDirectiveMetadata, parentCompilingComponentsPath: any[],
|
||||
childPromises: Promise<any>[]) {
|
||||
var compilingComponentsPath = ListWrapper.clone(parentCompilingComponentsPath);
|
||||
|
||||
var childCacheKey = childComponentDir.type.runtime;
|
||||
@ -225,18 +177,19 @@ export class TemplateCompiler {
|
||||
this._runtimeMetadataResolver.getViewPipesMetadata(childComponentDir.type.runtime);
|
||||
var childIsRecursive = ListWrapper.contains(compilingComponentsPath, childCacheKey);
|
||||
compilingComponentsPath.push(childCacheKey);
|
||||
this._compileComponentRuntime(childCacheKey, childComponentDir, childViewDirectives,
|
||||
childViewPipes, compilingComponentsPath);
|
||||
this._compileComponentRuntime(
|
||||
childCacheKey, childComponentDir, childViewDirectives, childViewPipes,
|
||||
compilingComponentsPath);
|
||||
if (!childIsRecursive) {
|
||||
// Only wait for a child if it is not a cycle
|
||||
childPromises.push(this._compiledTemplateDone.get(childCacheKey));
|
||||
}
|
||||
}
|
||||
|
||||
private _createViewFactoryRuntime(compMeta: CompileDirectiveMetadata,
|
||||
parsedTemplate: TemplateAst[],
|
||||
directives: CompileDirectiveMetadata[], styles: string[],
|
||||
pipes: CompilePipeMetadata[]): Function {
|
||||
private _createViewFactoryRuntime(
|
||||
compMeta: CompileDirectiveMetadata, parsedTemplate: TemplateAst[],
|
||||
directives: CompileDirectiveMetadata[], styles: string[],
|
||||
pipes: CompilePipeMetadata[]): Function {
|
||||
if (IS_DART || !this._genConfig.useJit) {
|
||||
var changeDetectorFactories = this._cdCompiler.compileComponentRuntime(
|
||||
compMeta.type, compMeta.changeDetection, parsedTemplate);
|
||||
@ -247,11 +200,14 @@ export class TemplateCompiler {
|
||||
(compMeta) => this._getNestedComponentViewFactory(compMeta));
|
||||
} else {
|
||||
var declarations = [];
|
||||
var viewFactoryExpr = this._createViewFactoryCodeGen('resolvedMetadataCache', compMeta,
|
||||
new SourceExpression([], 'styles'),
|
||||
parsedTemplate, pipes, declarations);
|
||||
var vars: {[key: string]: any} =
|
||||
{'exports': {}, 'styles': styles, 'resolvedMetadataCache': this._resolvedMetadataCache};
|
||||
var viewFactoryExpr = this._createViewFactoryCodeGen(
|
||||
'resolvedMetadataCache', compMeta, new SourceExpression([], 'styles'), parsedTemplate,
|
||||
pipes, declarations);
|
||||
var vars: {[key: string]: any} = {
|
||||
'exports': {},
|
||||
'styles': styles,
|
||||
'resolvedMetadataCache': this._resolvedMetadataCache
|
||||
};
|
||||
directives.forEach(dirMeta => {
|
||||
vars[dirMeta.type.name] = dirMeta.type.runtime;
|
||||
if (dirMeta.isComponent && dirMeta.type.runtime !== compMeta.type.runtime) {
|
||||
@ -272,25 +228,24 @@ export class TemplateCompiler {
|
||||
return this._compiledTemplateCache.get(compMeta.type.runtime).viewFactory;
|
||||
}
|
||||
|
||||
private _compileComponentCodeGen(compMeta: CompileDirectiveMetadata,
|
||||
directives: CompileDirectiveMetadata[],
|
||||
pipes: CompilePipeMetadata[],
|
||||
targetDeclarations: string[]): string {
|
||||
private _compileComponentCodeGen(
|
||||
compMeta: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
|
||||
pipes: CompilePipeMetadata[], targetDeclarations: string[]): string {
|
||||
let uniqueDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
|
||||
let uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
||||
var styleExpr = this._styleCompiler.compileComponentCodeGen(compMeta.template);
|
||||
var parsedTemplate = this._templateParser.parse(compMeta.template.template, uniqueDirectives,
|
||||
uniqPipes, compMeta.type.name);
|
||||
var parsedTemplate = this._templateParser.parse(
|
||||
compMeta.template.template, uniqueDirectives, uniqPipes, compMeta.type.name);
|
||||
var filteredPipes = filterPipes(parsedTemplate, uniqPipes);
|
||||
return this._createViewFactoryCodeGen(
|
||||
`${METADATA_CACHE_MODULE_REF}CODEGEN_RESOLVED_METADATA_CACHE`, compMeta, styleExpr,
|
||||
parsedTemplate, filteredPipes, targetDeclarations);
|
||||
}
|
||||
|
||||
private _createViewFactoryCodeGen(resolvedMetadataCacheExpr: string,
|
||||
compMeta: CompileDirectiveMetadata, styleExpr: SourceExpression,
|
||||
parsedTemplate: TemplateAst[], pipes: CompilePipeMetadata[],
|
||||
targetDeclarations: string[]): string {
|
||||
private _createViewFactoryCodeGen(
|
||||
resolvedMetadataCacheExpr: string, compMeta: CompileDirectiveMetadata,
|
||||
styleExpr: SourceExpression, parsedTemplate: TemplateAst[], pipes: CompilePipeMetadata[],
|
||||
targetDeclarations: string[]): string {
|
||||
var changeDetectorsExprs = this._cdCompiler.compileComponentCodeGen(
|
||||
compMeta.type, compMeta.changeDetection, parsedTemplate);
|
||||
var protoViewExprs = this._protoViewCompiler.compileProtoViewCodeGen(
|
||||
@ -308,8 +263,9 @@ export class TemplateCompiler {
|
||||
}
|
||||
|
||||
export class NormalizedComponentWithViewDirectives {
|
||||
constructor(public component: CompileDirectiveMetadata,
|
||||
public directives: CompileDirectiveMetadata[], public pipes: CompilePipeMetadata[]) {}
|
||||
constructor(
|
||||
public component: CompileDirectiveMetadata, public directives: CompileDirectiveMetadata[],
|
||||
public pipes: CompilePipeMetadata[]) {}
|
||||
}
|
||||
|
||||
class CompiledTemplate {
|
||||
@ -348,8 +304,9 @@ function removeDuplicates(items: CompileMetadataWithType[]): CompileMetadataWith
|
||||
let res = [];
|
||||
items.forEach(item => {
|
||||
let hasMatch =
|
||||
res.filter(r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl &&
|
||||
r.type.runtime == item.type.runtime)
|
||||
res.filter(
|
||||
r => 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);
|
||||
@ -401,8 +358,8 @@ class DirectiveCollector implements TemplateAstVisitor {
|
||||
}
|
||||
|
||||
|
||||
function filterPipes(template: TemplateAst[],
|
||||
allPipes: CompilePipeMetadata[]): CompilePipeMetadata[] {
|
||||
function filterPipes(
|
||||
template: TemplateAst[], allPipes: CompilePipeMetadata[]): CompilePipeMetadata[] {
|
||||
var visitor = new PipeVisitor();
|
||||
templateVisitAll(visitor, template);
|
||||
return allPipes.filter((pipeMeta) => SetWrapper.has(visitor.collector.pipes, pipeMeta.name));
|
||||
|
@ -1,8 +1,4 @@
|
||||
import {
|
||||
CompileTypeMetadata,
|
||||
CompileDirectiveMetadata,
|
||||
CompileTemplateMetadata
|
||||
} from './directive_metadata';
|
||||
import {CompileTypeMetadata, CompileDirectiveMetadata, CompileTemplateMetadata} from './directive_metadata';
|
||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
@ -14,41 +10,35 @@ import {Injectable} from 'angular2/src/core/di';
|
||||
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
||||
|
||||
|
||||
import {
|
||||
HtmlAstVisitor,
|
||||
HtmlElementAst,
|
||||
HtmlTextAst,
|
||||
HtmlAttrAst,
|
||||
HtmlAst,
|
||||
HtmlCommentAst,
|
||||
htmlVisitAll
|
||||
} from './html_ast';
|
||||
import {HtmlAstVisitor, HtmlElementAst, HtmlTextAst, HtmlAttrAst, HtmlAst, HtmlCommentAst, htmlVisitAll} from './html_ast';
|
||||
import {HtmlParser} from './html_parser';
|
||||
|
||||
import {preparseElement, PreparsedElement, PreparsedElementType} from './template_preparser';
|
||||
|
||||
@Injectable()
|
||||
export class TemplateNormalizer {
|
||||
constructor(private _xhr: XHR, private _urlResolver: UrlResolver,
|
||||
private _htmlParser: HtmlParser) {}
|
||||
constructor(
|
||||
private _xhr: XHR, private _urlResolver: UrlResolver, private _htmlParser: HtmlParser) {}
|
||||
|
||||
normalizeTemplate(directiveType: CompileTypeMetadata,
|
||||
template: CompileTemplateMetadata): Promise<CompileTemplateMetadata> {
|
||||
normalizeTemplate(directiveType: CompileTypeMetadata, template: CompileTemplateMetadata):
|
||||
Promise<CompileTemplateMetadata> {
|
||||
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));
|
||||
.then(
|
||||
templateContent => this.normalizeLoadedTemplate(
|
||||
directiveType, template, templateContent, sourceAbsUrl));
|
||||
} else {
|
||||
throw new BaseException(`No template specified for component ${directiveType.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
normalizeLoadedTemplate(directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata,
|
||||
template: string, templateAbsUrl: string): CompileTemplateMetadata {
|
||||
normalizeLoadedTemplate(
|
||||
directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata, template: string,
|
||||
templateAbsUrl: string): CompileTemplateMetadata {
|
||||
var rootNodesAndErrors = this._htmlParser.parse(template, directiveType.name);
|
||||
if (rootNodesAndErrors.errors.length > 0) {
|
||||
var errorString = rootNodesAndErrors.errors.join('\n');
|
||||
|
@ -11,23 +11,7 @@ import {splitNsName, mergeNsAndName} from './html_tags';
|
||||
import {ParseSourceSpan, ParseError, ParseLocation} from './parse_util';
|
||||
import {RecursiveAstVisitor, BindingPipe} from 'angular2/src/core/change_detection/parser/ast';
|
||||
|
||||
import {
|
||||
ElementAst,
|
||||
BoundElementPropertyAst,
|
||||
BoundEventAst,
|
||||
VariableAst,
|
||||
TemplateAst,
|
||||
TemplateAstVisitor,
|
||||
templateVisitAll,
|
||||
TextAst,
|
||||
BoundTextAst,
|
||||
EmbeddedTemplateAst,
|
||||
AttrAst,
|
||||
NgContentAst,
|
||||
PropertyBindingType,
|
||||
DirectiveAst,
|
||||
BoundDirectivePropertyAst
|
||||
} from './template_ast';
|
||||
import {ElementAst, BoundElementPropertyAst, BoundEventAst, VariableAst, TemplateAst, TemplateAstVisitor, templateVisitAll, TextAst, BoundTextAst, EmbeddedTemplateAst, AttrAst, NgContentAst, PropertyBindingType, DirectiveAst, BoundDirectivePropertyAst} from './template_ast';
|
||||
import {CssSelector, SelectorMatcher} from 'angular2/src/compiler/selector';
|
||||
|
||||
import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry';
|
||||
@ -35,15 +19,7 @@ import {preparseElement, PreparsedElement, PreparsedElementType} from './templat
|
||||
|
||||
import {isStyleUrlResolvable} from './style_url_resolver';
|
||||
|
||||
import {
|
||||
HtmlAstVisitor,
|
||||
HtmlAst,
|
||||
HtmlElementAst,
|
||||
HtmlAttrAst,
|
||||
HtmlTextAst,
|
||||
HtmlCommentAst,
|
||||
htmlVisitAll
|
||||
} from './html_ast';
|
||||
import {HtmlAstVisitor, HtmlAst, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, htmlVisitAll} from './html_ast';
|
||||
|
||||
import {splitAtColon} from './util';
|
||||
|
||||
@ -89,12 +65,14 @@ export class TemplateParseResult {
|
||||
|
||||
@Injectable()
|
||||
export class TemplateParser {
|
||||
constructor(private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
|
||||
private _htmlParser: HtmlParser,
|
||||
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
|
||||
constructor(
|
||||
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
|
||||
private _htmlParser: HtmlParser,
|
||||
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
|
||||
|
||||
parse(template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||
templateUrl: string): TemplateAst[] {
|
||||
parse(
|
||||
template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||
templateUrl: string): TemplateAst[] {
|
||||
var result = this.tryParse(template, directives, pipes, templateUrl);
|
||||
if (isPresent(result.errors)) {
|
||||
var errorString = result.errors.join('\n');
|
||||
@ -103,8 +81,9 @@ export class TemplateParser {
|
||||
return result.templateAst;
|
||||
}
|
||||
|
||||
tryParse(template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||
templateUrl: string): TemplateParseResult {
|
||||
tryParse(
|
||||
template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||
templateUrl: string): TemplateParseResult {
|
||||
var parseVisitor =
|
||||
new TemplateParseVisitor(directives, pipes, this._exprParser, this._schemaRegistry);
|
||||
var htmlAstWithErrors = this._htmlParser.parse(template, templateUrl);
|
||||
@ -128,15 +107,16 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
ngContentCount: number = 0;
|
||||
pipesByName: Map<string, CompilePipeMetadata>;
|
||||
|
||||
constructor(directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry) {
|
||||
constructor(
|
||||
directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry) {
|
||||
this.selectorMatcher = new SelectorMatcher();
|
||||
ListWrapper.forEachWithIndex(directives,
|
||||
(directive: CompileDirectiveMetadata, index: number) => {
|
||||
var selector = CssSelector.parse(directive.selector);
|
||||
this.selectorMatcher.addSelectables(selector, directive);
|
||||
this.directivesIndex.set(directive, index);
|
||||
});
|
||||
ListWrapper.forEachWithIndex(
|
||||
directives, (directive: CompileDirectiveMetadata, index: number) => {
|
||||
var selector = CssSelector.parse(directive.selector);
|
||||
this.selectorMatcher.addSelectables(selector, directive);
|
||||
this.directivesIndex.set(directive, index);
|
||||
});
|
||||
this.pipesByName = new Map<string, CompilePipeMetadata>();
|
||||
pipes.forEach(pipe => this.pipesByName.set(pipe.name, pipe));
|
||||
}
|
||||
@ -275,13 +255,14 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
elementOrDirectiveProps, isTemplateElement ? [] : vars, element.sourceSpan);
|
||||
var elementProps: BoundElementPropertyAst[] =
|
||||
this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directives);
|
||||
var children = htmlVisitAll(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this,
|
||||
element.children, Component.create(directives));
|
||||
var children = htmlVisitAll(
|
||||
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
|
||||
Component.create(directives));
|
||||
|
||||
// Override the actual selector when the `ngProjectAs` attribute is provided
|
||||
var projectionSelector = isPresent(preparsedElement.projectAs) ?
|
||||
CssSelector.parse(preparsedElement.projectAs)[0] :
|
||||
elementCssSelector;
|
||||
CssSelector.parse(preparsedElement.projectAs)[0] :
|
||||
elementCssSelector;
|
||||
var ngContentIndex = component.findNgContentIndex(projectionSelector);
|
||||
var parsedElement;
|
||||
|
||||
@ -296,21 +277,21 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||
} else if (isTemplateElement) {
|
||||
this._assertAllEventsPublishedByDirectives(directives, events);
|
||||
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps,
|
||||
element.sourceSpan);
|
||||
this._assertNoComponentsNorElementBindingsOnTemplate(
|
||||
directives, elementProps, element.sourceSpan);
|
||||
|
||||
parsedElement =
|
||||
new EmbeddedTemplateAst(attrs, events, vars, directives, children,
|
||||
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||
parsedElement = new EmbeddedTemplateAst(
|
||||
attrs, events, vars, directives, children, hasInlineTemplates ? null : ngContentIndex,
|
||||
element.sourceSpan);
|
||||
} else {
|
||||
this._assertOnlyOneComponent(directives, element.sourceSpan);
|
||||
var elementExportAsVars = vars.filter(varAst => varAst.value.length === 0);
|
||||
let ngContentIndex =
|
||||
hasInlineTemplates ? null : component.findNgContentIndex(projectionSelector);
|
||||
|
||||
parsedElement =
|
||||
new ElementAst(nodeName, attrs, elementProps, events, elementExportAsVars, directives,
|
||||
children, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||
parsedElement = new ElementAst(
|
||||
nodeName, attrs, elementProps, events, elementExportAsVars, directives, children,
|
||||
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||
}
|
||||
if (hasInlineTemplates) {
|
||||
var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
|
||||
@ -319,18 +300,19 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
templateElementOrDirectiveProps, [], element.sourceSpan);
|
||||
var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
|
||||
element.name, templateElementOrDirectiveProps, templateDirectives);
|
||||
this._assertNoComponentsNorElementBindingsOnTemplate(templateDirectives, templateElementProps,
|
||||
element.sourceSpan);
|
||||
this._assertNoComponentsNorElementBindingsOnTemplate(
|
||||
templateDirectives, templateElementProps, element.sourceSpan);
|
||||
|
||||
parsedElement = new EmbeddedTemplateAst([], [], templateVars, templateDirectives,
|
||||
[parsedElement], ngContentIndex, element.sourceSpan);
|
||||
parsedElement = new EmbeddedTemplateAst(
|
||||
[], [], templateVars, templateDirectives, [parsedElement], ngContentIndex,
|
||||
element.sourceSpan);
|
||||
}
|
||||
return parsedElement;
|
||||
}
|
||||
|
||||
private _parseInlineTemplateBinding(attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[],
|
||||
targetVars: VariableAst[]): boolean {
|
||||
private _parseInlineTemplateBinding(
|
||||
attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[], targetVars: VariableAst[]): boolean {
|
||||
var templateBindingsSource = null;
|
||||
if (attr.name == TEMPLATE_ATTR) {
|
||||
templateBindingsSource = attr.value;
|
||||
@ -346,8 +328,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
targetVars.push(new VariableAst(binding.key, binding.name, attr.sourceSpan));
|
||||
targetMatchableAttrs.push([binding.key, binding.name]);
|
||||
} else if (isPresent(binding.expression)) {
|
||||
this._parsePropertyAst(binding.key, binding.expression, attr.sourceSpan,
|
||||
targetMatchableAttrs, targetProps);
|
||||
this._parsePropertyAst(
|
||||
binding.key, binding.expression, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
||||
} else {
|
||||
targetMatchableAttrs.push([binding.key, '']);
|
||||
this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps);
|
||||
@ -358,9 +340,10 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
private _parseAttr(attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[], targetEvents: BoundEventAst[],
|
||||
targetVars: VariableAst[]): boolean {
|
||||
private _parseAttr(
|
||||
attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[], targetEvents: BoundEventAst[],
|
||||
targetVars: VariableAst[]): boolean {
|
||||
var attrName = this._normalizeAttributeName(attr.name);
|
||||
var attrValue = attr.value;
|
||||
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
|
||||
@ -368,8 +351,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
if (isPresent(bindParts)) {
|
||||
hasBinding = true;
|
||||
if (isPresent(bindParts[1])) { // match: bind-prop
|
||||
this._parseProperty(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetProps);
|
||||
this._parseProperty(
|
||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
||||
|
||||
} else if (isPresent(
|
||||
bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
|
||||
@ -377,32 +360,32 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars);
|
||||
|
||||
} else if (isPresent(bindParts[3])) { // match: on-event
|
||||
this._parseEvent(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetEvents);
|
||||
this._parseEvent(
|
||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
||||
|
||||
} else if (isPresent(bindParts[4])) { // match: bindon-prop
|
||||
this._parseProperty(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetProps);
|
||||
this._parseAssignmentEvent(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetEvents);
|
||||
this._parseProperty(
|
||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
||||
this._parseAssignmentEvent(
|
||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
||||
|
||||
} else if (isPresent(bindParts[6])) { // match: [(expr)]
|
||||
this._parseProperty(bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetProps);
|
||||
this._parseAssignmentEvent(bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetEvents);
|
||||
this._parseProperty(
|
||||
bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
||||
this._parseAssignmentEvent(
|
||||
bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
||||
|
||||
} else if (isPresent(bindParts[7])) { // match: [expr]
|
||||
this._parseProperty(bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetProps);
|
||||
this._parseProperty(
|
||||
bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
||||
|
||||
} else if (isPresent(bindParts[8])) { // match: (event)
|
||||
this._parseEvent(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||
targetEvents);
|
||||
this._parseEvent(
|
||||
bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
||||
}
|
||||
} else {
|
||||
hasBinding = this._parsePropertyInterpolation(attrName, attrValue, attr.sourceSpan,
|
||||
targetMatchableAttrs, targetProps);
|
||||
hasBinding = this._parsePropertyInterpolation(
|
||||
attrName, attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
||||
}
|
||||
if (!hasBinding) {
|
||||
this._parseLiteralAttr(attrName, attrValue, attr.sourceSpan, targetProps);
|
||||
@ -414,24 +397,25 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
return attrName.toLowerCase().startsWith('data-') ? attrName.substring(5) : attrName;
|
||||
}
|
||||
|
||||
private _parseVariable(identifier: string, value: string, sourceSpan: ParseSourceSpan,
|
||||
targetVars: VariableAst[]) {
|
||||
private _parseVariable(
|
||||
identifier: string, value: string, sourceSpan: ParseSourceSpan, targetVars: VariableAst[]) {
|
||||
if (identifier.indexOf('-') > -1) {
|
||||
this._reportError(`"-" is not allowed in variable names`, sourceSpan);
|
||||
}
|
||||
targetVars.push(new VariableAst(identifier, value, sourceSpan));
|
||||
}
|
||||
|
||||
private _parseProperty(name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[]) {
|
||||
this._parsePropertyAst(name, this._parseBinding(expression, sourceSpan), sourceSpan,
|
||||
targetMatchableAttrs, targetProps);
|
||||
private _parseProperty(
|
||||
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
|
||||
this._parsePropertyAst(
|
||||
name, this._parseBinding(expression, sourceSpan), sourceSpan, targetMatchableAttrs,
|
||||
targetProps);
|
||||
}
|
||||
|
||||
private _parsePropertyInterpolation(name: string, value: string, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[]): boolean {
|
||||
private _parsePropertyInterpolation(
|
||||
name: string, value: string, sourceSpan: ParseSourceSpan, targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[]): boolean {
|
||||
var expr = this._parseInterpolation(value, sourceSpan);
|
||||
if (isPresent(expr)) {
|
||||
this._parsePropertyAst(name, expr, sourceSpan, targetMatchableAttrs, targetProps);
|
||||
@ -440,21 +424,23 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
private _parsePropertyAst(name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][],
|
||||
targetProps: BoundElementOrDirectiveProperty[]) {
|
||||
private _parsePropertyAst(
|
||||
name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
|
||||
targetMatchableAttrs.push([name, ast.source]);
|
||||
targetProps.push(new BoundElementOrDirectiveProperty(name, ast, false, sourceSpan));
|
||||
}
|
||||
|
||||
private _parseAssignmentEvent(name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
||||
this._parseEvent(`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs,
|
||||
targetEvents);
|
||||
private _parseAssignmentEvent(
|
||||
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
||||
this._parseEvent(
|
||||
`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs, targetEvents);
|
||||
}
|
||||
|
||||
private _parseEvent(name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
||||
private _parseEvent(
|
||||
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
||||
// long format: 'target: eventName'
|
||||
var parts = splitAtColon(name, [null, name]);
|
||||
var target = parts[0];
|
||||
@ -466,46 +452,47 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
// so don't add the event name to the matchableAttrs
|
||||
}
|
||||
|
||||
private _parseLiteralAttr(name: string, value: string, sourceSpan: ParseSourceSpan,
|
||||
targetProps: BoundElementOrDirectiveProperty[]) {
|
||||
private _parseLiteralAttr(
|
||||
name: string, value: string, sourceSpan: ParseSourceSpan,
|
||||
targetProps: BoundElementOrDirectiveProperty[]) {
|
||||
targetProps.push(new BoundElementOrDirectiveProperty(
|
||||
name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan));
|
||||
}
|
||||
|
||||
private _parseDirectives(selectorMatcher: SelectorMatcher,
|
||||
elementCssSelector: CssSelector): CompileDirectiveMetadata[] {
|
||||
private _parseDirectives(selectorMatcher: SelectorMatcher, elementCssSelector: CssSelector):
|
||||
CompileDirectiveMetadata[] {
|
||||
var directives = [];
|
||||
selectorMatcher.match(elementCssSelector,
|
||||
(selector, directive) => { directives.push(directive); });
|
||||
selectorMatcher.match(
|
||||
elementCssSelector, (selector, directive) => { directives.push(directive); });
|
||||
// Need to sort the directives so that we get consistent results throughout,
|
||||
// as selectorMatcher uses Maps inside.
|
||||
// Also need to make components the first directive in the array
|
||||
ListWrapper.sort(directives,
|
||||
(dir1: CompileDirectiveMetadata, dir2: CompileDirectiveMetadata) => {
|
||||
var dir1Comp = dir1.isComponent;
|
||||
var dir2Comp = dir2.isComponent;
|
||||
if (dir1Comp && !dir2Comp) {
|
||||
return -1;
|
||||
} else if (!dir1Comp && dir2Comp) {
|
||||
return 1;
|
||||
} else {
|
||||
return this.directivesIndex.get(dir1) - this.directivesIndex.get(dir2);
|
||||
}
|
||||
});
|
||||
ListWrapper.sort(
|
||||
directives, (dir1: CompileDirectiveMetadata, dir2: CompileDirectiveMetadata) => {
|
||||
var dir1Comp = dir1.isComponent;
|
||||
var dir2Comp = dir2.isComponent;
|
||||
if (dir1Comp && !dir2Comp) {
|
||||
return -1;
|
||||
} else if (!dir1Comp && dir2Comp) {
|
||||
return 1;
|
||||
} else {
|
||||
return this.directivesIndex.get(dir1) - this.directivesIndex.get(dir2);
|
||||
}
|
||||
});
|
||||
return directives;
|
||||
}
|
||||
|
||||
private _createDirectiveAsts(elementName: string, directives: CompileDirectiveMetadata[],
|
||||
props: BoundElementOrDirectiveProperty[],
|
||||
possibleExportAsVars: VariableAst[],
|
||||
sourceSpan: ParseSourceSpan): DirectiveAst[] {
|
||||
private _createDirectiveAsts(
|
||||
elementName: string, directives: CompileDirectiveMetadata[],
|
||||
props: BoundElementOrDirectiveProperty[], possibleExportAsVars: VariableAst[],
|
||||
sourceSpan: ParseSourceSpan): DirectiveAst[] {
|
||||
var matchedVariables = new Set<string>();
|
||||
var directiveAsts = directives.map((directive: CompileDirectiveMetadata) => {
|
||||
var hostProperties: BoundElementPropertyAst[] = [];
|
||||
var hostEvents: BoundEventAst[] = [];
|
||||
var directiveProperties: BoundDirectivePropertyAst[] = [];
|
||||
this._createDirectiveHostPropertyAsts(elementName, directive.hostProperties, sourceSpan,
|
||||
hostProperties);
|
||||
this._createDirectiveHostPropertyAsts(
|
||||
elementName, directive.hostProperties, sourceSpan, hostProperties);
|
||||
this._createDirectiveHostEventAsts(directive.hostListeners, sourceSpan, hostEvents);
|
||||
this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties);
|
||||
var exportAsVars = [];
|
||||
@ -516,21 +503,21 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
matchedVariables.add(varAst.name);
|
||||
}
|
||||
});
|
||||
return new DirectiveAst(directive, directiveProperties, hostProperties, hostEvents,
|
||||
exportAsVars, sourceSpan);
|
||||
return new DirectiveAst(
|
||||
directive, directiveProperties, hostProperties, hostEvents, exportAsVars, sourceSpan);
|
||||
});
|
||||
possibleExportAsVars.forEach((varAst) => {
|
||||
if (varAst.value.length > 0 && !SetWrapper.has(matchedVariables, varAst.name)) {
|
||||
this._reportError(`There is no directive with "exportAs" set to "${varAst.value}"`,
|
||||
varAst.sourceSpan);
|
||||
this._reportError(
|
||||
`There is no directive with "exportAs" set to "${varAst.value}"`, varAst.sourceSpan);
|
||||
}
|
||||
});
|
||||
return directiveAsts;
|
||||
}
|
||||
|
||||
private _createDirectiveHostPropertyAsts(elementName: string, hostProps: {[key: string]: string},
|
||||
sourceSpan: ParseSourceSpan,
|
||||
targetPropertyAsts: BoundElementPropertyAst[]) {
|
||||
private _createDirectiveHostPropertyAsts(
|
||||
elementName: string, hostProps: {[key: string]: string}, sourceSpan: ParseSourceSpan,
|
||||
targetPropertyAsts: BoundElementPropertyAst[]) {
|
||||
if (isPresent(hostProps)) {
|
||||
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
|
||||
var exprAst = this._parseBinding(expression, sourceSpan);
|
||||
@ -540,9 +527,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private _createDirectiveHostEventAsts(hostListeners: {[key: string]: string},
|
||||
sourceSpan: ParseSourceSpan,
|
||||
targetEventAsts: BoundEventAst[]) {
|
||||
private _createDirectiveHostEventAsts(
|
||||
hostListeners: {[key: string]: string}, sourceSpan: ParseSourceSpan,
|
||||
targetEventAsts: BoundEventAst[]) {
|
||||
if (isPresent(hostListeners)) {
|
||||
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
|
||||
this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts);
|
||||
@ -550,9 +537,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private _createDirectivePropertyAsts(directiveProperties: {[key: string]: string},
|
||||
boundProps: BoundElementOrDirectiveProperty[],
|
||||
targetBoundDirectiveProps: BoundDirectivePropertyAst[]) {
|
||||
private _createDirectivePropertyAsts(
|
||||
directiveProperties: {[key: string]: string}, boundProps: BoundElementOrDirectiveProperty[],
|
||||
targetBoundDirectiveProps: BoundDirectivePropertyAst[]) {
|
||||
if (isPresent(directiveProperties)) {
|
||||
var boundPropsByName = new Map<string, BoundElementOrDirectiveProperty>();
|
||||
boundProps.forEach(boundProp => {
|
||||
@ -575,8 +562,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private _createElementPropertyAsts(elementName: string, props: BoundElementOrDirectiveProperty[],
|
||||
directives: DirectiveAst[]): BoundElementPropertyAst[] {
|
||||
private _createElementPropertyAsts(
|
||||
elementName: string, props: BoundElementOrDirectiveProperty[],
|
||||
directives: DirectiveAst[]): BoundElementPropertyAst[] {
|
||||
var boundElementProps: BoundElementPropertyAst[] = [];
|
||||
var boundDirectivePropsIndex = new Map<string, BoundDirectivePropertyAst>();
|
||||
directives.forEach((directive: DirectiveAst) => {
|
||||
@ -586,15 +574,16 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
});
|
||||
props.forEach((prop: BoundElementOrDirectiveProperty) => {
|
||||
if (!prop.isLiteral && isBlank(boundDirectivePropsIndex.get(prop.name))) {
|
||||
boundElementProps.push(this._createElementPropertyAst(elementName, prop.name,
|
||||
prop.expression, prop.sourceSpan));
|
||||
boundElementProps.push(this._createElementPropertyAst(
|
||||
elementName, prop.name, prop.expression, prop.sourceSpan));
|
||||
}
|
||||
});
|
||||
return boundElementProps;
|
||||
}
|
||||
|
||||
private _createElementPropertyAst(elementName: string, name: string, ast: AST,
|
||||
sourceSpan: ParseSourceSpan): BoundElementPropertyAst {
|
||||
private _createElementPropertyAst(
|
||||
elementName: string, name: string, ast: AST,
|
||||
sourceSpan: ParseSourceSpan): BoundElementPropertyAst {
|
||||
var unit = null;
|
||||
var bindingType;
|
||||
var boundPropertyName;
|
||||
@ -652,13 +641,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private _assertNoComponentsNorElementBindingsOnTemplate(directives: DirectiveAst[],
|
||||
elementProps: BoundElementPropertyAst[],
|
||||
sourceSpan: ParseSourceSpan) {
|
||||
private _assertNoComponentsNorElementBindingsOnTemplate(
|
||||
directives: DirectiveAst[], elementProps: BoundElementPropertyAst[],
|
||||
sourceSpan: ParseSourceSpan) {
|
||||
var componentTypeNames: string[] = this._findComponentDirectiveNames(directives);
|
||||
if (componentTypeNames.length > 0) {
|
||||
this._reportError(`Components on an embedded template: ${componentTypeNames.join(',')}`,
|
||||
sourceSpan);
|
||||
this._reportError(
|
||||
`Components on an embedded template: ${componentTypeNames.join(',')}`, sourceSpan);
|
||||
}
|
||||
elementProps.forEach(prop => {
|
||||
this._reportError(
|
||||
@ -667,12 +656,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
});
|
||||
}
|
||||
|
||||
private _assertAllEventsPublishedByDirectives(directives: DirectiveAst[],
|
||||
events: BoundEventAst[]) {
|
||||
private _assertAllEventsPublishedByDirectives(
|
||||
directives: DirectiveAst[], events: BoundEventAst[]) {
|
||||
var allDirectiveEvents = new Set<string>();
|
||||
directives.forEach(directive => {
|
||||
StringMapWrapper.forEach(directive.directive.outputs,
|
||||
(eventName: string, _) => { allDirectiveEvents.add(eventName); });
|
||||
StringMapWrapper.forEach(directive.directive.outputs, (eventName: string, _) => {
|
||||
allDirectiveEvents.add(eventName);
|
||||
});
|
||||
});
|
||||
events.forEach(event => {
|
||||
if (isPresent(event.target) || !SetWrapper.has(allDirectiveEvents, event.name)) {
|
||||
@ -700,8 +690,9 @@ class NonBindableVisitor implements HtmlAstVisitor {
|
||||
var selector = createElementCssSelector(ast.name, attrNameAndValues);
|
||||
var ngContentIndex = component.findNgContentIndex(selector);
|
||||
var children = htmlVisitAll(this, ast.children, EMPTY_COMPONENT);
|
||||
return new ElementAst(ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], children,
|
||||
ngContentIndex, ast.sourceSpan);
|
||||
return new ElementAst(
|
||||
ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], children, ngContentIndex,
|
||||
ast.sourceSpan);
|
||||
}
|
||||
visitComment(ast: HtmlCommentAst, context: any): any { return null; }
|
||||
visitAttr(ast: HtmlAttrAst, context: any): AttrAst {
|
||||
@ -714,8 +705,9 @@ class NonBindableVisitor implements HtmlAstVisitor {
|
||||
}
|
||||
|
||||
class BoundElementOrDirectiveProperty {
|
||||
constructor(public name: string, public expression: AST, public isLiteral: boolean,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
constructor(
|
||||
public name: string, public expression: AST, public isLiteral: boolean,
|
||||
public sourceSpan: ParseSourceSpan) {}
|
||||
}
|
||||
|
||||
export function splitClasses(classAttrValue: string): string[] {
|
||||
@ -740,8 +732,8 @@ class Component {
|
||||
}
|
||||
return new Component(matcher, wildcardNgContentIndex);
|
||||
}
|
||||
constructor(public ngContentIndexMatcher: SelectorMatcher,
|
||||
public wildcardNgContentIndex: number) {}
|
||||
constructor(
|
||||
public ngContentIndexMatcher: SelectorMatcher, public wildcardNgContentIndex: number) {}
|
||||
|
||||
findNgContentIndex(selector: CssSelector): number {
|
||||
var ngContentIndices = [];
|
||||
|
@ -59,8 +59,9 @@ export enum PreparsedElementType {
|
||||
}
|
||||
|
||||
export class PreparsedElement {
|
||||
constructor(public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string,
|
||||
public nonBindable: boolean, public projectAs: string) {}
|
||||
constructor(
|
||||
public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string,
|
||||
public nonBindable: boolean, public projectAs: string) {}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {Injectable, Inject} from 'angular2/src/core/di';
|
||||
import {
|
||||
StringWrapper,
|
||||
isPresent,
|
||||
isBlank,
|
||||
RegExpWrapper,
|
||||
normalizeBlank
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {StringWrapper, isPresent, isBlank, RegExpWrapper, normalizeBlank} from 'angular2/src/facade/lang';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {PACKAGE_ROOT_URL} from 'angular2/src/core/application_tokens';
|
||||
@ -21,7 +15,7 @@ export function createWithoutPackagePrefix(): UrlResolver {
|
||||
/**
|
||||
* A default provider for {@link PACKAGE_ROOT_URL} that maps to '/'.
|
||||
*/
|
||||
export var DEFAULT_PACKAGE_URL_PROVIDER = new Provider(PACKAGE_ROOT_URL, {useValue: "/"});
|
||||
export var DEFAULT_PACKAGE_URL_PROVIDER = new Provider(PACKAGE_ROOT_URL, {useValue: '/'});
|
||||
|
||||
/**
|
||||
* Used by the {@link Compiler} when resolving HTML and CSS template URLs.
|
||||
@ -40,7 +34,7 @@ export class UrlResolver {
|
||||
|
||||
constructor(@Inject(PACKAGE_ROOT_URL) packagePrefix: string = null) {
|
||||
if (isPresent(packagePrefix)) {
|
||||
this._packagePrefix = StringWrapper.stripRight(packagePrefix, "/") + "/";
|
||||
this._packagePrefix = StringWrapper.stripRight(packagePrefix, '/') + '/';
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +55,8 @@ export class UrlResolver {
|
||||
if (isPresent(baseUrl) && baseUrl.length > 0) {
|
||||
resolvedUrl = _resolveUrl(baseUrl, resolvedUrl);
|
||||
}
|
||||
if (isPresent(this._packagePrefix) && getUrlScheme(resolvedUrl) == "package") {
|
||||
resolvedUrl = resolvedUrl.replace("package:", this._packagePrefix);
|
||||
if (isPresent(this._packagePrefix) && getUrlScheme(resolvedUrl) == 'package') {
|
||||
resolvedUrl = resolvedUrl.replace('package:', this._packagePrefix);
|
||||
}
|
||||
return resolvedUrl;
|
||||
}
|
||||
@ -73,7 +67,7 @@ export class UrlResolver {
|
||||
*/
|
||||
export function getUrlScheme(url: string): string {
|
||||
var match = _split(url);
|
||||
return (match && match[_ComponentIndex.Scheme]) || "";
|
||||
return (match && match[_ComponentIndex.Scheme]) || '';
|
||||
}
|
||||
|
||||
// The code below is adapted from Traceur:
|
||||
@ -96,9 +90,9 @@ export function getUrlScheme(url: string): string {
|
||||
* @param {?string=} opt_fragment The URI-encoded fragment identifier.
|
||||
* @return {string} The fully combined URI.
|
||||
*/
|
||||
function _buildFromEncodedParts(opt_scheme?: string, opt_userInfo?: string, opt_domain?: string,
|
||||
opt_port?: string, opt_path?: string, opt_queryData?: string,
|
||||
opt_fragment?: string): string {
|
||||
function _buildFromEncodedParts(
|
||||
opt_scheme?: string, opt_userInfo?: string, opt_domain?: string, opt_port?: string,
|
||||
opt_path?: string, opt_queryData?: string, opt_fragment?: string): string {
|
||||
var out = [];
|
||||
|
||||
if (isPresent(opt_scheme)) {
|
||||
@ -196,24 +190,24 @@ function _buildFromEncodedParts(opt_scheme?: string, opt_userInfo?: string, opt_
|
||||
* @type {!RegExp}
|
||||
* @internal
|
||||
*/
|
||||
var _splitRe =
|
||||
RegExpWrapper.create('^' +
|
||||
'(?:' +
|
||||
'([^:/?#.]+)' + // scheme - ignore special characters
|
||||
// used by other URL parts such as :,
|
||||
// ?, /, #, and .
|
||||
':)?' +
|
||||
'(?://' +
|
||||
'(?:([^/?#]*)@)?' + // userInfo
|
||||
'([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters,
|
||||
// digits, dashes, dots, percent
|
||||
// escapes, and unicode characters.
|
||||
'(?::([0-9]+))?' + // port
|
||||
')?' +
|
||||
'([^?#]+)?' + // path
|
||||
'(?:\\?([^#]*))?' + // query
|
||||
'(?:#(.*))?' + // fragment
|
||||
'$');
|
||||
var _splitRe = RegExpWrapper.create(
|
||||
'^' +
|
||||
'(?:' +
|
||||
'([^:/?#.]+)' + // scheme - ignore special characters
|
||||
// used by other URL parts such as :,
|
||||
// ?, /, #, and .
|
||||
':)?' +
|
||||
'(?://' +
|
||||
'(?:([^/?#]*)@)?' + // userInfo
|
||||
'([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters,
|
||||
// digits, dashes, dots, percent
|
||||
// escapes, and unicode characters.
|
||||
'(?::([0-9]+))?' + // port
|
||||
')?' +
|
||||
'([^?#]+)?' + // path
|
||||
'(?:\\?([^#]*))?' + // query
|
||||
'(?:#(.*))?' + // fragment
|
||||
'$');
|
||||
|
||||
/**
|
||||
* The index of each URI component in the return value of goog.uri.utils.split.
|
||||
@ -244,7 +238,7 @@ enum _ComponentIndex {
|
||||
* on the browser's regular expression implementation. Never null, since
|
||||
* arbitrary strings may still look like path names.
|
||||
*/
|
||||
function _split(uri: string): Array<string | any> {
|
||||
function _split(uri: string): Array<string|any> {
|
||||
return RegExpWrapper.firstMatch(_splitRe, uri);
|
||||
}
|
||||
|
||||
@ -304,9 +298,10 @@ function _joinAndCanonicalizePath(parts: any[]): string {
|
||||
path = isBlank(path) ? '' : _removeDotSegments(path);
|
||||
parts[_ComponentIndex.Path] = path;
|
||||
|
||||
return _buildFromEncodedParts(parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo],
|
||||
parts[_ComponentIndex.Domain], parts[_ComponentIndex.Port], path,
|
||||
parts[_ComponentIndex.QueryData], parts[_ComponentIndex.Fragment]);
|
||||
return _buildFromEncodedParts(
|
||||
parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo], parts[_ComponentIndex.Domain],
|
||||
parts[_ComponentIndex.Port], path, parts[_ComponentIndex.QueryData],
|
||||
parts[_ComponentIndex.Fragment]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,4 @@
|
||||
import {
|
||||
IS_DART,
|
||||
StringWrapper,
|
||||
isBlank,
|
||||
isPresent,
|
||||
isString,
|
||||
isArray
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {IS_DART, StringWrapper, isBlank, isPresent, isString, isArray} from 'angular2/src/facade/lang';
|
||||
|
||||
var CAMEL_CASE_REGEXP = /([A-Z])/g;
|
||||
var DASH_CASE_REGEXP = /-([a-z])/g;
|
||||
@ -17,13 +10,13 @@ export var MODULE_SUFFIX = IS_DART ? '.dart' : '.js';
|
||||
export var CONST_VAR = IS_DART ? 'const' : 'var';
|
||||
|
||||
export function camelCaseToDashCase(input: string): string {
|
||||
return StringWrapper.replaceAllMapped(input, CAMEL_CASE_REGEXP,
|
||||
(m) => { return '-' + m[1].toLowerCase(); });
|
||||
return StringWrapper.replaceAllMapped(
|
||||
input, CAMEL_CASE_REGEXP, (m) => { return '-' + m[1].toLowerCase(); });
|
||||
}
|
||||
|
||||
export function dashCaseToCamelCase(input: string): string {
|
||||
return StringWrapper.replaceAllMapped(input, DASH_CASE_REGEXP,
|
||||
(m) => { return m[1].toUpperCase(); });
|
||||
return StringWrapper.replaceAllMapped(
|
||||
input, DASH_CASE_REGEXP, (m) => { return m[1].toUpperCase(); });
|
||||
}
|
||||
|
||||
export function escapeSingleQuoteString(input: string): string {
|
||||
|
@ -1,65 +1,18 @@
|
||||
import {
|
||||
isPresent,
|
||||
isBlank,
|
||||
Type,
|
||||
isString,
|
||||
StringWrapper,
|
||||
IS_DART,
|
||||
CONST_EXPR
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {isPresent, isBlank, Type, isString, StringWrapper, IS_DART, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {SetWrapper, StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {
|
||||
TemplateAst,
|
||||
TemplateAstVisitor,
|
||||
NgContentAst,
|
||||
EmbeddedTemplateAst,
|
||||
ElementAst,
|
||||
VariableAst,
|
||||
BoundEventAst,
|
||||
BoundElementPropertyAst,
|
||||
AttrAst,
|
||||
BoundTextAst,
|
||||
TextAst,
|
||||
DirectiveAst,
|
||||
BoundDirectivePropertyAst,
|
||||
templateVisitAll
|
||||
} from './template_ast';
|
||||
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
|
||||
import {CompileTypeMetadata, CompileDirectiveMetadata} from './directive_metadata';
|
||||
import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
|
||||
import {
|
||||
AppProtoView,
|
||||
AppView,
|
||||
flattenNestedViewRenderNodes,
|
||||
checkSlotCount
|
||||
} from 'angular2/src/core/linker/view';
|
||||
import {AppProtoView, AppView, flattenNestedViewRenderNodes, checkSlotCount} from 'angular2/src/core/linker/view';
|
||||
import {ViewType} from 'angular2/src/core/linker/view_type';
|
||||
import {AppViewManager_} from 'angular2/src/core/linker/view_manager';
|
||||
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
|
||||
import {Renderer, ParentRenderer} from 'angular2/src/core/render/api';
|
||||
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
||||
import {
|
||||
escapeSingleQuoteString,
|
||||
codeGenConstConstructorCall,
|
||||
codeGenValueFn,
|
||||
codeGenFnHeader,
|
||||
MODULE_SUFFIX,
|
||||
Statement,
|
||||
escapeValue,
|
||||
codeGenArray,
|
||||
codeGenFlatArray,
|
||||
Expression,
|
||||
flattenArray,
|
||||
CONST_VAR
|
||||
} from './util';
|
||||
import {escapeSingleQuoteString, codeGenConstConstructorCall, codeGenValueFn, codeGenFnHeader, MODULE_SUFFIX, Statement, escapeValue, codeGenArray, codeGenFlatArray, Expression, flattenArray, CONST_VAR} from './util';
|
||||
import {ResolvedProvider, Injectable, Injector} from 'angular2/src/core/di';
|
||||
|
||||
import {
|
||||
APP_VIEW_MODULE_REF,
|
||||
APP_EL_MODULE_REF,
|
||||
METADATA_MODULE_REF,
|
||||
CompileProtoView,
|
||||
CompileProtoElement
|
||||
} from './proto_view_compiler';
|
||||
import {APP_VIEW_MODULE_REF, APP_EL_MODULE_REF, METADATA_MODULE_REF, CompileProtoView, CompileProtoElement} from './proto_view_compiler';
|
||||
|
||||
export const VIEW_JIT_IMPORTS = CONST_EXPR({
|
||||
'AppView': AppView,
|
||||
@ -73,74 +26,77 @@ export const VIEW_JIT_IMPORTS = CONST_EXPR({
|
||||
export class ViewCompiler {
|
||||
constructor() {}
|
||||
|
||||
compileComponentRuntime(component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||
styles: Array<string | any[]>,
|
||||
protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
||||
changeDetectorFactories: Function[],
|
||||
componentViewFactory: Function): Function {
|
||||
var viewFactory = new RuntimeViewFactory(component, styles, protoViews, changeDetectorFactories,
|
||||
componentViewFactory);
|
||||
compileComponentRuntime(
|
||||
component: CompileDirectiveMetadata, template: TemplateAst[], styles: Array<string|any[]>,
|
||||
protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
||||
changeDetectorFactories: Function[], componentViewFactory: Function): Function {
|
||||
var viewFactory = new RuntimeViewFactory(
|
||||
component, styles, protoViews, changeDetectorFactories, componentViewFactory);
|
||||
return viewFactory.createViewFactory(template, 0, []);
|
||||
}
|
||||
|
||||
compileComponentCodeGen(component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||
styles: SourceExpression,
|
||||
protoViews: CompileProtoView<Expression, Expression>[],
|
||||
changeDetectorFactoryExpressions: SourceExpressions,
|
||||
componentViewFactory: Function): SourceExpression {
|
||||
compileComponentCodeGen(
|
||||
component: CompileDirectiveMetadata, template: TemplateAst[], styles: SourceExpression,
|
||||
protoViews: CompileProtoView<Expression, Expression>[],
|
||||
changeDetectorFactoryExpressions: SourceExpressions,
|
||||
componentViewFactory: Function): SourceExpression {
|
||||
var viewFactory = new CodeGenViewFactory(
|
||||
component, styles, protoViews, changeDetectorFactoryExpressions, componentViewFactory);
|
||||
var targetStatements: Statement[] = [];
|
||||
var viewFactoryExpression = viewFactory.createViewFactory(template, 0, targetStatements);
|
||||
return new SourceExpression(targetStatements.map(stmt => stmt.statement),
|
||||
viewFactoryExpression.expression);
|
||||
return new SourceExpression(
|
||||
targetStatements.map(stmt => stmt.statement), viewFactoryExpression.expression);
|
||||
}
|
||||
}
|
||||
|
||||
interface ViewFactory<EXPRESSION, STATEMENT> {
|
||||
createText(renderer: EXPRESSION, parent: EXPRESSION, text: string,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
createText(renderer: EXPRESSION, parent: EXPRESSION, text: string, targetStatements: STATEMENT[]):
|
||||
EXPRESSION;
|
||||
|
||||
createElement(renderer: EXPRESSION, parent: EXPRESSION, name: string, rootSelector: EXPRESSION,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
createElement(
|
||||
renderer: EXPRESSION, parent: EXPRESSION, name: string, rootSelector: EXPRESSION,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
|
||||
createTemplateAnchor(renderer: EXPRESSION, parent: EXPRESSION,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
createTemplateAnchor(renderer: EXPRESSION, parent: EXPRESSION, targetStatements: STATEMENT[]):
|
||||
EXPRESSION;
|
||||
|
||||
createGlobalEventListener(renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number,
|
||||
eventAst: BoundEventAst, targetStatements: STATEMENT[]): EXPRESSION;
|
||||
createGlobalEventListener(
|
||||
renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, eventAst: BoundEventAst,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
|
||||
createElementEventListener(renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number,
|
||||
renderNode: EXPRESSION, eventAst: BoundEventAst,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
createElementEventListener(
|
||||
renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, renderNode: EXPRESSION,
|
||||
eventAst: BoundEventAst, targetStatements: STATEMENT[]): EXPRESSION;
|
||||
|
||||
setElementAttribute(renderer: EXPRESSION, renderNode: EXPRESSION, attrName: string,
|
||||
attrValue: string, targetStatements: STATEMENT[]);
|
||||
setElementAttribute(
|
||||
renderer: EXPRESSION, renderNode: EXPRESSION, attrName: string, attrValue: string,
|
||||
targetStatements: STATEMENT[]);
|
||||
|
||||
createAppElement(appProtoEl: EXPRESSION, view: EXPRESSION, renderNode: EXPRESSION,
|
||||
parentAppEl: EXPRESSION, embeddedViewFactory: EXPRESSION,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
createAppElement(
|
||||
appProtoEl: EXPRESSION, view: EXPRESSION, renderNode: EXPRESSION, parentAppEl: EXPRESSION,
|
||||
embeddedViewFactory: EXPRESSION, targetStatements: STATEMENT[]): EXPRESSION;
|
||||
|
||||
createAndSetComponentView(renderer: EXPRESSION, viewManager: EXPRESSION, view: EXPRESSION,
|
||||
appEl: EXPRESSION, component: CompileDirectiveMetadata,
|
||||
contentNodesByNgContentIndex: EXPRESSION[][],
|
||||
targetStatements: STATEMENT[]);
|
||||
createAndSetComponentView(
|
||||
renderer: EXPRESSION, viewManager: EXPRESSION, view: EXPRESSION, appEl: EXPRESSION,
|
||||
component: CompileDirectiveMetadata, contentNodesByNgContentIndex: EXPRESSION[][],
|
||||
targetStatements: STATEMENT[]);
|
||||
|
||||
getProjectedNodes(projectableNodes: EXPRESSION, ngContentIndex: number): EXPRESSION;
|
||||
|
||||
appendProjectedNodes(renderer: EXPRESSION, parent: EXPRESSION, nodes: EXPRESSION,
|
||||
targetStatements: STATEMENT[]);
|
||||
appendProjectedNodes(
|
||||
renderer: EXPRESSION, parent: EXPRESSION, nodes: EXPRESSION, targetStatements: STATEMENT[]);
|
||||
|
||||
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
createViewFactory(
|
||||
asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||
targetStatements: STATEMENT[]): EXPRESSION;
|
||||
}
|
||||
|
||||
class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
private _nextVarId: number = 0;
|
||||
constructor(public component: CompileDirectiveMetadata, public styles: SourceExpression,
|
||||
public protoViews: CompileProtoView<Expression, Expression>[],
|
||||
public changeDetectorExpressions: SourceExpressions,
|
||||
public componentViewFactory: Function) {}
|
||||
constructor(
|
||||
public component: CompileDirectiveMetadata, public styles: SourceExpression,
|
||||
public protoViews: CompileProtoView<Expression, Expression>[],
|
||||
public changeDetectorExpressions: SourceExpressions, public componentViewFactory: Function) {}
|
||||
|
||||
private _nextVar(prefix: string): string {
|
||||
return `${prefix}${this._nextVarId++}_${this.component.type.name}`;
|
||||
@ -154,8 +110,8 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return `disposable${this._nextVarId++}_${this.component.type.name}`;
|
||||
}
|
||||
|
||||
createText(renderer: Expression, parent: Expression, text: string,
|
||||
targetStatements: Statement[]): Expression {
|
||||
createText(renderer: Expression, parent: Expression, text: string, targetStatements: Statement[]):
|
||||
Expression {
|
||||
var varName = this._nextRenderVar();
|
||||
var statement =
|
||||
`var ${varName} = ${renderer.expression}.createText(${isPresent(parent) ? parent.expression : null}, ${escapeSingleQuoteString(text)});`;
|
||||
@ -163,8 +119,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return new Expression(varName);
|
||||
}
|
||||
|
||||
createElement(renderer: Expression, parentRenderNode: Expression, name: string,
|
||||
rootSelector: Expression, targetStatements: Statement[]): Expression {
|
||||
createElement(
|
||||
renderer: Expression, parentRenderNode: Expression, name: string, rootSelector: Expression,
|
||||
targetStatements: Statement[]): Expression {
|
||||
var varName = this._nextRenderVar();
|
||||
var valueExpr;
|
||||
if (isPresent(rootSelector)) {
|
||||
@ -180,8 +137,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return new Expression(varName);
|
||||
}
|
||||
|
||||
createTemplateAnchor(renderer: Expression, parentRenderNode: Expression,
|
||||
targetStatements: Statement[]): Expression {
|
||||
createTemplateAnchor(
|
||||
renderer: Expression, parentRenderNode: Expression,
|
||||
targetStatements: Statement[]): Expression {
|
||||
var varName = this._nextRenderVar();
|
||||
var valueExpr =
|
||||
`${renderer.expression}.createTemplateAnchor(${isPresent(parentRenderNode) ? parentRenderNode.expression : null});`;
|
||||
@ -189,8 +147,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return new Expression(varName);
|
||||
}
|
||||
|
||||
createGlobalEventListener(renderer: Expression, appView: Expression, boundElementIndex: number,
|
||||
eventAst: BoundEventAst, targetStatements: Statement[]): Expression {
|
||||
createGlobalEventListener(
|
||||
renderer: Expression, appView: Expression, boundElementIndex: number, eventAst: BoundEventAst,
|
||||
targetStatements: Statement[]): Expression {
|
||||
var disposableVar = this._nextDisposableVar();
|
||||
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
|
||||
targetStatements.push(new Statement(
|
||||
@ -198,9 +157,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return new Expression(disposableVar);
|
||||
}
|
||||
|
||||
createElementEventListener(renderer: Expression, appView: Expression, boundElementIndex: number,
|
||||
renderNode: Expression, eventAst: BoundEventAst,
|
||||
targetStatements: Statement[]): Expression {
|
||||
createElementEventListener(
|
||||
renderer: Expression, appView: Expression, boundElementIndex: number, renderNode: Expression,
|
||||
eventAst: BoundEventAst, targetStatements: Statement[]): Expression {
|
||||
var disposableVar = this._nextDisposableVar();
|
||||
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
|
||||
targetStatements.push(new Statement(
|
||||
@ -208,15 +167,16 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return new Expression(disposableVar);
|
||||
}
|
||||
|
||||
setElementAttribute(renderer: Expression, renderNode: Expression, attrName: string,
|
||||
attrValue: string, targetStatements: Statement[]) {
|
||||
setElementAttribute(
|
||||
renderer: Expression, renderNode: Expression, attrName: string, attrValue: string,
|
||||
targetStatements: Statement[]) {
|
||||
targetStatements.push(new Statement(
|
||||
`${renderer.expression}.setElementAttribute(${renderNode.expression}, ${escapeSingleQuoteString(attrName)}, ${escapeSingleQuoteString(attrValue)});`));
|
||||
}
|
||||
|
||||
createAppElement(appProtoEl: Expression, appView: Expression, renderNode: Expression,
|
||||
parentAppEl: Expression, embeddedViewFactory: Expression,
|
||||
targetStatements: Statement[]): Expression {
|
||||
createAppElement(
|
||||
appProtoEl: Expression, appView: Expression, renderNode: Expression, parentAppEl: Expression,
|
||||
embeddedViewFactory: Expression, targetStatements: Statement[]): Expression {
|
||||
var appVar = this._nextAppVar();
|
||||
var varValue =
|
||||
`new ${APP_EL_MODULE_REF}AppElement(${appProtoEl.expression}, ${appView.expression},
|
||||
@ -225,10 +185,10 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return new Expression(appVar);
|
||||
}
|
||||
|
||||
createAndSetComponentView(renderer: Expression, viewManager: Expression, view: Expression,
|
||||
appEl: Expression, component: CompileDirectiveMetadata,
|
||||
contentNodesByNgContentIndex: Expression[][],
|
||||
targetStatements: Statement[]) {
|
||||
createAndSetComponentView(
|
||||
renderer: Expression, viewManager: Expression, view: Expression, appEl: Expression,
|
||||
component: CompileDirectiveMetadata, contentNodesByNgContentIndex: Expression[][],
|
||||
targetStatements: Statement[]) {
|
||||
var codeGenContentNodes;
|
||||
if (this.component.type.isHost) {
|
||||
codeGenContentNodes = `${view.expression}.projectableNodes`;
|
||||
@ -244,14 +204,15 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
return new Expression(`${projectableNodes.expression}[${ngContentIndex}]`, true);
|
||||
}
|
||||
|
||||
appendProjectedNodes(renderer: Expression, parent: Expression, nodes: Expression,
|
||||
targetStatements: Statement[]) {
|
||||
appendProjectedNodes(
|
||||
renderer: Expression, parent: Expression, nodes: Expression, targetStatements: Statement[]) {
|
||||
targetStatements.push(new Statement(
|
||||
`${renderer.expression}.projectNodes(${parent.expression}, ${APP_VIEW_MODULE_REF}flattenNestedViewRenderNodes(${nodes.expression}));`));
|
||||
}
|
||||
|
||||
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||
targetStatements: Statement[]): Expression {
|
||||
createViewFactory(
|
||||
asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||
targetStatements: Statement[]): Expression {
|
||||
var compileProtoView = this.protoViews[embeddedTemplateIndex];
|
||||
var isHostView = this.component.type.isHost;
|
||||
var isComponentView = embeddedTemplateIndex === 0 && !isHostView;
|
||||
@ -268,13 +229,8 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||
var viewFactoryName = codeGenViewFactoryName(this.component, embeddedTemplateIndex);
|
||||
var changeDetectorFactory = this.changeDetectorExpressions.expressions[embeddedTemplateIndex];
|
||||
var factoryArgs = [
|
||||
'parentRenderer',
|
||||
'viewManager',
|
||||
'containerEl',
|
||||
'projectableNodes',
|
||||
'rootSelector',
|
||||
'dynamicallyCreatedProviders',
|
||||
'rootInjector'
|
||||
'parentRenderer', 'viewManager', 'containerEl', 'projectableNodes', 'rootSelector',
|
||||
'dynamicallyCreatedProviders', 'rootInjector'
|
||||
];
|
||||
var initRendererStmts = [];
|
||||
var rendererExpr = `parentRenderer`;
|
||||
@ -316,16 +272,18 @@ ${codeGenFnHeader(factoryArgs, viewFactoryName)}{
|
||||
}
|
||||
|
||||
class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||
constructor(public component: CompileDirectiveMetadata, public styles: Array<string | any[]>,
|
||||
public protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
||||
public changeDetectorFactories: Function[], public componentViewFactory: Function) {}
|
||||
constructor(
|
||||
public component: CompileDirectiveMetadata, public styles: Array<string|any[]>,
|
||||
public protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
||||
public changeDetectorFactories: Function[], public componentViewFactory: Function) {}
|
||||
|
||||
createText(renderer: Renderer, parent: any, text: string, targetStatements: any[]): any {
|
||||
return renderer.createText(parent, text);
|
||||
}
|
||||
|
||||
createElement(renderer: Renderer, parent: any, name: string, rootSelector: string,
|
||||
targetStatements: any[]): any {
|
||||
createElement(
|
||||
renderer: Renderer, parent: any, name: string, rootSelector: string,
|
||||
targetStatements: any[]): any {
|
||||
var el;
|
||||
if (isPresent(rootSelector)) {
|
||||
el = renderer.selectRootElement(rootSelector);
|
||||
@ -339,36 +297,38 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||
return renderer.createTemplateAnchor(parent);
|
||||
}
|
||||
|
||||
createGlobalEventListener(renderer: Renderer, appView: AppView, boundElementIndex: number,
|
||||
eventAst: BoundEventAst, targetStatements: any[]): any {
|
||||
createGlobalEventListener(
|
||||
renderer: Renderer, appView: AppView, boundElementIndex: number, eventAst: BoundEventAst,
|
||||
targetStatements: any[]): any {
|
||||
return renderer.listenGlobal(
|
||||
eventAst.target, eventAst.name,
|
||||
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
|
||||
}
|
||||
|
||||
createElementEventListener(renderer: Renderer, appView: AppView, boundElementIndex: number,
|
||||
renderNode: any, eventAst: BoundEventAst,
|
||||
targetStatements: any[]): any {
|
||||
createElementEventListener(
|
||||
renderer: Renderer, appView: AppView, boundElementIndex: number, renderNode: any,
|
||||
eventAst: BoundEventAst, targetStatements: any[]): any {
|
||||
return renderer.listen(
|
||||
renderNode, eventAst.name,
|
||||
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
|
||||
}
|
||||
|
||||
setElementAttribute(renderer: Renderer, renderNode: any, attrName: string, attrValue: string,
|
||||
targetStatements: any[]) {
|
||||
setElementAttribute(
|
||||
renderer: Renderer, renderNode: any, attrName: string, attrValue: string,
|
||||
targetStatements: any[]) {
|
||||
renderer.setElementAttribute(renderNode, attrName, attrValue);
|
||||
}
|
||||
|
||||
createAppElement(appProtoEl: AppProtoElement, appView: AppView, renderNode: any,
|
||||
parentAppEl: AppElement, embeddedViewFactory: Function,
|
||||
targetStatements: any[]): any {
|
||||
createAppElement(
|
||||
appProtoEl: AppProtoElement, appView: AppView, renderNode: any, parentAppEl: AppElement,
|
||||
embeddedViewFactory: Function, targetStatements: any[]): any {
|
||||
return new AppElement(appProtoEl, appView, parentAppEl, renderNode, embeddedViewFactory);
|
||||
}
|
||||
|
||||
createAndSetComponentView(renderer: Renderer, viewManager: AppViewManager_, appView: AppView,
|
||||
appEl: AppElement, component: CompileDirectiveMetadata,
|
||||
contentNodesByNgContentIndex: Array<Array<any | any[]>>,
|
||||
targetStatements: any[]) {
|
||||
createAndSetComponentView(
|
||||
renderer: Renderer, viewManager: AppViewManager_, appView: AppView, appEl: AppElement,
|
||||
component: CompileDirectiveMetadata, contentNodesByNgContentIndex: Array<Array<any|any[]>>,
|
||||
targetStatements: any[]) {
|
||||
var flattenedContentNodes;
|
||||
if (this.component.type.isHost) {
|
||||
flattenedContentNodes = appView.projectableNodes;
|
||||
@ -389,8 +349,8 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||
renderer.projectNodes(parent, flattenNestedViewRenderNodes(nodes));
|
||||
}
|
||||
|
||||
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||
targetStatements: any[]): Function {
|
||||
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number, targetStatements: any[]):
|
||||
Function {
|
||||
var compileProtoView = this.protoViews[embeddedTemplateIndex];
|
||||
var isComponentView = compileProtoView.protoView.type === ViewType.COMPONENT;
|
||||
var renderComponentType = null;
|
||||
@ -398,8 +358,9 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||
projectableNodes: any[][], rootSelector: string = null,
|
||||
dynamicallyCreatedProviders: ResolvedProvider[] = null,
|
||||
rootInjector: Injector = null) => {
|
||||
checkSlotCount(this.component.type.name, this.component.template.ngContentSelectors.length,
|
||||
projectableNodes);
|
||||
checkSlotCount(
|
||||
this.component.type.name, this.component.template.ngContentSelectors.length,
|
||||
projectableNodes);
|
||||
var renderer;
|
||||
if (embeddedTemplateIndex === 0) {
|
||||
if (isBlank(renderComponentType)) {
|
||||
@ -411,16 +372,17 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||
renderer = <Renderer>parentRenderer;
|
||||
}
|
||||
var changeDetector = this.changeDetectorFactories[embeddedTemplateIndex]();
|
||||
var view =
|
||||
new AppView(compileProtoView.protoView, renderer, viewManager, projectableNodes,
|
||||
containerEl, dynamicallyCreatedProviders, rootInjector, changeDetector);
|
||||
var view = new AppView(
|
||||
compileProtoView.protoView, renderer, viewManager, projectableNodes, containerEl,
|
||||
dynamicallyCreatedProviders, rootInjector, changeDetector);
|
||||
var visitor = new ViewBuilderVisitor<any, any>(
|
||||
renderer, viewManager, projectableNodes, rootSelector, view, compileProtoView, [], this);
|
||||
var parentRenderNode =
|
||||
isComponentView ? renderer.createViewRoot(containerEl.nativeElement) : null;
|
||||
templateVisitAll(visitor, asts, new ParentElement(parentRenderNode, null, null));
|
||||
view.init(flattenArray(visitor.rootNodesOrAppElements, []), visitor.renderNodes,
|
||||
visitor.appDisposables, visitor.appElements);
|
||||
view.init(
|
||||
flattenArray(visitor.rootNodesOrAppElements, []), visitor.renderNodes,
|
||||
visitor.appDisposables, visitor.appElements);
|
||||
return view;
|
||||
};
|
||||
}
|
||||
@ -429,8 +391,9 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||
class ParentElement<EXPRESSION> {
|
||||
public contentNodesByNgContentIndex: Array<EXPRESSION>[];
|
||||
|
||||
constructor(public renderNode: EXPRESSION, public appEl: EXPRESSION,
|
||||
public component: CompileDirectiveMetadata) {
|
||||
constructor(
|
||||
public renderNode: EXPRESSION, public appEl: EXPRESSION,
|
||||
public component: CompileDirectiveMetadata) {
|
||||
if (isPresent(component)) {
|
||||
this.contentNodesByNgContentIndex =
|
||||
ListWrapper.createFixedSize(component.template.ngContentSelectors.length);
|
||||
@ -458,14 +421,15 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
|
||||
elementCount: number = 0;
|
||||
|
||||
constructor(public renderer: EXPRESSION, public viewManager: EXPRESSION,
|
||||
public projectableNodes: EXPRESSION, public rootSelector: EXPRESSION,
|
||||
public view: EXPRESSION, public protoView: CompileProtoView<EXPRESSION, EXPRESSION>,
|
||||
public targetStatements: STATEMENT[],
|
||||
public factory: ViewFactory<EXPRESSION, STATEMENT>) {}
|
||||
constructor(
|
||||
public renderer: EXPRESSION, public viewManager: EXPRESSION,
|
||||
public projectableNodes: EXPRESSION, public rootSelector: EXPRESSION, public view: EXPRESSION,
|
||||
public protoView: CompileProtoView<EXPRESSION, EXPRESSION>,
|
||||
public targetStatements: STATEMENT[], public factory: ViewFactory<EXPRESSION, STATEMENT>) {}
|
||||
|
||||
private _addRenderNode(renderNode: EXPRESSION, appEl: EXPRESSION, ngContentIndex: number,
|
||||
parent: ParentElement<EXPRESSION>) {
|
||||
private _addRenderNode(
|
||||
renderNode: EXPRESSION, appEl: EXPRESSION, ngContentIndex: number,
|
||||
parent: ParentElement<EXPRESSION>) {
|
||||
this.renderNodes.push(renderNode);
|
||||
if (isPresent(parent.component)) {
|
||||
if (isPresent(ngContentIndex)) {
|
||||
@ -476,12 +440,12 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private _getParentRenderNode(ngContentIndex: number,
|
||||
parent: ParentElement<EXPRESSION>): EXPRESSION {
|
||||
private _getParentRenderNode(ngContentIndex: number, parent: ParentElement<EXPRESSION>):
|
||||
EXPRESSION {
|
||||
return isPresent(parent.component) &&
|
||||
parent.component.template.encapsulation !== ViewEncapsulation.Native ?
|
||||
null :
|
||||
parent.renderNode;
|
||||
parent.component.template.encapsulation !== ViewEncapsulation.Native ?
|
||||
null :
|
||||
parent.renderNode;
|
||||
}
|
||||
|
||||
visitBoundText(ast: BoundTextAst, parent: ParentElement<EXPRESSION>): any {
|
||||
@ -505,8 +469,8 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
}
|
||||
} else {
|
||||
if (isPresent(parent.renderNode)) {
|
||||
this.factory.appendProjectedNodes(this.renderer, parent.renderNode, nodesExpression,
|
||||
this.renderStmts);
|
||||
this.factory.appendProjectedNodes(
|
||||
this.renderer, parent.renderNode, nodesExpression, this.renderStmts);
|
||||
} else {
|
||||
this.rootNodesOrAppElements.push(nodesExpression);
|
||||
}
|
||||
@ -529,22 +493,22 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
disposable = this.factory.createGlobalEventListener(
|
||||
this.renderer, this.view, protoEl.boundElementIndex, eventAst, this.renderStmts);
|
||||
} else {
|
||||
disposable = this.factory.createElementEventListener(this.renderer, this.view,
|
||||
protoEl.boundElementIndex, renderNode,
|
||||
eventAst, this.renderStmts);
|
||||
disposable = this.factory.createElementEventListener(
|
||||
this.renderer, this.view, protoEl.boundElementIndex, renderNode, eventAst,
|
||||
this.renderStmts);
|
||||
}
|
||||
this.appDisposables.push(disposable);
|
||||
});
|
||||
for (var i = 0; i < protoEl.attrNameAndValues.length; i++) {
|
||||
var attrName = protoEl.attrNameAndValues[i][0];
|
||||
var attrValue = protoEl.attrNameAndValues[i][1];
|
||||
this.factory.setElementAttribute(this.renderer, renderNode, attrName, attrValue,
|
||||
this.renderStmts);
|
||||
this.factory.setElementAttribute(
|
||||
this.renderer, renderNode, attrName, attrValue, this.renderStmts);
|
||||
}
|
||||
var appEl = null;
|
||||
if (isPresent(protoEl.appProtoEl)) {
|
||||
appEl = this.factory.createAppElement(protoEl.appProtoEl, this.view, renderNode, parent.appEl,
|
||||
null, this.appStmts);
|
||||
appEl = this.factory.createAppElement(
|
||||
protoEl.appProtoEl, this.view, renderNode, parent.appEl, null, this.appStmts);
|
||||
this.appElements.push(appEl);
|
||||
}
|
||||
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
|
||||
@ -553,9 +517,9 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
renderNode, isPresent(appEl) ? appEl : parent.appEl, component);
|
||||
templateVisitAll(this, ast.children, newParent);
|
||||
if (isPresent(appEl) && isPresent(component)) {
|
||||
this.factory.createAndSetComponentView(this.renderer, this.viewManager, this.view, appEl,
|
||||
component, newParent.contentNodesByNgContentIndex,
|
||||
this.appStmts);
|
||||
this.factory.createAndSetComponentView(
|
||||
this.renderer, this.viewManager, this.view, appEl, component,
|
||||
newParent.contentNodesByNgContentIndex, this.appStmts);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -569,8 +533,9 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
var embeddedViewFactory = this.factory.createViewFactory(
|
||||
ast.children, protoEl.embeddedTemplateIndex, this.targetStatements);
|
||||
|
||||
var appEl = this.factory.createAppElement(protoEl.appProtoEl, this.view, renderNode,
|
||||
parent.appEl, embeddedViewFactory, this.appStmts);
|
||||
var appEl = this.factory.createAppElement(
|
||||
protoEl.appProtoEl, this.view, renderNode, parent.appEl, embeddedViewFactory,
|
||||
this.appStmts);
|
||||
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
|
||||
this.appElements.push(appEl);
|
||||
return null;
|
||||
@ -585,15 +550,15 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
||||
}
|
||||
|
||||
|
||||
function codeGenEventHandler(view: Expression, boundElementIndex: number,
|
||||
eventName: string): string {
|
||||
function codeGenEventHandler(
|
||||
view: Expression, boundElementIndex: number, eventName: string): string {
|
||||
return codeGenValueFn(
|
||||
['event'],
|
||||
`${view.expression}.triggerEventHandlers(${escapeValue(eventName)}, event, ${boundElementIndex})`);
|
||||
}
|
||||
|
||||
function codeGenViewFactoryName(component: CompileDirectiveMetadata,
|
||||
embeddedTemplateIndex: number): string {
|
||||
function codeGenViewFactoryName(
|
||||
component: CompileDirectiveMetadata, embeddedTemplateIndex: number): string {
|
||||
return `viewFactory_${component.type.name}${embeddedTemplateIndex}`;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user