parent
aae5a4cece
commit
d894aa9101
@ -61,6 +61,8 @@ import {
|
|||||||
DefaultDomCompiler,
|
DefaultDomCompiler,
|
||||||
APP_ID_RANDOM_BINDING
|
APP_ID_RANDOM_BINDING
|
||||||
} from 'angular2/src/render/render';
|
} from 'angular2/src/render/render';
|
||||||
|
import {ElementSchemaRegistry} from 'angular2/src/render/dom/schema/element_schema_registry';
|
||||||
|
import {DomElementSchemaRegistry} from 'angular2/src/render/dom/schema/dom_element_schema_registry';
|
||||||
import {
|
import {
|
||||||
SharedStylesHost,
|
SharedStylesHost,
|
||||||
DomSharedStylesHost
|
DomSharedStylesHost
|
||||||
@ -113,6 +115,7 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
|
|||||||
bind(Renderer).toAlias(DomRenderer),
|
bind(Renderer).toAlias(DomRenderer),
|
||||||
APP_ID_RANDOM_BINDING,
|
APP_ID_RANDOM_BINDING,
|
||||||
DefaultDomCompiler,
|
DefaultDomCompiler,
|
||||||
|
bind(ElementSchemaRegistry).toValue(new DomElementSchemaRegistry()),
|
||||||
bind(RenderCompiler).toAlias(DefaultDomCompiler),
|
bind(RenderCompiler).toAlias(DefaultDomCompiler),
|
||||||
DomSharedStylesHost,
|
DomSharedStylesHost,
|
||||||
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
|
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
import {CompilePipeline} from './compile_pipeline';
|
import {CompilePipeline} from './compile_pipeline';
|
||||||
import {ViewLoader, TemplateAndStyles} from 'angular2/src/render/dom/compiler/view_loader';
|
import {ViewLoader, TemplateAndStyles} from 'angular2/src/render/dom/compiler/view_loader';
|
||||||
import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory';
|
import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory';
|
||||||
|
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
|
||||||
import {Parser} from 'angular2/src/change_detection/change_detection';
|
import {Parser} from 'angular2/src/change_detection/change_detection';
|
||||||
import * as pvm from '../view/proto_view_merger';
|
import * as pvm from '../view/proto_view_merger';
|
||||||
import {DOCUMENT_TOKEN, APP_ID_TOKEN} from '../dom_tokens';
|
import {DOCUMENT_TOKEN, APP_ID_TOKEN} from '../dom_tokens';
|
||||||
@ -30,7 +31,8 @@ import {prependAll} from '../util';
|
|||||||
* the CompilePipeline and the CompileSteps.
|
* the CompilePipeline and the CompileSteps.
|
||||||
*/
|
*/
|
||||||
export class DomCompiler extends RenderCompiler {
|
export class DomCompiler extends RenderCompiler {
|
||||||
constructor(private _stepFactory: CompileStepFactory, private _viewLoader: ViewLoader,
|
constructor(private _schemaRegistry: ElementSchemaRegistry,
|
||||||
|
private _stepFactory: CompileStepFactory, private _viewLoader: ViewLoader,
|
||||||
private _sharedStylesHost: SharedStylesHost) {
|
private _sharedStylesHost: SharedStylesHost) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -84,7 +86,8 @@ export class DomCompiler extends RenderCompiler {
|
|||||||
this._sharedStylesHost.addStyles(compiledStyles);
|
this._sharedStylesHost.addStyles(compiledStyles);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PromiseWrapper.resolve(compileElements[0].inheritedProtoView.build());
|
return PromiseWrapper.resolve(
|
||||||
|
compileElements[0].inheritedProtoView.build(this._schemaRegistry));
|
||||||
}
|
}
|
||||||
|
|
||||||
_normalizeViewEncapsulationIfThereAreNoStyles(viewDef: ViewDefinition): ViewDefinition {
|
_normalizeViewEncapsulationIfThereAreNoStyles(viewDef: ViewDefinition): ViewDefinition {
|
||||||
@ -105,8 +108,8 @@ export class DomCompiler extends RenderCompiler {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DefaultDomCompiler extends DomCompiler {
|
export class DefaultDomCompiler extends DomCompiler {
|
||||||
constructor(parser: Parser, viewLoader: ViewLoader, sharedStylesHost: SharedStylesHost,
|
constructor(schemaRegistry: ElementSchemaRegistry, parser: Parser, viewLoader: ViewLoader,
|
||||||
@Inject(APP_ID_TOKEN) appId: any) {
|
sharedStylesHost: SharedStylesHost, @Inject(APP_ID_TOKEN) appId: any) {
|
||||||
super(new DefaultStepFactory(parser, appId), viewLoader, sharedStylesHost);
|
super(schemaRegistry, new DefaultStepFactory(parser, appId), viewLoader, sharedStylesHost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
|
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
|
||||||
|
import {ElementSchemaRegistry} from './element_schema_registry';
|
||||||
|
|
||||||
|
export class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
||||||
|
hasProperty(elm: any, propName: string): boolean {
|
||||||
|
var tagName = DOM.tagName(elm);
|
||||||
|
if (tagName.indexOf('-') !== -1) {
|
||||||
|
// can't tell now as we don't know which properties a custom element will get
|
||||||
|
// once it is instantiated
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return DOM.hasProperty(elm, propName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getMappedPropName(propName: string): string {
|
||||||
|
var mappedPropName = StringMapWrapper.get(DOM.attrToPropMap, propName);
|
||||||
|
return isPresent(mappedPropName) ? mappedPropName : propName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
export class ElementSchemaRegistry {
|
||||||
|
hasProperty(elm: any, propName: string): boolean { return true; }
|
||||||
|
getMappedPropName(propName: string): string { return propName; }
|
||||||
|
}
|
@ -20,6 +20,7 @@ import {
|
|||||||
|
|
||||||
import {DomProtoView, DomProtoViewRef, resolveInternalDomProtoView} from './proto_view';
|
import {DomProtoView, DomProtoViewRef, resolveInternalDomProtoView} from './proto_view';
|
||||||
import {DomElementBinder, Event, HostAction} from './element_binder';
|
import {DomElementBinder, Event, HostAction} from './element_binder';
|
||||||
|
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
|
||||||
|
|
||||||
import * as api from '../../api';
|
import * as api from '../../api';
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ export class ProtoViewBuilder {
|
|||||||
|
|
||||||
setHostAttribute(name: string, value: string) { this.hostAttributes.set(name, value); }
|
setHostAttribute(name: string, value: string) { this.hostAttributes.set(name, value); }
|
||||||
|
|
||||||
build(): api.ProtoViewDto {
|
build(schemaRegistry: ElementSchemaRegistry): api.ProtoViewDto {
|
||||||
var domElementBinders = [];
|
var domElementBinders = [];
|
||||||
|
|
||||||
var apiElementBinders = [];
|
var apiElementBinders = [];
|
||||||
@ -91,12 +92,12 @@ export class ProtoViewBuilder {
|
|||||||
directiveIndex: dbb.directiveIndex,
|
directiveIndex: dbb.directiveIndex,
|
||||||
propertyBindings: dbb.propertyBindings,
|
propertyBindings: dbb.propertyBindings,
|
||||||
eventBindings: dbb.eventBindings,
|
eventBindings: dbb.eventBindings,
|
||||||
hostPropertyBindings:
|
hostPropertyBindings: buildElementPropertyBindings(schemaRegistry, ebb.element, true,
|
||||||
buildElementPropertyBindings(ebb.element, isPresent(ebb.componentId),
|
dbb.hostPropertyBindings, new Set())
|
||||||
dbb.hostPropertyBindings, directiveTemplatePropertyNames)
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var nestedProtoView = isPresent(ebb.nestedProtoView) ? ebb.nestedProtoView.build() : null;
|
var nestedProtoView =
|
||||||
|
isPresent(ebb.nestedProtoView) ? ebb.nestedProtoView.build(schemaRegistry) : null;
|
||||||
if (isPresent(nestedProtoView)) {
|
if (isPresent(nestedProtoView)) {
|
||||||
transitiveNgContentCount += nestedProtoView.transitiveNgContentCount;
|
transitiveNgContentCount += nestedProtoView.transitiveNgContentCount;
|
||||||
}
|
}
|
||||||
@ -113,7 +114,7 @@ export class ProtoViewBuilder {
|
|||||||
directives: apiDirectiveBinders,
|
directives: apiDirectiveBinders,
|
||||||
nestedProtoView: nestedProtoView,
|
nestedProtoView: nestedProtoView,
|
||||||
propertyBindings:
|
propertyBindings:
|
||||||
buildElementPropertyBindings(ebb.element, isPresent(ebb.componentId),
|
buildElementPropertyBindings(schemaRegistry, ebb.element, isPresent(ebb.componentId),
|
||||||
ebb.propertyBindings, directiveTemplatePropertyNames),
|
ebb.propertyBindings, directiveTemplatePropertyNames),
|
||||||
variableBindings: ebb.variableBindings,
|
variableBindings: ebb.variableBindings,
|
||||||
eventBindings: ebb.eventBindings,
|
eventBindings: ebb.eventBindings,
|
||||||
@ -325,14 +326,15 @@ const ATTRIBUTE_PREFIX = 'attr';
|
|||||||
const CLASS_PREFIX = 'class';
|
const CLASS_PREFIX = 'class';
|
||||||
const STYLE_PREFIX = 'style';
|
const STYLE_PREFIX = 'style';
|
||||||
|
|
||||||
function buildElementPropertyBindings(protoElement: /*element*/ any, isNgComponent: boolean,
|
function buildElementPropertyBindings(
|
||||||
bindingsInTemplate: Map<string, ASTWithSource>,
|
schemaRegistry: ElementSchemaRegistry, protoElement: /*element*/ any, isNgComponent: boolean,
|
||||||
directiveTempaltePropertyNames: Set<string>):
|
bindingsInTemplate: Map<string, ASTWithSource>, directiveTempaltePropertyNames: Set<string>):
|
||||||
List<api.ElementPropertyBinding> {
|
List<api.ElementPropertyBinding> {
|
||||||
var propertyBindings = [];
|
var propertyBindings = [];
|
||||||
MapWrapper.forEach(bindingsInTemplate, (ast, propertyNameInTemplate) => {
|
MapWrapper.forEach(bindingsInTemplate, (ast, propertyNameInTemplate) => {
|
||||||
var propertyBinding = createElementPropertyBinding(ast, propertyNameInTemplate);
|
var propertyBinding = createElementPropertyBinding(schemaRegistry, ast, propertyNameInTemplate);
|
||||||
if (isValidElementPropertyBinding(protoElement, isNgComponent, propertyBinding)) {
|
if (isValidElementPropertyBinding(schemaRegistry, protoElement, isNgComponent,
|
||||||
|
propertyBinding)) {
|
||||||
propertyBindings.push(propertyBinding);
|
propertyBindings.push(propertyBinding);
|
||||||
} else if (!SetWrapper.has(directiveTempaltePropertyNames, propertyNameInTemplate)) {
|
} else if (!SetWrapper.has(directiveTempaltePropertyNames, propertyNameInTemplate)) {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
@ -342,29 +344,25 @@ function buildElementPropertyBindings(protoElement: /*element*/ any, isNgCompone
|
|||||||
return propertyBindings;
|
return propertyBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidElementPropertyBinding(protoElement: /*element*/ any, isNgComponent: boolean,
|
function isValidElementPropertyBinding(schemaRegistry: ElementSchemaRegistry,
|
||||||
|
protoElement: /*element*/ any, isNgComponent: boolean,
|
||||||
binding: api.ElementPropertyBinding): boolean {
|
binding: api.ElementPropertyBinding): boolean {
|
||||||
if (binding.type === api.PropertyBindingType.PROPERTY) {
|
if (binding.type === api.PropertyBindingType.PROPERTY) {
|
||||||
var tagName = DOM.tagName(protoElement);
|
if (!isNgComponent) {
|
||||||
var possibleCustomElement = tagName.indexOf('-') !== -1;
|
return schemaRegistry.hasProperty(protoElement, binding.property);
|
||||||
if (possibleCustomElement && !isNgComponent) {
|
|
||||||
// can't tell now as we don't know which properties a custom element will get
|
|
||||||
// once it is instantiated
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
|
// TODO(pk): change this logic as soon as we can properly detect custom elements
|
||||||
return DOM.hasProperty(protoElement, binding.property);
|
return DOM.hasProperty(protoElement, binding.property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createElementPropertyBinding(ast: ASTWithSource, propertyNameInTemplate: string):
|
function createElementPropertyBinding(schemaRegistry: ElementSchemaRegistry, ast: ASTWithSource,
|
||||||
api.ElementPropertyBinding {
|
propertyNameInTemplate: string): api.ElementPropertyBinding {
|
||||||
var parts = StringWrapper.split(propertyNameInTemplate, PROPERTY_PARTS_SEPARATOR);
|
var parts = StringWrapper.split(propertyNameInTemplate, PROPERTY_PARTS_SEPARATOR);
|
||||||
if (parts.length === 1) {
|
if (parts.length === 1) {
|
||||||
var propName = parts[0];
|
var propName = schemaRegistry.getMappedPropName(parts[0]);
|
||||||
var mappedPropName = StringMapWrapper.get(DOM.attrToPropMap, propName);
|
|
||||||
propName = isPresent(mappedPropName) ? mappedPropName : propName;
|
|
||||||
return new api.ElementPropertyBinding(api.PropertyBindingType.PROPERTY, ast, propName);
|
return new api.ElementPropertyBinding(api.PropertyBindingType.PROPERTY, ast, propName);
|
||||||
} else if (parts[0] == ATTRIBUTE_PREFIX) {
|
} else if (parts[0] == ATTRIBUTE_PREFIX) {
|
||||||
return new api.ElementPropertyBinding(api.PropertyBindingType.ATTRIBUTE, ast, parts[1]);
|
return new api.ElementPropertyBinding(api.PropertyBindingType.ATTRIBUTE, ast, parts[1]);
|
||||||
|
@ -56,6 +56,8 @@ import {
|
|||||||
SharedStylesHost,
|
SharedStylesHost,
|
||||||
DomSharedStylesHost
|
DomSharedStylesHost
|
||||||
} from 'angular2/src/render/render';
|
} from 'angular2/src/render/render';
|
||||||
|
import {ElementSchemaRegistry} from 'angular2/src/render/dom/schema/element_schema_registry';
|
||||||
|
import {DomElementSchemaRegistry} from 'angular2/src/render/dom/schema/dom_element_schema_registry';
|
||||||
import {Serializer} from "angular2/src/web-workers/shared/serializer";
|
import {Serializer} from "angular2/src/web-workers/shared/serializer";
|
||||||
import {Log} from './utils';
|
import {Log} from './utils';
|
||||||
|
|
||||||
@ -98,6 +100,7 @@ function _getAppBindings() {
|
|||||||
bind(APP_ID_TOKEN).toValue('a'),
|
bind(APP_ID_TOKEN).toValue('a'),
|
||||||
DefaultDomCompiler,
|
DefaultDomCompiler,
|
||||||
bind(RenderCompiler).toAlias(DefaultDomCompiler),
|
bind(RenderCompiler).toAlias(DefaultDomCompiler),
|
||||||
|
bind(ElementSchemaRegistry).toValue(new DomElementSchemaRegistry()),
|
||||||
DomSharedStylesHost,
|
DomSharedStylesHost,
|
||||||
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
|
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
|
||||||
bind(DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES).toValue(false),
|
bind(DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES).toValue(false),
|
||||||
|
@ -11,6 +11,8 @@ import 'package:angular2/src/render/dom/compiler/compile_pipeline.dart';
|
|||||||
import 'package:angular2/src/render/dom/compiler/style_inliner.dart';
|
import 'package:angular2/src/render/dom/compiler/style_inliner.dart';
|
||||||
import 'package:angular2/src/render/dom/compiler/style_url_resolver.dart';
|
import 'package:angular2/src/render/dom/compiler/style_url_resolver.dart';
|
||||||
import 'package:angular2/src/render/dom/compiler/view_loader.dart';
|
import 'package:angular2/src/render/dom/compiler/view_loader.dart';
|
||||||
|
import 'package:angular2/src/render/dom/schema/element_schema_registry.dart';
|
||||||
|
import 'package:angular2/src/render/dom/schema/dom_element_schema_registry.dart';
|
||||||
import 'package:angular2/src/render/xhr.dart' show XHR;
|
import 'package:angular2/src/render/xhr.dart' show XHR;
|
||||||
import 'package:angular2/src/reflection/reflection.dart';
|
import 'package:angular2/src/reflection/reflection.dart';
|
||||||
import 'package:angular2/src/services/url_resolver.dart';
|
import 'package:angular2/src/services/url_resolver.dart';
|
||||||
@ -33,7 +35,7 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
|
|||||||
{bool generateRegistrations: true,
|
{bool generateRegistrations: true,
|
||||||
bool generateChangeDetectors: true}) async {
|
bool generateChangeDetectors: true}) async {
|
||||||
var viewDefResults = await createViewDefinitions(reader, entryPoint);
|
var viewDefResults = await createViewDefinitions(reader, entryPoint);
|
||||||
var extractor = new _TemplateExtractor(new XhrImpl(reader, entryPoint));
|
var extractor = new _TemplateExtractor(new DomElementSchemaRegistry(), new XhrImpl(reader, entryPoint));
|
||||||
|
|
||||||
var registrations = new reg.Codegen();
|
var registrations = new reg.Codegen();
|
||||||
var changeDetectorClasses = new change.Codegen();
|
var changeDetectorClasses = new change.Codegen();
|
||||||
@ -83,14 +85,16 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
|
|||||||
class _TemplateExtractor {
|
class _TemplateExtractor {
|
||||||
final CompileStepFactory _factory;
|
final CompileStepFactory _factory;
|
||||||
ViewLoader _loader;
|
ViewLoader _loader;
|
||||||
|
ElementSchemaRegistry _schemaRegistry;
|
||||||
|
|
||||||
_TemplateExtractor(XHR xhr)
|
_TemplateExtractor(ElementSchemaRegistry schemaRegistry, XHR xhr)
|
||||||
: _factory = new CompileStepFactory(new ng.Parser(new ng.Lexer())) {
|
: _factory = new CompileStepFactory(new ng.Parser(new ng.Lexer())) {
|
||||||
var urlResolver = new UrlResolver();
|
var urlResolver = new UrlResolver();
|
||||||
var styleUrlResolver = new StyleUrlResolver(urlResolver);
|
var styleUrlResolver = new StyleUrlResolver(urlResolver);
|
||||||
var styleInliner = new StyleInliner(xhr, styleUrlResolver, urlResolver);
|
var styleInliner = new StyleInliner(xhr, styleUrlResolver, urlResolver);
|
||||||
|
|
||||||
_loader = new ViewLoader(xhr, styleInliner, styleUrlResolver);
|
_loader = new ViewLoader(xhr, styleInliner, styleUrlResolver);
|
||||||
|
_schemaRegistry = schemaRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<_ExtractResult> extractTemplates(ViewDefinition viewDef) async {
|
Future<_ExtractResult> extractTemplates(ViewDefinition viewDef) async {
|
||||||
@ -110,7 +114,7 @@ class _TemplateExtractor {
|
|||||||
|
|
||||||
var compileElements =
|
var compileElements =
|
||||||
pipeline.processElements(DOM.createTemplate(templateAndStyles.template), ViewType.COMPONENT, viewDef);
|
pipeline.processElements(DOM.createTemplate(templateAndStyles.template), ViewType.COMPONENT, viewDef);
|
||||||
var protoViewDto = compileElements[0].inheritedProtoView.build();
|
var protoViewDto = compileElements[0].inheritedProtoView.build(_schemaRegistry);
|
||||||
|
|
||||||
reflector.reflectionCapabilities = savedReflectionCapabilities;
|
reflector.reflectionCapabilities = savedReflectionCapabilities;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
} from 'angular2/src/render/api';
|
} from 'angular2/src/render/api';
|
||||||
import {CompileStep} from 'angular2/src/render/dom/compiler/compile_step';
|
import {CompileStep} from 'angular2/src/render/dom/compiler/compile_step';
|
||||||
import {CompileStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory';
|
import {CompileStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory';
|
||||||
|
import {ElementSchemaRegistry} from 'angular2/src/render/dom/schema/element_schema_registry';
|
||||||
import {ViewLoader, TemplateAndStyles} from 'angular2/src/render/dom/compiler/view_loader';
|
import {ViewLoader, TemplateAndStyles} from 'angular2/src/render/dom/compiler/view_loader';
|
||||||
|
|
||||||
import {resolveInternalDomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
import {resolveInternalDomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
||||||
@ -48,7 +49,8 @@ export function runCompilerCommonTests() {
|
|||||||
var tplLoader = new FakeViewLoader(urlData);
|
var tplLoader = new FakeViewLoader(urlData);
|
||||||
mockStepFactory =
|
mockStepFactory =
|
||||||
new MockStepFactory([new MockStep(processElementClosure, processStyleClosure)]);
|
new MockStepFactory([new MockStep(processElementClosure, processStyleClosure)]);
|
||||||
return new DomCompiler(mockStepFactory, tplLoader, sharedStylesHost);
|
return new DomCompiler(new ElementSchemaRegistry(), mockStepFactory, tplLoader,
|
||||||
|
sharedStylesHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('compile', () => {
|
describe('compile', () => {
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
import {
|
||||||
|
beforeEach,
|
||||||
|
ddescribe,
|
||||||
|
xdescribe,
|
||||||
|
describe,
|
||||||
|
expect,
|
||||||
|
iit,
|
||||||
|
inject,
|
||||||
|
it,
|
||||||
|
xit,
|
||||||
|
IS_DARTIUM
|
||||||
|
} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import {DomElementSchemaRegistry} from 'angular2/src/render/dom/schema/dom_element_schema_registry';
|
||||||
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
// DOMElementSchema can only be used on the JS side where we can safely
|
||||||
|
// use reflection for DOM elements
|
||||||
|
if (IS_DARTIUM) return;
|
||||||
|
|
||||||
|
var registry;
|
||||||
|
|
||||||
|
beforeEach(() => { registry = new DomElementSchemaRegistry(); });
|
||||||
|
|
||||||
|
describe('DOMElementSchema', () => {
|
||||||
|
|
||||||
|
it('should detect properties on regular elements', () => {
|
||||||
|
var divEl = DOM.createElement('div');
|
||||||
|
expect(registry.hasProperty(divEl, 'id')).toBeTruthy();
|
||||||
|
expect(registry.hasProperty(divEl, 'title')).toBeTruthy();
|
||||||
|
expect(registry.hasProperty(divEl, 'unknown')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for custom-like elements', () => {
|
||||||
|
var customLikeEl = DOM.createElement('custom-like');
|
||||||
|
expect(registry.hasProperty(customLikeEl, 'unknown')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not re-map property names that are not specified in DOM facade',
|
||||||
|
() => { expect(registry.getMappedPropName('readonly')).toEqual('readOnly'); });
|
||||||
|
|
||||||
|
it('should not re-map property names that are not specified in DOM facade', () => {
|
||||||
|
expect(registry.getMappedPropName('title')).toEqual('title');
|
||||||
|
expect(registry.getMappedPropName('exotic-unknown')).toEqual('exotic-unknown');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -11,6 +11,7 @@ import {
|
|||||||
IS_DARTIUM
|
IS_DARTIUM
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import {DomElementSchemaRegistry} from 'angular2/src/render/dom/schema/dom_element_schema_registry';
|
||||||
import {ProtoViewBuilder} from 'angular2/src/render/dom/view/proto_view_builder';
|
import {ProtoViewBuilder} from 'angular2/src/render/dom/view/proto_view_builder';
|
||||||
import {ASTWithSource, AST} from 'angular2/src/change_detection/change_detection';
|
import {ASTWithSource, AST} from 'angular2/src/change_detection/change_detection';
|
||||||
import {PropertyBindingType, ViewType, ViewEncapsulation} from 'angular2/src/render/api';
|
import {PropertyBindingType, ViewType, ViewEncapsulation} from 'angular2/src/render/api';
|
||||||
@ -31,7 +32,7 @@ export function main() {
|
|||||||
|
|
||||||
it('should throw for unknown properties', () => {
|
it('should throw for unknown properties', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('unknownProperty', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('unknownProperty', emptyExpr());
|
||||||
expect(() => builder.build())
|
expect(() => builder.build(new DomElementSchemaRegistry()))
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
`Can't bind to 'unknownProperty' since it isn't a known property of the '<div>' element and there are no matching directives with a corresponding property`);
|
`Can't bind to 'unknownProperty' since it isn't a known property of the '<div>' element and there are no matching directives with a corresponding property`);
|
||||||
});
|
});
|
||||||
@ -40,20 +41,20 @@ export function main() {
|
|||||||
var binder = builder.bindElement(el('<div/>'));
|
var binder = builder.bindElement(el('<div/>'));
|
||||||
binder.bindDirective(0).bindProperty('someDirProperty', emptyExpr(), 'directiveProperty');
|
binder.bindDirective(0).bindProperty('someDirProperty', emptyExpr(), 'directiveProperty');
|
||||||
binder.bindProperty('directiveProperty', emptyExpr());
|
binder.bindProperty('directiveProperty', emptyExpr());
|
||||||
expect(() => builder.build()).not.toThrow();
|
expect(() => builder.build(new DomElementSchemaRegistry())).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow unknown properties on custom elements', () => {
|
it('should allow unknown properties on custom elements', () => {
|
||||||
var binder = builder.bindElement(el('<some-custom/>'));
|
var binder = builder.bindElement(el('<some-custom/>'));
|
||||||
binder.bindProperty('unknownProperty', emptyExpr());
|
binder.bindProperty('unknownProperty', emptyExpr());
|
||||||
expect(() => builder.build()).not.toThrow();
|
expect(() => builder.build(new DomElementSchemaRegistry())).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw for unknown properties on custom elements if there is an ng component', () => {
|
it('should throw for unknown properties on custom elements if there is an ng component', () => {
|
||||||
var binder = builder.bindElement(el('<some-custom/>'));
|
var binder = builder.bindElement(el('<some-custom/>'));
|
||||||
binder.bindProperty('unknownProperty', emptyExpr());
|
binder.bindProperty('unknownProperty', emptyExpr());
|
||||||
binder.setComponentId('someComponent');
|
binder.setComponentId('someComponent');
|
||||||
expect(() => builder.build())
|
expect(() => builder.build(new DomElementSchemaRegistry()))
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
`Can't bind to 'unknownProperty' since it isn't a known property of the '<some-custom>' element and there are no matching directives with a corresponding property`);
|
`Can't bind to 'unknownProperty' since it isn't a known property of the '<some-custom>' element and there are no matching directives with a corresponding property`);
|
||||||
});
|
});
|
||||||
@ -65,9 +66,9 @@ export function main() {
|
|||||||
// TODO(tbosch): This is just a temporary test that makes sure that the dart server and
|
// TODO(tbosch): This is just a temporary test that makes sure that the dart server and
|
||||||
// dart browser is in sync. Change this to "not contains notifyBinding"
|
// dart browser is in sync. Change this to "not contains notifyBinding"
|
||||||
// when https://github.com/angular/angular/issues/3019 is solved.
|
// when https://github.com/angular/angular/issues/3019 is solved.
|
||||||
it('should throw for unknown properties', () => {
|
it('should not throw for unknown properties', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('unknownProperty', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('unknownProperty', emptyExpr());
|
||||||
expect(() => builder.build()).not.toThrow();
|
expect(() => builder.build(new DomElementSchemaRegistry())).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -76,19 +77,19 @@ export function main() {
|
|||||||
describe('property normalization', () => {
|
describe('property normalization', () => {
|
||||||
it('should normalize "innerHtml" to "innerHTML"', () => {
|
it('should normalize "innerHtml" to "innerHTML"', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('innerHtml', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('innerHtml', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].property).toEqual('innerHTML');
|
expect(pv.elementBinders[0].propertyBindings[0].property).toEqual('innerHTML');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should normalize "tabindex" to "tabIndex"', () => {
|
it('should normalize "tabindex" to "tabIndex"', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('tabindex', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('tabindex', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].property).toEqual('tabIndex');
|
expect(pv.elementBinders[0].propertyBindings[0].property).toEqual('tabIndex');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should normalize "readonly" to "readOnly"', () => {
|
it('should normalize "readonly" to "readOnly"', () => {
|
||||||
builder.bindElement(el('<input/>')).bindProperty('readonly', emptyExpr());
|
builder.bindElement(el('<input/>')).bindProperty('readonly', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].property).toEqual('readOnly');
|
expect(pv.elementBinders[0].propertyBindings[0].property).toEqual('readOnly');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -97,32 +98,32 @@ export function main() {
|
|||||||
describe('property binding types', () => {
|
describe('property binding types', () => {
|
||||||
it('should detect property names', () => {
|
it('should detect property names', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('tabindex', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('tabindex', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].type).toEqual(PropertyBindingType.PROPERTY);
|
expect(pv.elementBinders[0].propertyBindings[0].type).toEqual(PropertyBindingType.PROPERTY);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect attribute names', () => {
|
it('should detect attribute names', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('attr.someName', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('attr.someName', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].type)
|
expect(pv.elementBinders[0].propertyBindings[0].type)
|
||||||
.toEqual(PropertyBindingType.ATTRIBUTE);
|
.toEqual(PropertyBindingType.ATTRIBUTE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect class names', () => {
|
it('should detect class names', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('class.someName', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('class.someName', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].type).toEqual(PropertyBindingType.CLASS);
|
expect(pv.elementBinders[0].propertyBindings[0].type).toEqual(PropertyBindingType.CLASS);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect style names', () => {
|
it('should detect style names', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('style.someName', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('style.someName', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].type).toEqual(PropertyBindingType.STYLE);
|
expect(pv.elementBinders[0].propertyBindings[0].type).toEqual(PropertyBindingType.STYLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect style units', () => {
|
it('should detect style units', () => {
|
||||||
builder.bindElement(el('<div/>')).bindProperty('style.someName.someUnit', emptyExpr());
|
builder.bindElement(el('<div/>')).bindProperty('style.someName.someUnit', emptyExpr());
|
||||||
var pv = builder.build();
|
var pv = builder.build(new DomElementSchemaRegistry());
|
||||||
expect(pv.elementBinders[0].propertyBindings[0].unit).toEqual('someUnit');
|
expect(pv.elementBinders[0].propertyBindings[0].unit).toEqual('someUnit');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -30,6 +30,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
|
|||||||
import {cloneAndQueryProtoView} from 'angular2/src/render/dom/util';
|
import {cloneAndQueryProtoView} from 'angular2/src/render/dom/util';
|
||||||
import {resolveInternalDomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
import {resolveInternalDomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
||||||
import {ProtoViewBuilder} from 'angular2/src/render/dom/view/proto_view_builder';
|
import {ProtoViewBuilder} from 'angular2/src/render/dom/view/proto_view_builder';
|
||||||
|
import {ElementSchemaRegistry} from 'angular2/src/render/dom/schema/element_schema_registry';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('ProtoViewMerger integration test', () => {
|
describe('ProtoViewMerger integration test', () => {
|
||||||
@ -247,7 +248,7 @@ export function main() {
|
|||||||
var builder = new ProtoViewBuilder(DOM.createTemplate(''), ViewType.COMPONENT,
|
var builder = new ProtoViewBuilder(DOM.createTemplate(''), ViewType.COMPONENT,
|
||||||
ViewEncapsulation.NONE);
|
ViewEncapsulation.NONE);
|
||||||
builder.setHostAttribute('a', 'b');
|
builder.setHostAttribute('a', 'b');
|
||||||
var componentProtoViewDto = builder.build();
|
var componentProtoViewDto = builder.build(new ElementSchemaRegistry());
|
||||||
tb.merge([rootProtoViewDto, componentProtoViewDto])
|
tb.merge([rootProtoViewDto, componentProtoViewDto])
|
||||||
.then(mergeMappings => {
|
.then(mergeMappings => {
|
||||||
var domPv = resolveInternalDomProtoView(mergeMappings.mergedProtoViewRef);
|
var domPv = resolveInternalDomProtoView(mergeMappings.mergedProtoViewRef);
|
||||||
|
@ -25,6 +25,7 @@ import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util'
|
|||||||
|
|
||||||
import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
|
import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
|
||||||
import {ViewLoader, DefaultDomCompiler, SharedStylesHost} from 'angular2/src/render/render';
|
import {ViewLoader, DefaultDomCompiler, SharedStylesHost} from 'angular2/src/render/render';
|
||||||
|
import {DomElementSchemaRegistry} from 'angular2/src/render/dom/schema/dom_element_schema_registry';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
BrowserDomAdapter.makeCurrent();
|
BrowserDomAdapter.makeCurrent();
|
||||||
@ -37,8 +38,9 @@ export function main() {
|
|||||||
count, [BenchmarkComponentNoBindings, BenchmarkComponentWithBindings]);
|
count, [BenchmarkComponentNoBindings, BenchmarkComponentWithBindings]);
|
||||||
var urlResolver = new UrlResolver();
|
var urlResolver = new UrlResolver();
|
||||||
var appRootUrl = new AppRootUrl("");
|
var appRootUrl = new AppRootUrl("");
|
||||||
var renderCompiler = new DefaultDomCompiler(
|
var renderCompiler =
|
||||||
new Parser(new Lexer()), new ViewLoader(null, null, null), new SharedStylesHost(), 'a');
|
new DefaultDomCompiler(new DomElementSchemaRegistry(), new Parser(new Lexer()),
|
||||||
|
new ViewLoader(null, null, null), new SharedStylesHost(), 'a');
|
||||||
var compiler =
|
var compiler =
|
||||||
new Compiler(reader, cache, viewResolver, new ComponentUrlMapper(), urlResolver,
|
new Compiler(reader, cache, viewResolver, new ComponentUrlMapper(), urlResolver,
|
||||||
renderCompiler, new ProtoViewFactory(new DynamicChangeDetection()), appRootUrl);
|
renderCompiler, new ProtoViewFactory(new DynamicChangeDetection()), appRootUrl);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user