Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 61b1ec8

Browse files
committed
Added publishTypes to @NgComponent/@ngdirective and implemented caching of directive metadata.
1 parent 13c5091 commit 61b1ec8

File tree

3 files changed

+89
-34
lines changed

3 files changed

+89
-34
lines changed

lib/block.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class Block implements ElementWrapper {
112112
} else {
113113
nodeModule.type(type, type, visibility: visibility);
114114
}
115+
for (var publishType in ref.directive.$publishTypes) {
116+
nodeModule.factory(publishType,
117+
(Injector injector) => injector.get(type),
118+
visibility: visibility);
119+
}
115120
nodeAttrs[ref.directive.$name] = ref.value;
116121
if (ref.directive.isStructural) {
117122
blockListFactory = (Injector injector) => $blockListFactory([node], ref.blockTypes, injector);

lib/directive.dart

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,20 @@ String _COMPONENT = '-component';
44
String _DIRECTIVE = '-directive';
55
String _ATTR_DIRECTIVE = '-attr' + _DIRECTIVE;
66

7-
class NgComponent {
7+
class NgAnnotationBase {
8+
final String visibility;
9+
final List<Type> publishTypes;
10+
11+
const NgAnnotationBase({
12+
this.visibility: NgDirective.LOCAL_VISIBILITY,
13+
this.publishTypes
14+
});
15+
}
16+
17+
class NgComponent extends NgAnnotationBase {
818
final String template;
919
final String templateUrl;
1020
final String cssUrl;
11-
final String visibility;
1221
final Map<String, String> map;
1322
final String publishAs;
1423
final bool applyAuthorStyles;
@@ -18,30 +27,31 @@ class NgComponent {
1827
this.template,
1928
this.templateUrl,
2029
this.cssUrl,
21-
this.visibility: NgDirective.LOCAL_VISIBILITY,
30+
visibility,
2231
this.map,
2332
this.publishAs,
2433
this.applyAuthorStyles,
25-
this.resetStyleInheritance
26-
});
34+
this.resetStyleInheritance,
35+
publishTypes : const <Type>[]
36+
}) : super(visibility: visibility, publishTypes: publishTypes);
2737
}
2838

29-
class NgDirective {
39+
class NgDirective extends NgAnnotationBase {
3040
static const String LOCAL_VISIBILITY = 'local';
3141
static const String CHILDREN_VISIBILITY = 'children';
3242
static const String DIRECT_CHILDREN_VISIBILITY = 'direct_children';
3343

3444
final String selector;
3545
final String transclude;
3646
final int priority;
37-
final String visibility;
3847

3948
const NgDirective({
4049
this.selector,
4150
this.transclude,
4251
this.priority : 0,
43-
this.visibility: LOCAL_VISIBILITY
44-
});
52+
visibility,
53+
publishTypes : const <Type>[]
54+
}) : super(visibility: visibility, publishTypes: publishTypes);
4555
}
4656

