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