@@ -11,7 +11,7 @@ abstract class BoundComponentFactory {
11
11
List <Key > get callArgs;
12
12
Function call (dom.Element element);
13
13
14
- static async .Future <ViewFactory > _viewFuture (
14
+ static async .Future <ViewFactory > _viewFactoryFuture (
15
15
Component component, ViewCache viewCache, DirectiveMap directives) {
16
16
if (component.template != null ) {
17
17
return new async .Future .value (viewCache.fromHtml (component.template, directives));
@@ -67,20 +67,27 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
67
67
Component get _component => _ref.annotation as Component ;
68
68
69
69
String _tag;
70
- async .Future <Iterable <dom.StyleElement >> _styleElementsFuture;
71
- async .Future <ViewFactory > _viewFuture;
70
+ async .Future <List <dom.StyleElement >> _styleElementsFuture;
71
+ List <dom.StyleElement > _styleElements;
72
+ async .Future <ViewFactory > _shadowViewFactoryFuture;
73
+ ViewFactory _shadowViewFactory;
72
74
73
75
BoundShadowDomComponentFactory (this ._componentFactory, this ._ref, this ._directives, this ._injector) {
74
76
_tag = _component.selector.toLowerCase ();
75
- _styleElementsFuture = async .Future .wait (_component.cssUrls.map (_styleFuture));
77
+ _styleElementsFuture = async .Future .wait (_component.cssUrls.map (_urlToStyle))
78
+ ..then ((stylesElements) => _styleElements = stylesElements);
76
79
77
- _viewFuture = BoundComponentFactory ._viewFuture (
80
+ _shadowViewFactoryFuture = BoundComponentFactory ._viewFactoryFuture (
78
81
_component,
82
+ // TODO(misko): Why do we create a new one per Component. This kind of defeats the caching.
79
83
new PlatformViewCache (_componentFactory.viewCache, _tag, _componentFactory.platform),
80
84
_directives);
85
+ if (_shadowViewFactoryFuture != null ) {
86
+ _shadowViewFactoryFuture.then ((viewFactory) => _shadowViewFactory = viewFactory);
87
+ }
81
88
}
82
89
83
- async .Future <dom.StyleElement > _styleFuture (cssUrl) {
90
+ async .Future <dom.StyleElement > _urlToStyle (cssUrl) {
84
91
Http http = _componentFactory.http;
85
92
TemplateCache templateCache = _componentFactory.templateCache;
86
93
WebPlatform platform = _componentFactory.platform;
@@ -109,7 +116,7 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
109
116
110
117
// If the css shim is required, it means that scoping does not
111
118
// work, and adding the style to the head of the document is
112
- // preferrable .
119
+ // preferable .
113
120
if (platform.cssShimRequired) {
114
121
dom.document.head.append (styleElement);
115
122
return null ;
@@ -128,50 +135,59 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
128
135
EventHandler _) {
129
136
var s = traceEnter (View_createComponent );
130
137
try {
131
- var shadowDom = element.createShadowRoot ()
138
+ var shadowScope = scope.createChild (new HashMap ()); // Isolate
139
+ ComponentDirectiveInjector shadowInjector;
140
+ dom.ShadowRoot shadowRoot = element.createShadowRoot ();
141
+ shadowRoot
132
142
..applyAuthorStyles = _component.applyAuthorStyles
133
143
..resetStyleInheritance = _component.resetStyleInheritance;
134
144
135
- var shadowScope = scope.createChild (new HashMap ()); // Isolate
145
+ List <async.Future > futures = < async .Future > [];
146
+ TemplateLoader templateLoader = new TemplateLoader (shadowRoot, futures);
147
+ var eventHandler = new ShadowRootEventHandler (
148
+ shadowRoot, injector.getByKey (EXPANDO_KEY ), injector.getByKey (EXCEPTION_HANDLER_KEY ));
149
+ shadowInjector = new ComponentDirectiveInjector (
150
+ injector, this ._injector, eventHandler, shadowScope, templateLoader, shadowRoot, null );
151
+ shadowInjector.bindByKey (_ref.typeKey, _ref.factory , _ref.paramKeys,
152
+ _ref.annotation.visibility);
153
+ dom.Node firstViewNode = null ;
154
+
155
+ // Load ngBase CSS
156
+ if (_component.useNgBaseCss == true && baseCss.urls.isNotEmpty) {
157
+ if (baseCss.styles == null ) {
158
+ futures.add (async .Future
159
+ .wait (baseCss.urls.map (_urlToStyle))
160
+ .then ((List <dom.StyleElement > cssList) {
161
+ baseCss.styles = cssList;
162
+ _insertCss (cssList, shadowRoot, shadowRoot.firstChild);
163
+ }));
164
+ } else {
165
+ _insertCss (baseCss.styles, shadowRoot, shadowRoot.firstChild);
166
+ }
167
+ }
136
168
137
- async .Future <Iterable <dom.StyleElement >> cssFuture;
138
- if (_component.useNgBaseCss == true ) {
139
- cssFuture = async .Future .wait ([async .Future .wait (baseCss.urls.map (_styleFuture)), _styleElementsFuture]).then ((twoLists) {
140
- assert (twoLists.length == 2 );return []
141
- ..addAll (twoLists[0 ])
142
- ..addAll (twoLists[1 ]);
143
- });
144
- } else {
145
- cssFuture = _styleElementsFuture;
169
+ if (_styleElementsFuture != null ) {
170
+ if (_styleElements == null ) {
171
+ futures.add (_styleElementsFuture .then ((List <dom.StyleElement > styles) =>
172
+ _insertCss (styles, shadowRoot, firstViewNode)));
173
+ } else {
174
+ _insertCss (_styleElements, shadowRoot);
175
+ }
146
176
}
147
177
148
- ComponentDirectiveInjector shadowInjector;
149
178
150
- TemplateLoader templateLoader = new TemplateLoader (cssFuture.then ((Iterable <dom.StyleElement > cssList) {
151
- cssList.where ((styleElement) => styleElement != null ).forEach ((styleElement) {
152
- shadowDom.append (styleElement.clone (true ));
153
- });
154
- if (_viewFuture != null ) {
155
- return _viewFuture.then ((ViewFactory viewFactory) {
156
- if (shadowScope.isAttached) {
157
- shadowDom.nodes.addAll (viewFactory.call (shadowInjector.scope, shadowInjector).nodes);
158
- }
159
- return shadowDom;
160
- });
179
+ if (_shadowViewFactoryFuture != null ) {
180
+ if (_shadowViewFactory == null ) {
181
+ futures.add (_shadowViewFactoryFuture.then ((ViewFactory viewFactory) =>
182
+ firstViewNode = _insertView (viewFactory, shadowRoot, shadowScope, shadowInjector)));
183
+ } else {
184
+ _insertView (_shadowViewFactory, shadowRoot, shadowScope, shadowInjector);
161
185
}
162
- return shadowDom;
163
- }));
164
-
165
- var probe;
166
- var eventHandler = new ShadowRootEventHandler (
167
- shadowDom, injector.getByKey (EXPANDO_KEY ), injector.getByKey (EXCEPTION_HANDLER_KEY ));
168
- shadowInjector = new ComponentDirectiveInjector (injector, _injector, eventHandler, shadowScope,
169
- templateLoader, shadowDom, null );
170
- shadowInjector.bindByKey (_ref.typeKey, _ref.factory , _ref.paramKeys, _ref.annotation.visibility);
186
+ }
171
187
172
188
if (_componentFactory.config.elementProbeEnabled) {
173
- probe = _componentFactory.expando[shadowDom ] = shadowInjector.elementProbe;
174
- shadowScope.on (ScopeEvent .DESTROY ).listen ((ScopeEvent ) => _componentFactory.expando[shadowDom ] = null );
189
+ ElementProbe probe = _componentFactory.expando[shadowRoot ] = shadowInjector.elementProbe;
190
+ shadowScope.on (ScopeEvent .DESTROY ).listen ((ScopeEvent ) => _componentFactory.expando[shadowRoot ] = null );
175
191
}
176
192
177
193
var controller = shadowInjector.getByKey (_ref.typeKey);
@@ -185,6 +201,36 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
185
201
}
186
202
};
187
203
}
204
+
205
+ _insertCss (List <dom.StyleElement > cssList,
206
+ dom.ShadowRoot shadowRoot,
207
+ [dom.Node insertBefore = null ]) {
208
+ var s = traceEnter (View_styles );
209
+ for (int i = 0 ; i < cssList.length; i++ ) {
210
+ var styleElement = cssList[i];
211
+ if (styleElement != null ) {
212
+ shadowRoot.insertBefore (styleElement.clone (true ), insertBefore);
213
+ }
214
+ }
215
+ traceLeave (s);
216
+ }
217
+
218
+ dom.Node _insertView (ViewFactory viewFactory,
219
+ dom.ShadowRoot shadowRoot,
220
+ Scope shadowScope,
221
+ ComponentDirectiveInjector shadowInjector) {
222
+ dom.Node first = null ;
223
+ if (shadowScope.isAttached) {
224
+ View shadowView = viewFactory.call (shadowScope, shadowInjector);
225
+ List <dom.Node > shadowViewNodes = shadowView.nodes;
226
+ for (var j = 0 ; j < shadowViewNodes.length; j++ ) {
227
+ var node = shadowViewNodes[j];
228
+ if (j == 0 ) first = node;
229
+ shadowRoot.append (node);
230
+ }
231
+ }
232
+ return first;
233
+ }
188
234
}
189
235
190
236
class _ComponentAssetKey {
0 commit comments