Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit ebe3edc

Browse files
committed
chore(element_binder): Refactor the component factory
1 parent 22fb0bb commit ebe3edc

File tree

5 files changed

+149
-130
lines changed

5 files changed

+149
-130
lines changed

lib/core_dom/element_binder.dart

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ class TemplateElementBinder extends ElementBinder {
1414
return _directiveCache = [template];
1515
}
1616

17-
TemplateElementBinder(_perf, _expando, _parser, this.template, this.templateBinder,
17+
TemplateElementBinder(_perf, _expando, _parser, _componentFactory, this.template, this.templateBinder,
1818
onEvents, bindAttrs, childMode)
19-
: super(_perf, _expando, _parser, null, null, onEvents, bindAttrs, childMode);
19+
: super(_perf, _expando, _parser, _componentFactory, null, null, onEvents, bindAttrs, childMode);
2020

2121
String toString() => "[TemplateElementBinder template:$template]";
2222

@@ -41,6 +41,7 @@ class ElementBinder {
4141
final Profiler _perf;
4242
final Expando _expando;
4343
final Parser _parser;
44+
final ComponentFactory _componentFactory;
4445
final Map onEvents;
4546
final Map bindAttrs;
4647

@@ -52,7 +53,7 @@ class ElementBinder {
5253
// Can be either COMPILE_CHILDREN or IGNORE_CHILDREN
5354
final String childMode;
5455

55-
ElementBinder(this._perf, this._expando, this._parser, this.component, this.decorators,
56+
ElementBinder(this._perf, this._expando, this._parser, this._componentFactory, this.component, this.decorators,
5657
this.onEvents, this.bindAttrs, this.childMode);
5758

5859
final bool hasTemplate = false;
@@ -214,26 +215,7 @@ class ElementBinder {
214215
}
215216
nodesAttrsDirectives.add(ref);
216217
} else if (ref.annotation is Component) {
217-
//nodeModule.factory(type, new ComponentFactory(node, ref.directive), visibility: visibility);
218-
// TODO(misko): there should be no need to wrap function like this.
219-
nodeModule.factory(ref.type, (Injector injector) {
220-
var component = ref.annotation as Component;
221-
Compiler compiler = injector.get(Compiler);
222-
Scope scope = injector.get(Scope);
223-
ViewCache viewCache = injector.get(ViewCache);
224-
Http http = injector.get(Http);
225-
TemplateCache templateCache = injector.get(TemplateCache);
226-
DirectiveMap directives = injector.get(DirectiveMap);
227-
NgBaseCss baseCss = injector.get(NgBaseCss);
228-
// This is a bit of a hack since we are returning different type then we are.
229-
var componentFactory = new _ComponentFactory(node, ref.type, component,
230-
injector.get(dom.NodeTreeSanitizer), _expando, baseCss);
231-
var controller = componentFactory.call(injector, scope, viewCache, http, templateCache,
232-
directives);
233-
234-
componentFactory.shadowScope.context[component.publishAs] = controller;
235-
return controller;
236-
}, visibility: visibility);
218+
nodeModule.factory(ref.type, _componentFactory.call(node, ref), visibility: visibility);
237219
} else {
238220
nodeModule.type(ref.type, visibility: visibility);
239221
}

lib/core_dom/element_binder_builder.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ class ElementBinderFactory {
55
final Parser _parser;
66
final Profiler _perf;
77
final Expando _expando;
8+
final ComponentFactory _componentFactory;
89

9-
ElementBinderFactory(this._parser, this._perf, this._expando);
10+
ElementBinderFactory(this._parser, this._perf, this._expando, this._componentFactory);
1011

1112
// TODO: Optimize this to re-use a builder.
1213
ElementBinderBuilder builder() => new ElementBinderBuilder(this);
1314

1415
ElementBinder binder(ElementBinderBuilder b) =>
15-
new ElementBinder(_perf, _expando, _parser,
16+
new ElementBinder(_perf, _expando, _parser, _componentFactory,
1617
b.component, b.decorators, b.onEvents, b.bindAttrs, b.childMode);
1718
TemplateElementBinder templateBinder(ElementBinderBuilder b, ElementBinder transclude) =>
18-
new TemplateElementBinder(_perf, _expando, _parser,
19+
new TemplateElementBinder(_perf, _expando, _parser, _componentFactory,
1920
b.template, transclude, b.onEvents, b.bindAttrs, b.childMode);
2021
}
2122

lib/core_dom/module_internal.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ part 'http.dart';
3333
part 'mustache.dart';
3434
part 'node_cursor.dart';
3535
part 'selector.dart';
36+
part 'shadow_dom_component_factory.dart';
3637
part 'tagging_compiler.dart';
3738
part 'tagging_view_factory.dart';
3839
part 'template_cache.dart';
@@ -52,6 +53,7 @@ class CoreDomModule extends Module {
5253
type(AttrMustache);
5354

5455
type(Compiler, implementedBy: TaggingCompiler);
56+
type(ComponentFactory, implementedBy: ShadowDomComponentFactory);
5557
type(Http);
5658
type(UrlRewriter);
5759
type(HttpBackend);
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
part of angular.core.dom_internal;
2+
3+
abstract class ComponentFactory {
4+
FactoryFn call(dom.Node node, DirectiveRef ref);
5+
}
6+
7+
class ShadowDomComponentFactory implements ComponentFactory {
8+
final Expando _expando;
9+
10+
ShadowDomComponentFactory(this._expando);
11+
12+
FactoryFn call(dom.Node node, DirectiveRef ref) {
13+
return (Injector injector) {
14+
var component = ref.annotation as Component;
15+
Compiler compiler = injector.get(Compiler);
16+
Scope scope = injector.get(Scope);
17+
ViewCache viewCache = injector.get(ViewCache);
18+
Http http = injector.get(Http);
19+
TemplateCache templateCache = injector.get(TemplateCache);
20+
DirectiveMap directives = injector.get(DirectiveMap);
21+
NgBaseCss baseCss = injector.get(NgBaseCss);
22+
// This is a bit of a hack since we are returning different type then we are.
23+
var componentFactory = new _ComponentFactory(node, ref.type, component,
24+
injector.get(dom.NodeTreeSanitizer), _expando, baseCss);
25+
var controller = componentFactory.call(injector, scope, viewCache, http, templateCache,
26+
directives);
27+
28+
componentFactory.shadowScope.context[component.publishAs] = controller;
29+
return controller;
30+
};
31+
}
32+
}
33+
34+
35+
/**
36+
* ComponentFactory is responsible for setting up components. This includes
37+
* the shadowDom, fetching template, importing styles, setting up attribute
38+
* mappings, publishing the controller, and compiling and caching the template.
39+
*/
40+
class _ComponentFactory implements Function {
41+
42+
final dom.Element element;
43+
final Type type;
44+
final Component component;
45+
final dom.NodeTreeSanitizer treeSanitizer;
46+
final Expando _expando;
47+
final NgBaseCss _baseCss;
48+
49+
dom.ShadowRoot shadowDom;
50+
Scope shadowScope;
51+
Injector shadowInjector;
52+
var controller;
53+
54+
_ComponentFactory(this.element, this.type, this.component, this.treeSanitizer,
55+
this._expando, this._baseCss);
56+
57+
dynamic call(Injector injector, Scope scope,
58+
ViewCache viewCache, Http http, TemplateCache templateCache,
59+
DirectiveMap directives) {
60+
shadowDom = element.createShadowRoot()
61+
..applyAuthorStyles = component.applyAuthorStyles
62+
..resetStyleInheritance = component.resetStyleInheritance;
63+
64+
shadowScope = scope.createChild({}); // Isolate
65+
// TODO(pavelgj): fetching CSS with Http is mainly an attempt to
66+
// work around an unfiled Chrome bug when reloading same CSS breaks
67+
// styles all over the page. We shouldn't be doing browsers work,
68+
// so change back to using @import once Chrome bug is fixed or a
69+
// better work around is found.
70+
List<async.Future<String>> cssFutures = new List();
71+
var cssUrls = []..addAll(_baseCss.urls)..addAll(component.cssUrls);
72+
if (cssUrls.isNotEmpty) {
73+
cssUrls.forEach((css) => cssFutures.add(http
74+
.get(css, cache: templateCache).then(
75+
(resp) => resp.responseText,
76+
onError: (e) => '/*\n$e\n*/\n')
77+
));
78+
} else {
79+
cssFutures.add(new async.Future.value(null));
80+
}
81+
var viewFuture;
82+
if (component.template != null) {
83+
viewFuture = new async.Future.value(viewCache.fromHtml(
84+
component.template, directives));
85+
} else if (component.templateUrl != null) {
86+
viewFuture = viewCache.fromUrl(component.templateUrl, directives);
87+
}
88+
TemplateLoader templateLoader = new TemplateLoader(
89+
async.Future.wait(cssFutures).then((Iterable<String> cssList) {
90+
if (cssList != null) {
91+
shadowDom.setInnerHtml(
92+
cssList
93+
.where((css) => css != null)
94+
.map((css) => '<style>$css</style>')
95+
.join(''),
96+
treeSanitizer: treeSanitizer);
97+
}
98+
if (viewFuture != null) {
99+
return viewFuture.then((ViewFactory viewFactory) {
100+
return (!shadowScope.isAttached) ?
101+
shadowDom :
102+
attachViewToShadowDom(viewFactory);
103+
});
104+
}
105+
return shadowDom;
106+
}));
107+
controller = createShadowInjector(injector, templateLoader).get(type);
108+
if (controller is ShadowRootAware) {
109+
templateLoader.template.then((_) {
110+
if (!shadowScope.isAttached) return;
111+
(controller as ShadowRootAware).onShadowRoot(shadowDom);
112+
});
113+
}
114+
return controller;
115+
}
116+
117+
dom.ShadowRoot attachViewToShadowDom(ViewFactory viewFactory) {
118+
var view = viewFactory(shadowInjector);
119+
shadowDom.nodes.addAll(view.nodes);
120+
return shadowDom;
121+
}
122+
123+
Injector createShadowInjector(injector, TemplateLoader templateLoader) {
124+
var probe;
125+
var shadowModule = new Module()
126+
..type(type)
127+
..type(NgElement)
128+
..type(EventHandler, implementedBy: ShadowRootEventHandler)
129+
..value(Scope, shadowScope)
130+
..value(TemplateLoader, templateLoader)
131+
..value(dom.ShadowRoot, shadowDom)
132+
..factory(ElementProbe, (_) => probe);
133+
shadowInjector = injector.createChild([shadowModule], name: SHADOW_DOM_INJECTOR_NAME);
134+
probe = _expando[shadowDom] = new ElementProbe(
135+
injector.get(ElementProbe), shadowDom, shadowInjector, shadowScope);
136+
return shadowInjector;
137+
}
138+
}

lib/core_dom/view_factory.dart

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -143,110 +143,6 @@ class ViewCache {
143143
}
144144
}
145145

146-
/**
147-
* ComponentFactory is responsible for setting up components. This includes
148-
* the shadowDom, fetching template, importing styles, setting up attribute
149-
* mappings, publishing the controller, and compiling and caching the template.
150-
*/
151-
class _ComponentFactory implements Function {
152-
153-
final dom.Element element;
154-
final Type type;
155-
final Component component;
156-
final dom.NodeTreeSanitizer treeSanitizer;
157-
final Expando _expando;
158-
final NgBaseCss _baseCss;
159-
160-
dom.ShadowRoot shadowDom;
161-
Scope shadowScope;
162-
Injector shadowInjector;
163-
var controller;
164-
165-
_ComponentFactory(this.element, this.type, this.component, this.treeSanitizer,
166-
this._expando, this._baseCss);
167-
168-
dynamic call(Injector injector, Scope scope,
169-
ViewCache viewCache, Http http, TemplateCache templateCache,
170-
DirectiveMap directives) {
171-
shadowDom = element.createShadowRoot()
172-
..applyAuthorStyles = component.applyAuthorStyles
173-
..resetStyleInheritance = component.resetStyleInheritance;
174-
175-
shadowScope = scope.createChild({}); // Isolate
176-
// TODO(pavelgj): fetching CSS with Http is mainly an attempt to
177-
// work around an unfiled Chrome bug when reloading same CSS breaks
178-
// styles all over the page. We shouldn't be doing browsers work,
179-
// so change back to using @import once Chrome bug is fixed or a
180-
// better work around is found.
181-
List<async.Future<String>> cssFutures = new List();
182-
var cssUrls = []..addAll(_baseCss.urls)..addAll(component.cssUrls);
183-
if (cssUrls.isNotEmpty) {
184-
cssUrls.forEach((css) => cssFutures.add(http
185-
.get(css, cache: templateCache).then((resp) => resp.responseText,
186-
onError: (e) => '/*\n$e\n*/\n')
187-
));
188-
} else {
189-
cssFutures.add(new async.Future.value(null));
190-
}
191-
var viewFuture;
192-
if (component.template != null) {
193-
viewFuture = new async.Future.value(viewCache.fromHtml(
194-
component.template, directives));
195-
} else if (component.templateUrl != null) {
196-
viewFuture = viewCache.fromUrl(component.templateUrl, directives);
197-
}
198-
TemplateLoader templateLoader = new TemplateLoader(
199-
async.Future.wait(cssFutures).then((Iterable<String> cssList) {
200-
if (cssList != null) {
201-
shadowDom.setInnerHtml(
202-
cssList
203-
.where((css) => css != null)
204-
.map((css) => '<style>$css</style>')
205-
.join(''),
206-
treeSanitizer: treeSanitizer);
207-
}
208-
if (viewFuture != null) {
209-
return viewFuture.then((ViewFactory viewFactory) {
210-
return (!shadowScope.isAttached) ?
211-
shadowDom :
212-
attachViewToShadowDom(viewFactory);
213-
});
214-
}
215-
return shadowDom;
216-
}));
217-
controller = createShadowInjector(injector, templateLoader).get(type);
218-
if (controller is ShadowRootAware) {
219-
templateLoader.template.then((_) {
220-
if (!shadowScope.isAttached) return;
221-
(controller as ShadowRootAware).onShadowRoot(shadowDom);
222-
});
223-
}
224-
return controller;
225-
}
226-
227-
dom.ShadowRoot attachViewToShadowDom(ViewFactory viewFactory) {
228-
var view = viewFactory(shadowInjector);
229-
shadowDom.nodes.addAll(view.nodes);
230-
return shadowDom;
231-
}
232-
233-
Injector createShadowInjector(injector, TemplateLoader templateLoader) {
234-
var probe;
235-
var shadowModule = new Module()
236-
..type(type)
237-
..type(NgElement)
238-
..type(EventHandler, implementedBy: ShadowRootEventHandler)
239-
..value(Scope, shadowScope)
240-
..value(TemplateLoader, templateLoader)
241-
..value(dom.ShadowRoot, shadowDom)
242-
..factory(ElementProbe, (_) => probe);
243-
shadowInjector = injector.createChild([shadowModule], name: SHADOW_DOM_INJECTOR_NAME);
244-
probe = _expando[shadowDom] = new ElementProbe(
245-
injector.get(ElementProbe), shadowDom, shadowInjector, shadowScope);
246-
return shadowInjector;
247-
}
248-
}
249-
250146
class _AnchorAttrs extends NodeAttrs {
251147
DirectiveRef _directiveRef;
252148

0 commit comments

Comments
 (0)