1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | var HttpError = require('@themost/common/errors').HttpError;
|
11 | var AngularServerModule = require('./../angular/module').AngularServerModule;
|
12 | var _ = require('lodash');
|
13 | var LangUtils = require('@themost/common/utils').LangUtils;
|
14 | var HttpApplicationService = require('../types').HttpApplicationService;
|
15 |
|
16 | var HashMap = require('hashmap');
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | function TemplateCacheStrategy(app) {
|
25 | TemplateCacheStrategy.super_.bind(this)(app);
|
26 | var map = new HashMap();
|
27 | |
28 |
|
29 |
|
30 |
|
31 | this.get = function(key) {
|
32 | return map.get(key);
|
33 | };
|
34 | |
35 |
|
36 |
|
37 |
|
38 | this.put = function(key, value) {
|
39 | map.set(key, value);
|
40 | };
|
41 |
|
42 | this.clear = function() {
|
43 | map.clear();
|
44 | }
|
45 | }
|
46 | LangUtils.inherits(TemplateCacheStrategy, HttpApplicationService);
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | function PostExecuteResultArgs() {
|
53 | |
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | |
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | }
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | function HttpInternalProvider($context, $await, $q) {
|
77 |
|
78 | function $http(requestConfig) {
|
79 | var config = {
|
80 | method: 'get',
|
81 | cookie: $context.request.headers.cookie
|
82 | };
|
83 | _.assign(config, requestConfig);
|
84 | var deferred = $q.defer(), promise = deferred.promise;
|
85 |
|
86 | $await(function(resolve, reject) {
|
87 | promise.success = function(fn) {
|
88 | promise.then(function(response) {
|
89 | fn(response.data, response.status, response.headers, config);
|
90 | resolve();
|
91 | });
|
92 | return promise;
|
93 | };
|
94 | promise.error = function(fn) {
|
95 | promise.then(null, function(response) {
|
96 | fn(response.data, response.status, response.headers, config);
|
97 | reject(new HttpError(response.status));
|
98 | });
|
99 | return promise;
|
100 | };
|
101 |
|
102 | $context.getApplication().executeRequest(config).then(function(response) {
|
103 | response.status = response.statusCode;
|
104 | response.data = response.body;
|
105 | deferred.resolve(response);
|
106 | }).catch(function(err) {
|
107 | if (err) {
|
108 | deferred.reject({ data: err.message, status:500, headers:{} });
|
109 | }
|
110 | });
|
111 | });
|
112 | return promise;
|
113 |
|
114 | }
|
115 |
|
116 | ['get', 'delete', 'head', 'jsonp'].forEach(function(name) {
|
117 | $http[name] = function(url, config) {
|
118 | return $http(_.assign(config || {}, {
|
119 | method: name,
|
120 | url: url
|
121 | }));
|
122 | };
|
123 | });
|
124 |
|
125 | ['post', 'put'].forEach(function(name) {
|
126 | $http[name] = function(url, data, config) {
|
127 | return $http(_.assign(config || {}, {
|
128 | method: name,
|
129 | url: url,
|
130 | data: data
|
131 | }));
|
132 | };
|
133 | });
|
134 |
|
135 | return $http;
|
136 | }
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 | function DirectiveEngine() {
|
144 |
|
145 | }
|
146 |
|
147 |
|
148 |
|
149 |
|
150 | DirectiveEngine.prototype.postExecuteResult = function(args, callback) {
|
151 | try {
|
152 |
|
153 | callback = callback || function() {};
|
154 |
|
155 | const context = args.context, view = args.target;
|
156 |
|
157 | if (typeof context === 'undefined' || context === null) {
|
158 | return callback();
|
159 | }
|
160 |
|
161 | if (typeof view === 'undefined' || view === null) {
|
162 | return callback();
|
163 | }
|
164 |
|
165 | if (typeof view.body !== 'string') {
|
166 | return callback();
|
167 | }
|
168 |
|
169 | if (!args.context.getApplication().hasService(AngularServerModule)) {
|
170 | args.context.getApplication().useService(AngularServerModule);
|
171 | }
|
172 |
|
173 | |
174 |
|
175 |
|
176 | let templateCache;
|
177 | if (!context.getApplication().hasService(TemplateCacheStrategy)) {
|
178 | context.getApplication().useService(TemplateCacheStrategy);
|
179 | }
|
180 | templateCache = context.getApplication().getService(TemplateCacheStrategy);
|
181 | |
182 |
|
183 |
|
184 | const angularServer = context.getApplication().getService(AngularServerModule);
|
185 |
|
186 |
|
187 | let document = angularServer.createDocument(view.body);
|
188 |
|
189 | const angular = document.parentWindow.angular;
|
190 |
|
191 | let app;
|
192 | if (this.hasOwnProperty('hasBootstrap') && typeof this.hasBootstrap === 'function') {
|
193 | app = this.hasBootstrap(angular);
|
194 | }
|
195 | else {
|
196 | app = angularServer.doBootstrap(angular);
|
197 | }
|
198 | |
199 |
|
200 |
|
201 |
|
202 | const promises = [];
|
203 | app.config(function($sceDelegateProvider) {
|
204 | |
205 |
|
206 |
|
207 |
|
208 |
|
209 | $sceDelegateProvider.resourceUrlWhitelist([
|
210 | '/templates/server/*.html'
|
211 | ]);
|
212 | });
|
213 | app.service('$context', function() {
|
214 | return context;
|
215 | }).service('$templateCache', function() {
|
216 | return {
|
217 | get: function(templatePath) {
|
218 | return templateCache.get(templatePath)
|
219 | },
|
220 | put: function(templatePath, templateContent) {
|
221 | templateCache.put(templatePath, templateContent);
|
222 | }
|
223 | }
|
224 | }).service('$serverState', function() {
|
225 | return {
|
226 | templatePath:view.templatePath
|
227 | };
|
228 | })
|
229 | .service('$await', function($q, $window, $timeout, $rootScope) {
|
230 |
|
231 | var asyncQueueLength = 0;
|
232 |
|
233 | |
234 |
|
235 |
|
236 | return function $await(fn) {
|
237 | $q(function(resolve, reject) {
|
238 | try {
|
239 | asyncQueueLength += 1;
|
240 | fn.call(document.parentWindow,function() {
|
241 | asyncQueueLength -= 1;
|
242 | $timeout(function() {
|
243 | if (asyncQueueLength === 0) {
|
244 | $rootScope.$emit('$asyncContentLoaded');
|
245 | }
|
246 | });
|
247 | return resolve();
|
248 | }, function(err) {
|
249 | asyncQueueLength -= 1;
|
250 | $timeout(function() {
|
251 | if (asyncQueueLength === 0) {
|
252 | $rootScope.$emit('$asyncContentLoaded', err);
|
253 | }
|
254 | });
|
255 | return reject(err);
|
256 | });
|
257 | }
|
258 | catch(err) {
|
259 | asyncQueueLength -= 1;
|
260 | $timeout(function() {
|
261 | if (asyncQueueLength === 0) {
|
262 | $rootScope.$emit('$asyncContentLoaded', err);
|
263 | }
|
264 | });
|
265 | return reject(err);
|
266 | }
|
267 | });
|
268 | };
|
269 | });
|
270 | app.service('$http', HttpInternalProvider);
|
271 |
|
272 | _.forEach(_.keys(angularServer.services), function(name) {
|
273 | app.service(name, angularServer.services[name]);
|
274 | });
|
275 |
|
276 |
|
277 | _.forEach(_.keys(angularServer.directives), function(name) {
|
278 | app.directive(name, angularServer.directives[name]);
|
279 | });
|
280 |
|
281 | _.forEach(_.keys(angularServer.filters), function(name) {
|
282 | app.filter(name, angularServer.filters[name]);
|
283 | });
|
284 |
|
285 | _.forEach(_.keys(angularServer.controllers), function(name) {
|
286 | app.controller(name, angularServer.controllers[name]);
|
287 | });
|
288 |
|
289 | var appElement = angular.element(document).find('*[server-app=\'server\']').get(0);
|
290 | if (typeof appElement === 'undefined') {
|
291 | appElement = angular.element(document).find('body').get(0);
|
292 | }
|
293 | if (appElement) {
|
294 |
|
295 |
|
296 | var $q = angular.injector(['ng']).get('$q');
|
297 |
|
298 | var $rootScope = angular.injector(['ng']).get('$rootScope');
|
299 |
|
300 |
|
301 | app.run(function($rootScope, $await) {
|
302 | if (_.isObject(view.data)) {
|
303 | _.assign($rootScope, view.data);
|
304 | }
|
305 |
|
306 | $rootScope.$on('$asyncContentLoaded', function(event, args)
|
307 | {
|
308 | if (args) {
|
309 |
|
310 | return callback(args);
|
311 | }
|
312 |
|
313 | view.body = document.innerHTML;
|
314 |
|
315 | return callback();
|
316 | });
|
317 |
|
318 | $await(function(resolve) {
|
319 | return resolve();
|
320 | });
|
321 | });
|
322 |
|
323 | if (app.name == null) {
|
324 | return callback(new TypeError('Angular for server application module name is undefined'));
|
325 | }
|
326 | if (typeof app.name !== 'string') {
|
327 | return callback(new TypeError('Angular for server application name should be a string'));
|
328 | }
|
329 |
|
330 | angular.bootstrap(appElement, [app.name]);
|
331 |
|
332 | }
|
333 | else {
|
334 | return callback();
|
335 | }
|
336 | }
|
337 | catch (e) {
|
338 | callback(e);
|
339 | }
|
340 | };
|
341 |
|
342 |
|
343 |
|
344 |
|
345 | DirectiveEngine.createInstance = function() {
|
346 | return new DirectiveEngine();
|
347 | };
|
348 |
|
349 | if (typeof exports !== 'undefined') {
|
350 | module.exports.createInstance = DirectiveEngine.createInstance;
|
351 | module.exports.DirectiveEngine = DirectiveEngine;
|
352 | module.exports.PostExecuteResultArgs = PostExecuteResultArgs;
|
353 | }
|