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 @@ -63,6 +63,8 @@ import {
DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES
} from 'angular2/src/render/dom/dom_renderer';
import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler';
import {ElementSchemaRegistry} from 'angular2/src/render/dom/schema/element_schema_registry';
import {DomElementSchemaRegistry} from 'angular2/src/render/dom/schema/dom_element_schema_registry';
import {internalView} from 'angular2/src/core/compiler/view_ref';
import {appComponentRefPromiseToken, appComponentTypeToken} from './application_tokens';

Expand Down Expand Up @@ -113,6 +115,7 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
DefaultDomCompiler,
bind(Renderer).toAlias(DomRenderer),
bind(RenderCompiler).toAlias(DefaultDomCompiler),
bind(ElementSchemaRegistry).toFactory(() => new DomElementSchemaRegistry([])),
ProtoViewFactory,
AppViewPool,
bind(APP_VIEW_POOL_CAPACITY).toValue(10000),
Expand Down
19 changes: 19 additions & 0 deletions modules/angular2/src/mock/element_schema_registry_mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {CONST_EXPR} from 'angular2/src/facade/lang';
import {ElementSchemaRegistryImpl} from 'angular2/src/render/dom/schema/element_schema_registry';
import {ElementSchemaEntry} from 'angular2/src/render/dom/schema/element_schema_entry';

class MockElementSchemaEntry implements ElementSchemaEntry {
constructor(public tagName: string, public extendsElement: string = null) {}

hasProperty(propName: string): boolean { return true; }

getMappedPropName(propName: string): string { return propName; }
}

export class MockElementSchemaRegistry extends ElementSchemaRegistryImpl {
constructor(entries: List<ElementSchemaEntry> = CONST_EXPR([])) { super(entries); }

handleEntryNotFound(tagName: string): ElementSchemaEntry {
return new MockElementSchemaEntry(tagName);
}
}
8 changes: 5 additions & 3 deletions modules/angular2/src/render/dom/compiler/compile_pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import {CompileControl} from './compile_control';
import {CompileStep} from './compile_step';
import {ProtoViewBuilder} from '../view/proto_view_builder';
import {ProtoViewDto, ViewType} from '../../api';
import {ElementSchemaRegistry} from '../schema/element_schema_registry';

