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