Merge pull request #13893 from colemanw/dev/core#821
[civicrm-core.git] / js / angular-crmResource / byModule.js
CommitLineData
a2dc0f82
TO
1// crmResource: Given a templateUrl "~/mymodule/myfile.html", load the matching HTML.
2// This implementation loads partials and strings in per-module batches.
3// FIXME: handling of CRM.strings not well tested; may be racy
4(function(angular, $, _) {
5 angular.module('crmResource', []);
6
7 angular.module('crmResource').factory('crmResource', function($q, $http) {
8 var modules = {}; // moduleQueue[module] = 'loading'|Object;
9 var templates = {}; // templates[url] = HTML;
10
11 function CrmResourceModule(name) {
12 this.name = name;
13 this.status = 'new'; // loading|loaded|error
14 this.data = null;
15 this.deferreds = [];
16 }
17
18 angular.extend(CrmResourceModule.prototype, {
19 createDeferred: function createDeferred() {
20 var deferred = $q.defer();
21 switch (this.status) {
22 case 'new':
23 case 'loading':
24 this.deferreds.push(deferred);
25 break;
26 case 'loaded':
27 deferred.resolve(this.data);
28 break;
29 case 'error':
30 deferred.reject();
31 break;
32 default:
33 throw 'Unknown status: ' + this.status;
34 }
35 return deferred.promise;
36 },
37 load: function load() {
38 var module = this;
39 this.status = 'loading';
578d3d13 40 var moduleUrl = CRM.url('civicrm/ajax/angular-modules', {modules: module.name, l: CRM.config.lcMessages, r: CRM.angular.cacheCode});
a2dc0f82
TO
41 $http.get(moduleUrl)
42 .success(function httpSuccess(data) {
43 if (data[module.name]) {
44 module.onSuccess(data[module.name]);
45 }
46 else {
47 module.onError();
48 }
49 })
50 .error(function httpError() {
51 module.onError();
52 });
53 },
54 onSuccess: function onSuccess(data) {
55 var module = this;
56 this.data = data;
57 this.status = 'loaded';
58 if (this.data.partials) {
59 angular.extend(templates, this.data.partials);
60 }
61 if (this.data.strings) {
e3d90d6c 62 CRM.addStrings(this.data.domain, this.data.strings);
a2dc0f82
TO
63 }
64 angular.forEach(this.deferreds, function(deferred) {
65 deferred.resolve(module.data);
66 });
67 delete this.deferreds;
68 },
69 onError: function onError() {
70 this.status = 'error';
71 angular.forEach(this.deferreds, function(deferred) {
72 deferred.reject();
73 });
74 delete this.deferreds;
75 }
76 });
77
78 return {
79 // @return Promise<ModuleData>
80 getModule: function getModule(name) {
81 if (!modules[name]) {
82 modules[name] = new CrmResourceModule(name);
83 modules[name].load();
84 }
85 return modules[name].createDeferred();
86 },
87 // @return string|Promise<string>
88 getUrl: function getUrl(url) {
89 if (templates[url]) {
90 return templates[url];
91 }
92
93 var parts = url.split('/');
94 var deferred = $q.defer();
95 this.getModule(parts[1]).then(
96 function() {
97 if (templates[url]) {
98 deferred.resolve({
99 status: 200,
100 headers: function(name) {
101 var headers = {'Content-type': 'text/html'};
102 return name ? headers[name] : headers;
103 },
104 data: templates[url]
105 });
106 }
107 else {
108 deferred.reject({status: 500}); // FIXME
109 }
110 },
111 function() {
112 deferred.reject({status: 500}); // FIXME
113 }
114 );
115
116 return deferred.promise;
117 }
118 };
119 });
120
121 angular.module('crmResource').config(function($provide) {
122 $provide.decorator('$templateCache', function($delegate, $http, $q, crmResource) {
123 var origGet = $delegate.get;
124 var urlPat = /^~\//;
125 $delegate.get = function(url) {
126 if (urlPat.test(url)) {
127 return crmResource.getUrl(url);
128 }
129 else {
130 return origGet.call(this, url);
131 }
132 };
133 return $delegate;
134 });
135 });
136
137})(angular, CRM.$, CRM._);