voltar 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/fonts/FontAwesome.otf +0 -0
  6. data/app/assets/fonts/Simple-Line-Icons.eot +0 -0
  7. data/app/assets/fonts/Simple-Line-Icons.svg +1369 -0
  8. data/app/assets/fonts/Simple-Line-Icons.ttf +0 -0
  9. data/app/assets/fonts/Simple-Line-Icons.woff +0 -0
  10. data/app/assets/fonts/fontawesome-webfont.eot +0 -0
  11. data/app/assets/fonts/fontawesome-webfont.svg +520 -0
  12. data/app/assets/fonts/fontawesome-webfont.ttf +0 -0
  13. data/app/assets/fonts/fontawesome-webfont.woff +0 -0
  14. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  15. data/app/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  16. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  17. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  18. data/app/assets/fonts/sourcesanspro/sourcesanspro-bold.woff +0 -0
  19. data/app/assets/fonts/sourcesanspro/sourcesanspro-light.woff +0 -0
  20. data/app/assets/fonts/sourcesanspro/sourcesanspro.woff +0 -0
  21. data/app/assets/javascripts/voltar/app.js +203 -0
  22. data/app/assets/javascripts/voltar/application.js +33 -0
  23. data/app/assets/javascripts/voltar/controllers/app_ctrl.js.erb +673 -0
  24. data/app/assets/javascripts/voltar/directives/app_directives.js +345 -0
  25. data/app/assets/javascripts/voltar/factories/app_services.js +255 -0
  26. data/app/assets/javascripts/voltar/stripe.js.coffee +2 -0
  27. data/app/assets/stylesheets/voltar/app.css +4990 -0
  28. data/app/assets/stylesheets/voltar/application.css +23 -0
  29. data/app/assets/stylesheets/voltar/voltar.css.scss +93 -0
  30. data/app/controllers/voltar/application_controller.rb +4 -0
  31. data/app/controllers/voltar/dashboard_controller.rb +11 -0
  32. data/app/helpers/voltar/application_helper.rb +4 -0
  33. data/app/views/layouts/voltar/application.html.erb +40 -0
  34. data/app/views/voltar/account/_billing.html.erb +552 -0
  35. data/app/views/voltar/account/_locations.html.erb +135 -0
  36. data/app/views/voltar/account/_managers.html +134 -0
  37. data/app/views/voltar/account/_password.html.erb +57 -0
  38. data/app/views/voltar/account/_profile.html.erb +84 -0
  39. data/app/views/voltar/dashboard/index.html.erb +0 -0
  40. data/app/views/voltar/inventory/_delete_dialog.html.erb +16 -0
  41. data/app/views/voltar/inventory/_edit.html.erb +244 -0
  42. data/app/views/voltar/inventory/_index.html.erb +160 -0
  43. data/app/views/voltar/inventory/_mark_as_sold_dialog.html.erb +26 -0
  44. data/app/views/voltar/shared/_keen_js.html.haml +11 -0
  45. data/app/views/voltar/shared/_voltar_app.html.erb +83 -0
  46. data/app/views/voltar/shared/_voltar_aside.html.erb +71 -0
  47. data/app/views/voltar/shared/_voltar_footer.html.erb +13 -0
  48. data/app/views/voltar/shared/_voltar_header.html.erb +156 -0
  49. data/app/views/voltar/shared/app/_country_province_select.html +19 -0
  50. data/app/views/voltar/shared/app/_dashboard.html.erb +243 -0
  51. data/app/views/voltar/shared/app/_notifications.html.erb +13 -0
  52. data/app/views/voltar/shared/app/_spinner.html.erb +8 -0
  53. data/config/routes.rb +4 -0
  54. data/lib/tasks/voltar_tasks.rake +4 -0
  55. data/lib/voltar.rb +5 -0
  56. data/lib/voltar/engine.rb +15 -0
  57. data/lib/voltar/version.rb +3 -0
  58. data/test/dummy/README.rdoc +28 -0
  59. data/test/dummy/Rakefile +6 -0
  60. data/test/dummy/app/assets/javascripts/application.js +13 -0
  61. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  62. data/test/dummy/app/controllers/application_controller.rb +5 -0
  63. data/test/dummy/app/helpers/application_helper.rb +2 -0
  64. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  65. data/test/dummy/bin/bundle +3 -0
  66. data/test/dummy/bin/rails +4 -0
  67. data/test/dummy/bin/rake +4 -0
  68. data/test/dummy/bin/setup +29 -0
  69. data/test/dummy/config.ru +4 -0
  70. data/test/dummy/config/application.rb +26 -0
  71. data/test/dummy/config/boot.rb +5 -0
  72. data/test/dummy/config/database.yml +25 -0
  73. data/test/dummy/config/environment.rb +5 -0
  74. data/test/dummy/config/environments/development.rb +41 -0
  75. data/test/dummy/config/environments/production.rb +76 -0
  76. data/test/dummy/config/environments/test.rb +39 -0
  77. data/test/dummy/config/initializers/assets.rb +11 -0
  78. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  80. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  81. data/test/dummy/config/initializers/inflections.rb +16 -0
  82. data/test/dummy/config/initializers/mime_types.rb +4 -0
  83. data/test/dummy/config/initializers/session_store.rb +3 -0
  84. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  85. data/test/dummy/config/locales/en.yml +23 -0
  86. data/test/dummy/config/routes.rb +4 -0
  87. data/test/dummy/config/secrets.yml +22 -0
  88. data/test/dummy/log/development.log +0 -0
  89. data/test/dummy/public/404.html +67 -0
  90. data/test/dummy/public/422.html +67 -0
  91. data/test/dummy/public/500.html +66 -0
  92. data/test/dummy/public/favicon.ico +0 -0
  93. data/test/integration/navigation_test.rb +10 -0
  94. data/test/test_helper.rb +15 -0
  95. data/test/voltar_test.rb +7 -0
  96. data/vendor/assets/images/voltar/a0.jpg +0 -0
  97. data/vendor/assets/images/voltar/a1.jpg +0 -0
  98. data/vendor/assets/images/voltar/a10.jpg +0 -0
  99. data/vendor/assets/images/voltar/a2.jpg +0 -0
  100. data/vendor/assets/images/voltar/a3.jpg +0 -0
  101. data/vendor/assets/images/voltar/a4.jpg +0 -0
  102. data/vendor/assets/images/voltar/a5.jpg +0 -0
  103. data/vendor/assets/images/voltar/a6.jpg +0 -0
  104. data/vendor/assets/images/voltar/a7.jpg +0 -0
  105. data/vendor/assets/images/voltar/a8.jpg +0 -0
  106. data/vendor/assets/images/voltar/a9.jpg +0 -0
  107. data/vendor/assets/images/voltar/b0.jpg +0 -0
  108. data/vendor/assets/images/voltar/b1.jpg +0 -0
  109. data/vendor/assets/images/voltar/b2.jpg +0 -0
  110. data/vendor/assets/images/voltar/b3.jpg +0 -0
  111. data/vendor/assets/images/voltar/b4.jpg +0 -0
  112. data/vendor/assets/images/voltar/b5.jpg +0 -0
  113. data/vendor/assets/images/voltar/c0.jpg +0 -0
  114. data/vendor/assets/images/voltar/c1.jpg +0 -0
  115. data/vendor/assets/images/voltar/c2.jpg +0 -0
  116. data/vendor/assets/images/voltar/c3.jpg +0 -0
  117. data/vendor/assets/images/voltar/c4.jpg +0 -0
  118. data/vendor/assets/images/voltar/c5.jpg +0 -0
  119. data/vendor/assets/images/voltar/chosen-sprite.png +0 -0
  120. data/vendor/assets/images/voltar/chosen-sprite@2x.png +0 -0
  121. data/vendor/assets/images/voltar/logo.png +0 -0
  122. data/vendor/assets/images/voltar/p0.jpg +0 -0
  123. data/vendor/assets/javascripts/voltar/angular-animate.js +1689 -0
  124. data/vendor/assets/javascripts/voltar/angular-contenteditable.js +98 -0
  125. data/vendor/assets/javascripts/voltar/angular-cookies.js +206 -0
  126. data/vendor/assets/javascripts/voltar/angular-sanitize.js +647 -0
  127. data/vendor/assets/javascripts/voltar/angular-ui-router.js +3658 -0
  128. data/vendor/assets/javascripts/voltar/angular.js +22024 -0
  129. data/vendor/assets/javascripts/voltar/chosen.jquery.min.js +2 -0
  130. data/vendor/assets/javascripts/voltar/easypiechart/jquery.easy-pie-chart.js +209 -0
  131. data/vendor/assets/javascripts/voltar/flot/jquery.flot.min.js +29 -0
  132. data/vendor/assets/javascripts/voltar/flot/jquery.flot.orderBars.js +187 -0
  133. data/vendor/assets/javascripts/voltar/flot/jquery.flot.pie.min.js +56 -0
  134. data/vendor/assets/javascripts/voltar/flot/jquery.flot.resize.js +60 -0
  135. data/vendor/assets/javascripts/voltar/flot/jquery.flot.spline.js +212 -0
  136. data/vendor/assets/javascripts/voltar/flot/jquery.flot.tooltip.min.js +12 -0
  137. data/vendor/assets/javascripts/voltar/jquery.min.js +5 -0
  138. data/vendor/assets/javascripts/voltar/moment.js +2856 -0
  139. data/vendor/assets/javascripts/voltar/ngStorage.js +103 -0
  140. data/vendor/assets/javascripts/voltar/ocLazyLoad.js +906 -0
  141. data/vendor/assets/javascripts/voltar/smart-table.min.js +1 -0
  142. data/vendor/assets/javascripts/voltar/sparkline/jquery.sparkline.min.js +2 -0
  143. data/vendor/assets/javascripts/voltar/toaster.js +185 -0
  144. data/vendor/assets/javascripts/voltar/ui-bootstrap-tpls.js +4116 -0
  145. data/vendor/assets/javascripts/voltar/ui-jq.js +86 -0
  146. data/vendor/assets/javascripts/voltar/ui-load.js +93 -0
  147. data/vendor/assets/javascripts/voltar/ui-validate.js +119 -0
  148. data/vendor/assets/stylesheets/voltar/animate.css +1098 -0
  149. data/vendor/assets/stylesheets/voltar/bootstrap.css +6202 -0
  150. data/vendor/assets/stylesheets/voltar/chosen.css +399 -0
  151. data/vendor/assets/stylesheets/voltar/font-awesome.min.css +4 -0
  152. data/vendor/assets/stylesheets/voltar/font.css +18 -0
  153. data/vendor/assets/stylesheets/voltar/simple-line-icons.css +526 -0
  154. data/vendor/assets/stylesheets/voltar/toaster.css +213 -0
  155. metadata +333 -0
