1
1
part of angular.core.dom_internal;
2
2
3
3
var _ComponentFactory_call = traceCreateScope ('ComponentFactory#call()' );
4
+ var _ComponentFactory_styles = traceCreateScope ('ComponentFactory#styles()' );
4
5
5
6
abstract class ComponentFactory {
6
7
BoundComponentFactory bind (DirectiveRef ref, directives);
@@ -13,7 +14,7 @@ abstract class BoundComponentFactory {
13
14
List <Key > get callArgs;
14
15
Function call (dom.Element element);
15
16
16
- static async .Future <ViewFactory > _viewFuture (
17
+ static async .Future <ViewFactory > _viewFactoryFuture (
17
18
Component component, ViewCache viewCache, DirectiveMap directives) {
18
19
if (component.template != null ) {
19
20
return new async .Future .value (viewCache.fromHtml (component.template, directives));
@@ -67,20 +68,27 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
67
68
Component get _component => _ref.annotation as Component ;
68
69
69
70
String _tag;
70
- async .Future <Iterable <dom.StyleElement >> _styleElementsFuture;
71
- async .Future <ViewFactory > _viewFuture;
71
+ async .Future <List <dom.StyleElement >> _styleElementsFuture;
72
+ List <dom.StyleElement > _styleElements;
73
+ async .Future <ViewFactory > _shadowViewFactoryFuture;
74
+ ViewFactory _shadowViewFactory;
72
75
73
76
BoundShadowDomComponentFactory (this ._componentFactory, this ._ref, this ._directives) {
74
77
_tag = _component.selector.toLowerCase ();
75
- _styleElementsFuture = async .Future .wait (_component.cssUrls.map (_styleFuture));
78
+ _styleElementsFuture = async .Future .wait (_component.cssUrls.map (_urlToStyle))
79
+ ..then ((stylesElements) => _styleElements = stylesElements);
76
80
77
- _viewFuture = BoundComponentFactory ._viewFuture (
81
+ _shadowViewFactoryFuture = BoundComponentFactory ._viewFactoryFuture (
78
82
_component,
83
+ // TODO(misko): Why do we create a new one per Component. This kind of defeats the caching.
79
84
new PlatformViewCache (_componentFactory.viewCache, _tag, _componentFactory.platform),
80
85
_directives);
86
+ if (_shadowViewFactoryFuture != null ) {
87
+ _shadowViewFactoryFuture.then ((viewFactory) => _shadowViewFactory = viewFactory);
88
+ }
81
89
}
82
90
83
- async .Future <dom.StyleElement > _styleFuture (cssUrl) {
91
+ async .Future <dom.StyleElement > _urlToStyle (cssUrl) {
84
92
Http http = _componentFactory.http;
85
93
TemplateCache templateCache = _componentFactory.templateCache;
86
94
WebPlatform platform = _componentFactory.platform;
@@ -109,7 +117,7 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
109
117
110
118
// If the css shim is required, it means that scoping does not
111
119
// work, and adding the style to the head of the document is
112
- // preferrable .
120
+ // preferable .
113
121
if (platform.cssShimRequired) {
114
122
dom.document.head.append (styleElement);
115
123
return null ;
@@ -128,47 +136,57 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
128
136
EventHandler eventHandler) {
129
137
var s = traceEnter (_ComponentFactory_call );
130
138
try {
131
- var shadowDom = element.createShadowRoot ()
139
+ var shadowScope = scope.createChild (new HashMap ()); // Isolate
140
+ ComponentDirectiveInjector shadowInjector;
141
+ dom.ShadowRoot shadowRoot = element.createShadowRoot ();
142
+ shadowRoot
132
143
..applyAuthorStyles = _component.applyAuthorStyles
133
144
..resetStyleInheritance = _component.resetStyleInheritance;
134
145
135
- var shadowScope = scope.createChild (new HashMap ()); // Isolate
146
+ List <async.Future > futures = < async .Future > [];
147
+ TemplateLoader templateLoader = new TemplateLoader (shadowRoot, futures);
148
+ shadowInjector = new ShadowDomComponentDirectiveInjector (
149
+ injector, injector.appInjector, shadowScope, templateLoader, shadowRoot);
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
+ }
136
167
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;
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
+ }
146
175
}
147
176
148
- ComponentDirectiveInjector shadowInjector;
149
177
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
- });
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);
161
184
}
162
- return shadowDom;
163
- }));
164
-
165
- var probe;
166
- shadowInjector = new ShadowDomComponentDirectiveInjector (injector, injector.appInjector, shadowScope, templateLoader, shadowDom);
167
- shadowInjector.bindByKey (_ref.typeKey, _ref.factory , _ref.paramKeys, _ref.annotation.visibility);
185
+ }
168
186
169
187
if (_componentFactory.config.elementProbeEnabled) {
170
- probe = _componentFactory.expando[shadowDom ] = shadowInjector.elementProbe;
171
- 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 );
172
190
}
173
191
174
192
var controller = shadowInjector.getByKey (_ref.typeKey);
@@ -181,6 +199,36 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory {
181
199
}
182
200
};
183
201
}
202
+
203
+ _insertCss (List <dom.StyleElement > cssList,
204
+ dom.ShadowRoot shadowRoot,
205
+ [dom.Node insertBefore = null ]) {
206
+ var s = traceEnter (_ComponentFactory_styles );
207
+ for (int i = 0 ; i < cssList.length; i++ ) {
208
+ var styleElement = cssList[i];
209
+ if (styleElement != null ) {
210
+ shadowRoot.insertBefore (styleElement.clone (true ), insertBefore);
211
+ }
212
+ }
213
+ traceLeave (s);
214
+ }
215
+
216
+ dom.Node _insertView (ViewFactory viewFactory,
217
+ dom.ShadowRoot shadowRoot,
218
+ Scope shadowScope,
219
+ ShadowDomComponentDirectiveInjector shadowInjector) {
220
+ dom.Node first = null ;
221
+ if (shadowScope.isAttached) {
222
+ View shadowView = viewFactory.call (shadowScope, shadowInjector);
223
+ List <dom.Node > shadowViewNodes = shadowView.nodes;
224
+ for (var j = 0 ; j < shadowViewNodes.length; j++ ) {
225
+ var node = shadowViewNodes[j];
226
+ if (j == 0 ) first = node;
227
+ shadowRoot.append (node);
228
+ }
229
+ }
230
+ return first;
231
+ }
184
232
}
185
233
186
234
class _ComponentAssetKey {
0 commit comments