-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathregistry.js
171 lines (144 loc) · 5.29 KB
/
registry.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import {Filter, Parser, Directive, Inject, InjectAsProperty} from './annotations';
/**
* Prepares a class constructor for angular depency injection.
*
* Searches for annotations and creates a decorator which creates the instance
* and injects all necesarry deps.
*
* @param {Function} controller
* @return {Function}
*/
export function getPreparedConstructor(controller) {
var parser = new Parser(controller);
var annotations = parser.getAnnotations(Inject).reverse();
var $inject = [];
for (let annotation of annotations) {
$inject = $inject.concat(annotation.deps);
}
var injectsViaInjectCount = $inject.length;
var injectAsProperty = parser.getAnnotations(InjectAsProperty);
var propertyMap = {};
if (!injectAsProperty.length && !annotations.length) {
return false;
}
for (let annotation of injectAsProperty) {
$inject.push(annotation.propertyName);
propertyMap[annotation.propertyName] = $inject.length - 1;
}
var constructor = $inject;
constructor.push((...deps) => {
var args = deps.slice(0, injectsViaInjectCount);
var instance = new controller(...args);
for (let name in propertyMap) {
instance[name] = deps[propertyMap[name]];
}
return instance;
});
// constructor.$inject = $inject;
return constructor;
}
/**
* Registers a new angular filter.
*
* @param angularModule created with angular.module()
* @param {Function} controller
*/
export function registerModuleFilter(angularModule, controller) {
var parser = new Parser(controller);
var annotations = parser.getAnnotations(Filter);
if (!annotations.length) {
throw 'No Filter annotations on class ' + controller
}
var FilterAnnotation = annotations[annotations.length-1];
var constructor = getPreparedConstructor(controller);
if (!constructor) {
constructor = function() {
let instance = new controller();
return instance.filter;
};
angularModule.filter(FilterAnnotation.name, constructor);
} else {
var diFunction = constructor[constructor.length - 1];
var overwrittenConstructor = constructor;
overwrittenConstructor[overwrittenConstructor.length - 1] = function(...deps) {
var instance = diFunction(...deps);
return instance.filter.bind(instance);
};
angularModule.filter(FilterAnnotation.name, overwrittenConstructor);
}
}
/**
* Registers a new angular directive.
*
* @param angularModule created with angular.module()
* @param {Function} controller
*/
export function registerModuleDirective(angularModule, controller) {
var parser = new Parser(controller);
var annotations = parser.getAnnotations(Directive);
if (!annotations.length) {
throw 'No Directive annotations on class ' + controller
}
var constructor = getPreparedConstructor(controller);
if (!constructor) constructor = controller;
var DirectiveAnnotation = annotations[0];
var definition = DirectiveAnnotation.options || {};
if (!definition.controller) {
definition.controller = constructor;
}
if (!definition.link) {
if (angular.isString(definition.require)) {
definition.require = [definition.require];
}
if (angular.isArray(definition.require) && DirectiveAnnotation.name !== definition.require[0]) {
definition.require.unshift(DirectiveAnnotation.name);
}
definition.link = function(scope, element, attr, ctrl, transclude) {
var ownController, controllersToPass;
// console.log('link', DirectiveAnnotation.name, definition.require, [ctrl]);
if (angular.isArray(ctrl)) {
ownController = ctrl.shift();
} else {
ownController = ctrl;
}
if (angular.isArray(ctrl) && 1 === ctrl.length) {
ctrl = ctrl[0];
}
if (ownController && ownController.link) {
ownController.link.apply(ownController, [scope, element, attr, ctrl, transclude]);
}
};
}
var options = angular.isFunction(definition) || angular.isArray(definition)
? definition
: function(){ return definition; };
angularModule.directive(
DirectiveAnnotation.name,
options
);
}
/**
* Adds the ability to load controllers based on es6 module names like 'ng-controller="myApp/controllers/MyControllerA"'.
*
* @param angularModule
*/
export function registerControllerDecorator(angularModule) {
angularModule.config(function ($provide) {
$provide.decorator("$controller", ['$delegate', ($delegate) => {
return function (...args) {
if (angular.isString(args[0])) {
try {
var moduleClass = System.get(args[0]);
if (moduleClass) {
var preparedConstructor = getPreparedConstructor(moduleClass.default);
args[0] = preparedConstructor || moduleClass.default;
}
} catch (e) {
throw e;
}
}
return $delegate(...args);
};
}]);
});
}