' : used to provide context in case of error
+ elementDescription: string; // e.g. '
' : used to provide context in case of
+ // error
constructor(element, compilationUnit = '') {
this.element = element;
@@ -34,7 +42,7 @@ export class CompileElement {
this.distanceToInheritedBinder = 0;
this.compileChildren = true;
// description is calculated here as compilation steps may change the element
- var tplDesc = assertionsEnabled()? getElementDescription(element) : null;
+ var tplDesc = assertionsEnabled() ? getElementDescription(element) : null;
if (compilationUnit !== '') {
this.elementDescription = compilationUnit;
if (isPresent(tplDesc)) this.elementDescription += ": " + tplDesc;
@@ -50,7 +58,8 @@ export class CompileElement {
bindElement() {
if (!this.isBound()) {
var parentBinder = this.inheritedElementBinder;
- this.inheritedElementBinder = this.inheritedProtoView.bindElement(this.element, this.elementDescription);
+ this.inheritedElementBinder =
+ this.inheritedProtoView.bindElement(this.element, this.elementDescription);
if (isPresent(parentBinder)) {
this.inheritedElementBinder.setParent(parentBinder, this.distanceToInheritedBinder);
}
@@ -59,22 +68,18 @@ export class CompileElement {
return this.inheritedElementBinder;
}
- refreshAttrs() {
- this._attrs = null;
- }
+ refreshAttrs() { this._attrs = null; }
- attrs():Map
{
+ attrs(): Map {
if (isBlank(this._attrs)) {
this._attrs = DOM.attributeMap(this.element);
}
return this._attrs;
}
- refreshClassList() {
- this._classList = null;
- }
+ refreshClassList() { this._classList = null; }
- classList():List {
+ classList(): List {
if (isBlank(this._classList)) {
this._classList = ListWrapper.create();
var elClassList = DOM.classList(this.element);
@@ -84,12 +89,11 @@ export class CompileElement {
}
return this._classList;
}
-
}
// return an HTML representation of an element start tag - without its content
// this is used to give contextual information in case of errors
-function getElementDescription(domElement):string {
+function getElementDescription(domElement): string {
var buf = new StringJoiner();
var atts = DOM.attributeMap(domElement);
@@ -100,9 +104,9 @@ function getElementDescription(domElement):string {
addDescriptionAttribute(buf, "id", MapWrapper.get(atts, "id"));
addDescriptionAttribute(buf, "class", MapWrapper.get(atts, "class"));
MapWrapper.forEach(atts, (attValue, attName) => {
- if (attName !== "id" && attName !== "class") {
- addDescriptionAttribute(buf, attName, attValue);
- }
+ if (attName !== "id" && attName !== "class") {
+ addDescriptionAttribute(buf, attName, attValue);
+ }
});
buf.add(">");
@@ -110,12 +114,12 @@ function getElementDescription(domElement):string {
}
-function addDescriptionAttribute(buffer:StringJoiner, attName:string, attValue) {
+function addDescriptionAttribute(buffer: StringJoiner, attName: string, attValue) {
if (isPresent(attValue)) {
- if (attValue.length === 0) {
- buffer.add(' ' + attName);
- } else {
- buffer.add(' ' + attName + '="' + attValue + '"');
- }
+ if (attValue.length === 0) {
+ buffer.add(' ' + attName);
+ } else {
+ buffer.add(' ' + attName + '="' + attValue + '"');
+ }
}
}
diff --git a/modules/angular2/src/render/dom/compiler/compile_pipeline.js b/modules/angular2/src/render/dom/compiler/compile_pipeline.ts
similarity index 78%
rename from modules/angular2/src/render/dom/compiler/compile_pipeline.js
rename to modules/angular2/src/render/dom/compiler/compile_pipeline.ts
index d8e4e15e19..36783edf20 100644
--- a/modules/angular2/src/render/dom/compiler/compile_pipeline.js
+++ b/modules/angular2/src/render/dom/compiler/compile_pipeline.ts
@@ -12,12 +12,11 @@ import {ProtoViewDto} from '../../api';
* all elements in a template.
*/
export class CompilePipeline {
- _control:CompileControl;
- constructor(steps:List) {
- this._control = new CompileControl(steps);
- }
+ _control: CompileControl;
+ constructor(steps: List) { this._control = new CompileControl(steps); }
- process(rootElement, protoViewType:number = null, compilationCtxtDescription:string = ''):List {
+ process(rootElement, protoViewType: number = null,
+ compilationCtxtDescription: string = ''): List {
if (isBlank(protoViewType)) {
protoViewType = ProtoViewDto.COMPONENT_VIEW_TYPE;
}
@@ -25,13 +24,12 @@ export class CompilePipeline {
var rootCompileElement = new CompileElement(rootElement, compilationCtxtDescription);
rootCompileElement.inheritedProtoView = new ProtoViewBuilder(rootElement, protoViewType);
rootCompileElement.isViewRoot = true;
- this._process(results, null, rootCompileElement,
- compilationCtxtDescription
- );
+ this._process(results, null, rootCompileElement, compilationCtxtDescription);
return results;
}
- _process(results, parent:CompileElement, current:CompileElement, compilationCtxtDescription:string = '') {
+ _process(results, parent: CompileElement, current: CompileElement,
+ compilationCtxtDescription: string = '') {
var additionalChildren = this._control.internalProcess(results, 0, parent, current);
if (current.compileChildren) {
@@ -44,7 +42,7 @@ export class CompilePipeline {
var childCompileElement = new CompileElement(node, compilationCtxtDescription);
childCompileElement.inheritedProtoView = current.inheritedProtoView;
childCompileElement.inheritedElementBinder = current.inheritedElementBinder;
- childCompileElement.distanceToInheritedBinder = current.distanceToInheritedBinder+1;
+ childCompileElement.distanceToInheritedBinder = current.distanceToInheritedBinder + 1;
this._process(results, current, childCompileElement);
}
node = nextNode;
@@ -52,7 +50,7 @@ export class CompilePipeline {
}
if (isPresent(additionalChildren)) {
- for (var i=0; i):List {
+ createSteps(template: ViewDefinition, subTaskPromises: List>): List {
return null;
}
}
@@ -27,7 +27,7 @@ export class DefaultStepFactory extends CompileStepFactory {
this._shadowDomStrategy = shadowDomStrategy;
}
- createSteps(template: ViewDefinition, subTaskPromises: List) {
+ createSteps(template: ViewDefinition, subTaskPromises: List>) {
return [
new ViewSplitter(this._parser),
new PropertyBindingParser(this._parser),
diff --git a/modules/angular2/src/render/dom/compiler/compiler.js b/modules/angular2/src/render/dom/compiler/compiler.ts
similarity index 70%
rename from modules/angular2/src/render/dom/compiler/compiler.js
rename to modules/angular2/src/render/dom/compiler/compiler.ts
index ad9e2ad23a..2d4ab3b7c4 100644
--- a/modules/angular2/src/render/dom/compiler/compiler.js
+++ b/modules/angular2/src/render/dom/compiler/compiler.ts
@@ -1,10 +1,16 @@
-import {Injectable} from 'angular2/src/di/annotations_impl';
+import {Injectable} from 'angular2/di';
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
import {BaseException, isPresent} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/dom/dom_adapter';
-import {ViewDefinition, ProtoViewDto, DirectiveMetadata, RenderCompiler, RenderProtoViewRef} from '../../api';
+import {
+ ViewDefinition,
+ ProtoViewDto,
+ DirectiveMetadata,
+ RenderCompiler,
+ RenderProtoViewRef
+} from '../../api';
import {CompilePipeline} from './compile_pipeline';
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory';
@@ -26,26 +32,27 @@ export class DomCompiler extends RenderCompiler {
this._stepFactory = stepFactory;
}
- compile(template: ViewDefinition):Promise {
+ compile(template: ViewDefinition): Promise {
var tplPromise = this._templateLoader.load(template);
- return PromiseWrapper.then(tplPromise,
- (el) => this._compileTemplate(template, el, ProtoViewDto.COMPONENT_VIEW_TYPE),
- (_) => { throw new BaseException(`Failed to load the template "${template.componentId}"`); }
- );
+ return PromiseWrapper.then(
+ tplPromise, (el) => this._compileTemplate(template, el, ProtoViewDto.COMPONENT_VIEW_TYPE),
+ (_) => {
+ throw new BaseException(`Failed to load the template "${template.componentId}"`);
+ });
}
- compileHost(directiveMetadata: DirectiveMetadata):Promise {
+ compileHost(directiveMetadata: DirectiveMetadata): Promise {
var hostViewDef = new ViewDefinition({
componentId: directiveMetadata.id,
- absUrl: null,
- template: null,
+ absUrl: null, template: null,
directives: [directiveMetadata]
});
var element = DOM.createElement(directiveMetadata.selector);
return this._compileTemplate(hostViewDef, element, ProtoViewDto.HOST_VIEW_TYPE);
}
- _compileTemplate(viewDef: ViewDefinition, tplElement, protoViewType:number):Promise {
+ _compileTemplate(viewDef: ViewDefinition, tplElement,
+ protoViewType: number): Promise {
var subTaskPromises = [];
var pipeline = new CompilePipeline(this._stepFactory.createSteps(viewDef, subTaskPromises));
var compileElements = pipeline.process(tplElement, protoViewType, viewDef.componentId);
@@ -62,7 +69,8 @@ export class DomCompiler extends RenderCompiler {
@Injectable()
export class DefaultDomCompiler extends DomCompiler {
- constructor(parser:Parser, shadowDomStrategy:ShadowDomStrategy, templateLoader: TemplateLoader) {
+ constructor(parser: Parser, shadowDomStrategy: ShadowDomStrategy,
+ templateLoader: TemplateLoader) {
super(new DefaultStepFactory(parser, shadowDomStrategy), templateLoader);
}
}
diff --git a/modules/angular2/src/render/dom/compiler/directive_parser.js b/modules/angular2/src/render/dom/compiler/directive_parser.ts
similarity index 74%
rename from modules/angular2/src/render/dom/compiler/directive_parser.js
rename to modules/angular2/src/render/dom/compiler/directive_parser.ts
index 3523f054a6..507a263852 100644
--- a/modules/angular2/src/render/dom/compiler/directive_parser.js
+++ b/modules/angular2/src/render/dom/compiler/directive_parser.ts
@@ -1,4 +1,11 @@
-import {isPresent, isBlank, BaseException, assertionsEnabled, RegExpWrapper, StringWrapper} from 'angular2/src/facade/lang';
+import {
+ isPresent,
+ isBlank,
+ BaseException,
+ assertionsEnabled,
+ RegExpWrapper,
+ StringWrapper
+} from 'angular2/src/facade/lang';
import {List, MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {Parser} from 'angular2/change_detection';
@@ -16,17 +23,16 @@ import {dashCaseToCamelCase, camelCaseToDashCase, EVENT_TARGET_SEPARATOR} from '
* Parses the directives on a single element. Assumes ViewSplitter has already created
* elements for template directives.
*/
-export class DirectiveParser extends CompileStep {
- _selectorMatcher:SelectorMatcher;
- _directives:List;
- _parser:Parser;
+export class DirectiveParser implements CompileStep {
+ _selectorMatcher: SelectorMatcher;
+ _directives: List;
+ _parser: Parser;
- constructor(parser: Parser, directives:List) {
- super();
+ constructor(parser: Parser, directives: List) {
this._parser = parser;
this._selectorMatcher = new SelectorMatcher();
this._directives = directives;
- for (var i=0; i {
- cssSelector.addAttribute(attrName, attrValue);
- });
+ MapWrapper.forEach(attrs,
+ (attrValue, attrName) => { cssSelector.addAttribute(attrName, attrValue); });
var componentDirective;
var foundDirectiveIndices = [];
@@ -66,7 +72,8 @@ export class DirectiveParser extends CompileStep {
// components need to go first, so it is easier to locate them in the result.
ListWrapper.insert(foundDirectiveIndices, 0, directiveIndex);
if (isPresent(componentDirective)) {
- throw new BaseException(`Only one component directive is allowed per element - check ${current.elementDescription}`);
+ throw new BaseException(
+ `Only one component directive is allowed per element - check ${current.elementDescription}`);
}
componentDirective = directive;
elementBinder.setComponentId(directive.id);
@@ -95,7 +102,8 @@ export class DirectiveParser extends CompileStep {
}
if (isPresent(directive.hostProperties)) {
MapWrapper.forEach(directive.hostProperties, (hostPropertyName, directivePropertyName) => {
- this._bindHostProperty(hostPropertyName, directivePropertyName, current, directiveBinderBuilder);
+ this._bindHostProperty(hostPropertyName, directivePropertyName, current,
+ directiveBinderBuilder);
});
}
if (isPresent(directive.hostAttributes)) {
@@ -104,9 +112,8 @@ export class DirectiveParser extends CompileStep {
});
}
if (isPresent(directive.readAttributes)) {
- ListWrapper.forEach(directive.readAttributes, (attrName) => {
- elementBinder.readAttribute(attrName);
- });
+ ListWrapper.forEach(directive.readAttributes,
+ (attrName) => { elementBinder.readAttribute(attrName); });
}
});
}
@@ -115,27 +122,21 @@ export class DirectiveParser extends CompileStep {
var pipes = this._splitBindConfig(bindConfig);
var elProp = ListWrapper.removeAt(pipes, 0);
- var bindingAst = MapWrapper.get(
- compileElement.bindElement().propertyBindings,
- dashCaseToCamelCase(elProp)
- );
+ var bindingAst =
+ MapWrapper.get(compileElement.bindElement().propertyBindings, dashCaseToCamelCase(elProp));
if (isBlank(bindingAst)) {
var attributeValue = MapWrapper.get(compileElement.attrs(), camelCaseToDashCase(elProp));
if (isPresent(attributeValue)) {
- bindingAst = this._parser.wrapLiteralPrimitive(
- attributeValue,
- compileElement.elementDescription
- );
+ bindingAst =
+ this._parser.wrapLiteralPrimitive(attributeValue, compileElement.elementDescription);
}
}
// Bindings are optional, so this binding only needs to be set up if an expression is given.
if (isPresent(bindingAst)) {
var fullExpAstWithBindPipes = this._parser.addPipes(bindingAst, pipes);
- directiveBinderBuilder.bindProperty(
- dirProperty, fullExpAstWithBindPipes
- );
+ directiveBinderBuilder.bindProperty(dirProperty, fullExpAstWithBindPipes);
}
}
@@ -154,24 +155,23 @@ export class DirectiveParser extends CompileStep {
directiveBinderBuilder.bindHostAction(actionName, actionExpression, ast);
}
- _bindHostProperty(hostPropertyName, directivePropertyName, compileElement, directiveBinderBuilder) {
+ _bindHostProperty(hostPropertyName, directivePropertyName, compileElement,
+ directiveBinderBuilder) {
var ast = this._parser.parseBinding(directivePropertyName,
- `hostProperties of ${compileElement.elementDescription}`);
+ `hostProperties of ${compileElement.elementDescription}`);
directiveBinderBuilder.bindHostProperty(hostPropertyName, ast);
}
_addHostAttribute(attrName, attrValue, compileElement) {
if (StringWrapper.equals(attrName, 'class')) {
- ListWrapper.forEach(attrValue.split(' '), (className) => {
- DOM.addClass(compileElement.element, className);
- });
+ ListWrapper.forEach(attrValue.split(' '),
+ (className) => { DOM.addClass(compileElement.element, className); });
} else if (!DOM.hasAttribute(compileElement.element, attrName)) {
DOM.setAttribute(compileElement.element, attrName, attrValue);
}
}
- _splitBindConfig(bindConfig:string) {
+ _splitBindConfig(bindConfig: string) {
return ListWrapper.map(bindConfig.split('|'), (s) => s.trim());
}
}
-
diff --git a/modules/angular2/src/render/dom/compiler/property_binding_parser.js b/modules/angular2/src/render/dom/compiler/property_binding_parser.ts
similarity index 62%
rename from modules/angular2/src/render/dom/compiler/property_binding_parser.js
rename to modules/angular2/src/render/dom/compiler/property_binding_parser.ts
index d868ac73bd..63f8f726e2 100644
--- a/modules/angular2/src/render/dom/compiler/property_binding_parser.js
+++ b/modules/angular2/src/render/dom/compiler/property_binding_parser.ts
@@ -22,92 +22,82 @@ var BIND_NAME_REGEXP = RegExpWrapper.create(
/**
* Parses the property bindings on a single element.
*/
-export class PropertyBindingParser extends CompileStep {
- _parser:Parser;
+export class PropertyBindingParser implements CompileStep {
+ _parser: Parser;
- constructor(parser:Parser) {
- super();
- this._parser = parser;
- }
+ constructor(parser: Parser) { this._parser = parser; }
- process(parent:CompileElement, current:CompileElement, control:CompileControl) {
+ process(parent: CompileElement, current: CompileElement, control: CompileControl) {
var attrs = current.attrs();
var newAttrs = MapWrapper.create();
MapWrapper.forEach(attrs, (attrValue, attrName) => {
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
if (isPresent(bindParts)) {
- if (isPresent(bindParts[1])) { // match: bind-prop
+ if (isPresent(bindParts[1])) { // match: bind-prop
this._bindProperty(bindParts[5], attrValue, current, newAttrs);
- } else if (isPresent(bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
+ } else if (isPresent(
+ bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
var identifier = bindParts[5];
var value = attrValue == '' ? '\$implicit' : attrValue;
this._bindVariable(identifier, value, current, newAttrs);
- } else if (isPresent(bindParts[3])) { // match: on-event
+ } else if (isPresent(bindParts[3])) { // match: on-event
this._bindEvent(bindParts[5], attrValue, current, newAttrs);
- } else if (isPresent(bindParts[4])) { // match: bindon-prop
+ } else if (isPresent(bindParts[4])) { // match: bindon-prop
this._bindProperty(bindParts[5], attrValue, current, newAttrs);
this._bindAssignmentEvent(bindParts[5], attrValue, current, newAttrs);
- } else if (isPresent(bindParts[6])) { // match: [(expr)]
+ } else if (isPresent(bindParts[6])) { // match: [(expr)]
this._bindProperty(bindParts[6], attrValue, current, newAttrs);
this._bindAssignmentEvent(bindParts[6], attrValue, current, newAttrs);
- } else if (isPresent(bindParts[7])) { // match: [expr]
+ } else if (isPresent(bindParts[7])) { // match: [expr]
this._bindProperty(bindParts[7], attrValue, current, newAttrs);
- } else if (isPresent(bindParts[8])) { // match: (event)
+ } else if (isPresent(bindParts[8])) { // match: (event)
this._bindEvent(bindParts[8], attrValue, current, newAttrs);
}
} else {
- var expr = this._parser.parseInterpolation(
- attrValue, current.elementDescription
- );
+ var expr = this._parser.parseInterpolation(attrValue, current.elementDescription);
if (isPresent(expr)) {
this._bindPropertyAst(attrName, expr, current, newAttrs);
}
}
});
- MapWrapper.forEach(newAttrs, (attrValue, attrName) => {
- MapWrapper.set(attrs, attrName, attrValue);
- });
+ MapWrapper.forEach(newAttrs,
+ (attrValue, attrName) => { MapWrapper.set(attrs, attrName, attrValue); });
}
- _bindVariable(identifier, value, current:CompileElement, newAttrs) {
+ _bindVariable(identifier, value, current: CompileElement, newAttrs) {
current.bindElement().bindVariable(dashCaseToCamelCase(identifier), value);
MapWrapper.set(newAttrs, identifier, value);
}
- _bindProperty(name, expression, current:CompileElement, newAttrs) {
- this._bindPropertyAst(
- name,
- this._parser.parseBinding(expression, current.elementDescription),
- current,
- newAttrs
- );
+ _bindProperty(name, expression, current: CompileElement, newAttrs) {
+ this._bindPropertyAst(name, this._parser.parseBinding(expression, current.elementDescription),
+ current, newAttrs);
}
- _bindPropertyAst(name, ast, current:CompileElement, newAttrs) {
+ _bindPropertyAst(name, ast, current: CompileElement, newAttrs) {
var binder = current.bindElement();
var camelCaseName = dashCaseToCamelCase(name);
binder.bindProperty(camelCaseName, ast);
MapWrapper.set(newAttrs, name, ast.source);
}
- _bindAssignmentEvent(name, expression, current:CompileElement, newAttrs) {
+ _bindAssignmentEvent(name, expression, current: CompileElement, newAttrs) {
this._bindEvent(name, `${expression}=$event`, current, newAttrs);
}
- _bindEvent(name, expression, current:CompileElement, newAttrs) {
+ _bindEvent(name, expression, current: CompileElement, newAttrs) {
current.bindElement().bindEvent(
- dashCaseToCamelCase(name), this._parser.parseAction(expression, current.elementDescription)
- );
+ dashCaseToCamelCase(name),
+ this._parser.parseAction(expression, current.elementDescription));
// Don't detect directives for event names for now,
// so don't add the event name to the CompileElement.attrs
}
-
}
diff --git a/modules/angular2/src/render/dom/compiler/selector.js b/modules/angular2/src/render/dom/compiler/selector.ts
similarity index 51%
rename from modules/angular2/src/render/dom/compiler/selector.js
rename to modules/angular2/src/render/dom/compiler/selector.ts
index 6386753396..8823524a44 100644
--- a/modules/angular2/src/render/dom/compiler/selector.js
+++ b/modules/angular2/src/render/dom/compiler/selector.ts
@@ -1,17 +1,24 @@
import {List, Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
-import {isPresent, isBlank, RegExpWrapper, RegExpMatcherWrapper, StringWrapper, BaseException} from 'angular2/src/facade/lang';
+import {
+ isPresent,
+ isBlank,
+ RegExpWrapper,
+ RegExpMatcherWrapper,
+ StringWrapper,
+ BaseException
+} from 'angular2/src/facade/lang';
const _EMPTY_ATTR_VALUE = '';
// TODO: Can't use `const` here as
// in Dart this is not transpiled into `final` yet...
-var _SELECTOR_REGEXP =
- RegExpWrapper.create('(\\:not\\()|' + //":not("
- '([-\\w]+)|' + // "tag"
- '(?:\\.([-\\w]+))|' + // ".class"
- '(?:\\[([-\\w*]+)(?:=([^\\]]*))?\\])|' + // "[name]", "[name=value]" or "[name*=value]"
- '(?:\\))|' + // ")"
- '(\\s*,\\s*)'); // ","
+var _SELECTOR_REGEXP = RegExpWrapper.create(
+ '(\\:not\\()|' + //":not("
+ '([-\\w]+)|' + // "tag"
+ '(?:\\.([-\\w]+))|' + // ".class"
+ '(?:\\[([-\\w*]+)(?:=([^\\]]*))?\\])|' + // "[name]", "[name=value]" or "[name*=value]"
+ '(?:\\))|' + // ")"
+ '(\\s*,\\s*)'); // ","
/**
* A css selector contains an element name,
@@ -19,110 +26,107 @@ var _SELECTOR_REGEXP =
* of selecting subsets out of them.
*/
export class CssSelector {
- element:string;
- classNames:List;
- attrs:List;
+ element: string;
+ classNames: List;
+ attrs: List;
notSelector: CssSelector;
- static parse(selector:string): List {
+ static parse(selector: string): List {
var results = ListWrapper.create();
var _addResult = (res, cssSel) => {
- if (isPresent(cssSel.notSelector) && isBlank(cssSel.element)
- && ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) {
+ if (isPresent(cssSel.notSelector) && isBlank(cssSel.element) &&
+ ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) {
cssSel.element = "*";
- }
- ListWrapper.push(res, cssSel);
- }
- var cssSelector = new CssSelector();
- var matcher = RegExpWrapper.matcher(_SELECTOR_REGEXP, selector);
- var match;
- var current = cssSelector;
- while (isPresent(match = RegExpMatcherWrapper.next(matcher))) {
- if (isPresent(match[1])) {
- if (isPresent(cssSelector.notSelector)) {
- throw new BaseException('Nesting :not is not allowed in a selector');
- }
- current.notSelector = new CssSelector();
- current = current.notSelector;
- }
- if (isPresent(match[2])) {
- current.setElement(match[2]);
- }
- if (isPresent(match[3])) {
- current.addClassName(match[3]);
- }
- if (isPresent(match[4])) {
- current.addAttribute(match[4], match[5]);
- }
- if (isPresent(match[6])) {
- _addResult(results, cssSelector);
- cssSelector = current = new CssSelector();
- }
- }
- _addResult(results, cssSelector);
- return results;
+ } ListWrapper.push(res, cssSel);
}
+ var cssSelector = new CssSelector();
+ var matcher = RegExpWrapper.matcher(_SELECTOR_REGEXP, selector);
+ var match;
+ var current = cssSelector;
+ while (isPresent(match = RegExpMatcherWrapper.next(matcher))) {
+ if (isPresent(match[1])) {
+ if (isPresent(cssSelector.notSelector)) {
+ throw new BaseException('Nesting :not is not allowed in a selector');
+ }
+ current.notSelector = new CssSelector();
+ current = current.notSelector;
+ }
+ if (isPresent(match[2])) {
+ current.setElement(match[2]);
+ }
+ if (isPresent(match[3])) {
+ current.addClassName(match[3]);
+ }
+ if (isPresent(match[4])) {
+ current.addAttribute(match[4], match[5]);
+ }
+ if (isPresent(match[6])) {
+ _addResult(results, cssSelector);
+ cssSelector = current = new CssSelector();
+ }
+ }
+ _addResult(results, cssSelector);
+ return results;
+}
- constructor() {
- this.element = null;
- this.classNames = ListWrapper.create();
- this.attrs = ListWrapper.create();
- this.notSelector = null;
- }
+constructor() {
+ this.element = null;
+ this.classNames = ListWrapper.create();
+ this.attrs = ListWrapper.create();
+ this.notSelector = null;
+}
- isElementSelector():boolean {
- return isPresent(this.element) &&
- ListWrapper.isEmpty(this.classNames) &&
- ListWrapper.isEmpty(this.attrs) &&
- isBlank(this.notSelector);
- }
+isElementSelector(): boolean {
+ return isPresent(this.element) && ListWrapper.isEmpty(this.classNames) &&
+ ListWrapper.isEmpty(this.attrs) && isBlank(this.notSelector);
+}
- setElement(element:string = null) {
- if (isPresent(element)) {
- element = element.toLowerCase();
+setElement(element: string = null) {
+ if (isPresent(element)) {
+ element = element.toLowerCase();
+ }
+ this.element = element;
+}
+
+addAttribute(name: string, value: string = _EMPTY_ATTR_VALUE) {
+ ListWrapper.push(this.attrs, name.toLowerCase());
+ if (isPresent(value)) {
+ value = value.toLowerCase();
+ } else {
+ value = _EMPTY_ATTR_VALUE;
+ }
+ ListWrapper.push(this.attrs, value);
+}
+
+addClassName(name: string) {
+ ListWrapper.push(this.classNames, name.toLowerCase());
+}
+
+toString(): string {
+ var res = '';
+ if (isPresent(this.element)) {
+ res += this.element;
+ }
+ if (isPresent(this.classNames)) {
+ for (var i = 0; i < this.classNames.length; i++) {
+ res += '.' + this.classNames[i];
}
- this.element = element;
}
-
- addAttribute(name:string, value:string = _EMPTY_ATTR_VALUE) {
- ListWrapper.push(this.attrs, name.toLowerCase());
- if (isPresent(value)) {
- value = value.toLowerCase();
- } else {
- value = _EMPTY_ATTR_VALUE;
- }
- ListWrapper.push(this.attrs, value);
- }
-
- addClassName(name:string) {
- ListWrapper.push(this.classNames, name.toLowerCase());
- }
-
- toString():string {
- var res = '';
- if (isPresent(this.element)) {
- res += this.element;
- }
- if (isPresent(this.classNames)) {
- for (var i=0; i 0) {
+ res += '=' + attrValue;
}
+ res += ']';
}
- if (isPresent(this.attrs)) {
- for (var i=0; i 0) {
- res += '=' + attrValue;
- }
- res += ']';
- }
- }
- if (isPresent(this.notSelector)) {
- res += ":not(" + this.notSelector.toString() + ")";
- }
- return res;
}
+ if (isPresent(this.notSelector)) {
+ res += ":not(" + this.notSelector.toString() + ")";
+ }
+ return res;
+}
}
/**
@@ -130,13 +134,20 @@ export class CssSelector {
* are contained in a given CssSelector.
*/
export class SelectorMatcher {
- _elementMap:Map;
- _elementPartialMap:Map;
- _classMap:Map;
- _classPartialMap:Map;
- _attrValueMap:Map;
- _attrValuePartialMap:Map;
- _listContexts:List;
+ static createNotMatcher(notSelector:CssSelector) {
+ var notMatcher = new SelectorMatcher();
+ notMatcher._addSelectable(notSelector, null, null);
+ return notMatcher;
+ }
+
+ private _elementMap: Map;
+ private _elementPartialMap: Map;
+ private _classMap: Map;
+ private _classPartialMap: Map;
+ private _attrValueMap: Map;
+ private _attrValuePartialMap: Map;
+ private _listContexts: List;
+
constructor() {
this._elementMap = MapWrapper.create();
this._elementPartialMap = MapWrapper.create();
@@ -150,14 +161,14 @@ export class SelectorMatcher {
this._listContexts = ListWrapper.create();
}
- addSelectables(cssSelectors:List, callbackCtxt) {
+ addSelectables(cssSelectors: List, callbackCtxt: any) {
var listContext = null;
if (cssSelectors.length > 1) {
- listContext= new SelectorListContext(cssSelectors);
+ listContext = new SelectorListContext(cssSelectors);
ListWrapper.push(this._listContexts, listContext);
}
for (var i = 0; i < cssSelectors.length; i++) {
- this.addSelectable(cssSelectors[i], callbackCtxt, listContext);
+ this._addSelectable(cssSelectors[i], callbackCtxt, listContext);
}
}
@@ -166,7 +177,7 @@ export class SelectorMatcher {
* @param cssSelector A css selector
* @param callbackCtxt An opaque object that will be given to the callback of the `match` function
*/
- addSelectable(cssSelector, callbackCtxt, listContext: SelectorListContext) {
+ private _addSelectable(cssSelector: CssSelector, callbackCtxt: any, listContext: SelectorListContext) {
var matcher = this;
var element = cssSelector.element;
var classNames = cssSelector.classNames;
@@ -184,7 +195,7 @@ export class SelectorMatcher {
}
if (isPresent(classNames)) {
- for (var index = 0; index, name:string, selectable) {
- var terminalList = MapWrapper.get(map, name)
+ private _addTerminal(map: Map, name: string, selectable: SelectorContext) {
+ var terminalList = MapWrapper.get(map, name);
if (isBlank(terminalList)) {
terminalList = ListWrapper.create();
MapWrapper.set(map, name, terminalList);
@@ -224,8 +235,8 @@ export class SelectorMatcher {
ListWrapper.push(terminalList, selectable);
}
- _addPartial(map:Map, name:string) {
- var matcher = MapWrapper.get(map, name)
+ private _addPartial(map: Map, name: string) {
+ var matcher = MapWrapper.get(map, name);
if (isBlank(matcher)) {
matcher = new SelectorMatcher();
MapWrapper.set(map, name, matcher);
@@ -240,7 +251,7 @@ export class SelectorMatcher {
* @param matchedCallback This callback will be called with the object handed into `addSelectable`
* @return boolean true if a match was found
*/
- match(cssSelector:CssSelector, matchedCallback:Function):boolean {
+ match(cssSelector: CssSelector, matchedCallback /*: (CssSelector, any) => void*/): boolean {
var result = false;
var element = cssSelector.element;
var classNames = cssSelector.classNames;
@@ -251,35 +262,42 @@ export class SelectorMatcher {
}
result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result;
- result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) || result;
+ result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) ||
+ result;
if (isPresent(classNames)) {
- for (var index = 0; index = null, name, cssSelector, matchedCallback):boolean {
+ _matchTerminal(map: Map, name, cssSelector: CssSelector,
+ matchedCallback /*: (CssSelector, any) => void*/): boolean {
if (isBlank(map) || isBlank(name)) {
return false;
}
@@ -294,18 +312,19 @@ export class SelectorMatcher {
}
var selectable;
var result = false;
- for (var index=0; index = null, name, cssSelector, matchedCallback):boolean {
+ _matchPartial(map: Map, name, cssSelector: CssSelector,
+ matchedCallback /*: (CssSelector, any) => void*/): boolean {
if (isBlank(map) || isBlank(name)) {
return false;
}
- var nestedSelector = MapWrapper.get(map, name)
+ var nestedSelector = MapWrapper.get(map, name);
if (isBlank(nestedSelector)) {
return false;
}
@@ -321,7 +340,7 @@ class SelectorListContext {
selectors: List;
alreadyMatched: boolean;
- constructor(selectors:List) {
+ constructor(selectors: List) {
this.selectors = selectors;
this.alreadyMatched = false;
}
@@ -329,26 +348,27 @@ class SelectorListContext {
// Store context to pass back selector and context when a selector is matched
class SelectorContext {
- selector:CssSelector;
- notSelector:CssSelector;
- cbContext; // callback context
+ selector: CssSelector;
+ notSelector: CssSelector;
+ cbContext; // callback context
listContext: SelectorListContext;
- constructor(selector:CssSelector, cbContext, listContext: SelectorListContext) {
+ constructor(selector: CssSelector, cbContext: any, listContext: SelectorListContext) {
this.selector = selector;
this.notSelector = selector.notSelector;
this.cbContext = cbContext;
this.listContext = listContext;
}
- finalize(cssSelector: CssSelector, callback) {
+ finalize(cssSelector: CssSelector, callback /*: (CssSelector, any) => void*/) {
var result = true;
- if (isPresent(this.notSelector) && (isBlank(this.listContext) || !this.listContext.alreadyMatched)) {
- var notMatcher = new SelectorMatcher();
- notMatcher.addSelectable(this.notSelector, null, null);
+ if (isPresent(this.notSelector) &&
+ (isBlank(this.listContext) || !this.listContext.alreadyMatched)) {
+ var notMatcher = SelectorMatcher.createNotMatcher(this.notSelector);
result = !notMatcher.match(cssSelector, null);
}
- if (result && isPresent(callback) && (isBlank(this.listContext) || !this.listContext.alreadyMatched)) {
+ if (result && isPresent(callback) &&
+ (isBlank(this.listContext) || !this.listContext.alreadyMatched)) {
if (isPresent(this.listContext)) {
this.listContext.alreadyMatched = true;
}
diff --git a/modules/angular2/src/render/dom/compiler/template_loader.js b/modules/angular2/src/render/dom/compiler/template_loader.ts
similarity index 83%
rename from modules/angular2/src/render/dom/compiler/template_loader.js
rename to modules/angular2/src/render/dom/compiler/template_loader.ts
index 1894c31956..51e891bbd9 100644
--- a/modules/angular2/src/render/dom/compiler/template_loader.js
+++ b/modules/angular2/src/render/dom/compiler/template_loader.ts
@@ -1,4 +1,4 @@
-import {Injectable} from 'angular2/src/di/annotations_impl';
+import {Injectable} from 'angular2/di';
import {isBlank, isPresent, BaseException, stringify} from 'angular2/src/facade/lang';
import {Map, MapWrapper, StringMapWrapper, StringMap} from 'angular2/src/facade/collection';
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
@@ -16,14 +16,14 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
@Injectable()
export class TemplateLoader {
_xhr: XHR;
- _htmlCache: StringMap;
+ _htmlCache: StringMap;
constructor(xhr: XHR, urlResolver: UrlResolver) {
this._xhr = xhr;
this._htmlCache = StringMapWrapper.create();
}
- load(template: ViewDefinition):Promise {
+ load(template: ViewDefinition): Promise*element*/ any> {
if (isPresent(template.template)) {
return PromiseWrapper.resolve(DOM.createTemplate(template.template));
}
@@ -32,7 +32,7 @@ export class TemplateLoader {
var promise = StringMapWrapper.get(this._htmlCache, url);
if (isBlank(promise)) {
- promise = this._xhr.get(url).then(function (html) {
+ promise = this._xhr.get(url).then(function(html) {
var template = DOM.createTemplate(html);
return template;
});
@@ -41,7 +41,7 @@ export class TemplateLoader {
// We need to clone the result as others might change it
// (e.g. the compiler).
- return promise.then( (tplElement) => DOM.clone(tplElement) );
+ return promise.then((tplElement) => DOM.clone(tplElement));
}
throw new BaseException('View should have either the url or template property set');
diff --git a/modules/angular2/src/render/dom/compiler/text_interpolation_parser.js b/modules/angular2/src/render/dom/compiler/text_interpolation_parser.ts
similarity index 76%
rename from modules/angular2/src/render/dom/compiler/text_interpolation_parser.js
rename to modules/angular2/src/render/dom/compiler/text_interpolation_parser.ts
index 2758ae55fc..145270301c 100644
--- a/modules/angular2/src/render/dom/compiler/text_interpolation_parser.js
+++ b/modules/angular2/src/render/dom/compiler/text_interpolation_parser.ts
@@ -10,21 +10,18 @@ import {CompileControl} from './compile_control';
/**
* Parses interpolations in direct text child nodes of the current element.
*/
-export class TextInterpolationParser extends CompileStep {
- _parser:Parser;
+export class TextInterpolationParser implements CompileStep {
+ _parser: Parser;
- constructor(parser:Parser) {
- super();
- this._parser = parser;
- }
+ constructor(parser: Parser) { this._parser = parser; }
- process(parent:CompileElement, current:CompileElement, control:CompileControl) {
+ process(parent: CompileElement, current: CompileElement, control: CompileControl) {
if (!current.compileChildren) {
return;
}
var element = current.element;
var childNodes = DOM.childNodes(DOM.templateAwareRoot(element));
- for (var i=0; i {
if (StringWrapper.startsWith(attrName, '*')) {
var key = StringWrapper.substring(attrName, 1); // remove the star
if (hasTemplateBinding) {
// 2nd template binding detected
throw new BaseException(`Only one template directive per element is allowed: ` +
- `${templateBindings} and ${key} cannot be used simultaneously ` +
- `in ${current.elementDescription}`);
+ `${templateBindings} and ${key} cannot be used simultaneously ` +
+ `in ${current.elementDescription}`);
} else {
templateBindings = (attrValue.length == 0) ? key : key + ' ' + attrValue;
hasTemplateBinding = true;
@@ -67,7 +65,8 @@ export class ViewSplitter extends CompileStep {
this._moveChildNodes(DOM.content(current.element), DOM.content(viewRoot.element));
control.addChild(viewRoot);
}
- } if (hasTemplateBinding) {
+ }
+ if (hasTemplateBinding) {
var newParent = new CompileElement(DOM.createTemplate(''));
newParent.inheritedProtoView = current.inheritedProtoView;
newParent.inheritedElementBinder = current.inheritedElementBinder;
@@ -102,19 +101,17 @@ export class ViewSplitter extends CompileStep {
DOM.appendChild(newParentElement, currentElement);
}
- _parseTemplateBindings(templateBindings:string, compileElement:CompileElement) {
- var bindings = this._parser.parseTemplateBindings(templateBindings, compileElement.elementDescription);
- for (var i=0; i {
return MapWrapper.createFromPairs([
['id', meta.id],
['selector', meta.selector],
@@ -27,18 +27,18 @@ export function directiveMetadataToMap(meta: DirectiveMetadata): Map {
* [DirectiveMetadata] object. This creates a copy, that is, subsequent changes
* to `map` will not be mirrored in the [DirectiveMetadata] object.
*/
-export function directiveMetadataFromMap(map: Map): DirectiveMetadata {
+export function directiveMetadataFromMap(map: Map): DirectiveMetadata {
return new DirectiveMetadata({
- id: MapWrapper.get(map, 'id'),
- selector: MapWrapper.get(map, 'selector'),
- compileChildren: MapWrapper.get(map, 'compileChildren'),
- hostListeners: _cloneIfPresent(MapWrapper.get(map, 'hostListeners')),
- hostProperties: _cloneIfPresent(MapWrapper.get(map, 'hostProperties')),
- hostActions: _cloneIfPresent(MapWrapper.get(map, 'hostActions')),
- hostAttributes: _cloneIfPresent(MapWrapper.get(map, 'hostAttributes')),
- properties: _cloneIfPresent(MapWrapper.get(map, 'properties')),
- readAttributes: _cloneIfPresent(MapWrapper.get(map, 'readAttributes')),
- type: MapWrapper.get(map, 'type')
+ id:MapWrapper.get(map, 'id'),
+ selector:MapWrapper.get(map, 'selector'),
+ compileChildren:MapWrapper.get(map, 'compileChildren'),
+ hostListeners: