X Tutup
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions modules/angular2/src/core/application_common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ import {
DefaultDomCompiler,
APP_ID_RANDOM_BINDING
} 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 {
SharedStylesHost,
DomSharedStylesHost
Expand Down Expand Up @@ -113,6 +115,7 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
bind(Renderer).toAlias(DomRenderer),
APP_ID_RANDOM_BINDING,
DefaultDomCompiler,
bind(ElementSchemaRegistry).toValue(new DomElementSchemaRegistry()),
bind(RenderCompiler).toAlias(DefaultDomCompiler),
DomSharedStylesHost,
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
Expand Down
13 changes: 8 additions & 5 deletions modules/angular2/src/render/dom/compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import {CompilePipeline} from './compile_pipeline';
import {ViewLoader, TemplateAndStyles} from 'angular2/src/render/dom/compiler/view_loader';
import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory';
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
import {Parser} from 'angular2/src/change_detection/change_detection';
import * as pvm from '../view/proto_view_merger';
import {DOCUMENT_TOKEN, APP_ID_TOKEN} from '../dom_tokens';
Expand All @@ -30,7 +31,8 @@ import {prependAll} from '../util';
* the CompilePipeline and the CompileSteps.
*/
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) {
super();
}
Expand Down Expand Up @@ -84,7 +86,8 @@ export class DomCompiler extends RenderCompiler {
this._sharedStylesHost.addStyles(compiledStyles);
}

return PromiseWrapper.resolve(compileElements[0].inheritedProtoView.build());
return PromiseWrapper.resolve(
compileElements[0].inheritedProtoView.build(this._schemaRegistry));
}

