refactor(render): user render compiler
This commit is contained in:
@ -3,9 +3,14 @@ import {BaseException} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Template, ProtoView} from '../../api';
|
||||
import {CompilePipeline} from './compile_pipeline';
|
||||
import {TemplateLoader} from './template_loader';
|
||||
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
|
||||
import {CompileStepFactory} from './compile_step_factory';
|
||||
|
||||
/**
|
||||
* The compiler loads and translates the html templates of components into
|
||||
* nested ProtoViews. To decompose its functionality it uses
|
||||
* the CompilePipeline and the CompileSteps.
|
||||
*/
|
||||
export class Compiler {
|
||||
_templateLoader: TemplateLoader;
|
||||
_stepFactory: CompileStepFactory;
|
||||
|
@ -9,8 +9,6 @@ import {CompileStep} from './compile_step';
|
||||
import {CompileElement} from './compile_element';
|
||||
import {CompileControl} from './compile_control';
|
||||
|
||||
import {setterFactory} from 'angular2/src/render/dom/compiler/property_setter_factory';
|
||||
|
||||
import {DirectiveMetadata} from '../../api';
|
||||
import {dashCaseToCamelCase, camelCaseToDashCase} from '../util';
|
||||
|
||||
@ -72,7 +70,12 @@ export class DirectiveParser extends CompileStep {
|
||||
}
|
||||
if (isPresent(directive.setters)) {
|
||||
ListWrapper.forEach(directive.setters, (propertyName) => {
|
||||
directiveBinder.bindPropertySetter(propertyName, setterFactory(propertyName));
|
||||
elementBinder.bindPropertySetter(propertyName);
|
||||
});
|
||||
}
|
||||
if (isPresent(directive.readAttributes)) {
|
||||
ListWrapper.forEach(directive.readAttributes, (attrName) => {
|
||||
elementBinder.readAttribute(attrName);
|
||||
});
|
||||
}
|
||||
if (directive.type === DirectiveMetadata.VIEWPORT_TYPE) {
|
||||
|
@ -8,7 +8,6 @@ import {CompileElement} from './compile_element';
|
||||
import {CompileControl} from './compile_control';
|
||||
|
||||
import {dashCaseToCamelCase} from '../util';
|
||||
import {setterFactory} from 'angular2/src/render/dom/compiler/property_setter_factory';
|
||||
|
||||
// Group 1 = "bind-"
|
||||
// Group 2 = "var-" or "#"
|
||||
@ -92,7 +91,6 @@ export class PropertyBindingParser extends CompileStep {
|
||||
var binder = current.bindElement();
|
||||
var camelCaseName = dashCaseToCamelCase(name);
|
||||
binder.bindProperty(camelCaseName, ast);
|
||||
binder.bindPropertySetter(camelCaseName, setterFactory(camelCaseName));
|
||||
MapWrapper.set(newAttrs, name, ast.source);
|
||||
}
|
||||
|
||||
|
@ -1,125 +0,0 @@
|
||||
import {StringWrapper, RegExpWrapper, BaseException, isPresent, isBlank, isString, stringify} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {camelCaseToDashCase, dashCaseToCamelCase} from '../util';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
|
||||
const STYLE_SEPARATOR = '.';
|
||||
var propertySettersCache = StringMapWrapper.create();
|
||||
var innerHTMLSetterCache;
|
||||
|
||||
export function setterFactory(property: string): Function {
|
||||
var setterFn, styleParts, styleSuffix;
|
||||
if (StringWrapper.startsWith(property, ATTRIBUTE_PREFIX)) {
|
||||
setterFn = attributeSetterFactory(StringWrapper.substring(property, ATTRIBUTE_PREFIX.length));
|
||||
} else if (StringWrapper.startsWith(property, CLASS_PREFIX)) {
|
||||
setterFn = classSetterFactory(StringWrapper.substring(property, CLASS_PREFIX.length));
|
||||
} else if (StringWrapper.startsWith(property, STYLE_PREFIX)) {
|
||||
styleParts = property.split(STYLE_SEPARATOR);
|
||||
styleSuffix = styleParts.length > 2 ? ListWrapper.get(styleParts, 2) : '';
|
||||
setterFn = styleSetterFactory(ListWrapper.get(styleParts, 1), styleSuffix);
|
||||
} else if (StringWrapper.equals(property, 'innerHtml')) {
|
||||
if (isBlank(innerHTMLSetterCache)) {
|
||||
innerHTMLSetterCache = (el, value) => DOM.setInnerHTML(el, value);
|
||||
}
|
||||
setterFn = innerHTMLSetterCache;
|
||||
} else {
|
||||
property = resolvePropertyName(property);
|
||||
setterFn = StringMapWrapper.get(propertySettersCache, property);
|
||||
if (isBlank(setterFn)) {
|
||||
var propertySetterFn = reflector.setter(property);
|
||||
setterFn = function(receiver, value) {
|
||||
if (DOM.hasProperty(receiver, property)) {
|
||||
return propertySetterFn(receiver, value);
|
||||
}
|
||||
};
|
||||
StringMapWrapper.set(propertySettersCache, property, setterFn);
|
||||
}
|
||||
}
|
||||
return setterFn;
|
||||
}
|
||||
|
||||
const ATTRIBUTE_PREFIX = 'attr.';
|
||||
var attributeSettersCache = StringMapWrapper.create();
|
||||
|
||||
function _isValidAttributeValue(attrName:string, value: any): boolean {
|
||||
if (attrName == "role") {
|
||||
return isString(value);
|
||||
} else {
|
||||
return isPresent(value);
|
||||
}
|
||||
}
|
||||
|
||||
function attributeSetterFactory(attrName:string): Function {
|
||||
var setterFn = StringMapWrapper.get(attributeSettersCache, attrName);
|
||||
var dashCasedAttributeName;
|
||||
|
||||
if (isBlank(setterFn)) {
|
||||
dashCasedAttributeName = camelCaseToDashCase(attrName);
|
||||
setterFn = function(element, value) {
|
||||
if (_isValidAttributeValue(dashCasedAttributeName, value)) {
|
||||
DOM.setAttribute(element, dashCasedAttributeName, stringify(value));
|
||||
} else {
|
||||
if (isPresent(value)) {
|
||||
throw new BaseException("Invalid " + dashCasedAttributeName +
|
||||
" attribute, only string values are allowed, got '" + stringify(value) + "'");
|
||||
}
|
||||
DOM.removeAttribute(element, dashCasedAttributeName);
|
||||
}
|
||||
};
|
||||
StringMapWrapper.set(attributeSettersCache, attrName, setterFn);
|
||||
}
|
||||
|
||||
return setterFn;
|
||||
}
|
||||
|
||||
const CLASS_PREFIX = 'class.';
|
||||
var classSettersCache = StringMapWrapper.create();
|
||||
|
||||
function classSetterFactory(className:string): Function {
|
||||
var setterFn = StringMapWrapper.get(classSettersCache, className);
|
||||
var dashCasedClassName;
|
||||
if (isBlank(setterFn)) {
|
||||
dashCasedClassName = camelCaseToDashCase(className);
|
||||
setterFn = function(element, value) {
|
||||
if (value) {
|
||||
DOM.addClass(element, dashCasedClassName);
|
||||
} else {
|
||||
DOM.removeClass(element, dashCasedClassName);
|
||||
}
|
||||
};
|
||||
StringMapWrapper.set(classSettersCache, className, setterFn);
|
||||
}
|
||||
|
||||
return setterFn;
|
||||
}
|
||||
|
||||
const STYLE_PREFIX = 'style.';
|
||||
var styleSettersCache = StringMapWrapper.create();
|
||||
|
||||
function styleSetterFactory(styleName:string, styleSuffix:string): Function {
|
||||
var cacheKey = styleName + styleSuffix;
|
||||
var setterFn = StringMapWrapper.get(styleSettersCache, cacheKey);
|
||||
var dashCasedStyleName;
|
||||
|
||||
if (isBlank(setterFn)) {
|
||||
dashCasedStyleName = camelCaseToDashCase(styleName);
|
||||
setterFn = function(element, value) {
|
||||
var valAsStr;
|
||||
if (isPresent(value)) {
|
||||
valAsStr = stringify(value);
|
||||
DOM.setStyle(element, dashCasedStyleName, valAsStr + styleSuffix);
|
||||
} else {
|
||||
DOM.removeStyle(element, dashCasedStyleName);
|
||||
}
|
||||
};
|
||||
StringMapWrapper.set(styleSettersCache, cacheKey, setterFn);
|
||||
}
|
||||
|
||||
return setterFn;
|
||||
}
|
||||
|
||||
function resolvePropertyName(attrName:string): string {
|
||||
var mappedPropName = StringMapWrapper.get(DOM.attrToPropMap, attrName);
|
||||
return isPresent(mappedPropName) ? mappedPropName : attrName;
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -12,6 +13,7 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||
* Strategy to load component templates.
|
||||
* @publicModule angular2/angular2
|
||||
*/
|
||||
@Injectable()
|
||||
export class TemplateLoader {
|
||||
_xhr: XHR;
|
||||
_htmlCache: StringMap;
|
||||
|
@ -7,6 +7,8 @@ import {CompileStep} from './compile_step';
|
||||
import {CompileElement} from './compile_element';
|
||||
import {CompileControl} from './compile_control';
|
||||
|
||||
import {dashCaseToCamelCase} from '../util';
|
||||
|
||||
/**
|
||||
* Splits views at `<template>` elements or elements with `template` attribute:
|
||||
* For `<template>` elements:
|
||||
@ -105,10 +107,14 @@ export class ViewSplitter extends CompileStep {
|
||||
for (var i=0; i<bindings.length; i++) {
|
||||
var binding = bindings[i];
|
||||
if (binding.keyIsVar) {
|
||||
compileElement.bindElement().bindVariable(binding.key, binding.name);
|
||||
compileElement.bindElement().bindVariable(
|
||||
dashCaseToCamelCase(binding.key), binding.name
|
||||
);
|
||||
MapWrapper.set(compileElement.attrs(), binding.key, binding.name);
|
||||
} else if (isPresent(binding.expression)) {
|
||||
compileElement.bindElement().bindProperty(binding.key, binding.expression);
|
||||
compileElement.bindElement().bindProperty(
|
||||
dashCaseToCamelCase(binding.key), binding.expression
|
||||
);
|
||||
MapWrapper.set(compileElement.attrs(), binding.key, binding.expression.source);
|
||||
} else {
|
||||
DOM.setAttribute(compileElement.element, binding.key, '');
|
||||
|
Reference in New Issue
Block a user