@@ -6,29 +6,25 @@ class ElementBinderFactory {
6
6
final Profiler _perf;
7
7
final CompilerConfig _config;
8
8
final Expando _expando;
9
- final ComponentFactory _componentFactory ;
10
- final TranscludingComponentFactory _transcludingComponentFactory ;
11
- final ShadowDomComponentFactory _shadowDomComponentFactory ;
12
- final ASTParser _astParser ;
9
+ final ASTParser astParser ;
10
+ final ComponentFactory componentFactory ;
11
+ final ShadowDomComponentFactory shadowDomComponentFactory ;
12
+ final TranscludingComponentFactory transcludingComponentFactory ;
13
13
14
14
ElementBinderFactory (this ._parser, this ._perf, this ._config, this ._expando,
15
- this ._componentFactory,
16
- this ._transcludingComponentFactory,
17
- this ._shadowDomComponentFactory,
18
- this ._astParser);
15
+ this .astParser, this .componentFactory, this .shadowDomComponentFactory, this .transcludingComponentFactory);
19
16
20
17
// TODO: Optimize this to re-use a builder.
21
- ElementBinderBuilder builder (FormatterMap formatters) =>
22
- new ElementBinderBuilder (this , _astParser, formatters );
18
+ ElementBinderBuilder builder (FormatterMap formatters, DirectiveMap directives ) =>
19
+ new ElementBinderBuilder (this ,formatters, directives );
23
20
24
21
ElementBinder binder (ElementBinderBuilder b) =>
25
- new ElementBinder (_perf, _expando, _parser, _config, _componentFactory,
26
- _transcludingComponentFactory, _shadowDomComponentFactory ,
27
- b.component , b.decorators, b.onEvents, b.bindAttrs, b.childMode);
22
+
23
+ new ElementBinder (_perf, _expando, _parser, _config ,
24
+ b.componentData , b.decorators, b.onEvents, b.bindAttrs, b.childMode);
28
25
29
26
TemplateElementBinder templateBinder (ElementBinderBuilder b, ElementBinder transclude) =>
30
- new TemplateElementBinder (_perf, _expando, _parser, _config, _componentFactory,
31
- _transcludingComponentFactory, _shadowDomComponentFactory,
27
+ new TemplateElementBinder (_perf, _expando, _parser, _config,
32
28
b.template, transclude, b.onEvents, b.bindAttrs, b.childMode);
33
29
}
34
30
@@ -39,9 +35,9 @@ class ElementBinderFactory {
39
35
class ElementBinderBuilder {
40
36
static final RegExp _MAPPING = new RegExp (r'^(@|=>!|=>|<=>|&)\s*(.*)$' );
41
37
42
- ElementBinderFactory _factory;
43
- ASTParser _astParser ;
44
- FormatterMap _formatters;
38
+ final ElementBinderFactory _factory;
39
+ final DirectiveMap _directives ;
40
+ final FormatterMap _formatters;
45
41
46
42
/// "on-*" attribute names and values, added by a [DirectiveSelector]
47
43
final onEvents = < String , String > {};
@@ -50,12 +46,12 @@ class ElementBinderBuilder {
50
46
51
47
final decorators = < DirectiveRef > [];
52
48
DirectiveRef template;
53
- DirectiveRef component ;
49
+ BoundComponentData componentData ;
54
50
55
51
// Can be either COMPILE_CHILDREN or IGNORE_CHILDREN
56
52
String childMode = Directive .COMPILE_CHILDREN ;
57
53
58
- ElementBinderBuilder (this ._factory, this ._astParser , this ._formatters );
54
+ ElementBinderBuilder (this ._factory, this ._formatters , this ._directives );
59
55
60
56
/**
61
57
* Adds [DirectiveRef] s to this [ElementBinderBuilder] .
@@ -73,7 +69,17 @@ class ElementBinderBuilder {
73
69
if (annotation.children == Directive .TRANSCLUDE_CHILDREN ) {
74
70
template = ref;
75
71
} else if (annotation is Component ) {
76
- component = ref;
72
+ ComponentFactory factory ;
73
+ var annotation = ref.annotation as Component ;
74
+ if (annotation.useShadowDom == true ) {
75
+ factory = _factory.shadowDomComponentFactory;
76
+ } else if (annotation.useShadowDom == false ) {
77
+ factory = _factory.transcludingComponentFactory;
78
+ } else {
79
+ factory = _factory.componentFactory;
80
+ }
81
+
82
+ componentData = new BoundComponentData (ref, () => factory .bind (ref, _directives));
77
83
} else {
78
84
decorators.add (ref);
79
85
}
@@ -92,14 +98,14 @@ class ElementBinderBuilder {
92
98
var dstPath = match[2 ];
93
99
94
100
String dstExpression = dstPath.isEmpty ? attrName : dstPath;
95
- AST dstAST = _astParser (dstExpression); // no formatters
101
+ AST dstAST = _factory. astParser (dstExpression); // no formatters
96
102
97
103
// Look up the value of attrName and compute an AST
98
104
AST ast;
99
105
if (mode != '@' && mode != '&' ) {
100
106
var value = attrName == "." ? ref.value : (ref.element as dom.Element ).attributes[attrName];
101
107
if (value == null || value.isEmpty) { value = "''" ; }
102
- ast = _astParser (value, formatters: _formatters);
108
+ ast = _factory. astParser (value, formatters: _formatters);
103
109
}
104
110
105
111
ref.mappings.add (new MappingParts (attrName, ast, mode, dstAST, mapping));
@@ -113,3 +119,30 @@ class ElementBinderBuilder {
113
119
return template == null ? elBinder : _factory.templateBinder (this , elBinder);
114
120
}
115
121
}
122
+
123
+ /**
124
+ * Data used by the ComponentFactory to construct components.
125
+ */
126
+ class BoundComponentData {
127
+ final DirectiveRef ref;
128
+ BoundComponentFactory _instance;
129
+ Function _gen;
130
+ BoundComponentFactory get factory {
131
+ if (_instance != null ) return _instance;
132
+ _instance = _gen ();
133
+ _gen = null ; // Clear the gen function for GC.
134
+ return _instance;
135
+ }
136
+
137
+ Component get component => ref.annotation as Component ;
138
+ @Deprecated ('Use typeKey instead' )
139
+ Type get type => ref.type;
140
+ Key get typeKey => ref.typeKey;
141
+
142
+
143
+ /**
144
+ * * [ref] : The components directive ref
145
+ * * [_gen] : A function which returns a [BoundComponentFactory] . Called lazily.
146
+ */
147
+ BoundComponentData (this .ref, this ._gen);
148
+ }
0 commit comments