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.
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 );