Implemented URL query parsing for initial token /opa/?token=abcde
[src/app-framework-demo.git] / afb-client / bower_components / foundation-apps / js / angular / components / notification / notification.js
1 (function() {
2   'use strict';
3
4   angular.module('foundation.notification', ['foundation.core'])
5     .controller('ZfNotificationController', ZfNotificationController)
6     .directive('zfNotificationSet', zfNotificationSet)
7     .directive('zfNotification', zfNotification)
8     .directive('zfNotificationStatic', zfNotificationStatic)
9     .directive('zfNotify', zfNotify)
10     .factory('NotificationFactory', NotificationFactory)
11     .service('FoundationNotification', FoundationNotification)
12   ;
13
14   FoundationNotification.$inject = ['FoundationApi', 'NotificationFactory'];
15
16   function FoundationNotification(foundationApi, NotificationFactory) {
17     var service    = {};
18
19     service.activate = activate;
20     service.deactivate = deactivate;
21
22     return service;
23
24     //target should be element ID
25     function activate(target) {
26       foundationApi.publish(target, 'show');
27     }
28
29     //target should be element ID
30     function deactivate(target) {
31       foundationApi.publish(target, 'hide');
32     }
33
34     function toggle(target) {
35       foundationApi.publish(target, 'toggle');
36     }
37
38     function createNotificationSet(config) {
39       return new NotificationFactory(config);
40     }
41   }
42
43
44   ZfNotificationController.$inject = ['$scope', 'FoundationApi'];
45
46   function ZfNotificationController($scope, foundationApi) {
47     var controller    = this;
48     controller.notifications = $scope.notifications = $scope.notifications || [];
49
50     controller.addNotification = function(info) {
51       var id  = foundationApi.generateUuid();
52       info.id = id;
53       $scope.notifications.push(info);
54     };
55
56     controller.removeNotification = function(id) {
57       $scope.notifications.forEach(function(notification) {
58         if(notification.id === id) {
59           var ind = $scope.notifications.indexOf(notification);
60           $scope.notifications.splice(ind, 1);
61         }
62       });
63     };
64
65     controller.clearAll = function() {
66       while($scope.notifications.length > 0) {
67         $scope.notifications.pop();
68       }
69     };
70   }
71
72   zfNotificationSet.$inject = ['FoundationApi'];
73
74   function zfNotificationSet(foundationApi) {
75     var directive = {
76       restrict: 'EA',
77       templateUrl: 'components/notification/notification-set.html',
78       controller: 'ZfNotificationController',
79       replace: true,
80       scope: {
81         position: '@'
82       },
83       link: link
84     };
85
86     return directive;
87
88     function link(scope, element, attrs, controller) {
89       scope.position = scope.position ? scope.position.split(' ').join('-') : 'top-right';
90
91       foundationApi.subscribe(attrs.id, function(msg) {
92         if(msg === 'clearall') {
93           controller.clearAll();
94         }
95         else {
96           controller.addNotification(msg);
97           if (!scope.$root.$$phase) {
98             scope.$apply();
99           }
100         }
101       });
102     }
103   }
104
105   zfNotification.$inject = ['FoundationApi'];
106
107   function zfNotification(foundationApi) {
108     var directive = {
109       restrict: 'EA',
110       templateUrl: 'components/notification/notification.html',
111       replace: true,
112       transclude: true,
113       require: '^zfNotificationSet',
114       controller: function() { },
115       scope: {
116         title: '=?',
117         content: '=?',
118         image: '=?',
119         notifId: '=',
120         color: '=?',
121         autoclose: '=?'
122       },
123       compile: compile
124     };
125
126     return directive;
127
128     function compile() {
129
130       return {
131         pre: preLink,
132         post: postLink
133       };
134
135       function preLink(scope, iElement, iAttrs) {
136         iAttrs.$set('zf-closable', 'notification');
137       }
138
139       function postLink(scope, element, attrs, controller) {
140         scope.active = false;
141         var animationIn  = attrs.animationIn || 'fadeIn';
142         var animationOut = attrs.animationOut || 'fadeOut';
143         var hammerElem;
144
145         //due to dynamic insertion of DOM, we need to wait for it to show up and get working!
146         setTimeout(function() {
147           scope.active = true;
148           foundationApi.animate(element, scope.active, animationIn, animationOut);
149         }, 50);
150
151         scope.hide = function() {
152           scope.active = false;
153           foundationApi.animate(element, scope.active, animationIn, animationOut);
154           setTimeout(function() {
155             controller.removeNotification(scope.notifId);
156           }, 50);
157         };
158
159         // close if autoclose
160         if (scope.autoclose) {
161           setTimeout(function() {
162             if (scope.active) {
163               scope.hide();
164             }
165           }, parseInt(scope.autoclose));
166         };
167
168         // close on swipe
169         if (Hammer) {
170           hammerElem = new Hammer(element[0]);
171           // set the options for swipe (to make them a bit more forgiving in detection)
172           hammerElem.get('swipe').set({
173             direction: Hammer.DIRECTION_ALL,
174             threshold: 5, // this is how far the swipe has to travel
175             velocity: 0.5 // and this is how fast the swipe must travel
176           });
177         }
178
179         hammerElem.on('swipe', function() {
180           if (scope.active) {
181             scope.hide();
182           }
183         });
184       }
185     }
186   }
187
188   zfNotificationStatic.$inject = ['FoundationApi'];
189
190   function zfNotificationStatic(foundationApi) {
191     var directive = {
192       restrict: 'EA',
193       templateUrl: 'components/notification/notification-static.html',
194       replace: true,
195       transclude: true,
196       scope: {
197         title: '@?',
198         content: '@?',
199         image: '@?',
200         color: '@?',
201         autoclose: '@?'
202       },
203       compile: compile
204     };
205
206     return directive;
207
208     function compile() {
209       var type = 'notification';
210
211       return {
212         pre: preLink,
213         post: postLink
214       };
215
216       function preLink(scope, iElement, iAttrs, controller) {
217         iAttrs.$set('zf-closable', type);
218       }
219
220       function postLink(scope, element, attrs, controller) {
221         scope.position = attrs.position ? attrs.position.split(' ').join('-') : 'top-right';
222
223         var animationIn = attrs.animationIn || 'fadeIn';
224         var animationOut = attrs.animationOut || 'fadeOut';
225
226         //setup
227         foundationApi.subscribe(attrs.id, function(msg) {
228           if(msg == 'show' || msg == 'open') {
229             scope.show();
230             // close if autoclose
231             if (scope.autoclose) {
232               setTimeout(function() {
233                 if (scope.active) {
234                   scope.hide();
235                 }
236               }, parseInt(scope.autoclose));
237             };
238           } else if (msg == 'close' || msg == 'hide') {
239             scope.hide();
240           } else if (msg == 'toggle') {
241             scope.toggle();
242             // close if autoclose
243             if (scope.autoclose) {
244               setTimeout(function() {
245                 if (scope.active) {
246                   scope.toggle();
247                 }
248               }, parseInt(scope.autoclose));
249             };
250           }
251
252           foundationApi.animate(element, scope.active, animationIn, animationOut);
253           scope.$apply();
254
255           return;
256         });
257
258         scope.hide = function() {
259           scope.active = false;
260           foundationApi.animate(element, scope.active, animationIn, animationOut);
261           return;
262         };
263
264         scope.show = function() {
265           scope.active = true;
266           foundationApi.animate(element, scope.active, animationIn, animationOut);
267           return;
268         };
269
270         scope.toggle = function() {
271           scope.active = !scope.active;
272           foundationApi.animate(element, scope.active, animationIn, animationOut);
273           return;
274         };
275
276       }
277     }
278   }
279
280   zfNotify.$inject = ['FoundationApi'];
281
282   function zfNotify(foundationApi) {
283     var directive = {
284       restrict: 'A',
285       scope: {
286         title: '@?',
287         content: '@?',
288         color: '@?',
289         image: '@?',
290         autoclose: '@?'
291       },
292       link: link
293     };
294
295     return directive;
296
297     function link(scope, element, attrs, controller) {
298       element.on('click', function(e) {
299         foundationApi.publish(attrs.zfNotify, {
300           title: scope.title,
301           content: scope.content,
302           color: scope.color,
303           image: scope.image,
304           autoclose: scope.autoclose
305         });
306         e.preventDefault();
307       });
308     }
309   }
310
311   NotificationFactory.$inject = ['$http', '$templateCache', '$rootScope', '$compile', '$timeout', 'FoundationApi'];
312
313   function NotificationFactory($http, $templateCache, $rootScope, $compile, $timeout, foundationApi) {
314     return notificationFactory;
315
316     function notificationFactory(config) {
317       var self = this, //for prototype functions
318           container = angular.element(config.container || document.body),
319           id = config.id || foundationApi.generateUuid(),
320           attached = false,
321           destroyed = false,
322           html,
323           element,
324           scope,
325           contentScope
326       ;
327
328       var props = [
329         'position'
330       ];
331
332       assembleDirective();
333
334       self.addNotification = addNotification;
335       self.clearAll = clearAll;
336       self.destroy = destroy;
337
338       return {
339         addNotification: addNotification,
340         clearAll: clearAll,
341         destroy: destroy
342       };
343
344       function checkStatus() {
345         if(destroyed) {
346           throw "Error: Notification Set was destroyed. Delete the object and create a new NotificationFactory instance."
347         }
348       }
349
350       function addNotification(notification) {
351         checkStatus();
352         $timeout(function() {
353           foundationApi.publish(id, notification);
354         }, 0, false);
355       }
356
357       function clearAll() {
358         checkStatus();
359         $timeout(function() {
360           foundationApi.publish(id, 'clearall');
361         }, 0, false);
362       }
363
364       function init(state) {
365         if(!attached && html.length > 0) {
366           var modalEl = container.append(element);
367
368           scope.active = state;
369           $compile(element)(scope);
370
371           attached = true;
372         }
373       }
374
375       function assembleDirective() {
376         // check for duplicate element to prevent factory from cloning notification sets
377         if (document.getElementById(id)) {
378           return;
379         }
380         html = '<zf-notification-set id="' + id + '"></zf-notification-set>';
381
382         element = angular.element(html);
383
384         scope = $rootScope.$new();
385         
386         for(var i = 0; i < props.length; i++) {
387           if(config[props[i]]) {
388             element.attr(props[i], config[props[i]]);
389           }
390         }
391
392         // access view scope variables
393         if (config.contentScope) {
394           contentScope = config.contentScope;
395           for (var prop in contentScope) {
396             if (contentScope.hasOwnProperty(prop)) {
397               scope[prop] = contentScope[prop];
398             }
399           }
400         }
401         init(true);
402       }
403
404       function destroy() {
405         self.clearAll();
406         setTimeout(function() {
407           scope.$destroy();
408           element.remove();
409           destroyed = true;
410         }, 3000);
411         foundationApi.unsubscribe(id);
412       }
413
414     }
415
416   }
417 })();