_normalizeViewEncapsulationIfThereAreNoStyles(viewDef: ViewDefinition): ViewDefinition {
Expand All @@ -105,8 +108,8 @@ export class DomCompiler extends RenderCompiler {

@Injectable()
export class DefaultDomCompiler extends DomCompiler {
constructor(parser: Parser, viewLoader: ViewLoader, sharedStylesHost: SharedStylesHost,
@Inject(APP_ID_TOKEN) appId: any) {
super(new DefaultStepFactory(parser, appId), viewLoader, sharedStylesHost);
constructor(schemaRegistry: ElementSchemaRegistry, parser: Parser, viewLoader: ViewLoader,
sharedStylesHost: SharedStylesHost, @Inject(APP_ID_TOKEN) appId: any) {
super(schemaRegistry, new DefaultStepFactory(parser, appId), viewLoader, sharedStylesHost);
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export class ElementSchemaRegistry {
hasProperty(elm: any, propName: string): boolean { return true; }
getMappedPropName(propName: string): string { return propName; }
}
44 changes: 21 additions & 23 deletions modules/angular2/src/render/dom/view/proto_view_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {

import {DomProtoView, DomProtoViewRef, resolveInternalDomProtoView} from './proto_view';
import {DomElementBinder, Event, HostAction} from './element_binder';
import {ElementSchemaRegistry} from '../schema/element_schema_registry';

import * as api from '../../api';

Expand Down Expand Up @@ -68,7 +69,7 @@ export class ProtoViewBuilder {

setHostAttribute(name: string, value: string) { this.hostAttributes.set(name, value); }

build(): api.ProtoViewDto {
build(schemaRegistry: ElementSchemaRegistry): api.ProtoViewDto {
var domElementBinders = [];

var apiElementBinders = [];
Expand All @@ -91,12 +92,12 @@ export class ProtoViewBuilder {
directiveIndex: dbb.directiveIndex,
propertyBindings: dbb.propertyBindings,
eventBindings: dbb.eventBindings,
hostPropertyBindings:
buildElementPropertyBindings(ebb.element, isPresent(ebb.componentId),
dbb.hostPropertyBindings, directiveTemplatePropertyNames)
hostPropertyBindings: buildElementPropertyBindings(schemaRegistry, ebb.element, true,
dbb.hostPropertyBindings, new Set())
});
});
var nestedProtoView = isPresent(ebb.nestedProtoView) ? ebb.nestedProtoView.build() : null;
var nestedProtoView =
isPresent(ebb.nestedProtoView) ? ebb.nestedProtoView.build(schemaRegistry) : null;
if (isPresent(nestedProtoView)) {
transitiveNgContentCount += nestedProtoView.transitiveNgContentCount;
}
Expand All @@ -113,7 +114,7 @@ export class ProtoViewBuilder {
directives: apiDirectiveBinders,
nestedProtoView: nestedProtoView,
propertyBindings:
buildElementPropertyBindings(ebb.element, isPresent(ebb.componentId),
buildElementPropertyBindings(schemaRegistry, ebb.element, isPresent(ebb.componentId),
ebb.propertyBindings, directiveTemplatePropertyNames),
variableBindings: ebb.variableBindings,
eventBindings: ebb.eventBindings,
Expand Down Expand Up @@ -325,14 +326,15 @@ const ATTRIBUTE_PREFIX = 'attr';
const CLASS_PREFIX = 'class';
const STYLE_PREFIX = 'style';

function buildElementPropertyBindings(protoElement: /*element*/ any, isNgComponent: boolean,
bindingsInTemplate: Map<string, ASTWithSource>,
directiveTempaltePropertyNames: Set<string>):
function buildElementPropertyBindings(
schemaRegistry: ElementSchemaRegistry, protoElement: /*element*/ any, isNgComponent: boolean,
bindingsInTemplate: Map<string, ASTWithSource>, directiveTempaltePropertyNames: Set<string>):
List<api.ElementPropertyBinding> {
var propertyBindings = [];
MapWrapper.forEach(bindingsInTemplate, (ast, propertyNameInTemplate) => {
var propertyBinding = createElementPropertyBinding(ast, propertyNameInTemplate);
if (isValidElementPropertyBinding(protoElement, isNgComponent, propertyBinding)) {
var propertyBinding = createElementPropertyBinding(schemaRegistry, ast, propertyNameInTemplate);
if (isValidElementPropertyBinding(schemaRegistry, protoElement, isNgComponent,
propertyBinding)) {
propertyBindings.push(propertyBinding);
} else if (!SetWrapper.has(directiveTempaltePropertyNames, propertyNameInTemplate)) {
throw new BaseException(
Expand All @@ -342,29 +344,25 @@ function buildElementPropertyBindings(protoElement: /*element*/ any, isNgCompone
return propertyBindings;
}

function isValidElementPropertyBinding(protoElement: /*element*/ any, isNgComponent: boolean,
function isValidElementPropertyBinding(schemaRegistry: ElementSchemaRegistry,
protoElement: /*element*/ any, isNgComponent: boolean,
binding: api.ElementPropertyBinding): boolean {
if (binding.type === api.PropertyBindingType.PROPERTY) {
var tagName = DOM.tagName(protoElement);
var possibleCustomElement = tagName.indexOf('-') !== -1;
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;
if (!isNgComponent) {
return schemaRegistry.hasProperty(protoElement, binding.property);
} else {
// TODO(pk): change this logic as soon as we can properly detect custom elements
return DOM.hasProperty(protoElement, binding.property);
}
}
return true;
}

function createElementPropertyBinding(ast: ASTWithSource, propertyNameInTemplate: string):
api.ElementPropertyBinding {
function createElementPropertyBinding(schemaRegistry: ElementSchemaRegistry, ast: ASTWithSource,
propertyNameInTemplate: string): api.ElementPropertyBinding {
var parts = StringWrapper.split(propertyNameInTemplate, PROPERTY_PARTS_SEPARATOR);
if (parts.length === 1) {
var propName = parts[0];
var mappedPropName = StringMapWrapper.get(DOM.attrToPropMap, propName);
propName = isPresent(mappedPropName) ? mappedPropName : propName;
var propName = schemaRegistry.getMappedPropName(parts[0]);
return new api.ElementPropertyBinding(api.PropertyBindingType.PROPERTY, ast, propName);
} else if (parts[0] == ATTRIBUTE_PREFIX) {
return new api.ElementPropertyBinding(api.PropertyBindingType.ATTRIBUTE, ast, parts[1]);
Expand Down
3 changes: 3 additions & 0 deletions modules/angular2/src/test_lib/test_injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ import {
SharedStylesHost,
DomSharedStylesHost
} 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 {Log} from './utils';

Expand Down Expand Up @@ -98,6 +100,7 @@ function _getAppBindings() {
bind(APP_ID_TOKEN).toValue('a'),
DefaultDomCompiler,
bind(RenderCompiler).toAlias(DefaultDomCompiler),
bind(ElementSchemaRegistry).toValue(new DomElementSchemaRegistry()),
DomSharedStylesHost,
bind(SharedStylesHost).toAlias(DomSharedStylesHost),
bind(DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES).toValue(false),
Expand Down
10 changes: 7 additions & 3 deletions modules/angular2/src/transform/template_compiler/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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_url_resolver.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/reflection/reflection.dart';
import 'package:angular2/src/services/url_resolver.dart';
Expand All @@ -33,7 +35,7 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
{bool generateRegistrations: true,
bool generateChangeDetectors: true}) async {
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 changeDetectorClasses = new change.Codegen();
Expand Down Expand Up @@ -83,14 +85,16 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
class _TemplateExtractor {
final CompileStepFactory _factory;
ViewLoader _loader;
ElementSchemaRegistry _schemaRegistry;

_TemplateExtractor(XHR xhr)
_TemplateExtractor(ElementSchemaRegistry schemaRegistry, XHR xhr)
: _factory = new CompileStepFactory(new ng.Parser(new ng.Lexer())) {
var urlResolver = new UrlResolver();
var styleUrlResolver = new StyleUrlResolver(urlResolver);
var styleInliner = new StyleInliner(xhr, styleUrlResolver, urlResolver);

_loader = new ViewLoader(xhr, styleInliner, styleUrlResolver);
_schemaRegistry = schemaRegistry;
}

Future<_ExtractResult> extractTemplates(ViewDefinition viewDef) async {
Expand All @@ -110,7 +114,7 @@ class _TemplateExtractor {

var compileElements =
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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from 'angular2/src/render/api';
import {CompileStep} from 'angular2/src/render/dom/compiler/compile_step';
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 {resolveInternalDomProtoView} from 'angular2/src/render/dom/view/proto_view';
Expand All @@ -48,7 +49,8 @@ export function runCompilerCommonTests() {
var tplLoader = new FakeViewLoader(urlData);
mockStepFactory =
new MockStepFactory([new MockStep(processElementClosure, processStyleClosure)]);
return new DomCompiler(mockStepFactory, tplLoader, sharedStylesHost);
return new DomCompiler(new ElementSchemaRegistry(), mockStepFactory, tplLoader,
sharedStylesHost);
}

describe('compile', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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');
});
});
}
Loading
X Tutup