engine2 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/Rakefile +138 -0
  4. data/conf/message.yaml +93 -0
  5. data/conf/message_pl.yaml +93 -0
  6. data/engine2.gemspec +34 -0
  7. data/lib/engine2.rb +34 -0
  8. data/lib/engine2/action.rb +217 -0
  9. data/lib/engine2/core.rb +572 -0
  10. data/lib/engine2/handler.rb +134 -0
  11. data/lib/engine2/meta.rb +969 -0
  12. data/lib/engine2/meta/decode_meta.rb +110 -0
  13. data/lib/engine2/meta/delete_meta.rb +73 -0
  14. data/lib/engine2/meta/form_meta.rb +144 -0
  15. data/lib/engine2/meta/infra_meta.rb +292 -0
  16. data/lib/engine2/meta/link_meta.rb +133 -0
  17. data/lib/engine2/meta/list_meta.rb +284 -0
  18. data/lib/engine2/meta/save_meta.rb +63 -0
  19. data/lib/engine2/meta/view_meta.rb +22 -0
  20. data/lib/engine2/model.rb +390 -0
  21. data/lib/engine2/models/Files.rb +38 -0
  22. data/lib/engine2/models/UserInfo.rb +24 -0
  23. data/lib/engine2/post_bootstrap.rb +83 -0
  24. data/lib/engine2/pre_bootstrap.rb +27 -0
  25. data/lib/engine2/scheme.rb +202 -0
  26. data/lib/engine2/templates.rb +229 -0
  27. data/lib/engine2/type_info.rb +342 -0
  28. data/lib/engine2/version.rb +9 -0
  29. data/public/assets/javascripts.js +13 -0
  30. data/public/assets/styles.css +4 -0
  31. data/public/css/angular-motion.css +1022 -0
  32. data/public/css/angular-ui-tree.min.css +1 -0
  33. data/public/css/app.css +196 -0
  34. data/public/css/bootstrap-additions.css +1560 -0
  35. data/public/css/bootstrap.min.css +11 -0
  36. data/public/css/font-awesome.min.css +4 -0
  37. data/public/favicon.ico +0 -0
  38. data/public/fonts/FontAwesome.otf +0 -0
  39. data/public/fonts/fontawesome-webfont.eot +0 -0
  40. data/public/fonts/fontawesome-webfont.svg +655 -0
  41. data/public/fonts/fontawesome-webfont.ttf +0 -0
  42. data/public/fonts/fontawesome-webfont.woff +0 -0
  43. data/public/fonts/fontawesome-webfont.woff2 +0 -0
  44. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  45. data/public/fonts/glyphicons-halflings-regular.svg +288 -0
  46. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  47. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  48. data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  49. data/public/images/file.png +0 -0
  50. data/public/images/folder-closed.png +0 -0
  51. data/public/images/folder.png +0 -0
  52. data/public/images/node-closed-2.png +0 -0
  53. data/public/images/node-closed-light.png +0 -0
  54. data/public/images/node-closed.png +0 -0
  55. data/public/images/node-opened-2.png +0 -0
  56. data/public/images/node-opened-light.png +0 -0
  57. data/public/images/node-opened.png +0 -0
  58. data/public/img/ajax-loader-dark.gif +0 -0
  59. data/public/img/ajax-loader-light.gif +0 -0
  60. data/public/img/ajax-loader.gif +0 -0
  61. data/public/js/angular-animate.js +4115 -0
  62. data/public/js/angular-cookies.js +322 -0
  63. data/public/js/angular-local-storage.js +455 -0
  64. data/public/js/angular-route.js +1022 -0
  65. data/public/js/angular-sanitize.js +717 -0
  66. data/public/js/angular-strap.js +4339 -0
  67. data/public/js/angular-strap.tpl.js +43 -0
  68. data/public/js/angular-ui-tree.js +1569 -0
  69. data/public/js/angular.js +30714 -0
  70. data/public/js/i18n/angular-locale_pl.js +115 -0
  71. data/public/js/lodash.custom.min.js +97 -0
  72. data/public/js/ng-file-upload-shim.min.js +2 -0
  73. data/public/js/ng-file-upload.min.js +3 -0
  74. data/views/app.coffee +3 -0
  75. data/views/engine2.coffee +557 -0
  76. data/views/engine2actions.coffee +849 -0
  77. data/views/engine2templates.coffee +0 -0
  78. data/views/fields/blob.slim +22 -0
  79. data/views/fields/bs_select.slim +10 -0
  80. data/views/fields/bsselect_picker.slim +18 -0
  81. data/views/fields/bsselect_picker_opt.slim +22 -0
  82. data/views/fields/checkbox.slim +11 -0
  83. data/views/fields/checkbox_buttons.slim +6 -0
  84. data/views/fields/checkbox_buttons_opt.slim +8 -0
  85. data/views/fields/currency.slim +10 -0
  86. data/views/fields/date.slim +21 -0
  87. data/views/fields/date_range.slim +44 -0
  88. data/views/fields/date_time.slim +42 -0
  89. data/views/fields/datetime.slim +42 -0
  90. data/views/fields/decimal.slim +11 -0
  91. data/views/fields/decimal_date.slim +22 -0
  92. data/views/fields/decimal_time.slim +26 -0
  93. data/views/fields/email.slim +13 -0
  94. data/views/fields/file_store.slim +61 -0
  95. data/views/fields/input_text.slim +14 -0
  96. data/views/fields/integer.slim +11 -0
  97. data/views/fields/list_bsselect.slim +18 -0
  98. data/views/fields/list_bsselect_opt.slim +21 -0
  99. data/views/fields/list_buttons.slim +3 -0
  100. data/views/fields/list_buttons_opt.slim +5 -0
  101. data/views/fields/list_select.slim +11 -0
  102. data/views/fields/list_select_opt.slim +15 -0
  103. data/views/fields/password.slim +14 -0
  104. data/views/fields/radio_checkbox.slim +10 -0
  105. data/views/fields/scaffold.slim +2 -0
  106. data/views/fields/scaffold_picker.slim +20 -0
  107. data/views/fields/select_picker.slim +12 -0
  108. data/views/fields/select_picker_opt.slim +16 -0
  109. data/views/fields/text_area.slim +10 -0
  110. data/views/fields/time.slim +22 -0
  111. data/views/fields/typeahead_picker.slim +25 -0
  112. data/views/index.slim +44 -0
  113. data/views/infra/index.slim +5 -0
  114. data/views/infra/inspect.slim +81 -0
  115. data/views/modals/close_m.slim +15 -0
  116. data/views/modals/confirm_m.slim +19 -0
  117. data/views/modals/empty_m.slim +12 -0
  118. data/views/modals/menu_m.slim +13 -0
  119. data/views/modals/yes_no_m.slim +19 -0
  120. data/views/panels/menu_m.slim +9 -0
  121. data/views/scaffold/confirm.slim +3 -0
  122. data/views/scaffold/fields.slim +10 -0
  123. data/views/scaffold/form.slim +11 -0
  124. data/views/scaffold/list.slim +42 -0
  125. data/views/scaffold/message.slim +3 -0
  126. data/views/scaffold/search.slim +20 -0
  127. data/views/scaffold/view.slim +18 -0
  128. data/views/search_fields/bsmselect_picker.slim +25 -0
  129. data/views/search_fields/bsselect_picker.slim +24 -0
  130. data/views/search_fields/checkbox.slim +11 -0
  131. data/views/search_fields/checkbox2.slim +14 -0
  132. data/views/search_fields/checkbox_buttons.slim +10 -0
  133. data/views/search_fields/date_range.slim +46 -0
  134. data/views/search_fields/decimal_date_range.slim +47 -0
  135. data/views/search_fields/input_text.slim +18 -0
  136. data/views/search_fields/integer.slim +18 -0
  137. data/views/search_fields/integer_range.slim +27 -0
  138. data/views/search_fields/list_bsmselect.slim +24 -0
  139. data/views/search_fields/list_bsselect.slim +22 -0
  140. data/views/search_fields/list_buttons.slim +8 -0
  141. data/views/search_fields/list_select.slim +17 -0
  142. data/views/search_fields/scaffold_picker.slim +19 -0
  143. data/views/search_fields/select_picker.slim +17 -0
  144. data/views/search_fields/typeahead_picker.slim +25 -0
  145. 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 );