engine2 1.0.0
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 +7 -0
- data/Gemfile +2 -0
- data/Rakefile +138 -0
- data/conf/message.yaml +93 -0
- data/conf/message_pl.yaml +93 -0
- data/engine2.gemspec +34 -0
- data/lib/engine2.rb +34 -0
- data/lib/engine2/action.rb +217 -0
- data/lib/engine2/core.rb +572 -0
- data/lib/engine2/handler.rb +134 -0
- data/lib/engine2/meta.rb +969 -0
- data/lib/engine2/meta/decode_meta.rb +110 -0
- data/lib/engine2/meta/delete_meta.rb +73 -0
- data/lib/engine2/meta/form_meta.rb +144 -0
- data/lib/engine2/meta/infra_meta.rb +292 -0
- data/lib/engine2/meta/link_meta.rb +133 -0
- data/lib/engine2/meta/list_meta.rb +284 -0
- data/lib/engine2/meta/save_meta.rb +63 -0
- data/lib/engine2/meta/view_meta.rb +22 -0
- data/lib/engine2/model.rb +390 -0
- data/lib/engine2/models/Files.rb +38 -0
- data/lib/engine2/models/UserInfo.rb +24 -0
- data/lib/engine2/post_bootstrap.rb +83 -0
- data/lib/engine2/pre_bootstrap.rb +27 -0
- data/lib/engine2/scheme.rb +202 -0
- data/lib/engine2/templates.rb +229 -0
- data/lib/engine2/type_info.rb +342 -0
- data/lib/engine2/version.rb +9 -0
- data/public/assets/javascripts.js +13 -0
- data/public/assets/styles.css +4 -0
- data/public/css/angular-motion.css +1022 -0
- data/public/css/angular-ui-tree.min.css +1 -0
- data/public/css/app.css +196 -0
- data/public/css/bootstrap-additions.css +1560 -0
- data/public/css/bootstrap.min.css +11 -0
- data/public/css/font-awesome.min.css +4 -0
- data/public/favicon.ico +0 -0
- data/public/fonts/FontAwesome.otf +0 -0
- data/public/fonts/fontawesome-webfont.eot +0 -0
- data/public/fonts/fontawesome-webfont.svg +655 -0
- data/public/fonts/fontawesome-webfont.ttf +0 -0
- data/public/fonts/fontawesome-webfont.woff +0 -0
- data/public/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/public/fonts/glyphicons-halflings-regular.svg +288 -0
- data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/public/images/file.png +0 -0
- data/public/images/folder-closed.png +0 -0
- data/public/images/folder.png +0 -0
- data/public/images/node-closed-2.png +0 -0
- data/public/images/node-closed-light.png +0 -0
- data/public/images/node-closed.png +0 -0
- data/public/images/node-opened-2.png +0 -0
- data/public/images/node-opened-light.png +0 -0
- data/public/images/node-opened.png +0 -0
- data/public/img/ajax-loader-dark.gif +0 -0
- data/public/img/ajax-loader-light.gif +0 -0
- data/public/img/ajax-loader.gif +0 -0
- data/public/js/angular-animate.js +4115 -0
- data/public/js/angular-cookies.js +322 -0
- data/public/js/angular-local-storage.js +455 -0
- data/public/js/angular-route.js +1022 -0
- data/public/js/angular-sanitize.js +717 -0
- data/public/js/angular-strap.js +4339 -0
- data/public/js/angular-strap.tpl.js +43 -0
- data/public/js/angular-ui-tree.js +1569 -0
- data/public/js/angular.js +30714 -0
- data/public/js/i18n/angular-locale_pl.js +115 -0
- data/public/js/lodash.custom.min.js +97 -0
- data/public/js/ng-file-upload-shim.min.js +2 -0
- data/public/js/ng-file-upload.min.js +3 -0
- data/views/app.coffee +3 -0
- data/views/engine2.coffee +557 -0
- data/views/engine2actions.coffee +849 -0
- data/views/engine2templates.coffee +0 -0
- data/views/fields/blob.slim +22 -0
- data/views/fields/bs_select.slim +10 -0
- data/views/fields/bsselect_picker.slim +18 -0
- data/views/fields/bsselect_picker_opt.slim +22 -0
- data/views/fields/checkbox.slim +11 -0
- data/views/fields/checkbox_buttons.slim +6 -0
- data/views/fields/checkbox_buttons_opt.slim +8 -0
- data/views/fields/currency.slim +10 -0
- data/views/fields/date.slim +21 -0
- data/views/fields/date_range.slim +44 -0
- data/views/fields/date_time.slim +42 -0
- data/views/fields/datetime.slim +42 -0
- data/views/fields/decimal.slim +11 -0
- data/views/fields/decimal_date.slim +22 -0
- data/views/fields/decimal_time.slim +26 -0
- data/views/fields/email.slim +13 -0
- data/views/fields/file_store.slim +61 -0
- data/views/fields/input_text.slim +14 -0
- data/views/fields/integer.slim +11 -0
- data/views/fields/list_bsselect.slim +18 -0
- data/views/fields/list_bsselect_opt.slim +21 -0
- data/views/fields/list_buttons.slim +3 -0
- data/views/fields/list_buttons_opt.slim +5 -0
- data/views/fields/list_select.slim +11 -0
- data/views/fields/list_select_opt.slim +15 -0
- data/views/fields/password.slim +14 -0
- data/views/fields/radio_checkbox.slim +10 -0
- data/views/fields/scaffold.slim +2 -0
- data/views/fields/scaffold_picker.slim +20 -0
- data/views/fields/select_picker.slim +12 -0
- data/views/fields/select_picker_opt.slim +16 -0
- data/views/fields/text_area.slim +10 -0
- data/views/fields/time.slim +22 -0
- data/views/fields/typeahead_picker.slim +25 -0
- data/views/index.slim +44 -0
- data/views/infra/index.slim +5 -0
- data/views/infra/inspect.slim +81 -0
- data/views/modals/close_m.slim +15 -0
- data/views/modals/confirm_m.slim +19 -0
- data/views/modals/empty_m.slim +12 -0
- data/views/modals/menu_m.slim +13 -0
- data/views/modals/yes_no_m.slim +19 -0
- data/views/panels/menu_m.slim +9 -0
- data/views/scaffold/confirm.slim +3 -0
- data/views/scaffold/fields.slim +10 -0
- data/views/scaffold/form.slim +11 -0
- data/views/scaffold/list.slim +42 -0
- data/views/scaffold/message.slim +3 -0
- data/views/scaffold/search.slim +20 -0
- data/views/scaffold/view.slim +18 -0
- data/views/search_fields/bsmselect_picker.slim +25 -0
- data/views/search_fields/bsselect_picker.slim +24 -0
- data/views/search_fields/checkbox.slim +11 -0
- data/views/search_fields/checkbox2.slim +14 -0
- data/views/search_fields/checkbox_buttons.slim +10 -0
- data/views/search_fields/date_range.slim +46 -0
- data/views/search_fields/decimal_date_range.slim +47 -0
- data/views/search_fields/input_text.slim +18 -0
- data/views/search_fields/integer.slim +18 -0
- data/views/search_fields/integer_range.slim +27 -0
- data/views/search_fields/list_bsmselect.slim +24 -0
- data/views/search_fields/list_bsselect.slim +22 -0
- data/views/search_fields/list_buttons.slim +8 -0
- data/views/search_fields/list_select.slim +17 -0
- data/views/search_fields/scaffold_picker.slim +19 -0
- data/views/search_fields/select_picker.slim +17 -0
- data/views/search_fields/typeahead_picker.slim +25 -0
- metadata +327 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license AngularJS v1.5.3
|
|
3
|
+
* (c) 2010-2016 Google, Inc. http://angularjs.org
|
|
4
|
+
* License: MIT
|
|
5
|
+
*/
|
|
6
|
+
(function(window, angular, undefined) {'use strict';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @ngdoc module
|
|
10
|
+
* @name ngCookies
|
|
11
|
+
* @description
|
|
12
|
+
*
|
|
13
|
+
* # ngCookies
|
|
14
|
+
*
|
|
15
|
+
* The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
|
|
16
|
+
*
|
|
17
|
+
*
|
|
18
|
+
* <div doc-module-components="ngCookies"></div>
|
|
19
|
+
*
|
|
20
|
+
* See {@link ngCookies.$cookies `$cookies`} for usage.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
angular.module('ngCookies', ['ng']).
|
|
25
|
+
/**
|
|
26
|
+
* @ngdoc provider
|
|
27
|
+
* @name $cookiesProvider
|
|
28
|
+
* @description
|
|
29
|
+
* Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.
|
|
30
|
+
* */
|
|
31
|
+
provider('$cookies', [function $CookiesProvider() {
|
|
32
|
+
/**
|
|
33
|
+
* @ngdoc property
|
|
34
|
+
* @name $cookiesProvider#defaults
|
|
35
|
+
* @description
|
|
36
|
+
*
|
|
37
|
+
* Object containing default options to pass when setting cookies.
|
|
38
|
+
*
|
|
39
|
+
* The object may have following properties:
|
|
40
|
+
*
|
|
41
|
+
* - **path** - `{string}` - The cookie will be available only for this path and its
|
|
42
|
+
* sub-paths. By default, this is the URL that appears in your `<base>` tag.
|
|
43
|
+
* - **domain** - `{string}` - The cookie will be available only for this domain and
|
|
44
|
+
* its sub-domains. For security reasons the user agent will not accept the cookie
|
|
45
|
+
* if the current domain is not a sub-domain of this domain or equal to it.
|
|
46
|
+
* - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
|
|
47
|
+
* or a Date object indicating the exact date/time this cookie will expire.
|
|
48
|
+
* - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a
|
|
49
|
+
* secured connection.
|
|
50
|
+
*
|
|
51
|
+
* Note: By default, the address that appears in your `<base>` tag will be used as the path.
|
|
52
|
+
* This is important so that cookies will be visible for all routes when html5mode is enabled.
|
|
53
|
+
*
|
|
54
|
+
**/
|
|
55
|
+
var defaults = this.defaults = {};
|
|
56
|
+
|
|
57
|
+
function calcOptions(options) {
|
|
58
|
+
return options ? angular.extend({}, defaults, options) : defaults;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @ngdoc service
|
|
63
|
+
* @name $cookies
|
|
64
|
+
*
|
|
65
|
+
* @description
|
|
66
|
+
* Provides read/write access to browser's cookies.
|
|
67
|
+
*
|
|
68
|
+
* <div class="alert alert-info">
|
|
69
|
+
* Up until Angular 1.3, `$cookies` exposed properties that represented the
|
|
70
|
+
* current browser cookie values. In version 1.4, this behavior has changed, and
|
|
71
|
+
* `$cookies` now provides a standard api of getters, setters etc.
|
|
72
|
+
* </div>
|
|
73
|
+
*
|
|
74
|
+
* Requires the {@link ngCookies `ngCookies`} module to be installed.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
*
|
|
78
|
+
* ```js
|
|
79
|
+
* angular.module('cookiesExample', ['ngCookies'])
|
|
80
|
+
* .controller('ExampleController', ['$cookies', function($cookies) {
|
|
81
|
+
* // Retrieving a cookie
|
|
82
|
+
* var favoriteCookie = $cookies.get('myFavorite');
|
|
83
|
+
* // Setting a cookie
|
|
84
|
+
* $cookies.put('myFavorite', 'oatmeal');
|
|
85
|
+
* }]);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
|
|
89
|
+
return {
|
|
90
|
+
/**
|
|
91
|
+
* @ngdoc method
|
|
92
|
+
* @name $cookies#get
|
|
93
|
+
*
|
|
94
|
+
* @description
|
|
95
|
+
* Returns the value of given cookie key
|
|
96
|
+
*
|
|
97
|
+
* @param {string} key Id to use for lookup.
|
|
98
|
+
* @returns {string} Raw cookie value.
|
|
99
|
+
*/
|
|
100
|
+
get: function(key) {
|
|
101
|
+
return $$cookieReader()[key];
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @ngdoc method
|
|
106
|
+
* @name $cookies#getObject
|
|
107
|
+
*
|
|
108
|
+
* @description
|
|
109
|
+
* Returns the deserialized value of given cookie key
|
|
110
|
+
*
|
|
111
|
+
* @param {string} key Id to use for lookup.
|
|
112
|
+
* @returns {Object} Deserialized cookie value.
|
|
113
|
+
*/
|
|
114
|
+
getObject: function(key) {
|
|
115
|
+
var value = this.get(key);
|
|
116
|
+
return value ? angular.fromJson(value) : value;
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @ngdoc method
|
|
121
|
+
* @name $cookies#getAll
|
|
122
|
+
*
|
|
123
|
+
* @description
|
|
124
|
+
* Returns a key value object with all the cookies
|
|
125
|
+
*
|
|
126
|
+
* @returns {Object} All cookies
|
|
127
|
+
*/
|
|
128
|
+
getAll: function() {
|
|
129
|
+
return $$cookieReader();
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @ngdoc method
|
|
134
|
+
* @name $cookies#put
|
|
135
|
+
*
|
|
136
|
+
* @description
|
|
137
|
+
* Sets a value for given cookie key
|
|
138
|
+
*
|
|
139
|
+
* @param {string} key Id for the `value`.
|
|
140
|
+
* @param {string} value Raw value to be stored.
|
|
141
|
+
* @param {Object=} options Options object.
|
|
142
|
+
* See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
|
|
143
|
+
*/
|
|
144
|
+
put: function(key, value, options) {
|
|
145
|
+
$$cookieWriter(key, value, calcOptions(options));
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @ngdoc method
|
|
150
|
+
* @name $cookies#putObject
|
|
151
|
+
*
|
|
152
|
+
* @description
|
|
153
|
+
* Serializes and sets a value for given cookie key
|
|
154
|
+
*
|
|
155
|
+
* @param {string} key Id for the `value`.
|
|
156
|
+
* @param {Object} value Value to be stored.
|
|
157
|
+
* @param {Object=} options Options object.
|
|
158
|
+
* See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
|
|
159
|
+
*/
|
|
160
|
+
putObject: function(key, value, options) {
|
|
161
|
+
this.put(key, angular.toJson(value), options);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @ngdoc method
|
|
166
|
+
* @name $cookies#remove
|
|
167
|
+
*
|
|
168
|
+
* @description
|
|
169
|
+
* Remove given cookie
|
|
170
|
+
*
|
|
171
|
+
* @param {string} key Id of the key-value pair to delete.
|
|
172
|
+
* @param {Object=} options Options object.
|
|
173
|
+
* See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
|
|
174
|
+
*/
|
|
175
|
+
remove: function(key, options) {
|
|
176
|
+
$$cookieWriter(key, undefined, calcOptions(options));
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}];
|
|
180
|
+
}]);
|
|
181
|
+
|
|
182
|
+
angular.module('ngCookies').
|
|
183
|
+
/**
|
|
184
|
+
* @ngdoc service
|
|
185
|
+
* @name $cookieStore
|
|
186
|
+
* @deprecated
|
|
187
|
+
* @requires $cookies
|
|
188
|
+
*
|
|
189
|
+
* @description
|
|
190
|
+
* Provides a key-value (string-object) storage, that is backed by session cookies.
|
|
191
|
+
* Objects put or retrieved from this storage are automatically serialized or
|
|
192
|
+
* deserialized by angular's toJson/fromJson.
|
|
193
|
+
*
|
|
194
|
+
* Requires the {@link ngCookies `ngCookies`} module to be installed.
|
|
195
|
+
*
|
|
196
|
+
* <div class="alert alert-danger">
|
|
197
|
+
* **Note:** The $cookieStore service is **deprecated**.
|
|
198
|
+
* Please use the {@link ngCookies.$cookies `$cookies`} service instead.
|
|
199
|
+
* </div>
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
*
|
|
203
|
+
* ```js
|
|
204
|
+
* angular.module('cookieStoreExample', ['ngCookies'])
|
|
205
|
+
* .controller('ExampleController', ['$cookieStore', function($cookieStore) {
|
|
206
|
+
* // Put cookie
|
|
207
|
+
* $cookieStore.put('myFavorite','oatmeal');
|
|
208
|
+
* // Get cookie
|
|
209
|
+
* var favoriteCookie = $cookieStore.get('myFavorite');
|
|
210
|
+
* // Removing a cookie
|
|
211
|
+
* $cookieStore.remove('myFavorite');
|
|
212
|
+
* }]);
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
factory('$cookieStore', ['$cookies', function($cookies) {
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
/**
|
|
219
|
+
* @ngdoc method
|
|
220
|
+
* @name $cookieStore#get
|
|
221
|
+
*
|
|
222
|
+
* @description
|
|
223
|
+
* Returns the value of given cookie key
|
|
224
|
+
*
|
|
225
|
+
* @param {string} key Id to use for lookup.
|
|
226
|
+
* @returns {Object} Deserialized cookie value, undefined if the cookie does not exist.
|
|
227
|
+
*/
|
|
228
|
+
get: function(key) {
|
|
229
|
+
return $cookies.getObject(key);
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @ngdoc method
|
|
234
|
+
* @name $cookieStore#put
|
|
235
|
+
*
|
|
236
|
+
* @description
|
|
237
|
+
* Sets a value for given cookie key
|
|
238
|
+
*
|
|
239
|
+
* @param {string} key Id for the `value`.
|
|
240
|
+
* @param {Object} value Value to be stored.
|
|
241
|
+
*/
|
|
242
|
+
put: function(key, value) {
|
|
243
|
+
$cookies.putObject(key, value);
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @ngdoc method
|
|
248
|
+
* @name $cookieStore#remove
|
|
249
|
+
*
|
|
250
|
+
* @description
|
|
251
|
+
* Remove given cookie
|
|
252
|
+
*
|
|
253
|
+
* @param {string} key Id of the key-value pair to delete.
|
|
254
|
+
*/
|
|
255
|
+
remove: function(key) {
|
|
256
|
+
$cookies.remove(key);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
}]);
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* @name $$cookieWriter
|
|
264
|
+
* @requires $document
|
|
265
|
+
*
|
|
266
|
+
* @description
|
|
267
|
+
* This is a private service for writing cookies
|
|
268
|
+
*
|
|
269
|
+
* @param {string} name Cookie name
|
|
270
|
+
* @param {string=} value Cookie value (if undefined, cookie will be deleted)
|
|
271
|
+
* @param {Object=} options Object with options that need to be stored for the cookie.
|
|
272
|
+
*/
|
|
273
|
+
function $$CookieWriter($document, $log, $browser) {
|
|
274
|
+
var cookiePath = $browser.baseHref();
|
|
275
|
+
var rawDocument = $document[0];
|
|
276
|
+
|
|
277
|
+
function buildCookieString(name, value, options) {
|
|
278
|
+
var path, expires;
|
|
279
|
+
options = options || {};
|
|
280
|
+
expires = options.expires;
|
|
281
|
+
path = angular.isDefined(options.path) ? options.path : cookiePath;
|
|
282
|
+
if (angular.isUndefined(value)) {
|
|
283
|
+
expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
|
|
284
|
+
value = '';
|
|
285
|
+
}
|
|
286
|
+
if (angular.isString(expires)) {
|
|
287
|
+
expires = new Date(expires);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
|
|
291
|
+
str += path ? ';path=' + path : '';
|
|
292
|
+
str += options.domain ? ';domain=' + options.domain : '';
|
|
293
|
+
str += expires ? ';expires=' + expires.toUTCString() : '';
|
|
294
|
+
str += options.secure ? ';secure' : '';
|
|
295
|
+
|
|
296
|
+
// per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
|
|
297
|
+
// - 300 cookies
|
|
298
|
+
// - 20 cookies per unique domain
|
|
299
|
+
// - 4096 bytes per cookie
|
|
300
|
+
var cookieLength = str.length + 1;
|
|
301
|
+
if (cookieLength > 4096) {
|
|
302
|
+
$log.warn("Cookie '" + name +
|
|
303
|
+
"' possibly not set or overflowed because it was too large (" +
|
|
304
|
+
cookieLength + " > 4096 bytes)!");
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return str;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return function(name, value, options) {
|
|
311
|
+
rawDocument.cookie = buildCookieString(name, value, options);
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
$$CookieWriter.$inject = ['$document', '$log', '$browser'];
|
|
316
|
+
|
|
317
|
+
angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() {
|
|
318
|
+
this.$get = $$CookieWriter;
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
})(window, window.angular);
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An Angular module that gives you access to the browsers local storage
|
|
3
|
+
* @version v0.1.5 - 2014-11-04
|
|
4
|
+
* @link https://github.com/grevory/angular-local-storage
|
|
5
|
+
* @author grevory <greg@gregpike.ca>
|
|
6
|
+
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
7
|
+
*/
|
|
8
|
+
(function ( window, angular, undefined ) {
|
|
9
|
+
/*jshint globalstrict:true*/
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
var isDefined = angular.isDefined,
|
|
13
|
+
isUndefined = angular.isUndefined,
|
|
14
|
+
isNumber = angular.isNumber,
|
|
15
|
+
isObject = angular.isObject,
|
|
16
|
+
isArray = angular.isArray,
|
|
17
|
+
extend = angular.extend,
|
|
18
|
+
toJson = angular.toJson,
|
|
19
|
+
fromJson = angular.fromJson;
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
// Test if string is only contains numbers
|
|
23
|
+
// e.g '1' => true, "'1'" => true
|
|
24
|
+
function isStringNumber(num) {
|
|
25
|
+
return /^-?\d+\.?\d*$/.test(num.replace(/["']/g, ''));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var angularLocalStorage = angular.module('LocalStorageModule', []);
|
|
29
|
+
|
|
30
|
+
angularLocalStorage.provider('localStorageService', function() {
|
|
31
|
+
|
|
32
|
+
// You should set a prefix to avoid overwriting any local storage variables from the rest of your app
|
|
33
|
+
// e.g. localStorageServiceProvider.setPrefix('youAppName');
|
|
34
|
+
// With provider you can use config as this:
|
|
35
|
+
// myApp.config(function (localStorageServiceProvider) {
|
|
36
|
+
// localStorageServiceProvider.prefix = 'yourAppName';
|
|
37
|
+
// });
|
|
38
|
+
this.prefix = 'ls';
|
|
39
|
+
|
|
40
|
+
// You could change web storage type localstorage or sessionStorage
|
|
41
|
+
this.storageType = 'localStorage';
|
|
42
|
+
|
|
43
|
+
// Cookie options (usually in case of fallback)
|
|
44
|
+
// expiry = Number of days before cookies expire // 0 = Does not expire
|
|
45
|
+
// path = The web path the cookie represents
|
|
46
|
+
this.cookie = {
|
|
47
|
+
expiry: 30,
|
|
48
|
+
path: '/'
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Send signals for each of the following actions?
|
|
52
|
+
this.notify = {
|
|
53
|
+
setItem: true,
|
|
54
|
+
removeItem: false
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Setter for the prefix
|
|
58
|
+
this.setPrefix = function(prefix) {
|
|
59
|
+
this.prefix = prefix;
|
|
60
|
+
return this;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Setter for the storageType
|
|
64
|
+
this.setStorageType = function(storageType) {
|
|
65
|
+
this.storageType = storageType;
|
|
66
|
+
return this;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Setter for cookie config
|
|
70
|
+
this.setStorageCookie = function(exp, path) {
|
|
71
|
+
this.cookie = {
|
|
72
|
+
expiry: exp,
|
|
73
|
+
path: path
|
|
74
|
+
};
|
|
75
|
+
return this;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Setter for cookie domain
|
|
79
|
+
this.setStorageCookieDomain = function(domain) {
|
|
80
|
+
this.cookie.domain = domain;
|
|
81
|
+
return this;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Setter for notification config
|
|
85
|
+
// itemSet & itemRemove should be booleans
|
|
86
|
+
this.setNotify = function(itemSet, itemRemove) {
|
|
87
|
+
this.notify = {
|
|
88
|
+
setItem: itemSet,
|
|
89
|
+
removeItem: itemRemove
|
|
90
|
+
};
|
|
91
|
+
return this;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
this.$get = ['$rootScope', '$window', '$document', '$parse', function($rootScope, $window, $document, $parse) {
|
|
95
|
+
var self = this;
|
|
96
|
+
var prefix = self.prefix;
|
|
97
|
+
var cookie = self.cookie;
|
|
98
|
+
var notify = self.notify;
|
|
99
|
+
var storageType = self.storageType;
|
|
100
|
+
var webStorage;
|
|
101
|
+
|
|
102
|
+
// When Angular's $document is not available
|
|
103
|
+
if (!$document) {
|
|
104
|
+
$document = document;
|
|
105
|
+
} else if ($document[0]) {
|
|
106
|
+
$document = $document[0];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// If there is a prefix set in the config lets use that with an appended period for readability
|
|
110
|
+
if (prefix.substr(-1) !== '.') {
|
|
111
|
+
prefix = !!prefix ? prefix + '.' : '';
|
|
112
|
+
}
|
|
113
|
+
var deriveQualifiedKey = function(key) {
|
|
114
|
+
return prefix + key;
|
|
115
|
+
};
|
|
116
|
+
// Checks the browser to see if local storage is supported
|
|
117
|
+
var browserSupportsLocalStorage = (function () {
|
|
118
|
+
try {
|
|
119
|
+
var supported = (storageType in $window && $window[storageType] !== null);
|
|
120
|
+
|
|
121
|
+
// When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
|
|
122
|
+
// is available, but trying to call .setItem throws an exception.
|
|
123
|
+
//
|
|
124
|
+
// "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
|
|
125
|
+
// that exceeded the quota."
|
|
126
|
+
var key = deriveQualifiedKey('__' + Math.round(Math.random() * 1e7));
|
|
127
|
+
if (supported) {
|
|
128
|
+
webStorage = $window[storageType];
|
|
129
|
+
webStorage.setItem(key, '');
|
|
130
|
+
webStorage.removeItem(key);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return supported;
|
|
134
|
+
} catch (e) {
|
|
135
|
+
storageType = 'cookie';
|
|
136
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}());
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
// Directly adds a value to local storage
|
|
144
|
+
// If local storage is not available in the browser use cookies
|
|
145
|
+
// Example use: localStorageService.add('library','angular');
|
|
146
|
+
var addToLocalStorage = function (key, value) {
|
|
147
|
+
// Let's convert undefined values to null to get the value consistent
|
|
148
|
+
if (isUndefined(value)) {
|
|
149
|
+
value = null;
|
|
150
|
+
} else if (isObject(value) || isArray(value) || isNumber(+value || value)) {
|
|
151
|
+
value = toJson(value);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// If this browser does not support local storage use cookies
|
|
155
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
|
156
|
+
if (!browserSupportsLocalStorage) {
|
|
157
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (notify.setItem) {
|
|
161
|
+
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
|
|
162
|
+
}
|
|
163
|
+
return addToCookies(key, value);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
if (isObject(value) || isArray(value)) {
|
|
168
|
+
value = toJson(value);
|
|
169
|
+
}
|
|
170
|
+
if (webStorage) {webStorage.setItem(deriveQualifiedKey(key), value)};
|
|
171
|
+
if (notify.setItem) {
|
|
172
|
+
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType});
|
|
173
|
+
}
|
|
174
|
+
} catch (e) {
|
|
175
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
|
176
|
+
return addToCookies(key, value);
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// Directly get a value from local storage
|
|
182
|
+
// Example use: localStorageService.get('library'); // returns 'angular'
|
|
183
|
+
var getFromLocalStorage = function (key) {
|
|
184
|
+
|
|
185
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
|
186
|
+
if (!browserSupportsLocalStorage) {
|
|
187
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return getFromCookies(key);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
var item = webStorage ? webStorage.getItem(deriveQualifiedKey(key)) : null;
|
|
194
|
+
// angular.toJson will convert null to 'null', so a proper conversion is needed
|
|
195
|
+
// FIXME not a perfect solution, since a valid 'null' string can't be stored
|
|
196
|
+
if (!item || item === 'null') {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (item.charAt(0) === "{" || item.charAt(0) === "[" || isStringNumber(item)) {
|
|
201
|
+
return fromJson(item);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return item;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// Remove an item from local storage
|
|
208
|
+
// Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
|
|
209
|
+
var removeFromLocalStorage = function (key) {
|
|
210
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
|
211
|
+
if (!browserSupportsLocalStorage) {
|
|
212
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (notify.removeItem) {
|
|
216
|
+
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
|
|
217
|
+
}
|
|
218
|
+
return removeFromCookies(key);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
webStorage.removeItem(deriveQualifiedKey(key));
|
|
223
|
+
if (notify.removeItem) {
|
|
224
|
+
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: self.storageType});
|
|
225
|
+
}
|
|
226
|
+
} catch (e) {
|
|
227
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
|
228
|
+
return removeFromCookies(key);
|
|
229
|
+
}
|
|
230
|
+
return true;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// Return array of keys for local storage
|
|
234
|
+
// Example use: var keys = localStorageService.keys()
|
|
235
|
+
var getKeysForLocalStorage = function () {
|
|
236
|
+
|
|
237
|
+
if (!browserSupportsLocalStorage) {
|
|
238
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
var prefixLength = prefix.length;
|
|
243
|
+
var keys = [];
|
|
244
|
+
for (var key in webStorage) {
|
|
245
|
+
// Only return keys that are for this app
|
|
246
|
+
if (key.substr(0,prefixLength) === prefix) {
|
|
247
|
+
try {
|
|
248
|
+
keys.push(key.substr(prefixLength));
|
|
249
|
+
} catch (e) {
|
|
250
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return keys;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// Remove all data for this app from local storage
|
|
259
|
+
// Also optionally takes a regular expression string and removes the matching key-value pairs
|
|
260
|
+
// Example use: localStorageService.clearAll();
|
|
261
|
+
// Should be used mostly for development purposes
|
|
262
|
+
var clearAllFromLocalStorage = function (regularExpression) {
|
|
263
|
+
|
|
264
|
+
regularExpression = regularExpression || "";
|
|
265
|
+
//accounting for the '.' in the prefix when creating a regex
|
|
266
|
+
var tempPrefix = prefix.slice(0, -1);
|
|
267
|
+
var testRegex = new RegExp(tempPrefix + '.' + regularExpression);
|
|
268
|
+
|
|
269
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
|
270
|
+
if (!browserSupportsLocalStorage) {
|
|
271
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return clearAllFromCookies();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
var prefixLength = prefix.length;
|
|
278
|
+
|
|
279
|
+
for (var key in webStorage) {
|
|
280
|
+
// Only remove items that are for this app and match the regular expression
|
|
281
|
+
if (testRegex.test(key)) {
|
|
282
|
+
try {
|
|
283
|
+
removeFromLocalStorage(key.substr(prefixLength));
|
|
284
|
+
} catch (e) {
|
|
285
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
|
|
286
|
+
return clearAllFromCookies();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return true;
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// Checks the browser to see if cookies are supported
|
|
294
|
+
var browserSupportsCookies = (function() {
|
|
295
|
+
try {
|
|
296
|
+
return $window.navigator.cookieEnabled ||
|
|
297
|
+
("cookie" in $document && ($document.cookie.length > 0 ||
|
|
298
|
+
($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
|
|
299
|
+
} catch (e) {
|
|
300
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
}());
|
|
304
|
+
|
|
305
|
+
// Directly adds a value to cookies
|
|
306
|
+
// Typically used as a fallback is local storage is not available in the browser
|
|
307
|
+
// Example use: localStorageService.cookie.add('library','angular');
|
|
308
|
+
var addToCookies = function (key, value) {
|
|
309
|
+
|
|
310
|
+
if (isUndefined(value)) {
|
|
311
|
+
return false;
|
|
312
|
+
} else if(isArray(value) || isObject(value)) {
|
|
313
|
+
value = toJson(value);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (!browserSupportsCookies) {
|
|
317
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
try {
|
|
322
|
+
var expiry = '',
|
|
323
|
+
expiryDate = new Date(),
|
|
324
|
+
cookieDomain = '';
|
|
325
|
+
|
|
326
|
+
if (value === null) {
|
|
327
|
+
// Mark that the cookie has expired one day ago
|
|
328
|
+
expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
|
|
329
|
+
expiry = "; expires=" + expiryDate.toGMTString();
|
|
330
|
+
value = '';
|
|
331
|
+
} else if (cookie.expiry !== 0) {
|
|
332
|
+
expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
|
|
333
|
+
expiry = "; expires=" + expiryDate.toGMTString();
|
|
334
|
+
}
|
|
335
|
+
if (!!key) {
|
|
336
|
+
var cookiePath = "; path=" + cookie.path;
|
|
337
|
+
if(cookie.domain){
|
|
338
|
+
cookieDomain = "; domain=" + cookie.domain;
|
|
339
|
+
}
|
|
340
|
+
$document.cookie = deriveQualifiedKey(key) + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain;
|
|
341
|
+
}
|
|
342
|
+
} catch (e) {
|
|
343
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
return true;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
// Directly get a value from a cookie
|
|
350
|
+
// Example use: localStorageService.cookie.get('library'); // returns 'angular'
|
|
351
|
+
var getFromCookies = function (key) {
|
|
352
|
+
if (!browserSupportsCookies) {
|
|
353
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
var cookies = $document.cookie && $document.cookie.split(';') || [];
|
|
358
|
+
for(var i=0; i < cookies.length; i++) {
|
|
359
|
+
var thisCookie = cookies[i];
|
|
360
|
+
while (thisCookie.charAt(0) === ' ') {
|
|
361
|
+
thisCookie = thisCookie.substring(1,thisCookie.length);
|
|
362
|
+
}
|
|
363
|
+
if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) {
|
|
364
|
+
var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length))
|
|
365
|
+
try{
|
|
366
|
+
var obj = JSON.parse(storedValues);
|
|
367
|
+
return fromJson(obj)
|
|
368
|
+
}catch(e){
|
|
369
|
+
return storedValues
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return null;
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
var removeFromCookies = function (key) {
|
|
377
|
+
addToCookies(key,null);
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
var clearAllFromCookies = function () {
|
|
381
|
+
var thisCookie = null, thisKey = null;
|
|
382
|
+
var prefixLength = prefix.length;
|
|
383
|
+
var cookies = $document.cookie.split(';');
|
|
384
|
+
for(var i = 0; i < cookies.length; i++) {
|
|
385
|
+
thisCookie = cookies[i];
|
|
386
|
+
|
|
387
|
+
while (thisCookie.charAt(0) === ' ') {
|
|
388
|
+
thisCookie = thisCookie.substring(1, thisCookie.length);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
|
|
392
|
+
removeFromCookies(key);
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
var getStorageType = function() {
|
|
397
|
+
return storageType;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
// Add a listener on scope variable to save its changes to local storage
|
|
401
|
+
// Return a function which when called cancels binding
|
|
402
|
+
var bindToScope = function(scope, key, def, lsKey) {
|
|
403
|
+
lsKey = lsKey || key;
|
|
404
|
+
var value = getFromLocalStorage(lsKey);
|
|
405
|
+
|
|
406
|
+
if (value === null && isDefined(def)) {
|
|
407
|
+
value = def;
|
|
408
|
+
} else if (isObject(value) && isObject(def)) {
|
|
409
|
+
value = extend(def, value);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
$parse(key).assign(scope, value);
|
|
413
|
+
|
|
414
|
+
return scope.$watch(key, function(newVal) {
|
|
415
|
+
addToLocalStorage(lsKey, newVal);
|
|
416
|
+
}, isObject(scope[key]));
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
// Return localStorageService.length
|
|
420
|
+
// ignore keys that not owned
|
|
421
|
+
var lengthOfLocalStorage = function() {
|
|
422
|
+
var count = 0;
|
|
423
|
+
var storage = $window[storageType];
|
|
424
|
+
for(var i = 0; i < storage.length; i++) {
|
|
425
|
+
if(storage.key(i).indexOf(prefix) === 0 ) {
|
|
426
|
+
count++;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return count;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
return {
|
|
433
|
+
isSupported: browserSupportsLocalStorage,
|
|
434
|
+
getStorageType: getStorageType,
|
|
435
|
+
set: addToLocalStorage,
|
|
436
|
+
add: addToLocalStorage, //DEPRECATED
|
|
437
|
+
get: getFromLocalStorage,
|
|
438
|
+
keys: getKeysForLocalStorage,
|
|
439
|
+
remove: removeFromLocalStorage,
|
|
440
|
+
clearAll: clearAllFromLocalStorage,
|
|
441
|
+
bind: bindToScope,
|
|
442
|
+
deriveKey: deriveQualifiedKey,
|
|
443
|
+
length: lengthOfLocalStorage,
|
|
444
|
+
cookie: {
|
|
445
|
+
isSupported: browserSupportsCookies,
|
|
446
|
+
set: addToCookies,
|
|
447
|
+
add: addToCookies, //DEPRECATED
|
|
448
|
+
get: getFromCookies,
|
|
449
|
+
remove: removeFromCookies,
|
|
450
|
+
clearAll: clearAllFromCookies
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
}];
|
|
454
|
+
});
|
|
455
|
+
})( window, window.angular );
|