@@ -0,0 +1,103 @@
1
+ 'use strict';
2
+
3
+ (function() {
4
+
5
+ /**
6
+ * @ngdoc overview
7
+ * @name ngStorage
8
+ */
9
+
10
+ angular.module('ngStorage', []).
11
+
12
+ /**
13
+ * @ngdoc object
14
+ * @name ngStorage.$localStorage
15
+ * @requires $rootScope
16
+ * @requires $window
17
+ */
18
+
19
+ factory('$localStorage', _storageFactory('localStorage')).
20
+
21
+ /**
22
+ * @ngdoc object
23
+ * @name ngStorage.$sessionStorage
24
+ * @requires $rootScope
25
+ * @requires $window
26
+ */
27
+
28
+ factory('$sessionStorage', _storageFactory('sessionStorage'));
29
+
30
+ function _storageFactory(storageType) {
31
+ return [
32
+ '$rootScope',
33
+ '$window',
34
+
35
+ function(
36
+ $rootScope,
37
+ $window
38
+ ){
39
+ // #9: Assign a placeholder object if Web Storage is unavailable to prevent breaking the entire AngularJS app
40
+ var webStorage = $window[storageType] || (console.warn('This browser does not support Web Storage!'), {}),
41
+ $storage = {
42
+ $default: function(items) {
43
+ for (var k in items) {
44
+ angular.isDefined($storage[k]) || ($storage[k] = items[k]);
45
+ }
46
+
47
+ return $storage;
48
+ },
49
+ $reset: function(items) {
50
+ for (var k in $storage) {
51
+ '$' === k[0] || delete $storage[k];
52
+ }
53
+
54
+ return $storage.$default(items);
55
+ }
56
+ },
57
+ _last$storage,
58
+ _debounce;
59
+
60
+ for (var i = 0, k; i < webStorage.length; i++) {
61
+ // #8, #10: `webStorage.key(i)` may be an empty string (or throw an exception in IE9 if `webStorage` is empty)
62
+ (k = webStorage.key(i)) && 'ngStorage-' === k.slice(0, 10) && ($storage[k.slice(10)] = angular.fromJson(webStorage.getItem(k)));
63
+ }
64
+
65
+ _last$storage = angular.copy($storage);
66
+
67
+ $rootScope.$watch(function() {
68
+ _debounce || (_debounce = setTimeout(function() {
69
+ _debounce = null;
70
+
71
+ if (!angular.equals($storage, _last$storage)) {
72
+ angular.forEach($storage, function(v, k) {
73
+ angular.isDefined(v) && '$' !== k[0] && webStorage.setItem('ngStorage-' + k, angular.toJson(v));
74
+
75
+ delete _last$storage[k];
76
+ });
77
+
78
+ for (var k in _last$storage) {
79
+ webStorage.removeItem('ngStorage-' + k);
80
+ }
81
+
82
+ _last$storage = angular.copy($storage);
83
+ }
84
+ }, 100));
85
+ });
86
+
87
+ // #6: Use `$window.addEventListener` instead of `angular.element` to avoid the jQuery-specific `event.originalEvent`
88
+ 'localStorage' === storageType && $window.addEventListener && $window.addEventListener('storage', function(event) {
89
+ if ('ngStorage-' === event.key.slice(0, 10)) {
90
+ event.newValue ? $storage[event.key.slice(10)] = angular.fromJson(event.newValue) : delete $storage[event.key.slice(10)];
91
+
92
+ _last$storage = angular.copy($storage);
93
+
94
+ $rootScope.$apply();
95
+ }
96
+ });
97
+
98
+ return $storage;
99
+ }
100
+ ];
101
+ }
102
+
103
+ })();
@@ -0,0 +1,906 @@
1
+ /**
2
+ * oclazyload - Load modules on demand (lazy load) with angularJS
3
+ * @version v0.3.7
4
+ * @link https://github.com/ocombe/ocLazyLoad
5
+ * @license MIT
6
+ * @author Olivier Combe <olivier.combe@gmail.com>
7
+ */
8
+ (function() {
9
+ 'use strict';
10
+ var regModules = ['ng'],
11
+ regInvokes = [],
12
+ regConfigs = [],
13
+ justLoaded = [],
14
+ ocLazyLoad = angular.module('oc.lazyLoad', ['ng']),
15
+ broadcast = angular.noop;
16
+
17
+ ocLazyLoad.provider('$ocLazyLoad', ['$controllerProvider', '$provide', '$compileProvider', '$filterProvider', '$injector', '$animateProvider',
18
+ function($controllerProvider, $provide, $compileProvider, $filterProvider, $injector, $animateProvider) {
19
+ var modules = {},
20
+ providers = {
21
+ $controllerProvider: $controllerProvider,
22
+ $compileProvider: $compileProvider,
23
+ $filterProvider: $filterProvider,
24
+ $provide: $provide, // other things
25
+ $injector: $injector,
26
+ $animateProvider: $animateProvider
27
+ },
28
+ anchor = document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0],
29
+ jsLoader, cssLoader, templatesLoader,
30
+ debug = false,
31
+ events = false;
32
+
33
+ // Let's get the list of loaded modules & components
34
+ init(angular.element(window.document));
35
+
36
+ this.$get = ['$timeout', '$log', '$q', '$templateCache', '$http', '$rootElement', '$rootScope', '$cacheFactory', function($timeout, $log, $q, $templateCache, $http, $rootElement, $rootScope, $cacheFactory) {
37
+ var instanceInjector,
38
+ filesCache = $cacheFactory('ocLazyLoad');
39
+
40
+ if(!debug) {
41
+ $log = {};
42
+ $log['error'] = angular.noop;
43
+ $log['warn'] = angular.noop;
44
+ $log['info'] = angular.noop;
45
+ }
46
+
47
+ // Make this lazy because at the moment that $get() is called the instance injector hasn't been assigned to the rootElement yet
48
+ providers.getInstanceInjector = function() {
49
+ return (instanceInjector) ? instanceInjector : (instanceInjector = $rootElement.data('$injector'));
50
+ };
51
+
52
+ broadcast = function broadcast(eventName, params) {
53
+ if(events) {
54
+ $rootScope.$broadcast(eventName, params);
55
+ }
56
+ if(debug) {
57
+ $log.info(eventName, params);
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Load a js/css file
63
+ * @param type
64
+ * @param path
65
+ * @returns promise
66
+ */
67
+ var buildElement = function buildElement(type, path, params) {
68
+ var deferred = $q.defer(),
69
+ el, loaded,
70
+ cacheBuster = function cacheBuster(url) {
71
+ var dc = new Date().getTime();
72
+ if(url.indexOf('?') >= 0) {
73
+ if(url.substring(0, url.length - 1) === '&') {
74
+ return url + '_dc=' + dc;
75
+ }
76
+ return url + '&_dc=' + dc;
77
+ } else {
78
+ return url + '?_dc=' + dc;
79
+ }
80
+ };
81
+
82
+ // Store the promise early so the file load can be detected by other parallel lazy loads
83
+ // (ie: multiple routes on one page) a 'true' value isn't sufficient
84
+ // as it causes false positive load results.
85
+ if(angular.isUndefined(filesCache.get(path))) {
86
+ filesCache.put(path, deferred.promise);
87
+ }
88
+
89
+ // Switch in case more content types are added later
90
+ switch(type) {
91
+ case 'css':
92
+ el = document.createElement('link');
93
+ el.type = 'text/css';
94
+ el.rel = 'stylesheet';
95
+ el.href = params.cache === false ? cacheBuster(path) : path;
96
+ break;
97
+ case 'js':
98
+ el = document.createElement('script');
99
+ el.src = params.cache === false ? cacheBuster(path) : path;
100
+ break;
101
+ default:
102
+ deferred.reject(new Error('Requested type "' + type + '" is not known. Could not inject "' + path + '"'));
103
+ break;
104
+ }
105
+ el.onload = el['onreadystatechange'] = function(e) {
106
+ if((el['readyState'] && !(/^c|loade/.test(el['readyState']))) || loaded) return;
107
+ el.onload = el['onreadystatechange'] = null
108
+ loaded = 1;
109
+ broadcast('ocLazyLoad.fileLoaded', path);
110
+ deferred.resolve();
111
+ }
112
+ el.onerror = function(e) {
113
+ deferred.reject(new Error('Unable to load '+path));
114
+ }
115
+ el.async = 1;
116
+ anchor.insertBefore(el, anchor.lastChild);
117
+
118
+ return deferred.promise;
119
+ }
120
+
121
+ if(angular.isUndefined(jsLoader)) {
122
+ /**
123
+ * jsLoader function
124
+ * @type Function
125
+ * @param paths array list of js files to load
126
+ * @param callback to call when everything is loaded. We use a callback and not a promise
127
+ * @param params object config parameters
128
+ * because the user can overwrite jsLoader and it will probably not use promises :(
129
+ */
130
+ jsLoader = function(paths, callback, params) {
131
+ var promises = [];
132
+ angular.forEach(paths, function loading(path) {
133
+ promises.push(buildElement('js', path, params));
134
+ });
135
+ $q.all(promises).then(function success() {
136
+ callback();
137
+ }, function error(err) {
138
+ callback(err);
139
+ });
140
+ }
141
+ jsLoader.ocLazyLoadLoader = true;
142
+ }
143
+
144
+ if(angular.isUndefined(cssLoader)) {
145
+ /**
146
+ * cssLoader function
147
+ * @type Function
148
+ * @param paths array list of css files to load
149
+ * @param callback to call when everything is loaded. We use a callback and not a promise
150
+ * @param params object config parameters
151
+ * because the user can overwrite cssLoader and it will probably not use promises :(
152
+ */
153
+ cssLoader = function(paths, callback, params) {
154
+ var promises = [];
155
+ angular.forEach(paths, function loading(path) {
156
+ promises.push(buildElement('css', path, params));
157
+ });
158
+ $q.all(promises).then(function success() {
159
+ callback();
160
+ }, function error(err) {
161
+ callback(err);
162
+ });
163
+ }
164
+ cssLoader.ocLazyLoadLoader = true;
165
+ }
166
+
167
+ if(angular.isUndefined(templatesLoader)) {
168
+ /**
169
+ * templatesLoader function
170
+ * @type Function
171
+ * @param paths array list of css files to load
172
+ * @param callback to call when everything is loaded. We use a callback and not a promise
173
+ * @param params object config parameters for $http
174
+ * because the user can overwrite templatesLoader and it will probably not use promises :(
175
+ */
176
+ templatesLoader = function(paths, callback, params) {
177
+ if(angular.isString(paths)) {
178
+ paths = [paths];
179
+ }
180
+ var promises = [];
181
+ angular.forEach(paths, function(url) {
182
+ var deferred = $q.defer();
183
+ promises.push(deferred.promise);
184
+ $http.get(url, params).success(function(data) {
185
+ angular.forEach(angular.element(data), function(node) {
186
+ if(node.nodeName === 'SCRIPT' && node.type === 'text/ng-template') {
187
+ $templateCache.put(node.id, node.innerHTML);
188
+ }
189
+ });
190
+ if(angular.isUndefined(filesCache.get(url))) {
191
+ filesCache.put(url, true);
192
+ }
193
+ deferred.resolve();
194
+ }).error(function(data) {
195
+ var err = 'Error load template "' + url + '": ' + data;
196
+ $log.error(err);
197
+ deferred.reject(new Error(err));
198
+ });
199
+ });
200
+ return $q.all(promises).then(function success() {
201
+ callback();
202
+ }, function error(err) {
203
+ callback(err);
204
+ });
205
+ }
206
+ templatesLoader.ocLazyLoadLoader = true;
207
+ }
208
+
209
+ var filesLoader = function(config, params) {
210
+ var cssFiles = [],
211
+ templatesFiles = [],
212
+ jsFiles = [],
213
+ promises = [],
214
+ cachePromise = null;
215
+
216
+ angular.extend(params || {}, config);
217
+
218
+ angular.forEach(params.files, function(path) {
219
+ cachePromise = filesCache.get(path);
220
+ if(angular.isUndefined(cachePromise) || params.cache === false) {
221
+ if(/\.css[^\.]*$/.test(path) && cssFiles.indexOf(path) === -1) {
222
+ cssFiles.push(path);
223
+ } else if(/\.(htm|html)[^\.]*$/.test(path) && templatesFiles.indexOf(path) === -1) {
224
+ templatesFiles.push(path);
225
+ } else if (jsFiles.indexOf(path) === -1) {
226
+ jsFiles.push(path);
227
+ }
228
+ } else if (cachePromise) {
229
+ promises.push(cachePromise);
230
+ }
231
+ });
232
+
233
+ if(cssFiles.length > 0) {
234
+ var cssDeferred = $q.defer();
235
+ cssLoader(cssFiles, function(err) {
236
+ if(angular.isDefined(err) && cssLoader.hasOwnProperty('ocLazyLoadLoader')) {
237
+ $log.error(err);
238
+ cssDeferred.reject(err);
239
+ } else {
240
+ cssDeferred.resolve();
241
+ }
242
+ }, params);
243
+ promises.push(cssDeferred.promise);
244
+ }
245
+
246
+ if(templatesFiles.length > 0) {
247
+ var templatesDeferred = $q.defer();
248
+ templatesLoader(templatesFiles, function(err) {
249
+ if(angular.isDefined(err) && templatesLoader.hasOwnProperty('ocLazyLoadLoader')) {
250
+ $log.error(err);
251
+ templatesDeferred.reject(err);
252
+ } else {
253
+ templatesDeferred.resolve();
254
+ }
255
+ }, params);
256
+ promises.push(templatesDeferred.promise);
257
+ }
258
+
259
+ if(jsFiles.length > 0) {
260
+ var jsDeferred = $q.defer();
261
+ jsLoader(jsFiles, function(err) {
262
+ if(angular.isDefined(err) && jsLoader.hasOwnProperty('ocLazyLoadLoader')) {
263
+ $log.error(err);
264
+ jsDeferred.reject(err);
265
+ } else {
266
+ jsDeferred.resolve();
267
+ }
268
+ }, params);
269
+ promises.push(jsDeferred.promise);
270
+ }
271
+
272
+ return $q.all(promises);
273
+ }
274
+
275
+ return {
276
+ getModuleConfig: function(name) {
277
+ if(!modules[name]) {
278
+ return null;
279
+ }
280
+ return modules[name];
281
+ },
282
+
283
+ setModuleConfig: function(module) {
284
+ modules[module.name] = module;
285
+ return module;
286
+ },
287
+
288
+ getModules: function() {
289
+ return regModules;
290
+ },
291
+
292
+ // deprecated
293
+ loadTemplateFile: function(paths, params) {
294
+ return filesLoader({files: paths}, params);
295
+ },
296
+
297
+ load: function(module, params) {
298
+ var self = this,
299
+ config = null,
300
+ moduleCache = [],
301
+ deferredList = [],
302
+ deferred = $q.defer(),
303
+ moduleName,
304
+ errText;
305
+
306
+ if(angular.isUndefined(params)) {
307
+ params = {};
308
+ }
309
+
310
+ // If module is an array, break it down
311
+ if(angular.isArray(module)) {
312
+ // Resubmit each entry as a single module
313
+ angular.forEach(module, function(m) {
314
+ if (m) {
315
+ deferredList.push(self.load(m, params));
316
+ }
317
+ });
318
+
319
+ // Resolve the promise once everything has loaded
320
+ $q.all(deferredList).then(function() {
321
+ deferred.resolve(module);
322
+ });
323
+
324
+ return deferred.promise;
325
+ }
326
+
327
+ moduleName = getModuleName(module);
328
+
329
+ // Get or Set a configuration depending on what was passed in
330
+ if(typeof module === 'string') {
331
+ config = self.getModuleConfig(module);
332
+ if(!config) {
333
+ config = {
334
+ files: [module]
335
+ };
336
+ moduleName = null;
337
+ }
338
+ } else if(typeof module === 'object') {
339
+ config = self.setModuleConfig(module);
340
+ }
341
+
342
+ if(config === null) {
343
+ errText = 'Module "' + moduleName + '" is not configured, cannot load.';
344
+ $log.error(errText);
345
+ deferred.reject(new Error(errText));
346
+ } else {
347
+ // deprecated
348
+ if(angular.isDefined(config.template)) {
349
+ if(angular.isUndefined(config.files)) {
350
+ config.files = [];
351
+ }
352
+ if(angular.isString(config.template)) {
353
+ config.files.push(config.template);
354
+ } else if(angular.isArray(config.template)) {
355
+ config.files.concat(config.template);
356
+ }
357
+ }
358
+ }
359
+
360
+ moduleCache.push = function(value) {
361
+ if(this.indexOf(value) === -1) {
362
+ Array.prototype.push.apply(this, arguments);
363
+ }
364
+ };
365
+
366
+ // If this module has been loaded before, re-use it.
367
+ if(angular.isDefined(moduleName) && moduleExists(moduleName) && regModules.indexOf(moduleName) !== -1) {
368
+ moduleCache.push(moduleName);
369
+
370
+ // if we don't want to load new files, resolve here
371
+ if(angular.isUndefined(config.files)) {
372
+ deferred.resolve();
373
+ return deferred.promise;
374
+ }
375
+ }
376
+
377
+ var loadDependencies = function loadDependencies(module) {
378
+ var moduleName,
379
+ loadedModule,
380
+ requires,
381
+ diff,
382
+ promisesList = [];
383
+
384
+ moduleName = getModuleName(module);
385
+ if(moduleName === null) {
386
+ return $q.when();
387
+ } else {
388
+ try {
389
+ loadedModule = getModule(moduleName);
390
+ } catch(e) {
391
+ var deferred = $q.defer();
392
+ $log.error(e.message);
393
+ deferred.reject(e);
394
+ return deferred.promise;
395
+ }
396
+ requires = getRequires(loadedModule);
397
+ }
398
+
399
+ angular.forEach(requires, function(requireEntry) {
400
+ // If no configuration is provided, try and find one from a previous load.
401
+ // If there isn't one, bail and let the normal flow run
402
+ if(typeof requireEntry === 'string') {
403
+ var config = self.getModuleConfig(requireEntry);
404
+ if(config === null) {
405
+ moduleCache.push(requireEntry); // We don't know about this module, but something else might, so push it anyway.
406
+ return;
407
+ }
408
+ requireEntry = config;
409
+ }
410
+
411
+ // Check if this dependency has been loaded previously
412
+ if(moduleExists(requireEntry.name)) {
413
+ if(typeof module !== 'string') {
414
+ // compare against the already loaded module to see if the new definition adds any new files
415
+ diff = requireEntry.files.filter(function (n) {
416
+ return self.getModuleConfig(requireEntry.name).files.indexOf(n) < 0;
417
+ });
418
+
419
+ // If the module was redefined, advise via the console
420
+ if (diff.length !== 0) {
421
+ $log.warn('Module "', moduleName, '" attempted to redefine configuration for dependency. "', requireEntry.name, '"\n Additional Files Loaded:', diff);
422
+ }
423
+
424
+ // Push everything to the file loader, it will weed out the duplicates.
425
+ promisesList.push(filesLoader(requireEntry.files, params).then(function () {
426
+ return loadDependencies(requireEntry);
427
+ }));
428
+ }
429
+ return;
430
+ } else if(typeof requireEntry === 'object') {
431
+ if(requireEntry.hasOwnProperty('name') && requireEntry['name']) {
432
+ // The dependency doesn't exist in the module cache and is a new configuration, so store and push it.
433
+ self.setModuleConfig(requireEntry);
434
+ moduleCache.push(requireEntry['name']);
435
+ }
436
+
437
+ // CSS Loading Handler
438
+ if(requireEntry.hasOwnProperty('css') && requireEntry['css'].length !== 0) {
439
+ // Locate the document insertion point
440
+ angular.forEach(requireEntry['css'], function(path) {
441
+ buildElement('css', path, params);
442
+ });
443
+ }
444
+ // CSS End.
445
+ }
446
+
447
+ // Check if the dependency has any files that need to be loaded. If there are, push a new promise to the promise list.
448
+ if(requireEntry.hasOwnProperty('files') && requireEntry.files.length !== 0) {
449
+ if(requireEntry.files) {
450
+ promisesList.push(filesLoader(requireEntry, params).then(function() {
451
+ return loadDependencies(requireEntry);
452
+ }));
453
+ }
454
+ }
455
+ });
456
+
457
+ // Create a wrapper promise to watch the promise list and resolve it once everything is done.
458
+ return $q.all(promisesList);
459
+ }
460
+
461
+ filesLoader(config, params).then(function success() {
462
+ if(moduleName === null) {
463
+ deferred.resolve(module);
464
+ } else {
465
+ moduleCache.push(moduleName);
466
+ loadDependencies(moduleName).then(function success() {
467
+ try {
468
+ justLoaded = [];
469
+ register(providers, moduleCache, params);
470
+ } catch(e) {
471
+ $log.error(e.message);
472
+ deferred.reject(e);
473
+ return;
474
+ }
475
+ $timeout(function() {
476
+ deferred.resolve(module);
477
+ });
478
+ }, function error(err) {
479
+ $timeout(function() {
480
+ deferred.reject(err);
481
+ });
482
+ });
483
+ }
484
+ }, function error(err) {
485
+ deferred.reject(err);
486
+ });
487
+
488
+ return deferred.promise;
489
+ }
490
+ };
491
+ }];
492
+
493
+ this.config = function(config) {
494
+ if(angular.isDefined(config.jsLoader) || angular.isDefined(config.asyncLoader)) {
495
+ jsLoader = config.jsLoader || config.asyncLoader;
496
+ if(!angular.isFunction(jsLoader)) {
497
+ throw('The js loader needs to be a function');
498
+ }
499
+ }
500
+
501
+ if(angular.isDefined(config.cssLoader)) {
502
+ cssLoader = config.cssLoader;
503
+ if(!angular.isFunction(cssLoader)) {
504
+ throw('The css loader needs to be a function');
505
+ }
506
+ }
507
+
508
+ if(angular.isDefined(config.templatesLoader)) {
509
+ templatesLoader = config.templatesLoader;
510
+ if(!angular.isFunction(templatesLoader)) {
511
+ throw('The template loader needs to be a function');
512
+ }
513
+ }
514
+
515
+ // for bootstrap apps, we need to define the main module name
516
+ if(angular.isDefined(config.loadedModules)) {
517
+ var addRegModule = function(loadedModule) {
518
+ if(regModules.indexOf(loadedModule) < 0) {
519
+ regModules.push(loadedModule);
520
+ angular.forEach(angular.module(loadedModule).requires, addRegModule);
521
+ }
522
+ };
523
+ angular.forEach(config.loadedModules, addRegModule);
524
+ }
525
+
526
+ // If we want to define modules configs
527
+ if(angular.isDefined(config.modules)) {
528
+ if(angular.isArray(config.modules)) {
529
+ angular.forEach(config.modules, function(moduleConfig) {
530
+ modules[moduleConfig.name] = moduleConfig;
531
+ });
532
+ } else {
533
+ modules[config.modules.name] = config.modules;
534
+ }
535
+ }
536
+
537
+ if(angular.isDefined(config.debug)) {
538
+ debug = config.debug;
539
+ }
540
+
541
+ if(angular.isDefined(config.events)) {
542
+ events = config.events;
543
+ }
544
+ };
545
+ }]);
546
+
547
+ ocLazyLoad.directive('ocLazyLoad', ['$http', '$log', '$ocLazyLoad', '$compile', '$timeout', '$templateCache', '$animate',
548
+ function($http, $log, $ocLazyLoad, $compile, $timeout, $templateCache, $animate) {
549
+ return {
550
+ restrict: 'A',
551
+ terminal: true,
552
+ priority: 401, // 1 more than ngInclude
553
+ transclude: 'element',
554
+ controller: angular.noop,
555
+ compile: function(element, attrs) {
556
+ return function($scope, $element, $attr, ctrl, $transclude) {
557
+ var childScope,
558
+ evaluated = $scope.$eval($attr.ocLazyLoad),
559
+ onloadExp = evaluated && evaluated.onload ? evaluated.onload : '';
560
+
561
+ /**
562
+ * Destroy the current scope of this element and empty the html
563
+ */
564
+ function clearContent() {
565
+ if(childScope) {
566
+ childScope.$destroy();
567
+ childScope = null;
568
+ }
569
+ $element.html('');
570
+ }
571
+
572
+ /**
573
+ * Load a template from cache or url
574
+ * @param url
575
+ * @param callback
576
+ */
577
+ function loadTemplate(url, callback) {
578
+ var view;
579
+
580
+ if(typeof(view = $templateCache.get(url)) !== 'undefined') {
581
+ callback(view);
582
+ } else {
583
+ $http.get(url)
584
+ .success(function(data) {
585
+ $templateCache.put('view:' + url, data);
586
+ callback(data);
587
+ })
588
+ .error(function(data) {
589
+ $log.error('Error load template "' + url + '": ' + data);
590
+ });
591
+ }
592
+ }
593
+
594
+ $scope.$watch($attr.ocLazyLoad, function(moduleName) {
595
+ if(angular.isDefined(moduleName)) {
596
+ $ocLazyLoad.load(moduleName).then(function(moduleConfig) {
597
+ $transclude($scope, function cloneConnectFn(clone) {
598
+ $animate.enter(clone, null, $element);
599
+ });
600
+ });
601
+ } else {
602
+ clearContent();
603
+ }
604
+ }, true);
605
+ };
606
+ }
607
+ /*link: function($scope, $element, $attr) {
608
+
609
+ }*/
610
+ };
611
+ }]);
612
+
613
+ /**
614
+ * Get the list of required modules/services/... for this module
615
+ * @param module
616
+ * @returns {Array}
617
+ */
618
+ function getRequires(module) {
619
+ var requires = [];
620
+ angular.forEach(module.requires, function(requireModule) {
621
+ if(regModules.indexOf(requireModule) === -1) {
622
+ requires.push(requireModule);
623
+ }
624
+ });
625
+ return requires;
626
+ }
627
+
628
+ /**
629
+ * Check if a module exists and returns it if it does
630
+ * @param moduleName
631
+ * @returns {boolean}
632
+ */
633
+ function moduleExists(moduleName) {
634
+ try {
635
+ return angular.module(moduleName);
636
+ } catch(e) {
637
+ if(/No module/.test(e) || (e.message.indexOf('$injector:nomod') > -1)) {
638
+ return false;
639
+ }
640
+ }
641
+ }
642
+
643
+ function getModule(moduleName) {
644
+ try {
645
+ return angular.module(moduleName);
646
+ } catch(e) {
647
+ // this error message really suxx
648
+ if(/No module/.test(e) || (e .message.indexOf('$injector:nomod') > -1)) {
649
+ e.message = 'The module "'+moduleName+'" that you are trying to load does not exist. ' + e.message
650
+ }
651
+ throw e;
652
+ }
653
+ }
654
+
655
+ function invokeQueue(providers, queue, moduleName, reconfig) {
656
+ if(!queue) {
657
+ return;
658
+ }
659
+
660
+ var i, len, args, provider;
661
+ for(i = 0, len = queue.length; i < len; i++) {
662
+ args = queue[i];
663
+ if(angular.isArray(args)) {
664
+ if(providers !== null) {
665
+ if(providers.hasOwnProperty(args[0])) {
666
+ provider = providers[args[0]];
667
+ } else {
668
+ throw new Error('unsupported provider ' + args[0]);
669
+ }
670
+ }
671
+ var isNew = registerInvokeList(args[2][0]);
672
+ if(args[1] !== 'invoke') {
673
+ if(isNew && angular.isDefined(provider)) {
674
+ provider[args[1]].apply(provider, args[2]);
675
+ }
676
+ } else { // config block
677
+ var callInvoke = function(fct) {
678
+ var invoked = regConfigs.indexOf(moduleName+'-'+fct);
679
+ if(invoked === -1 || reconfig) {
680
+ if(invoked === -1) {
681
+ regConfigs.push(moduleName+'-'+fct);
682
+ }
683
+ if(angular.isDefined(provider)) {
684
+ provider[args[1]].apply(provider, args[2]);
685
+ }
686
+ }
687
+ }
688
+ if(angular.isFunction(args[2][0])) {
689
+ callInvoke(args[2][0]);
690
+ } else if(angular.isArray(args[2][0])) {
691
+ for(var j = 0, jlen = args[2][0].length; j < jlen; j++) {
692
+ if(angular.isFunction(args[2][0][j])) {
693
+ callInvoke(args[2][0][j]);
694
+ }
695
+ }
696
+ }
697
+ }
698
+ }
699
+ }
700
+ }
701
+
702
+ /**
703
+ * Register a new module and load it
704
+ * @param providers
705
+ * @param registerModules
706
+ * @returns {*}
707
+ */
708
+ function register(providers, registerModules, params) {
709
+ if(registerModules) {
710
+ var k, moduleName, moduleFn, runBlocks = [];
711
+ for(k = registerModules.length - 1; k >= 0; k--) {
712
+ moduleName = registerModules[k];
713
+ if(typeof moduleName !== 'string') {
714
+ moduleName = getModuleName(moduleName);
715
+ }
716
+ if(!moduleName || justLoaded.indexOf(moduleName) !== -1) {
717
+ continue;
718
+ }
719
+ var newModule = regModules.indexOf(moduleName) === -1;
720
+ moduleFn = angular.module(moduleName);
721
+ if(newModule) { // new module
722
+ regModules.push(moduleName);
723
+ register(providers, moduleFn.requires, params);
724
+ runBlocks = runBlocks.concat(moduleFn._runBlocks);
725
+ }
726
+ invokeQueue(providers, moduleFn._invokeQueue, moduleName, params.reconfig);
727
+ invokeQueue(providers, moduleFn._configBlocks, moduleName, params.reconfig); // angular 1.3+
728
+ broadcast(newModule ? 'ocLazyLoad.moduleLoaded' : 'ocLazyLoad.moduleReloaded', moduleName);
729
+ registerModules.pop();
730
+ justLoaded.push(moduleName);
731
+ }
732
+ var instanceInjector = providers.getInstanceInjector();
733
+ angular.forEach(runBlocks, function(fn) {
734
+ instanceInjector.invoke(fn);
735
+ });
736
+ }
737
+ }
738
+
739
+ /**
740
+ * Register an invoke
741
+ * @param invokeList
742
+ * @returns {*}
743
+ */
744
+ function registerInvokeList(invokeList) {
745
+ var newInvoke = false;
746
+ var onInvoke = function(invokeName) {
747
+ newInvoke = true;
748
+ regInvokes.push(invokeName);
749
+ broadcast('ocLazyLoad.componentLoaded', invokeName);
750
+ }
751
+ if(angular.isString(invokeList)) {
752
+ if(regInvokes.indexOf(invokeList) === -1) {
753
+ onInvoke(invokeList);
754
+ }
755
+ } else if(angular.isObject(invokeList)) {
756
+ angular.forEach(invokeList, function(invoke) {
757
+ if(angular.isString(invoke) && regInvokes.indexOf(invoke) === -1) {
758
+ onInvoke(invoke);
759
+ }
760
+ });
761
+ } else {
762
+ return true;
763
+ }
764
+ return newInvoke;
765
+ }
766
+
767
+ function getModuleName(module) {
768
+ if(module === null) {
769
+ return null;
770
+ }
771
+ var moduleName = null;
772
+ if(typeof module === 'string') {
773
+ moduleName = module;
774
+ } else if(typeof module === 'object' && module.hasOwnProperty('name') && typeof module.name === 'string') {
775
+ moduleName = module.name;
776
+ }
777
+ return moduleName;
778
+ }
779
+
780
+ /**
781
+ * Get the list of existing registered modules
782
+ * @param element
783
+ */
784
+ function init(element) {
785
+ var elements = [element],
786
+ appElement,
787
+ moduleName,
788
+ names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
789
+ NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
790
+
791
+ function append(elm) {
792
+ return (elm && elements.push(elm));
793
+ }
794
+
795
+ angular.forEach(names, function(name) {
796
+ names[name] = true;
797
+ append(document.getElementById(name));
798
+ name = name.replace(':', '\\:');
799
+ if(element.querySelectorAll) {
800
+ angular.forEach(element.querySelectorAll('.' + name), append);
801
+ angular.forEach(element.querySelectorAll('.' + name + '\\:'), append);
802
+ angular.forEach(element.querySelectorAll('[' + name + ']'), append);
803
+ }
804
+ });
805
+
806
+ //TODO: search the script tags for angular.bootstrap
807
+ angular.forEach(elements, function(elm) {
808
+ if(!appElement) {
809
+ var className = ' ' + element.className + ' ';
810
+ var match = NG_APP_CLASS_REGEXP.exec(className);
811
+ if(match) {
812
+ appElement = elm;
813
+ moduleName = (match[2] || '').replace(/\s+/g, ',');
814
+ } else {
815
+ angular.forEach(elm.attributes, function(attr) {
816
+ if(!appElement && names[attr.name]) {
817
+ appElement = elm;
818
+ moduleName = attr.value;
819
+ }
820
+ });
821
+ }
822
+ }
823
+ });
824
+
825
+ if(appElement) {
826
+ (function addReg(moduleName) {
827
+ if(regModules.indexOf(moduleName) === -1) {
828
+ // register existing modules
829
+ regModules.push(moduleName);
830
+ var mainModule = angular.module(moduleName);
831
+
832
+ // register existing components (directives, services, ...)
833
+ invokeQueue(null, mainModule._invokeQueue, moduleName);
834
+ invokeQueue(null, mainModule._configBlocks, moduleName); // angular 1.3+
835
+
836
+ angular.forEach(mainModule.requires, addReg);
837
+ }
838
+ })(moduleName);
839
+ }
840
+ }
841
+
842
+ // Array.indexOf polyfill for IE8
843
+ if (!Array.prototype.indexOf) {
844
+ Array.prototype.indexOf = function (searchElement, fromIndex) {
845
+
846
+ var k;
847
+
848
+ // 1. Let O be the result of calling ToObject passing
849
+ // the this value as the argument.
850
+ if (this == null) {
851
+ throw new TypeError('"this" is null or not defined');
852
+ }
853
+
854
+ var O = Object(this);
855
+
856
+ // 2. Let lenValue be the result of calling the Get
857
+ // internal method of O with the argument "length".
858
+ // 3. Let len be ToUint32(lenValue).
859
+ var len = O.length >>> 0;
860
+
861
+ // 4. If len is 0, return -1.
862
+ if (len === 0) {
863
+ return -1;
864
+ }
865
+
866
+ // 5. If argument fromIndex was passed let n be
867
+ // ToInteger(fromIndex); else let n be 0.
868
+ var n = +fromIndex || 0;
869
+
870
+ if (Math.abs(n) === Infinity) {
871
+ n = 0;
872
+ }
873
+
874
+ // 6. If n >= len, return -1.
875
+ if (n >= len) {
876
+ return -1;
877
+ }
878
+
879
+ // 7. If n >= 0, then Let k be n.
880
+ // 8. Else, n<0, Let k be len - abs(n).
881
+ // If k is less than 0, then let k be 0.
882
+ k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
883
+
884
+ // 9. Repeat, while k < len
885
+ while (k < len) {
886
+ // a. Let Pk be ToString(k).
887
+ // This is implicit for LHS operands of the in operator
888
+ // b. Let kPresent be the result of calling the
889
+ // HasProperty internal method of O with argument Pk.
890
+ // This step can be combined with c
891
+ // c. If kPresent is true, then
892
+ // i. Let elementK be the result of calling the Get
893
+ // internal method of O with the argument ToString(k).
894
+ // ii. Let same be the result of applying the
895
+ // Strict Equality Comparison Algorithm to
896
+ // searchElement and elementK.
897
+ // iii. If same is true, return k.
898
+ if (k in O && O[k] === searchElement) {
899
+ return k;
900
+ }
901
+ k++;
902
+ }
903
+ return -1;
904
+ };
905
+ }
906
+ })();