4757
/**
@@ -55,6 +65,8 @@ class NgShadowRootOptions {
5565
this.resetStyleInheritance = false]);
5666
}
5767

68+
Map<Type, Directive> _directiveCache = new Map<Type, Directive>();
69+
5870
// TODO(pavelgj): Get rid of Directive and use NgComponent/NgDirective directly.
5971
class Directive {
6072
Type type;
@@ -70,14 +82,23 @@ class Directive {
7082
Map<String, String> $map;
7183
String $visibility;
7284
NgShadowRootOptions $shadowRootOptions = new NgShadowRootOptions();
85+
List<Type> $publishTypes = <Type>[];
7386

7487
bool isComponent = false;
7588
bool isStructural = false;
7689

77-
Directive(this.type) {
90+
Directive._new(Type this.type);
91+
92+
factory Directive(Type type) {
93+
var instance = _directiveCache[type];
94+
if (instance != null) {
95+
return instance;
96+
}
97+
98+
instance = new Directive._new(type);
7899
var name = type.toString();
79100
var isAttr = false;
80-
$name = name.splitMapJoin(
101+
instance.$name = name.splitMapJoin(
81102
new RegExp(r'[A-Z]'),
82103
onMatch: (m) => '-' + m.group(0).toLowerCase())
83104
.substring(1);
@@ -91,38 +112,48 @@ class Directive {
91112
var selector;
92113
if (directive != null) {
93114
selector = directive.selector;
94-
$transclude = directive.transclude;
95-
$priority = directive.priority;
96-
$visibility = directive.visibility;
115+
instance.$transclude = directive.transclude;
116+
instance.$priority = directive.priority;
117+
instance.$visibility = directive.visibility;
118+
instance.$publishTypes = directive.publishTypes;
97119
}
98120
if (component != null) {
99-
$template = component.template;
100-
$templateUrl = component.templateUrl;
101-
$cssUrl = component.cssUrl;
102-
$visibility = component.visibility;
103-
$map = component.map;
104-
$publishAs = component.publishAs;
105-
$shadowRootOptions = new NgShadowRootOptions(component.applyAuthorStyles,
106-
component.resetStyleInheritance);
121+
instance.$template = component.template;
122+
instance.$templateUrl = component.templateUrl;
123+
instance.$cssUrl = component.cssUrl;
124+
instance.$visibility = component.visibility;
125+
instance.$map = component.map;
126+
instance.$publishAs = component.publishAs;
127+
instance.$shadowRootOptions =
128+
new NgShadowRootOptions(component.applyAuthorStyles,
129+
component.resetStyleInheritance);
130+
instance.$publishTypes = component.publishTypes;
107131
}
108132

109133
if (selector != null) {
110-
$name = selector;
111-
} else if ($name.endsWith(_ATTR_DIRECTIVE)) {
112-
$name = '[${$name.substring(0, $name.length - _ATTR_DIRECTIVE.length)}]';
113-
} else if ($name.endsWith(_DIRECTIVE)) {
114-
$name = $name.substring(0, $name.length - _DIRECTIVE.length);
115-
} else if ($name.endsWith(_COMPONENT)) {
116-
isComponent = true;
117-
$name = $name.substring(0, $name.length - _COMPONENT.length);
134+
instance.$name = selector;
135+
} else if (instance.$name.endsWith(_ATTR_DIRECTIVE)) {
136+
var attrName = instance.$name.
137+
substring(0, instance.$name.length - _ATTR_DIRECTIVE.length);
138+
instance.$name = '[$attrName]';
139+
} else if (instance.$name.endsWith(_DIRECTIVE)) {
140+
instance.$name = instance.$name.
141+
substring(0, instance.$name.length - _DIRECTIVE.length);
142+
} else if (instance.$name.endsWith(_COMPONENT)) {
143+
instance.isComponent = true;
144+
instance.$name = instance.$name.
145+
substring(0, instance.$name.length - _COMPONENT.length);
118146
} else {
119-
throw "Directive name '$name' must end with $_DIRECTIVE, $_ATTR_DIRECTIVE, $_COMPONENT or have a \$selector field.";
147+
throw "Directive name '$name' must end with $_DIRECTIVE, "
148+
"$_ATTR_DIRECTIVE, $_COMPONENT or have a \$selector field.";
120149
}
121150

122-
isStructural = $transclude != null;
123-
if (isComponent && $map == null) {
124-
$map = new Map<String, String>();
151+
instance.isStructural = instance.$transclude != null;
152+
if (instance.isComponent && instance.$map == null) {
153+
instance.$map = new Map<String, String>();
125154
}
155+
_directiveCache[type] = instance;
156+
return instance;
126157
}
127158
}
128159

test/compiler_spec.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ class IncludeTranscludeAttrDirective {
5454
}
5555
}
5656

57+
class PublishTypesDirectiveSuperType {
58+
}
59+
60+
@NgDirective(publishTypes: const [PublishTypesDirectiveSuperType])
61+
class PublishTypesAttrDirective implements PublishTypesDirectiveSuperType {
62+
static Injector _injector;
63+
PublishTypesAttrDirective(Injector injector) {
64+
_injector = injector;
65+
}
66+
}
67+
5768
main() {
5869

5970
describe('dte.compiler', () {
@@ -65,6 +76,7 @@ main() {
6576
beforeEach(module((AngularModule module) {
6677
module
6778
..directive(TabComponent)
79+
..directive(PublishTypesAttrDirective)
6880
..directive(PaneComponent)
6981
..directive(SimpleTranscludeInAttachAttrDirective)
7082
..directive(IncludeTranscludeAttrDirective)
@@ -487,6 +499,13 @@ main() {
487499
nextTurn();
488500
expect(element.textWithShadow()).toEqual('WORKED');
489501
})));
502+
503+
it('should "publish" controller to injector under provided publishTypes', inject(() {
504+
var element = $(r'<div publish-types></div>');
505+
$compile(element)(injector, element);
506+
expect(PublishTypesAttrDirective._injector.get(PublishTypesAttrDirective)).
507+
toBe(PublishTypesAttrDirective._injector.get(PublishTypesDirectiveSuperType));
508+
}));
490509
});
491510

492511
describe('controller scoping', () {

0 commit comments

Comments
 (0)