/**
* CompilePipeline for executing CompileSteps recursively for
* all elements in a template.
*/
export class CompilePipeline {
_control: CompileControl;
constructor(steps: List<CompileStep>, private _useNativeShadowDom: boolean = false) {
constructor(private _elementSchemaRegistry: ElementSchemaRegistry, steps: List<CompileStep>,
private _useNativeShadowDom: boolean = false) {
this._control = new CompileControl(steps);
}

Expand All @@ -24,8 +26,8 @@ export class CompilePipeline {
}
var results = [];
var rootCompileElement = new CompileElement(rootElement, compilationCtxtDescription);
rootCompileElement.inheritedProtoView =
new ProtoViewBuilder(rootElement, protoViewType, this._useNativeShadowDom);
rootCompileElement.inheritedProtoView = new ProtoViewBuilder(
this._elementSchemaRegistry, rootElement, protoViewType, this._useNativeShadowDom);
rootCompileElement.isViewRoot = true;
this._process(results, null, rootCompileElement, compilationCtxtDescription);
return results;
Expand Down
12 changes: 7 additions & 5 deletions modules/angular2/src/render/dom/compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {ViewLoader} from 'angular2/src/render/dom/compiler/view_loader';
import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory';
import {Parser} from 'angular2/src/change_detection/change_detection';
import {ShadowDomStrategy} from '../shadow_dom/shadow_dom_strategy';
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
import * as pvm from '../view/proto_view_merger';

/**
Expand All @@ -27,7 +28,7 @@ import * as pvm from '../view/proto_view_merger';
*/
export class DomCompiler extends RenderCompiler {
constructor(public _stepFactory: CompileStepFactory, public _viewLoader: ViewLoader,
public _useNativeShadowDom: boolean) {
private _schemaRegistry: ElementSchemaRegistry, public _useNativeShadowDom: boolean) {
super();
}

Expand Down Expand Up @@ -60,8 +61,8 @@ export class DomCompiler extends RenderCompiler {

_compileTemplate(viewDef: ViewDefinition, tplElement,
protoViewType: ViewType): Promise<ProtoViewDto> {
var pipeline =
new CompilePipeline(this._stepFactory.createSteps(viewDef), this._useNativeShadowDom);
var pipeline = new CompilePipeline(this._schemaRegistry, this._stepFactory.createSteps(viewDef),
this._useNativeShadowDom);
var compileElements = pipeline.process(tplElement, protoViewType, viewDef.componentId);

return PromiseWrapper.resolve(compileElements[0].inheritedProtoView.build());
Expand All @@ -70,8 +71,9 @@ export class DomCompiler extends RenderCompiler {

@Injectable()
export class DefaultDomCompiler extends DomCompiler {
constructor(parser: Parser, shadowDomStrategy: ShadowDomStrategy, viewLoader: ViewLoader) {
super(new DefaultStepFactory(parser, shadowDomStrategy), viewLoader,
constructor(parser: Parser, shadowDomStrategy: ShadowDomStrategy, viewLoader: ViewLoader,
schemaRegistry: ElementSchemaRegistry) {
super(new DefaultStepFactory(parser, shadowDomStrategy), viewLoader, schemaRegistry,
shadowDomStrategy.hasNativeContentElement());
}
}
18 changes: 18 additions & 0 deletions modules/angular2/src/render/dom/schema/dom_element_schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {DOM} from 'angular2/src/dom/dom_adapter';

import {ElementSchemaEntry} from './element_schema_entry';

export class DOMElementSchema implements ElementSchemaEntry {
private _domElement;

constructor(public tagName: string, public extendsElement: string = null) {
// TODO(pk): here are are creating a new DOM element for each entry which if far from being
// optimal. Consider changing the signature of hasProperty so it takes an element - in that
// case we would be constructing a new DOM elements only for potential web components.
this._domElement = DOM.createElement(tagName);
}

hasProperty(propName: string): boolean { return DOM.hasProperty(this._domElement, propName); }

getMappedPropName(propName: string): string { return null; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {ElementSchemaEntry} from './element_schema_entry';
import {DOMElementSchema} from './dom_element_schema';
import {ElementSchemaRegistryImpl} from './element_schema_registry';

export const DEFAULT_HTML_EL_NAME = 'HTMLElement';

export class DomElementSchemaRegistry extends ElementSchemaRegistryImpl {
constructor(entries: List<ElementSchemaEntry>,
private _defaultElementToExtend: string = DEFAULT_HTML_EL_NAME) {
super(entries);
}

handleEntryNotFound(tagName: string): ElementSchemaEntry {
return new DOMElementSchema(tagName, this._defaultElementToExtend);
}
}
21 changes: 21 additions & 0 deletions modules/angular2/src/render/dom/schema/element_schema_entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {StringMap, StringMapWrapper} from 'angular2/src/facade/collection';

export interface ElementSchemaEntry {
tagName: string;
extendsElement: string;
hasProperty(propName: string): boolean;
getMappedPropName(propName: string): string;
}

export class HashElementSchema implements ElementSchemaEntry {
constructor(public tagName: string, private _properties: StringMap<string, string>,
public extendsElement: string = null) {}

hasProperty(propName: string): boolean {
return StringMapWrapper.contains(this._properties, propName);
}

getMappedPropName(propName: string): string {
return StringMapWrapper.get(this._properties, propName);
}
}
60 changes: 60 additions & 0 deletions modules/angular2/src/render/dom/schema/element_schema_registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {isPresent, BaseException} from 'angular2/src/facade/lang';
import {List, Map} from 'angular2/src/facade/collection';

import {ElementSchemaEntry} from './element_schema_entry';

export class ElementSchemaRegistry {
hasProperty(elName: string, propName: string): boolean { return true; }

getMappedPropName(elName: string, propName: string): string { return propName; }
}

export class SchemaRegistryError extends BaseException {
constructor(message) { super(message); }
}

export class ElementSchemaRegistryImpl extends ElementSchemaRegistry {
private _schema: Map<string, ElementSchemaEntry> = new Map();

constructor(entries: List<ElementSchemaEntry>) {
super();
entries.forEach((entry) => this._schema.set(entry.tagName, entry));
}

hasProperty(elName: string, propName: string): boolean {
var entry = this.getEntry(elName);

while (!entry.hasProperty(propName) && isPresent(entry.extendsElement)) {
entry = this.getEntry(entry.extendsElement);
}

return entry.hasProperty(propName);
}

getMappedPropName(elName: string, propName: string): string {
var entry = this.getEntry(elName);
var mappedPropName = entry.getMappedPropName(propName);

while (!isPresent(mappedPropName) && isPresent(entry.extendsElement)) {
entry = this.getEntry(entry.extendsElement);
mappedPropName = entry.getMappedPropName(propName);
}

return isPresent(mappedPropName) ? mappedPropName : propName;
}

getEntry(tagName: string): ElementSchemaEntry {
var entry = this._schema.get(tagName);
if (!isPresent(entry)) {
entry = this.handleEntryNotFound(tagName);
if (isPresent(entry)) {
this._schema.set(tagName, entry);
}
}
return entry;
}

handleEntryNotFound(tagName: string): ElementSchemaEntry {
throw new SchemaRegistryError(`Missing schema entry for '${tagName}'`);
}
}
14 changes: 9 additions & 5 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 All @@ -36,11 +37,12 @@ export class ProtoViewBuilder {
rootTextBindings: Map<Node, ASTWithSource> = new Map();
ngContentCount: number = 0;

constructor(public rootElement, public type: api.ViewType,
public useNativeShadowDom: boolean = false) {}
constructor(private _elementSchemaRegistry: ElementSchemaRegistry, public rootElement,
public type: api.ViewType, public useNativeShadowDom: boolean = false) {}

bindElement(element: HTMLElement, description: string = null): ElementBinderBuilder {
var builder = new ElementBinderBuilder(this.elements.length, element, description);
var builder = new ElementBinderBuilder(this._elementSchemaRegistry, this.elements.length,
element, description);
this.elements.push(builder);
DOM.addClass(element, NG_BINDING_CLASS);

Expand Down Expand Up @@ -152,7 +154,8 @@ export class ElementBinderBuilder {
readAttributes: Map<string, string> = new Map();
componentId: string = null;

constructor(public index: number, public element, description: string) {}
constructor(private _elementSchemaRegistry: ElementSchemaRegistry, public index: number,
public element, description: string) {}

setParent(parent: ElementBinderBuilder, distanceToParent: number): ElementBinderBuilder {
this.parent = parent;
Expand All @@ -178,7 +181,8 @@ export class ElementBinderBuilder {
if (isPresent(this.nestedProtoView)) {
throw new BaseException('Only one nested view per element is allowed');
}
this.nestedProtoView = new ProtoViewBuilder(rootElement, api.ViewType.EMBEDDED);
this.nestedProtoView =
new ProtoViewBuilder(this._elementSchemaRegistry, rootElement, api.ViewType.EMBEDDED);
return this.nestedProtoView;
}

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 @@ -57,6 +57,8 @@ import {
DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES
} from 'angular2/src/render/dom/dom_renderer';
import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler';
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 @@ -101,6 +103,7 @@ function _getAppBindings() {
bind(DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES).toValue(false),
bind(Renderer).toAlias(DomRenderer),
bind(RenderCompiler).toAlias(DefaultDomCompiler),
bind(ElementSchemaRegistry).toFactory(() => new DomElementSchemaRegistry([])),
ProtoViewFactory,
AppViewPool,
AppViewManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {CompileStep} from 'angular2/src/render/dom/compiler/compile_step';
import {CompileStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory';
import {CompileControl} from 'angular2/src/render/dom/compiler/compile_control';
import {ViewLoader} from 'angular2/src/render/dom/compiler/view_loader';
import {MockElementSchemaRegistry} from 'angular2/src/mock/element_schema_registry_mock';

import {resolveInternalDomProtoView} from 'angular2/src/render/dom/view/proto_view';

Expand All @@ -36,7 +37,7 @@ export function runCompilerCommonTests() {
}
var tplLoader = new FakeViewLoader(urlData);
mockStepFactory = new MockStepFactory([new MockStep(processClosure)]);
return new DomCompiler(mockStepFactory, tplLoader, false);
return new DomCompiler(mockStepFactory, tplLoader, new MockElementSchemaRegistry(), false);
}

describe('compile', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {CompileControl} from 'angular2/src/render/dom/compiler/compile_control';
import {ViewDefinition, DirectiveMetadata} from 'angular2/src/render/api';
import {Lexer, Parser} from 'angular2/src/change_detection/change_detection';
import {ElementBinderBuilder} from 'angular2/src/render/dom/view/proto_view_builder';
import {MockElementSchemaRegistry} from 'angular2/src/mock/element_schema_registry_mock';

export function main() {
describe('DirectiveParser', () => {
Expand All @@ -35,7 +36,7 @@ export function main() {
function createPipeline(propertyBindings = null, directives = null) {
if (isBlank(directives)) directives = annotatedDirectives;

return new CompilePipeline([
return new CompilePipeline(new MockElementSchemaRegistry(), [
new MockStep((parent, current, control) => {
if (isPresent(propertyBindings)) {
StringMapWrapper.forEach(propertyBindings, (ast, name) => {
Expand Down
Loading