@@ -24,13 +24,11 @@ final CONTENT_PORT_KEY = new Key(ContentPort);
24
24
final TEMPLATE_LOADER_KEY = new Key (TemplateLoader );
25
25
final SHADOW_ROOT_KEY = new Key (ShadowRoot );
26
26
27
+ final num MAX_DEPTH = 1 << 30 ;
28
+
27
29
const int VISIBILITY_LOCAL = - 1 ;
28
30
const int VISIBILITY_DIRECT_CHILD = - 2 ;
29
31
const int VISIBILITY_CHILDREN = - 3 ;
30
- const int VISIBILITY_COMPONENT_OFFSET = VISIBILITY_CHILDREN ;
31
- const int VISIBILITY_COMPONENT_LOCAL = VISIBILITY_LOCAL + VISIBILITY_COMPONENT_OFFSET ;
32
- const int VISIBILITY_COMPONENT_DIRECT_CHILD = VISIBILITY_DIRECT_CHILD + VISIBILITY_COMPONENT_OFFSET ;
33
- const int VISIBILITY_COMPONENT_CHILDREN = VISIBILITY_CHILDREN + VISIBILITY_COMPONENT_OFFSET ;
34
32
35
33
const int UNDEFINED_ID = 0 ;
36
34
const int INJECTOR_KEY_ID = 1 ;
@@ -52,6 +50,8 @@ const int CONTENT_PORT_KEY_ID = 16;
52
50
const int EVENT_HANDLER_KEY_ID = 17 ;
53
51
const int KEEP_ME_LAST = 18 ;
54
52
53
+ EventHandler eventHandler (DirectiveInjector di) => di._eventHandler;
54
+
55
55
class DirectiveInjector implements DirectiveBinder {
56
56
static bool _isInit = false ;
57
57
static initUID () {
@@ -99,9 +99,9 @@ class DirectiveInjector implements DirectiveBinder {
99
99
, EVENT_HANDLER_KEY
100
100
, KEEP_ME_LAST
101
101
];
102
-
102
+
103
103
final DirectiveInjector _parent;
104
- final Injector appInjector ;
104
+ final Injector _appInjector ;
105
105
final Node _node;
106
106
final NodeAttrs _nodeAttrs;
107
107
final Animate _animate;
@@ -134,21 +134,17 @@ class DirectiveInjector implements DirectiveBinder {
134
134
case VISIBILITY_LOCAL : return Visibility .LOCAL ;
135
135
case VISIBILITY_DIRECT_CHILD : return Visibility .DIRECT_CHILD ;
136
136
case VISIBILITY_CHILDREN : return Visibility .CHILDREN ;
137
- case VISIBILITY_COMPONENT_LOCAL : return Visibility .LOCAL ;
138
- case VISIBILITY_COMPONENT_DIRECT_CHILD : return Visibility .DIRECT_CHILD ;
139
- case VISIBILITY_COMPONENT_CHILDREN : return Visibility .CHILDREN ;
140
137
default : return null ;
141
138
}
142
139
}
143
140
144
141
static Binding _tempBinding = new Binding ();
145
142
146
- DirectiveInjector (DirectiveInjector parent, Injector appInjector, this ._node, this ._nodeAttrs,
143
+ DirectiveInjector (this ._parent, appInjector, this ._node, this ._nodeAttrs,
147
144
this ._eventHandler, this .scope, this ._animate)
148
- : appInjector = appInjector,
149
- _parent = parent == null ? new DefaultDirectiveInjector (appInjector) : parent;
145
+ : _appInjector = appInjector;
150
146
151
- DirectiveInjector ._default (this ._parent, this .appInjector )
147
+ DirectiveInjector ._default (this ._parent, this ._appInjector )
152
148
: _node = null ,
153
149
_nodeAttrs = null ,
154
150
_eventHandler = null ,
@@ -195,54 +191,72 @@ class DirectiveInjector implements DirectiveBinder {
195
191
else { throw 'Maximum number of directives per element reached.' ; }
196
192
}
197
193
194
+ // Get a key from the directive injector chain. When it is exhausted, get from
195
+ // the current application injector chain.
198
196
Object get (Type type) => getByKey (new Key (type));
199
- Object getFromParent (Type type) => _parent. get ( type);
197
+ Object getFromParent (Type type) => getFromParentByKey ( new Key ( type) );
200
198
201
199
Object getByKey (Key key) {
202
200
var oldTag = _TAG_GET .makeCurrent ();
203
201
try {
204
- return _getByKey (key);
202
+ return _getByKey (key, _appInjector );
205
203
} on ResolvingError catch (e, s) {
206
204
e.appendKey (key);
207
205
rethrow ;
208
206
} finally {
209
207
oldTag.makeCurrent ();
210
208
}
211
209
}
212
- Object getFromParentByKey (Key key) => _parent.getByKey (key);
213
210
214
- Object _getByKey (Key key) {
211
+ Object getFromParentByKey (Key key) {
212
+ if (_parent == null ) {
213
+ return _appInjector.getByKey (key);
214
+ } else {
215
+ return _parent._getByKey (key, _appInjector);
216
+ }
217
+ }
218
+
219
+ Object _getByKey (Key key, Injector appInjector) {
215
220
int uid = key.uid;
216
221
if (uid == null || uid == UNDEFINED_ID ) return appInjector.getByKey (key);
217
222
bool isDirective = uid < 0 ;
218
223
return isDirective ? _getDirectiveByKey (key, uid, appInjector) : _getById (uid);
219
224
}
220
225
221
- Object _getDirectiveByKey (Key k, int visType, Injector i) {
222
- do {
223
- if (_key0 == null ) break ; if (identical (_key0, k)) return _obj0 == null ? _obj0 = _new (_pKeys0, _factory0) : _obj0;
224
- if (_key1 == null ) break ; if (identical (_key1, k)) return _obj1 == null ? _obj1 = _new (_pKeys1, _factory1) : _obj1;
225
- if (_key2 == null ) break ; if (identical (_key2, k)) return _obj2 == null ? _obj2 = _new (_pKeys2, _factory2) : _obj2;
226
- if (_key3 == null ) break ; if (identical (_key3, k)) return _obj3 == null ? _obj3 = _new (_pKeys3, _factory3) : _obj3;
227
- if (_key4 == null ) break ; if (identical (_key4, k)) return _obj4 == null ? _obj4 = _new (_pKeys4, _factory4) : _obj4;
228
- if (_key5 == null ) break ; if (identical (_key5, k)) return _obj5 == null ? _obj5 = _new (_pKeys5, _factory5) : _obj5;
229
- if (_key6 == null ) break ; if (identical (_key6, k)) return _obj6 == null ? _obj6 = _new (_pKeys6, _factory6) : _obj6;
230
- if (_key7 == null ) break ; if (identical (_key7, k)) return _obj7 == null ? _obj7 = _new (_pKeys7, _factory7) : _obj7;
231
- if (_key8 == null ) break ; if (identical (_key8, k)) return _obj8 == null ? _obj8 = _new (_pKeys8, _factory8) : _obj8;
232
- if (_key9 == null ) break ; if (identical (_key9, k)) return _obj9 == null ? _obj9 = _new (_pKeys9, _factory9) : _obj9;
233
- } while (false );
234
- switch (visType) {
235
- case VISIBILITY_LOCAL : return appInjector.getByKey (k);
236
- case VISIBILITY_DIRECT_CHILD : return _parent._getDirectiveByKey (k, VISIBILITY_LOCAL , i);
237
- case VISIBILITY_CHILDREN : return _parent._getDirectiveByKey (k, VISIBILITY_CHILDREN , i);
238
- // SHADOW
239
- case VISIBILITY_COMPONENT_LOCAL : return _parent._getDirectiveByKey (k, VISIBILITY_LOCAL , i);
240
- case VISIBILITY_COMPONENT_DIRECT_CHILD : return _parent._getDirectiveByKey (k, VISIBILITY_DIRECT_CHILD , i);
241
- case VISIBILITY_COMPONENT_CHILDREN : return _parent._getDirectiveByKey (k, VISIBILITY_CHILDREN , i);
226
+ num _getDepth (int visType) {
227
+ switch (visType) {
228
+ case VISIBILITY_LOCAL : return 0 ;
229
+ case VISIBILITY_DIRECT_CHILD : return 1 ;
230
+ case VISIBILITY_CHILDREN : return MAX_DEPTH ;
242
231
default : throw null ;
243
232
}
244
233
}
245
234
235
+ _getDirectiveByKey (Key k, int visType, Injector appInjector) {
236
+ num depth = _getDepth (visType);
237
+ // ci stands for currentInjector, abbreviated for readability.
238
+ var ci = this ;
239
+ while (ci != null && depth >= 0 ) {
240
+ do {
241
+ if (ci._key0 == null ) break ; if (identical (ci._key0, k)) return ci._obj0 == null ? ci._obj0 = ci._new (ci._pKeys0, ci._factory0) : ci._obj0;
242
+ if (ci._key1 == null ) break ; if (identical (ci._key1, k)) return ci._obj1 == null ? ci._obj1 = ci._new (ci._pKeys1, ci._factory1) : ci._obj1;
243
+ if (ci._key2 == null ) break ; if (identical (ci._key2, k)) return ci._obj2 == null ? ci._obj2 = ci._new (ci._pKeys2, ci._factory2) : ci._obj2;
244
+ if (ci._key3 == null ) break ; if (identical (ci._key3, k)) return ci._obj3 == null ? ci._obj3 = ci._new (ci._pKeys3, ci._factory3) : ci._obj3;
245
+ if (ci._key4 == null ) break ; if (identical (ci._key4, k)) return ci._obj4 == null ? ci._obj4 = ci._new (ci._pKeys4, ci._factory4) : ci._obj4;
246
+ if (ci._key5 == null ) break ; if (identical (ci._key5, k)) return ci._obj5 == null ? ci._obj5 = ci._new (ci._pKeys5, ci._factory5) : ci._obj5;
247
+ if (ci._key6 == null ) break ; if (identical (ci._key6, k)) return ci._obj6 == null ? ci._obj6 = ci._new (ci._pKeys6, ci._factory6) : ci._obj6;
248
+ if (ci._key7 == null ) break ; if (identical (ci._key7, k)) return ci._obj7 == null ? ci._obj7 = ci._new (ci._pKeys7, ci._factory7) : ci._obj7;
249
+ if (ci._key8 == null ) break ; if (identical (ci._key8, k)) return ci._obj8 == null ? ci._obj8 = ci._new (ci._pKeys8, ci._factory8) : ci._obj8;
250
+ if (ci._key9 == null ) break ; if (identical (ci._key9, k)) return ci._obj9 == null ? ci._obj9 = ci._new (ci._pKeys9, ci._factory9) : ci._obj9;
251
+ } while (false );
252
+ // Future feature: Component Injectors fall-through only if directly called.
253
+ // if ((ci is ComponentDirectiveInjector) && !identical(ci, this)) break;
254
+ ci = ci._parent;
255
+ depth-- ;
256
+ }
257
+ return appInjector.getByKey (k);
258
+ }
259
+
246
260
List get directives {
247
261
var directives = [];
248
262
if (_obj0 != null ) directives.add (_obj0);
@@ -260,7 +274,7 @@ class DirectiveInjector implements DirectiveBinder {
260
274
261
275
Object _getById (int keyId) {
262
276
switch (keyId) {
263
- case INJECTOR_KEY_ID : return appInjector ;
277
+ case INJECTOR_KEY_ID : return _appInjector ;
264
278
case DIRECTIVE_INJECTOR_KEY_ID : return this ;
265
279
case NODE_KEY_ID : return _node;
266
280
case ELEMENT_KEY_ID : return _node;
@@ -270,7 +284,13 @@ class DirectiveInjector implements DirectiveBinder {
270
284
case ELEMENT_PROBE_KEY_ID : return elementProbe;
271
285
case NG_ELEMENT_KEY_ID : return ngElement;
272
286
case EVENT_HANDLER_KEY_ID : return _eventHandler;
273
- case CONTENT_PORT_KEY_ID : return _parent._getById (keyId);
287
+ case CONTENT_PORT_KEY_ID :
288
+ var currentInjector = _parent;
289
+ while (currentInjector != null ) {
290
+ if (currentInjector is ComponentDirectiveInjector ) return currentInjector._contentPort;
291
+ currentInjector = currentInjector._parent;
292
+ }
293
+ return null ;
274
294
default : new NoProviderError (_KEYS [keyId]);
275
295
}
276
296
}
@@ -279,29 +299,30 @@ class DirectiveInjector implements DirectiveBinder {
279
299
var oldTag = _TAG_GET .makeCurrent ();
280
300
int size = paramKeys.length;
281
301
var obj;
302
+ var appInjector = this ._appInjector;
282
303
if (size > 15 ) {
283
304
var params = new List (paramKeys.length);
284
305
for (var i = 0 ; i < paramKeys.length; i++ ) {
285
- params[i] = _getByKey (paramKeys[i]);
306
+ params[i] = _getByKey (paramKeys[i], appInjector );
286
307
}
287
308
_TAG_INSTANTIATE .makeCurrent ();
288
309
obj = Function .apply (fn, params);
289
310
} else {
290
- var a01 = size >= 01 ? _getByKey (paramKeys[00 ]) : null ;
291
- var a02 = size >= 02 ? _getByKey (paramKeys[01 ]) : null ;
292
- var a03 = size >= 03 ? _getByKey (paramKeys[02 ]) : null ;
293
- var a04 = size >= 04 ? _getByKey (paramKeys[03 ]) : null ;
294
- var a05 = size >= 05 ? _getByKey (paramKeys[04 ]) : null ;
295
- var a06 = size >= 06 ? _getByKey (paramKeys[05 ]) : null ;
296
- var a07 = size >= 07 ? _getByKey (paramKeys[06 ]) : null ;
297
- var a08 = size >= 08 ? _getByKey (paramKeys[07 ]) : null ;
298
- var a09 = size >= 09 ? _getByKey (paramKeys[08 ]) : null ;
299
- var a10 = size >= 10 ? _getByKey (paramKeys[09 ]) : null ;
300
- var a11 = size >= 11 ? _getByKey (paramKeys[10 ]) : null ;
301
- var a12 = size >= 12 ? _getByKey (paramKeys[11 ]) : null ;
302
- var a13 = size >= 13 ? _getByKey (paramKeys[12 ]) : null ;
303
- var a14 = size >= 14 ? _getByKey (paramKeys[13 ]) : null ;
304
- var a15 = size >= 15 ? _getByKey (paramKeys[14 ]) : null ;
311
+ var a01 = size >= 01 ? _getByKey (paramKeys[00 ], appInjector ) : null ;
312
+ var a02 = size >= 02 ? _getByKey (paramKeys[01 ], appInjector ) : null ;
313
+ var a03 = size >= 03 ? _getByKey (paramKeys[02 ], appInjector ) : null ;
314
+ var a04 = size >= 04 ? _getByKey (paramKeys[03 ], appInjector ) : null ;
315
+ var a05 = size >= 05 ? _getByKey (paramKeys[04 ], appInjector ) : null ;
316
+ var a06 = size >= 06 ? _getByKey (paramKeys[05 ], appInjector ) : null ;
317
+ var a07 = size >= 07 ? _getByKey (paramKeys[06 ], appInjector ) : null ;
318
+ var a08 = size >= 08 ? _getByKey (paramKeys[07 ], appInjector ) : null ;
319
+ var a09 = size >= 09 ? _getByKey (paramKeys[08 ], appInjector ) : null ;
320
+ var a10 = size >= 10 ? _getByKey (paramKeys[09 ], appInjector ) : null ;
321
+ var a11 = size >= 11 ? _getByKey (paramKeys[10 ], appInjector ) : null ;
322
+ var a12 = size >= 12 ? _getByKey (paramKeys[11 ], appInjector ) : null ;
323
+ var a13 = size >= 13 ? _getByKey (paramKeys[12 ], appInjector ) : null ;
324
+ var a14 = size >= 14 ? _getByKey (paramKeys[13 ], appInjector ) : null ;
325
+ var a15 = size >= 15 ? _getByKey (paramKeys[14 ], appInjector ) : null ;
305
326
_TAG_INSTANTIATE .makeCurrent ();
306
327
switch (size) {
307
328
case 00 : obj = fn (); break ;
@@ -367,14 +388,15 @@ class TemplateDirectiveInjector extends DirectiveInjector {
367
388
368
389
}
369
390
370
- abstract class ComponentDirectiveInjector extends DirectiveInjector {
391
+ class ComponentDirectiveInjector extends DirectiveInjector {
371
392
372
393
final TemplateLoader _templateLoader;
373
394
final ShadowRoot _shadowRoot;
395
+ final ContentPort _contentPort;
374
396
375
397
ComponentDirectiveInjector (DirectiveInjector parent, Injector appInjector,
376
398
EventHandler eventHandler, Scope scope,
377
- this ._templateLoader, this ._shadowRoot)
399
+ this ._templateLoader, this ._shadowRoot, this ._contentPort )
378
400
: super (parent, appInjector, parent._node, parent._nodeAttrs, eventHandler, scope,
379
401
parent._animate);
380
402
@@ -386,56 +408,16 @@ abstract class ComponentDirectiveInjector extends DirectiveInjector {
386
408
}
387
409
}
388
410
389
- _getDirectiveByKey (Key k, int visType, Injector i) =>
390
- super ._getDirectiveByKey (k, visType + VISIBILITY_COMPONENT_OFFSET , i);
391
- }
392
-
393
- class ShadowlessComponentDirectiveInjector extends ComponentDirectiveInjector {
394
- final ContentPort _contentPort;
395
-
396
- ShadowlessComponentDirectiveInjector (DirectiveInjector parent, Injector appInjector,
397
- EventHandler eventHandler, Scope scope,
398
- templateLoader, shadowRoot, this ._contentPort)
399
- : super (parent, appInjector, eventHandler, scope, templateLoader, shadowRoot);
400
-
401
- Object _getById (int keyId) {
402
- switch (keyId) {
403
- case CONTENT_PORT_KEY_ID : return _contentPort;
404
- default : return super ._getById (keyId);
405
- }
406
- }
407
- }
408
-
409
- class ShadowDomComponentDirectiveInjector extends ComponentDirectiveInjector {
410
- ShadowDomComponentDirectiveInjector (DirectiveInjector parent, Injector appInjector,
411
- Scope scope, templateLoader, shadowRoot)
412
- : super (parent, appInjector, new ShadowRootEventHandler (shadowRoot,
413
- parent.getByKey (EXPANDO_KEY ),
414
- parent.getByKey (EXCEPTION_HANDLER_KEY )),
415
- scope, templateLoader, shadowRoot);
416
-
417
411
ElementProbe get elementProbe {
418
412
if (_elementProbe == null ) {
419
413
ElementProbe parentProbe = _parent == null ? null : _parent.elementProbe;
420
414
_elementProbe = new ElementProbe (parentProbe, _shadowRoot, this , scope);
421
415
}
422
416
return _elementProbe;
423
417
}
424
- }
425
418
426
- @Injectable ()
427
- class DefaultDirectiveInjector extends DirectiveInjector {
428
- DefaultDirectiveInjector (Injector appInjector): super ._default (null , appInjector);
429
- DefaultDirectiveInjector .newAppInjector (DirectiveInjector parent, Injector appInjector)
430
- : super ._default (parent, appInjector);
431
-
432
- Object getByKey (Key key) => appInjector.getByKey (key);
433
- _getDirectiveByKey (Key key, int visType, Injector i) =>
434
- _parent == null ? i.getByKey (key) : _parent._getDirectiveByKey (key, visType, i);
435
- _getById (int keyId) {
436
- switch (keyId) {
437
- case CONTENT_PORT_KEY_ID : return null ;
438
- default : throw new NoProviderError (DirectiveInjector ._KEYS [keyId]);
439
- }
440
- }
419
+ // Add 1 to visibility to allow to skip over current component injector.
420
+ // For example, a local directive is visible from its component injector children.
421
+ num _getDepth (int visType) => super ._getDepth (visType) + 1 ;
441
422
}
423
+
0 commit comments