Skip to content

Commit c68fa27

Browse files
committed
refactor(render): remove recursion from renderer
The goal is to make implementing a renderer straight forward. BREAKING_CHANGE: - Renderer interface was redone / simplified. - `DirectDomRenderer` was replaced by `DomRenderer`. - `DirectDomRenderer.setImperativeComponentRootNodes` is replaced by the following 2 steps: 1. `ViewManager.getComponentView(elementRef) -> ViewRef` 2. `DomRenderer.setComponentViewRootNodes(viewRef, rootNodes)` - all `@View` annotations need to have a template, but the template may be empty. Previously views that had a `renderer` property did not have to have a `template`. - `dynamicComponentLoader.loadIntoNewLocation` does no more allow to pass an element, but requires a css selector. Special syntax: `:document` can be used as prefix to search globally on the document instead of in the provided parent view. Part of #1675
1 parent d2507ac commit c68fa27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1221
-2207
lines changed

modules/angular2/angular2.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ export * from './directives';
55
export * from './forms';
66
export {Observable, EventEmitter} from 'angular2/src/facade/async';
77
export * from 'angular2/src/render/api';
8-
export {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
8+
export {DomRenderer, DOCUMENT_TOKEN} from 'angular2/src/render/dom/dom_renderer';

modules/angular2/src/core/application.js

+23-31
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,14 @@ import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
3333
import {AppViewManagerUtils} from 'angular2/src/core/compiler/view_manager_utils';
3434
import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
3535
import {Renderer, RenderCompiler} from 'angular2/src/render/api';
36-
import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
37-
import * as rc from 'angular2/src/render/dom/compiler/compiler';
38-
import * as rvf from 'angular2/src/render/dom/view/view_factory';
39-
import * as rvh from 'angular2/src/render/dom/view/view_hydrator';
36+
import {DomRenderer, DOCUMENT_TOKEN} from 'angular2/src/render/dom/dom_renderer';
37+
import {resolveInternalDomView} from 'angular2/src/render/dom/view/view';
38+
import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler';
4039
import {internalView} from 'angular2/src/core/compiler/view_ref';
4140

4241
import {
4342
appComponentRefToken,
44-
appElementToken,
45-
appComponentAnnotatedTypeToken,
46-
appDocumentToken,
43+
appComponentAnnotatedTypeToken
4744
} from './application_tokens';
4845

4946
var _rootInjector: Injector;
@@ -56,28 +53,25 @@ var _rootBindings = [
5653

5754
function _injectorBindings(appComponentType): List<Binding> {
5855
return [
59-
bind(appDocumentToken).toValue(DOM.defaultDoc()),
56+
bind(DOCUMENT_TOKEN).toValue(DOM.defaultDoc()),
6057
bind(appComponentAnnotatedTypeToken).toFactory((reader) => {
6158
// TODO(rado): investigate whether to support bindings on root component.
6259
return reader.read(appComponentType);
6360
}, [DirectiveMetadataReader]),
6461

65-
bind(appElementToken).toFactory((appComponentAnnotatedType, appDocument) => {
66-
var selector = appComponentAnnotatedType.annotation.selector;
67-
var element = DOM.querySelector(appDocument, selector);
68-
if (isBlank(element)) {
69-
throw new BaseException(`The app selector "${selector}" did not match any elements`);
70-
}
71-
return element;
72-
}, [appComponentAnnotatedTypeToken, appDocumentToken]),
73-
bind(appComponentRefToken).toAsyncFactory((dynamicComponentLoader, injector, appElement,
62+
bind(appComponentRefToken).toAsyncFactory((dynamicComponentLoader, injector,
7463
appComponentAnnotatedType, testability, registry) => {
7564

76-
// We need to do this here to ensure that we create Testability and
77-
// it's ready on the window for users.
78-
registry.registerApplication(appElement, testability);
79-
return dynamicComponentLoader.loadIntoNewLocation(appComponentAnnotatedType.type, null, appElement, injector);
80-
}, [DynamicComponentLoader, Injector, appElementToken, appComponentAnnotatedTypeToken,
65+
var selector = appComponentAnnotatedType.annotation.selector;
66+
return dynamicComponentLoader.loadIntoNewLocation(appComponentAnnotatedType.type, null, selector, injector).then( (componentRef) => {
67+
var domView = resolveInternalDomView(componentRef.hostView.render);
68+
// We need to do this here to ensure that we create Testability and
69+
// it's ready on the window for users.
70+
registry.registerApplication(domView.boundElements[0], testability);
71+
72+
return componentRef;
73+
});
74+
}, [DynamicComponentLoader, Injector, appComponentAnnotatedTypeToken,
8175
Testability, TestabilityRegistry]),
8276

8377
bind(appComponentType).toFactory((ref) => ref.instance,
@@ -89,18 +83,16 @@ function _injectorBindings(appComponentType): List<Binding> {
8983
}, [VmTurnZone]),
9084
bind(ShadowDomStrategy).toFactory(
9185
(styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, doc.head),
92-
[StyleUrlResolver, appDocumentToken]),
93-
DirectDomRenderer,
94-
bind(Renderer).toClass(DirectDomRenderer),
95-
bind(RenderCompiler).toClass(rc.DefaultDomCompiler),
86+
[StyleUrlResolver, DOCUMENT_TOKEN]),
9687
// TODO(tbosch): We need an explicit factory here, as
9788
// we are getting errors in dart2js with mirrors...
98-
bind(rvf.ViewFactory).toFactory(
99-
(capacity, eventManager, shadowDomStrategy) => new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
100-
[rvf.VIEW_POOL_CAPACITY, EventManager, ShadowDomStrategy]
89+
bind(DomRenderer).toFactory(
90+
(eventManager, shadowDomStrategy, doc) => new DomRenderer(eventManager, shadowDomStrategy, doc),
91+
[EventManager, ShadowDomStrategy, DOCUMENT_TOKEN]
10192
),
102-
bind(rvf.VIEW_POOL_CAPACITY).toValue(10000),
103-
rvh.RenderViewHydrator,
93+
DefaultDomCompiler,
94+
bind(Renderer).toAlias(DomRenderer),
95+
bind(RenderCompiler).toAlias(DefaultDomCompiler),
10496
ProtoViewFactory,
10597
// TODO(tbosch): We need an explicit factory here, as
10698
// we are getting errors in dart2js with mirrors...
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import {OpaqueToken} from 'angular2/di';
22

33
export var appComponentRefToken:OpaqueToken = new OpaqueToken('ComponentRef');
4-
export var appElementToken:OpaqueToken = new OpaqueToken('AppElement');
54
export var appComponentAnnotatedTypeToken:OpaqueToken = new OpaqueToken('AppComponentAnnotatedType');
6-
export var appDocumentToken:OpaqueToken = new OpaqueToken('AppDocument');

modules/angular2/src/core/compiler/compiler.js

+8-23
Original file line numberDiff line numberDiff line change
@@ -133,21 +133,14 @@ export class Compiler {
133133
if (isBlank(template)) {
134134
return null;
135135
}
136-
if (isPresent(template.renderer)) {
137-
var directives = [];
138-
pvPromise = this._render.createImperativeComponentProtoView(template.renderer).then( (renderPv) => {
139-
return this._compileNestedProtoViews(null, componentBinding, renderPv, directives, true);
140-
});
141-
} else {
142-
var directives = ListWrapper.map(
143-
this._flattenDirectives(template),
144-
(directive) => this._bindDirective(directive)
145-
);
146-
var renderTemplate = this._buildRenderTemplate(component, template, directives);
147-
pvPromise = this._render.compile(renderTemplate).then( (renderPv) => {
148-
return this._compileNestedProtoViews(null, componentBinding, renderPv, directives, true);
149-
});
150-
}
136+
var directives = ListWrapper.map(
137+
this._flattenDirectives(template),
138+
(directive) => this._bindDirective(directive)
139+
);
140+
var renderTemplate = this._buildRenderTemplate(component, template, directives);
141+
pvPromise = this._render.compile(renderTemplate).then( (renderPv) => {
142+
return this._compileNestedProtoViews(null, componentBinding, renderPv, directives, true);
143+
});
151144

152145
MapWrapper.set(this._compiling, component, pvPromise);
153146
return pvPromise;
@@ -187,14 +180,6 @@ export class Compiler {
187180
});
188181

189182
var protoViewDone = (_) => {
190-
var childComponentRenderPvRefs = [];
191-
ListWrapper.forEach(protoView.elementBinders, (eb) => {
192-
if (isPresent(eb.componentDirective)) {
193-
var componentPv = eb.nestedProtoView;
194-
ListWrapper.push(childComponentRenderPvRefs, isPresent(componentPv) ? componentPv.render : null);
195-
}
196-
});
197-
this._render.mergeChildComponentProtoViews(protoView.render, childComponentRenderPvRefs);
198183
return protoView;
199184
};
200185
if (nestedPVPromises.length > 0) {

modules/angular2/src/core/compiler/dynamic_component_loader.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ export class DynamicComponentLoader {
6262
}
6363

6464
/**
65-
* Loads a component in the element specified by elementOrSelector. The loaded component receives
65+
* Loads a component in the element specified by elementSelector. The loaded component receives
6666
* injection normally as a hosted view.
6767
*/
68-
loadIntoNewLocation(typeOrBinding, parentComponentLocation:ElementRef, elementOrSelector:any,
68+
loadIntoNewLocation(typeOrBinding, parentComponentLocation:ElementRef, elementSelector:string,
6969
injector:Injector = null):Promise<ComponentRef> {
7070
return this._compiler.compileInHost(this._getBinding(typeOrBinding)).then(hostProtoViewRef => {
7171
var hostViewRef = this._viewManager.createInPlaceHostView(
72-
parentComponentLocation, elementOrSelector, hostProtoViewRef, injector);
72+
parentComponentLocation, elementSelector, hostProtoViewRef, injector);
7373
var newLocation = new ElementRef(hostViewRef, 0);
7474
var component = this._viewManager.getComponent(newLocation);
7575

modules/angular2/src/core/compiler/element_injector.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ export class ElementInjector extends TreeNode {
894894

895895
_getPreBuiltObjectByKeyId(keyId:int) {
896896
var staticKeys = StaticKeys.instance();
897-
if (keyId === staticKeys.viewManagerId) return this._preBuiltObjects.viewManagerId;
897+
if (keyId === staticKeys.viewManagerId) return this._preBuiltObjects.viewManager;
898898

899899
//TODO add other objects as needed
900900
return _undefined;

modules/angular2/src/core/compiler/element_ref.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {DOM} from 'angular2/src/dom/dom_adapter';
22
import {normalizeBlank} from 'angular2/src/facade/lang';
33
import {ViewRef} from './view_ref';
4-
import {DirectDomViewRef} from 'angular2/src/render/dom/direct_dom_renderer';
4+
import {resolveInternalDomView} from 'angular2/src/render/dom/view/view';
55

66
/**
77
* @exportedAs angular2/view
@@ -23,8 +23,7 @@ export class ElementRef {
2323
// We need a more general way to read/write to the DOM element
2424
// via a proper abstraction in the render layer
2525
get domElement() {
26-
var renderViewRef:DirectDomViewRef = this.parentView.render;
27-
return renderViewRef.delegate.boundElements[this.boundElementIndex];
26+
return resolveInternalDomView(this.parentView.render).boundElements[this.boundElementIndex];
2827
}
2928

3029
/**

modules/angular2/src/core/compiler/view.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class AppView {
3232
componentChildViews: List<AppView>;
3333
/// Host views that were added by an imperative view.
3434
/// This is a dynamically growing / shrinking array.
35-
imperativeHostViews: List<AppView>;
35+
inPlaceHostViews: List<AppView>;
3636
viewContainers: List<AppViewContainer>;
3737
preBuiltObjects: List<PreBuiltObjects>;
3838
proto: AppProtoView;
@@ -64,7 +64,7 @@ export class AppView {
6464
this.context = null;
6565
this.locals = new Locals(null, MapWrapper.clone(protoLocals)); //TODO optimize this
6666
this.renderer = renderer;
67-
this.imperativeHostViews = [];
67+
this.inPlaceHostViews = [];
6868
}
6969

7070
init(changeDetector:ChangeDetector, elementInjectors:List, rootElementInjectors:List,

0 commit comments

Comments
 (0)