ng-toaster-rails 0.4.10.0 → 0.4.10.1
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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/ng-toaster-rails/version.rb +1 -1
- data/vendor/assets/javascripts/toaster.js +180 -133
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 401242d3f02d3e2b48f7fd684785ebe9e4c1fc42
|
4
|
+
data.tar.gz: a76c7190683446075a7bb399de98eabfb4ec1d9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d9ad77fa42a8867b4b3e6369ffb2f6b72b7b018b8ff70e5aca2d13fff0d4439f50a61b9e3fac2f74c27d46bbe3149bdf2feaaaa2bb51758baa13977c1a346ca
|
7
|
+
data.tar.gz: 2aafe6b0227879f872ac3bcbbe1383267c524b592eee2b532390dadaa5d5660fbb999c71810047b6d6a8735120997f42a9631ad94304ac0711ff3393b86298e9
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# ng-toaster-rails
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/ng-toaster-rails)
|
4
|
+
|
3
5
|
ng-toaster-rails wraps the [AngularJS-Toaster](https://github.com/jirikavi/AngularJS-Toaster) library in a rails engine for simple use with the asset pipeline provided by Rails 3.1 and higher. The gem includes the development (non-minified) source for ease of exploration. The asset pipeline will minify in production.
|
4
6
|
|
5
7
|
For more info on customizing the library, please refer to the [doc](https://github.com/jirikavi/AngularJS-Toaster)
|
@@ -3,11 +3,11 @@
|
|
3
3
|
|
4
4
|
/*
|
5
5
|
* AngularJS Toaster
|
6
|
-
* Version: 0.4.10
|
6
|
+
* Version: 0.4.10+
|
7
7
|
*
|
8
|
-
* Copyright 2013 Jiri Kavulak.
|
9
|
-
* All Rights Reserved.
|
10
|
-
* Use, reproduction, distribution, and modification of this code is subject to the terms and
|
8
|
+
* Copyright 2013-2014 Jiri Kavulak.
|
9
|
+
* All Rights Reserved.
|
10
|
+
* Use, reproduction, distribution, and modification of this code is subject to the terms and
|
11
11
|
* conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
|
12
12
|
*
|
13
13
|
* Author: Jiri Kavulak
|
@@ -16,15 +16,15 @@
|
|
16
16
|
|
17
17
|
angular.module('toaster', ['ngAnimate'])
|
18
18
|
.constant('toasterConfig', {
|
19
|
-
'limit': 0, // limits max number of toasts
|
19
|
+
'limit': 0, // limits max number of toasts
|
20
20
|
'tap-to-dismiss': true,
|
21
21
|
'close-button': false,
|
22
22
|
'newest-on-top': true,
|
23
23
|
//'fade-in': 1000, // done in css
|
24
24
|
//'on-fade-in': undefined, // not implemented
|
25
25
|
//'fade-out': 1000, // done in css
|
26
|
-
//
|
27
|
-
//'extended-time-out': 1000,
|
26
|
+
//'on-fade-out': undefined, // not implemented
|
27
|
+
//'extended-time-out': 1000, // not implemented
|
28
28
|
'time-out': 5000, // Set timeOut and extendedTimeout to 0 to make it sticky
|
29
29
|
'icon-classes': {
|
30
30
|
error: 'toast-error',
|
@@ -33,18 +33,22 @@ angular.module('toaster', ['ngAnimate'])
|
|
33
33
|
success: 'toast-success',
|
34
34
|
warning: 'toast-warning'
|
35
35
|
},
|
36
|
-
'body-output-type': ''
|
36
|
+
'body-output-type': '', // Options: '', 'trustedHtml', 'template', 'templateWithData'
|
37
37
|
'body-template': 'toasterBodyTmpl.html',
|
38
38
|
'icon-class': 'toast-info',
|
39
|
-
'position-class': 'toast-top-right',
|
39
|
+
'position-class': 'toast-top-right', // Options (see CSS):
|
40
|
+
// 'toast-top-full-width', 'toast-bottom-full-width', 'toast-center',
|
41
|
+
// 'toast-top-left', 'toast-top-center', 'toast-top-rigt',
|
42
|
+
// 'toast-bottom-left', 'toast-bottom-center', 'toast-bottom-rigt',
|
40
43
|
'title-class': 'toast-title',
|
41
44
|
'message-class': 'toast-message',
|
45
|
+
'prevent-duplicates': false,
|
42
46
|
'mouseover-timer-stop': true // stop timeout on mouseover and restart timer on mouseout
|
43
47
|
})
|
44
48
|
.service('toaster', ['$rootScope', 'toasterConfig', function ($rootScope, toasterConfig) {
|
45
|
-
this.pop = function (type, title, body, timeout, bodyOutputType, clickHandler) {
|
49
|
+
this.pop = function (type, title, body, timeout, bodyOutputType, clickHandler, toasterId) {
|
46
50
|
if (angular.isObject(type)) {
|
47
|
-
var params = type; //
|
51
|
+
var params = type; // Enable named parameters as pop argument
|
48
52
|
this.toast = {
|
49
53
|
type: params.type,
|
50
54
|
title: params.title,
|
@@ -53,8 +57,8 @@ angular.module('toaster', ['ngAnimate'])
|
|
53
57
|
bodyOutputType: params.bodyOutputType,
|
54
58
|
clickHandler: params.clickHandler
|
55
59
|
};
|
56
|
-
|
57
|
-
else {
|
60
|
+
toasterId = params.toasterId;
|
61
|
+
} else {
|
58
62
|
this.toast = {
|
59
63
|
type: type,
|
60
64
|
title: title,
|
@@ -64,93 +68,124 @@ angular.module('toaster', ['ngAnimate'])
|
|
64
68
|
clickHandler: clickHandler
|
65
69
|
};
|
66
70
|
}
|
67
|
-
$rootScope.$emit('toaster-newToast');
|
71
|
+
$rootScope.$emit('toaster-newToast', toasterId);
|
68
72
|
};
|
69
73
|
|
70
74
|
this.clear = function () {
|
71
75
|
$rootScope.$emit('toaster-clearToasts');
|
72
76
|
};
|
73
|
-
|
77
|
+
|
78
|
+
// Create one method per icon class, to allow to call toaster.info() and similar
|
74
79
|
for (var type in toasterConfig['icon-classes']) {
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
this[type] = (function (toasterType) {
|
81
|
+
return function(title, body, timeout, bodyOutputType, clickHandler, toasterId) {
|
82
|
+
if (angular.isString(title)) {
|
83
|
+
this.pop(toasterType, title, body, timeout, bodyOutputType, clickHandler, toasterId);
|
84
|
+
} else { // 'title' is actually an object with options
|
85
|
+
this.pop(angular.extend(title, { type: toasterType }));
|
86
|
+
}
|
87
|
+
};
|
88
|
+
})(type);
|
83
89
|
}
|
84
90
|
}])
|
85
|
-
.factory('
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
91
|
+
.factory('toasterEventRegistry',['$rootScope', function($rootScope) {
|
92
|
+
var deregisterNewToast = null,
|
93
|
+
deregisterClearToasts = null,
|
94
|
+
newToastEventSubscribers = [],
|
95
|
+
clearToastsEventSubscribers = [],
|
96
|
+
toasterFactory;
|
97
|
+
|
98
|
+
toasterFactory = {
|
99
|
+
setup: function () {
|
100
|
+
if (!deregisterNewToast) {
|
101
|
+
deregisterNewToast = $rootScope.$on('toaster-newToast', function (event, toasterId) {
|
102
|
+
for (var i = 0, len = newToastEventSubscribers.length; i < len; i++) {
|
103
|
+
newToastEventSubscribers[i](event, toasterId);
|
104
|
+
}
|
105
|
+
});
|
106
|
+
}
|
107
|
+
|
108
|
+
if (!deregisterClearToasts) {
|
109
|
+
deregisterClearToasts = $rootScope.$on('toaster-clearToasts', function (event) {
|
110
|
+
for (var i = 0, len = clearToastsEventSubscribers.length; i < len; i++) {
|
111
|
+
clearToastsEventSubscribers[i](event);
|
112
|
+
}
|
113
|
+
});
|
114
|
+
}
|
115
|
+
},
|
116
|
+
|
117
|
+
subscribeToNewToastEvent: function(onNewToast) {
|
118
|
+
newToastEventSubscribers.push(onNewToast);
|
119
|
+
},
|
120
|
+
subscribeToClearToastsEvent: function(onClearToasts) {
|
121
|
+
clearToastsEventSubscribers.push(onClearToasts);
|
122
|
+
},
|
123
|
+
unsubscribeToNewToastEvent: function(onNewToast) {
|
124
|
+
var index = newToastEventSubscribers.indexOf(onNewToast);
|
125
|
+
if (index >= 0)
|
126
|
+
newToastEventSubscribers.splice(index, 1);
|
127
|
+
|
128
|
+
if (newToastEventSubscribers.length === 0) {
|
129
|
+
deregisterNewToast();
|
130
|
+
deregisterNewToast = null;
|
131
|
+
}
|
132
|
+
},
|
133
|
+
unsubscribeToClearToastsEvent: function(onClearToasts) {
|
134
|
+
var index = clearToastsEventSubscribers.indexOf(onClearToasts);
|
135
|
+
if (index >= 0)
|
136
|
+
clearToastsEventSubscribers.splice(index, 1);
|
137
|
+
|
138
|
+
if (clearToastsEventSubscribers.length === 0) {
|
139
|
+
deregisterClearToasts();
|
140
|
+
deregisterClearToasts = null;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
};
|
109
144
|
return {
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
function ($parse, $rootScope, $interval, $sce, toasterConfig, toaster, toasterRegisterEvents) {
|
145
|
+
setup: toasterFactory.setup,
|
146
|
+
subscribeToNewToastEvent: toasterFactory.subscribeToNewToastEvent,
|
147
|
+
subscribeToClearToastsEvent: toasterFactory.subscribeToClearToastsEvent,
|
148
|
+
unsubscribeToNewToastEvent: toasterFactory.unsubscribeToNewToastEvent,
|
149
|
+
unsubscribeToClearToastsEvent: toasterFactory.unsubscribeToClearToastsEvent
|
150
|
+
};
|
151
|
+
}])
|
152
|
+
.directive('toasterContainer', ['$parse', '$rootScope', '$interval', '$sce', 'toasterConfig', 'toaster', 'toasterEventRegistry',
|
153
|
+
function ($parse, $rootScope, $interval, $sce, toasterConfig, toaster, toasterEventRegistry) {
|
120
154
|
return {
|
121
155
|
replace: true,
|
122
156
|
restrict: 'EA',
|
123
|
-
scope: true, // creates an internal scope for this directive
|
157
|
+
scope: true, // creates an internal scope for this directive (one per directive instance)
|
124
158
|
link: function (scope, elm, attrs) {
|
125
159
|
var id = 0,
|
126
160
|
mergedConfig;
|
127
161
|
|
162
|
+
// Merges configuration set in directive with default one
|
128
163
|
mergedConfig = angular.extend({}, toasterConfig, scope.$eval(attrs.toasterOptions));
|
129
164
|
|
130
165
|
scope.config = {
|
166
|
+
toasterId: mergedConfig['toaster-id'],
|
131
167
|
position: mergedConfig['position-class'],
|
132
168
|
title: mergedConfig['title-class'],
|
133
169
|
message: mergedConfig['message-class'],
|
134
170
|
tap: mergedConfig['tap-to-dismiss'],
|
135
171
|
closeButton: mergedConfig['close-button'],
|
136
172
|
animation: mergedConfig['animation-class'],
|
137
|
-
mouseoverTimer:
|
173
|
+
mouseoverTimer: mergedConfig['mouseover-timer-stop']
|
138
174
|
};
|
139
175
|
|
140
|
-
scope
|
141
|
-
|
142
|
-
|
143
|
-
scope.$on("$destroy",function () {
|
144
|
-
if (scope.deregClearToasts) scope.deregClearToasts();
|
145
|
-
if (scope.deregNewToast) scope.deregNewToast();
|
146
|
-
scope.deregClearToasts=null;
|
147
|
-
scope.deregNewToast=null;
|
148
|
-
toasterRegisterEvents.deregisterNewToastEvent();
|
149
|
-
toasterRegisterEvents.deregisterClearAllToastsEvent();
|
176
|
+
scope.$on("$destroy", function () {
|
177
|
+
toasterEventRegistry.unsubscribeToNewToastEvent(scope._onNewToast);
|
178
|
+
toasterEventRegistry.unsubscribeToClearToastsEvent(scope._onClearToasts);
|
150
179
|
});
|
151
180
|
|
152
|
-
|
153
|
-
|
181
|
+
function setTimeout(toast, time) {
|
182
|
+
toast.timeoutPromise = $interval(function () {
|
183
|
+
scope.removeToast(toast.id);
|
184
|
+
}, time, 1);
|
185
|
+
}
|
186
|
+
|
187
|
+
scope.configureTimer = function (toast) {
|
188
|
+
var timeout = angular.isNumber(toast.timeout) ? toast.timeout : mergedConfig['time-out'];
|
154
189
|
if (timeout > 0)
|
155
190
|
setTimeout(toast, timeout);
|
156
191
|
};
|
@@ -160,8 +195,13 @@ function ($parse, $rootScope, $interval, $sce, toasterConfig, toaster, toasterRe
|
|
160
195
|
if (!toast.type)
|
161
196
|
toast.type = mergedConfig['icon-class'];
|
162
197
|
|
163
|
-
|
164
|
-
|
198
|
+
// Prevent adding duplicate toasts if it's set
|
199
|
+
if (mergedConfig['prevent-duplicates'] === true &&
|
200
|
+
scope.toasters.length > 0 &&
|
201
|
+
scope.toasters[scope.toasters.length - 1].body === toast.body)
|
202
|
+
return;
|
203
|
+
|
204
|
+
toast.id = ++id;
|
165
205
|
|
166
206
|
// Set the toast.bodyOutputType to the default if it isn't set
|
167
207
|
toast.bodyOutputType = toast.bodyOutputType || mergedConfig['body-output-type'];
|
@@ -193,97 +233,104 @@ function ($parse, $rootScope, $interval, $sce, toasterConfig, toaster, toasterRe
|
|
193
233
|
scope.toasters.shift();
|
194
234
|
}
|
195
235
|
}
|
196
|
-
|
197
|
-
toast.mouseover = false;
|
198
236
|
}
|
199
|
-
|
200
|
-
function
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
237
|
+
|
238
|
+
scope.removeToast = function (id) {
|
239
|
+
var i, len, toast;
|
240
|
+
for (i = 0, len = scope.toasters.length; i < len; i++) {
|
241
|
+
if (scope.toasters[i].id === id) {
|
242
|
+
removeToast(i);
|
243
|
+
break;
|
244
|
+
}
|
245
|
+
}
|
246
|
+
};
|
247
|
+
|
248
|
+
function removeToast(toastIndex) {
|
249
|
+
var toast = scope.toasters[toastIndex];
|
250
|
+
if (toast) {
|
251
|
+
if (toast.timeoutPromise) {
|
252
|
+
$interval.cancel(toast.timeoutPromise);
|
253
|
+
}
|
254
|
+
scope.toasters.splice(toastIndex, 1);
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
function removeAllToasts() {
|
259
|
+
for (var i = scope.toasters.length; i >= 0; i--) {
|
260
|
+
removeToast(i);
|
261
|
+
}
|
205
262
|
}
|
206
263
|
|
207
264
|
scope.toasters = [];
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
265
|
+
|
266
|
+
scope._onNewToast = function (event, toasterId) {
|
267
|
+
// Compatibility: if toaster has no toasterId defined, and if call to display
|
268
|
+
// hasn't either, then the request is for us
|
269
|
+
if (scope.config.toasterId === undefined && toasterId === undefined ||
|
270
|
+
// Otherwise, we check if the event is for this toaster
|
271
|
+
toasterId !== undefined && toasterId === scope.config.toasterId)
|
212
272
|
addToast(toaster.toast);
|
213
|
-
|
214
|
-
|
273
|
+
};
|
274
|
+
scope._onClearToasts = function (event) {
|
275
|
+
removeAllToasts();
|
276
|
+
};
|
215
277
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
});
|
221
|
-
}
|
278
|
+
toasterEventRegistry.setup();
|
279
|
+
|
280
|
+
toasterEventRegistry.subscribeToNewToastEvent(scope._onNewToast);
|
281
|
+
toasterEventRegistry.subscribeToClearToastsEvent(scope._onClearToasts);
|
222
282
|
},
|
223
283
|
controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
|
224
|
-
|
284
|
+
// Called on mouseover
|
225
285
|
$scope.stopTimer = function (toast) {
|
226
|
-
toast.mouseover = true;
|
227
286
|
if ($scope.config.mouseoverTimer === true) {
|
228
|
-
if (toast.
|
229
|
-
$interval.cancel(toast.
|
230
|
-
toast.
|
287
|
+
if (toast.timeoutPromise) {
|
288
|
+
$interval.cancel(toast.timeoutPromise);
|
289
|
+
toast.timeoutPromise = null;
|
231
290
|
}
|
232
291
|
}
|
233
292
|
};
|
234
293
|
|
294
|
+
// Called on mouseout
|
235
295
|
$scope.restartTimer = function (toast) {
|
236
|
-
toast.mouseover = false;
|
237
296
|
if ($scope.config.mouseoverTimer === true) {
|
238
|
-
if (!toast.
|
297
|
+
if (!toast.timeoutPromise)
|
239
298
|
$scope.configureTimer(toast);
|
240
|
-
}
|
241
|
-
|
242
|
-
$scope.removeToast(toaster.id);
|
243
|
-
}
|
244
|
-
};
|
245
|
-
|
246
|
-
$scope.removeToast = function (id) {
|
247
|
-
var i = 0;
|
248
|
-
for (i; i < $scope.toasters.length; i++) {
|
249
|
-
if ($scope.toasters[i].id === id)
|
250
|
-
break;
|
299
|
+
} else if (toast.timeoutPromise === null) {
|
300
|
+
$scope.removeToast(toast.id);
|
251
301
|
}
|
252
|
-
$scope.toasters.splice(i, 1);
|
253
302
|
};
|
254
303
|
|
255
|
-
$scope.click = function (
|
256
|
-
if ($scope.config.tap === true || isCloseButton
|
304
|
+
$scope.click = function (toast, isCloseButton) {
|
305
|
+
if ($scope.config.tap === true || isCloseButton === true) {
|
257
306
|
var removeToast = true;
|
258
|
-
if (
|
259
|
-
if (angular.isFunction(
|
260
|
-
removeToast =
|
261
|
-
}
|
262
|
-
|
263
|
-
|
264
|
-
}
|
265
|
-
else {
|
307
|
+
if (toast.clickHandler) {
|
308
|
+
if (angular.isFunction(toast.clickHandler)) {
|
309
|
+
removeToast = toast.clickHandler(toast, isCloseButton);
|
310
|
+
} else if (angular.isFunction($scope.$parent.$eval(toast.clickHandler))) {
|
311
|
+
removeToast = $scope.$parent.$eval(toast.clickHandler)(toast, isCloseButton);
|
312
|
+
} else {
|
266
313
|
console.log("TOAST-NOTE: Your click handler is not inside a parent scope of toaster-container.");
|
267
314
|
}
|
268
315
|
}
|
269
316
|
if (removeToast) {
|
270
|
-
$scope.removeToast(
|
317
|
+
$scope.removeToast(toast.id);
|
271
318
|
}
|
272
319
|
}
|
273
320
|
};
|
274
321
|
}],
|
275
322
|
template:
|
276
|
-
'<div
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
'</div>' +
|
323
|
+
'<div id="toast-container" ng-class="[config.position, config.animation]">' +
|
324
|
+
'<div ng-repeat="toaster in toasters" class="toast" ng-class="toaster.type" ng-click="click(toaster)" ng-mouseover="stopTimer(toaster)" ng-mouseout="restartTimer(toaster)">' +
|
325
|
+
'<button class="toast-close-button" ng-show="config.closeButton" ng-click="click(toaster, true)">×</button>' +
|
326
|
+
'<div ng-class="config.title">{{toaster.title}}</div>' +
|
327
|
+
'<div ng-class="config.message" ng-switch on="toaster.bodyOutputType">' +
|
328
|
+
'<div ng-switch-when="trustedHtml" ng-bind-html="toaster.html"></div>' +
|
329
|
+
'<div ng-switch-when="template"><div ng-include="toaster.bodyTemplate"></div></div>' +
|
330
|
+
'<div ng-switch-when="templateWithData"><div ng-include="toaster.bodyTemplate"></div></div>' +
|
331
|
+
'<div ng-switch-default >{{toaster.body}}</div>' +
|
286
332
|
'</div>' +
|
333
|
+
'</div>' +
|
287
334
|
'</div>'
|
288
335
|
};
|
289
336
|
}]);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ng-toaster-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.10.
|
4
|
+
version: 0.4.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fdibartolo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Rails engine for jirikavi/AngularJS-Toaster: "AngularJS Toaster is a
|
14
14
|
customized version of "toastr" non-blocking notification javascript library"'
|