zwr 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/controllers/.keep +0 -0
- data/app/assets/javascripts/directives/.keep +0 -0
- data/app/assets/javascripts/includes/.keep +0 -0
- data/app/assets/javascripts/includes/angular-local-storage.js +446 -0
- data/app/assets/javascripts/includes/xml2json.js +567 -0
- data/app/assets/javascripts/services/.keep +0 -0
- data/app/assets/javascripts/templates/.keep +0 -0
- data/app/assets/javascripts/templates/404.html +67 -0
- data/app/assets/javascripts/zwr.js.coffee +12 -0
- data/lib/generators/zwr/angular/directive_generator.rb +29 -0
- data/lib/generators/zwr/angular/include_generator.rb +9 -0
- data/lib/generators/zwr/angular/page_generator.rb +25 -0
- data/lib/generators/zwr/angular/service_generator.rb +30 -0
- data/lib/generators/zwr/angular/template_generator.rb +9 -0
- data/lib/zwr.rb +14 -8
- data/lib/zwr/app_template.rb +3 -2
- data/lib/zwr/templates/home.html.haml +2 -2
- data/lib/zwr/zwr_mongoid.rb +15 -0
- data/zwr.gemspec +2 -2
- metadata +16 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96c982be5d8c56abeb24702d370bfa484a0032d0
|
4
|
+
data.tar.gz: 7b28e5b299ec174bcf5280f28d123ac681038390
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5949292837a2f2650cbf5b3b9c0b63ff186c4d20fd974ee10db74680534ba4d5e39de83a69ea81b8035241d7c39fd32fe1280a52ecad295ad37f2740041008db
|
7
|
+
data.tar.gz: 50d6512c81b3303e168a254cceeec17e3748b4c2eccf783f23a63351573b4f201b0861d43c8e26b21c5f3b4bf5cedd2a3ce30a8fc36a6f4cb5639d52401228d4
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,446 @@
|
|
1
|
+
/*jshint globalstrict:true*/
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
var isDefined = angular.isDefined,
|
5
|
+
isUndefined = angular.isUndefined,
|
6
|
+
isNumber = angular.isNumber,
|
7
|
+
isObject = angular.isObject,
|
8
|
+
isArray = angular.isArray,
|
9
|
+
extend = angular.extend,
|
10
|
+
toJson = angular.toJson,
|
11
|
+
fromJson = angular.fromJson;
|
12
|
+
|
13
|
+
|
14
|
+
// Test if string is only contains numbers
|
15
|
+
// e.g '1' => true, "'1'" => true
|
16
|
+
function isStringNumber(num) {
|
17
|
+
return /^-?\d+\.?\d*$/.test(num.replace(/["']/g, ''));
|
18
|
+
}
|
19
|
+
|
20
|
+
var angularLocalStorage = angular.module('LocalStorageModule', []);
|
21
|
+
|
22
|
+
angularLocalStorage.provider('localStorageService', function() {
|
23
|
+
|
24
|
+
// You should set a prefix to avoid overwriting any local storage variables from the rest of your app
|
25
|
+
// e.g. localStorageServiceProvider.setPrefix('youAppName');
|
26
|
+
// With provider you can use config as this:
|
27
|
+
// myApp.config(function (localStorageServiceProvider) {
|
28
|
+
// localStorageServiceProvider.prefix = 'yourAppName';
|
29
|
+
// });
|
30
|
+
this.prefix = 'ls';
|
31
|
+
|
32
|
+
// You could change web storage type localstorage or sessionStorage
|
33
|
+
this.storageType = 'localStorage';
|
34
|
+
|
35
|
+
// Cookie options (usually in case of fallback)
|
36
|
+
// expiry = Number of days before cookies expire // 0 = Does not expire
|
37
|
+
// path = The web path the cookie represents
|
38
|
+
this.cookie = {
|
39
|
+
expiry: 30,
|
40
|
+
path: '/'
|
41
|
+
};
|
42
|
+
|
43
|
+
// Send signals for each of the following actions?
|
44
|
+
this.notify = {
|
45
|
+
setItem: true,
|
46
|
+
removeItem: false
|
47
|
+
};
|
48
|
+
|
49
|
+
// Setter for the prefix
|
50
|
+
this.setPrefix = function(prefix) {
|
51
|
+
this.prefix = prefix;
|
52
|
+
return this;
|
53
|
+
};
|
54
|
+
|
55
|
+
// Setter for the storageType
|
56
|
+
this.setStorageType = function(storageType) {
|
57
|
+
this.storageType = storageType;
|
58
|
+
return this;
|
59
|
+
};
|
60
|
+
|
61
|
+
// Setter for cookie config
|
62
|
+
this.setStorageCookie = function(exp, path) {
|
63
|
+
this.cookie = {
|
64
|
+
expiry: exp,
|
65
|
+
path: path
|
66
|
+
};
|
67
|
+
return this;
|
68
|
+
};
|
69
|
+
|
70
|
+
// Setter for cookie domain
|
71
|
+
this.setStorageCookieDomain = function(domain) {
|
72
|
+
this.cookie.domain = domain;
|
73
|
+
return this;
|
74
|
+
};
|
75
|
+
|
76
|
+
// Setter for notification config
|
77
|
+
// itemSet & itemRemove should be booleans
|
78
|
+
this.setNotify = function(itemSet, itemRemove) {
|
79
|
+
this.notify = {
|
80
|
+
setItem: itemSet,
|
81
|
+
removeItem: itemRemove
|
82
|
+
};
|
83
|
+
return this;
|
84
|
+
};
|
85
|
+
|
86
|
+
this.$get = ['$rootScope', '$window', '$document', '$parse', function($rootScope, $window, $document, $parse) {
|
87
|
+
var self = this;
|
88
|
+
var prefix = self.prefix;
|
89
|
+
var cookie = self.cookie;
|
90
|
+
var notify = self.notify;
|
91
|
+
var storageType = self.storageType;
|
92
|
+
var webStorage;
|
93
|
+
|
94
|
+
// When Angular's $document is not available
|
95
|
+
if (!$document) {
|
96
|
+
$document = document;
|
97
|
+
} else if ($document[0]) {
|
98
|
+
$document = $document[0];
|
99
|
+
}
|
100
|
+
|
101
|
+
// If there is a prefix set in the config lets use that with an appended period for readability
|
102
|
+
if (prefix.substr(-1) !== '.') {
|
103
|
+
prefix = !!prefix ? prefix + '.' : '';
|
104
|
+
}
|
105
|
+
var deriveQualifiedKey = function(key) {
|
106
|
+
return prefix + key;
|
107
|
+
};
|
108
|
+
// Checks the browser to see if local storage is supported
|
109
|
+
var browserSupportsLocalStorage = (function () {
|
110
|
+
try {
|
111
|
+
var supported = (storageType in $window && $window[storageType] !== null);
|
112
|
+
|
113
|
+
// When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
|
114
|
+
// is available, but trying to call .setItem throws an exception.
|
115
|
+
//
|
116
|
+
// "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
|
117
|
+
// that exceeded the quota."
|
118
|
+
var key = deriveQualifiedKey('__' + Math.round(Math.random() * 1e7));
|
119
|
+
if (supported) {
|
120
|
+
webStorage = $window[storageType];
|
121
|
+
webStorage.setItem(key, '');
|
122
|
+
webStorage.removeItem(key);
|
123
|
+
}
|
124
|
+
|
125
|
+
return supported;
|
126
|
+
} catch (e) {
|
127
|
+
storageType = 'cookie';
|
128
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
129
|
+
return false;
|
130
|
+
}
|
131
|
+
}());
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
// Directly adds a value to local storage
|
136
|
+
// If local storage is not available in the browser use cookies
|
137
|
+
// Example use: localStorageService.add('library','angular');
|
138
|
+
var addToLocalStorage = function (key, value) {
|
139
|
+
// Let's convert undefined values to null to get the value consistent
|
140
|
+
if (isUndefined(value)) {
|
141
|
+
value = null;
|
142
|
+
} else if (isObject(value) || isArray(value) || isNumber(+value || value)) {
|
143
|
+
value = toJson(value);
|
144
|
+
}
|
145
|
+
|
146
|
+
// If this browser does not support local storage use cookies
|
147
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
148
|
+
if (!browserSupportsLocalStorage) {
|
149
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
150
|
+
}
|
151
|
+
|
152
|
+
if (notify.setItem) {
|
153
|
+
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
|
154
|
+
}
|
155
|
+
return addToCookies(key, value);
|
156
|
+
}
|
157
|
+
|
158
|
+
try {
|
159
|
+
if (isObject(value) || isArray(value)) {
|
160
|
+
value = toJson(value);
|
161
|
+
}
|
162
|
+
if (webStorage) {webStorage.setItem(deriveQualifiedKey(key), value)};
|
163
|
+
if (notify.setItem) {
|
164
|
+
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType});
|
165
|
+
}
|
166
|
+
} catch (e) {
|
167
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
168
|
+
return addToCookies(key, value);
|
169
|
+
}
|
170
|
+
return true;
|
171
|
+
};
|
172
|
+
|
173
|
+
// Directly get a value from local storage
|
174
|
+
// Example use: localStorageService.get('library'); // returns 'angular'
|
175
|
+
var getFromLocalStorage = function (key) {
|
176
|
+
|
177
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
178
|
+
if (!browserSupportsLocalStorage) {
|
179
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning','LOCAL_STORAGE_NOT_SUPPORTED');
|
180
|
+
}
|
181
|
+
|
182
|
+
return getFromCookies(key);
|
183
|
+
}
|
184
|
+
|
185
|
+
var item = webStorage ? webStorage.getItem(deriveQualifiedKey(key)) : null;
|
186
|
+
// angular.toJson will convert null to 'null', so a proper conversion is needed
|
187
|
+
// FIXME not a perfect solution, since a valid 'null' string can't be stored
|
188
|
+
if (!item || item === 'null') {
|
189
|
+
return null;
|
190
|
+
}
|
191
|
+
|
192
|
+
if (item.charAt(0) === "{" || item.charAt(0) === "[" || isStringNumber(item)) {
|
193
|
+
return fromJson(item);
|
194
|
+
}
|
195
|
+
|
196
|
+
return item;
|
197
|
+
};
|
198
|
+
|
199
|
+
// Remove an item from local storage
|
200
|
+
// Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
|
201
|
+
var removeFromLocalStorage = function (key) {
|
202
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
203
|
+
if (!browserSupportsLocalStorage) {
|
204
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
205
|
+
}
|
206
|
+
|
207
|
+
if (notify.removeItem) {
|
208
|
+
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
|
209
|
+
}
|
210
|
+
return removeFromCookies(key);
|
211
|
+
}
|
212
|
+
|
213
|
+
try {
|
214
|
+
webStorage.removeItem(deriveQualifiedKey(key));
|
215
|
+
if (notify.removeItem) {
|
216
|
+
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: self.storageType});
|
217
|
+
}
|
218
|
+
} catch (e) {
|
219
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
220
|
+
return removeFromCookies(key);
|
221
|
+
}
|
222
|
+
return true;
|
223
|
+
};
|
224
|
+
|
225
|
+
// Return array of keys for local storage
|
226
|
+
// Example use: var keys = localStorageService.keys()
|
227
|
+
var getKeysForLocalStorage = function () {
|
228
|
+
|
229
|
+
if (!browserSupportsLocalStorage) {
|
230
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
231
|
+
return false;
|
232
|
+
}
|
233
|
+
|
234
|
+
var prefixLength = prefix.length;
|
235
|
+
var keys = [];
|
236
|
+
for (var key in webStorage) {
|
237
|
+
// Only return keys that are for this app
|
238
|
+
if (key.substr(0,prefixLength) === prefix) {
|
239
|
+
try {
|
240
|
+
keys.push(key.substr(prefixLength));
|
241
|
+
} catch (e) {
|
242
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
|
243
|
+
return [];
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
return keys;
|
248
|
+
};
|
249
|
+
|
250
|
+
// Remove all data for this app from local storage
|
251
|
+
// Also optionally takes a regular expression string and removes the matching key-value pairs
|
252
|
+
// Example use: localStorageService.clearAll();
|
253
|
+
// Should be used mostly for development purposes
|
254
|
+
var clearAllFromLocalStorage = function (regularExpression) {
|
255
|
+
|
256
|
+
regularExpression = regularExpression || "";
|
257
|
+
//accounting for the '.' in the prefix when creating a regex
|
258
|
+
var tempPrefix = prefix.slice(0, -1);
|
259
|
+
var testRegex = new RegExp(tempPrefix + '.' + regularExpression);
|
260
|
+
|
261
|
+
if (!browserSupportsLocalStorage || self.storageType === 'cookie') {
|
262
|
+
if (!browserSupportsLocalStorage) {
|
263
|
+
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
264
|
+
}
|
265
|
+
|
266
|
+
return clearAllFromCookies();
|
267
|
+
}
|
268
|
+
|
269
|
+
var prefixLength = prefix.length;
|
270
|
+
|
271
|
+
for (var key in webStorage) {
|
272
|
+
// Only remove items that are for this app and match the regular expression
|
273
|
+
if (testRegex.test(key)) {
|
274
|
+
try {
|
275
|
+
removeFromLocalStorage(key.substr(prefixLength));
|
276
|
+
} catch (e) {
|
277
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
|
278
|
+
return clearAllFromCookies();
|
279
|
+
}
|
280
|
+
}
|
281
|
+
}
|
282
|
+
return true;
|
283
|
+
};
|
284
|
+
|
285
|
+
// Checks the browser to see if cookies are supported
|
286
|
+
var browserSupportsCookies = (function() {
|
287
|
+
try {
|
288
|
+
return $window.navigator.cookieEnabled ||
|
289
|
+
("cookie" in $document && ($document.cookie.length > 0 ||
|
290
|
+
($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
|
291
|
+
} catch (e) {
|
292
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
293
|
+
return false;
|
294
|
+
}
|
295
|
+
}());
|
296
|
+
|
297
|
+
// Directly adds a value to cookies
|
298
|
+
// Typically used as a fallback is local storage is not available in the browser
|
299
|
+
// Example use: localStorageService.cookie.add('library','angular');
|
300
|
+
var addToCookies = function (key, value) {
|
301
|
+
|
302
|
+
if (isUndefined(value)) {
|
303
|
+
return false;
|
304
|
+
} else if(isArray(value) || isObject(value)) {
|
305
|
+
value = toJson(value);
|
306
|
+
}
|
307
|
+
|
308
|
+
if (!browserSupportsCookies) {
|
309
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
310
|
+
return false;
|
311
|
+
}
|
312
|
+
|
313
|
+
try {
|
314
|
+
var expiry = '',
|
315
|
+
expiryDate = new Date(),
|
316
|
+
cookieDomain = '';
|
317
|
+
|
318
|
+
if (value === null) {
|
319
|
+
// Mark that the cookie has expired one day ago
|
320
|
+
expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
|
321
|
+
expiry = "; expires=" + expiryDate.toGMTString();
|
322
|
+
value = '';
|
323
|
+
} else if (cookie.expiry !== 0) {
|
324
|
+
expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
|
325
|
+
expiry = "; expires=" + expiryDate.toGMTString();
|
326
|
+
}
|
327
|
+
if (!!key) {
|
328
|
+
var cookiePath = "; path=" + cookie.path;
|
329
|
+
if(cookie.domain){
|
330
|
+
cookieDomain = "; domain=" + cookie.domain;
|
331
|
+
}
|
332
|
+
$document.cookie = deriveQualifiedKey(key) + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain;
|
333
|
+
}
|
334
|
+
} catch (e) {
|
335
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error',e.message);
|
336
|
+
return false;
|
337
|
+
}
|
338
|
+
return true;
|
339
|
+
};
|
340
|
+
|
341
|
+
// Directly get a value from a cookie
|
342
|
+
// Example use: localStorageService.cookie.get('library'); // returns 'angular'
|
343
|
+
var getFromCookies = function (key) {
|
344
|
+
if (!browserSupportsCookies) {
|
345
|
+
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
346
|
+
return false;
|
347
|
+
}
|
348
|
+
|
349
|
+
var cookies = $document.cookie && $document.cookie.split(';') || [];
|
350
|
+
for(var i=0; i < cookies.length; i++) {
|
351
|
+
var thisCookie = cookies[i];
|
352
|
+
while (thisCookie.charAt(0) === ' ') {
|
353
|
+
thisCookie = thisCookie.substring(1,thisCookie.length);
|
354
|
+
}
|
355
|
+
if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) {
|
356
|
+
var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length))
|
357
|
+
try{
|
358
|
+
var obj = JSON.parse(storedValues);
|
359
|
+
return fromJson(obj)
|
360
|
+
}catch(e){
|
361
|
+
return storedValues
|
362
|
+
}
|
363
|
+
}
|
364
|
+
}
|
365
|
+
return null;
|
366
|
+
};
|
367
|
+
|
368
|
+
var removeFromCookies = function (key) {
|
369
|
+
addToCookies(key,null);
|
370
|
+
};
|
371
|
+
|
372
|
+
var clearAllFromCookies = function () {
|
373
|
+
var thisCookie = null, thisKey = null;
|
374
|
+
var prefixLength = prefix.length;
|
375
|
+
var cookies = $document.cookie.split(';');
|
376
|
+
for(var i = 0; i < cookies.length; i++) {
|
377
|
+
thisCookie = cookies[i];
|
378
|
+
|
379
|
+
while (thisCookie.charAt(0) === ' ') {
|
380
|
+
thisCookie = thisCookie.substring(1, thisCookie.length);
|
381
|
+
}
|
382
|
+
|
383
|
+
var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
|
384
|
+
removeFromCookies(key);
|
385
|
+
}
|
386
|
+
};
|
387
|
+
|
388
|
+
var getStorageType = function() {
|
389
|
+
return storageType;
|
390
|
+
};
|
391
|
+
|
392
|
+
// Add a listener on scope variable to save its changes to local storage
|
393
|
+
// Return a function which when called cancels binding
|
394
|
+
var bindToScope = function(scope, key, def, lsKey) {
|
395
|
+
lsKey = lsKey || key;
|
396
|
+
var value = getFromLocalStorage(lsKey);
|
397
|
+
|
398
|
+
if (value === null && isDefined(def)) {
|
399
|
+
value = def;
|
400
|
+
} else if (isObject(value) && isObject(def)) {
|
401
|
+
value = extend(def, value);
|
402
|
+
}
|
403
|
+
|
404
|
+
$parse(key).assign(scope, value);
|
405
|
+
|
406
|
+
return scope.$watch(key, function(newVal) {
|
407
|
+
addToLocalStorage(lsKey, newVal);
|
408
|
+
}, isObject(scope[key]));
|
409
|
+
};
|
410
|
+
|
411
|
+
// Return localStorageService.length
|
412
|
+
// ignore keys that not owned
|
413
|
+
var lengthOfLocalStorage = function() {
|
414
|
+
var count = 0;
|
415
|
+
var storage = $window[storageType];
|
416
|
+
for(var i = 0; i < storage.length; i++) {
|
417
|
+
if(storage.key(i).indexOf(prefix) === 0 ) {
|
418
|
+
count++;
|
419
|
+
}
|
420
|
+
}
|
421
|
+
return count;
|
422
|
+
};
|
423
|
+
|
424
|
+
return {
|
425
|
+
isSupported: browserSupportsLocalStorage,
|
426
|
+
getStorageType: getStorageType,
|
427
|
+
set: addToLocalStorage,
|
428
|
+
add: addToLocalStorage, //DEPRECATED
|
429
|
+
get: getFromLocalStorage,
|
430
|
+
keys: getKeysForLocalStorage,
|
431
|
+
remove: removeFromLocalStorage,
|
432
|
+
clearAll: clearAllFromLocalStorage,
|
433
|
+
bind: bindToScope,
|
434
|
+
deriveKey: deriveQualifiedKey,
|
435
|
+
length: lengthOfLocalStorage,
|
436
|
+
cookie: {
|
437
|
+
isSupported: browserSupportsCookies,
|
438
|
+
set: addToCookies,
|
439
|
+
add: addToCookies, //DEPRECATED
|
440
|
+
get: getFromCookies,
|
441
|
+
remove: removeFromCookies,
|
442
|
+
clearAll: clearAllFromCookies
|
443
|
+
}
|
444
|
+
};
|
445
|
+
}];
|
446
|
+
});
|
@@ -0,0 +1,567 @@
|
|
1
|
+
/*
|
2
|
+
Copyright 2011-2013 Abdulla Abdurakhmanov
|
3
|
+
Original sources are available at https://code.google.com/p/x2js/
|
4
|
+
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
you may not use this file except in compliance with the License.
|
7
|
+
You may obtain a copy of the License at
|
8
|
+
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
See the License for the specific language governing permissions and
|
15
|
+
limitations under the License.
|
16
|
+
*/
|
17
|
+
|
18
|
+
function X2JS(config) {
|
19
|
+
'use strict';
|
20
|
+
|
21
|
+
var VERSION = "1.1.5";
|
22
|
+
|
23
|
+
config = config || {};
|
24
|
+
initConfigDefaults();
|
25
|
+
initRequiredPolyfills();
|
26
|
+
|
27
|
+
function initConfigDefaults() {
|
28
|
+
if(config.escapeMode === undefined) {
|
29
|
+
config.escapeMode = true;
|
30
|
+
}
|
31
|
+
config.attributePrefix = config.attributePrefix || "_";
|
32
|
+
config.arrayAccessForm = config.arrayAccessForm || "none";
|
33
|
+
config.emptyNodeForm = config.emptyNodeForm || "text";
|
34
|
+
if(config.enableToStringFunc === undefined) {
|
35
|
+
config.enableToStringFunc = true;
|
36
|
+
}
|
37
|
+
config.arrayAccessFormPaths = config.arrayAccessFormPaths || [];
|
38
|
+
if(config.skipEmptyTextNodesForObj === undefined) {
|
39
|
+
config.skipEmptyTextNodesForObj = true;
|
40
|
+
}
|
41
|
+
if(config.stripWhitespaces === undefined) {
|
42
|
+
config.stripWhitespaces = true;
|
43
|
+
}
|
44
|
+
config.datetimeAccessFormPaths = config.datetimeAccessFormPaths || [];
|
45
|
+
}
|
46
|
+
|
47
|
+
var DOMNodeTypes = {
|
48
|
+
ELEMENT_NODE : 1,
|
49
|
+
TEXT_NODE : 3,
|
50
|
+
CDATA_SECTION_NODE : 4,
|
51
|
+
COMMENT_NODE : 8,
|
52
|
+
DOCUMENT_NODE : 9
|
53
|
+
};
|
54
|
+
|
55
|
+
function initRequiredPolyfills() {
|
56
|
+
function pad(number) {
|
57
|
+
var r = String(number);
|
58
|
+
if ( r.length === 1 ) {
|
59
|
+
r = '0' + r;
|
60
|
+
}
|
61
|
+
return r;
|
62
|
+
}
|
63
|
+
// Hello IE8-
|
64
|
+
if(typeof String.prototype.trim !== 'function') {
|
65
|
+
String.prototype.trim = function() {
|
66
|
+
return this.replace(/^\s+|^\n+|(\s|\n)+$/g, '');
|
67
|
+
}
|
68
|
+
}
|
69
|
+
if(typeof Date.prototype.toISOString !== 'function') {
|
70
|
+
// Implementation from http://stackoverflow.com/questions/2573521/how-do-i-output-an-iso-8601-formatted-string-in-javascript
|
71
|
+
Date.prototype.toISOString = function() {
|
72
|
+
return this.getUTCFullYear()
|
73
|
+
+ '-' + pad( this.getUTCMonth() + 1 )
|
74
|
+
+ '-' + pad( this.getUTCDate() )
|
75
|
+
+ 'T' + pad( this.getUTCHours() )
|
76
|
+
+ ':' + pad( this.getUTCMinutes() )
|
77
|
+
+ ':' + pad( this.getUTCSeconds() )
|
78
|
+
+ '.' + String( (this.getUTCMilliseconds()/1000).toFixed(3) ).slice( 2, 5 )
|
79
|
+
+ 'Z';
|
80
|
+
};
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
function getNodeLocalName( node ) {
|
85
|
+
var nodeLocalName = node.localName;
|
86
|
+
if(nodeLocalName == null) // Yeah, this is IE!!
|
87
|
+
nodeLocalName = node.baseName;
|
88
|
+
if(nodeLocalName == null || nodeLocalName=="") // =="" is IE too
|
89
|
+
nodeLocalName = node.nodeName;
|
90
|
+
return nodeLocalName;
|
91
|
+
}
|
92
|
+
|
93
|
+
function getNodePrefix(node) {
|
94
|
+
return node.prefix;
|
95
|
+
}
|
96
|
+
|
97
|
+
function escapeXmlChars(str) {
|
98
|
+
if(typeof(str) == "string")
|
99
|
+
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/');
|
100
|
+
else
|
101
|
+
return str;
|
102
|
+
}
|
103
|
+
|
104
|
+
function unescapeXmlChars(str) {
|
105
|
+
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(///g, '\/');
|
106
|
+
}
|
107
|
+
|
108
|
+
function toArrayAccessForm(obj, childName, path) {
|
109
|
+
switch(config.arrayAccessForm) {
|
110
|
+
case "property":
|
111
|
+
if(!(obj[childName] instanceof Array))
|
112
|
+
obj[childName+"_asArray"] = [obj[childName]];
|
113
|
+
else
|
114
|
+
obj[childName+"_asArray"] = obj[childName];
|
115
|
+
break;
|
116
|
+
/*case "none":
|
117
|
+
break;*/
|
118
|
+
}
|
119
|
+
|
120
|
+
if(!(obj[childName] instanceof Array) && config.arrayAccessFormPaths.length > 0) {
|
121
|
+
var idx = 0;
|
122
|
+
for(; idx < config.arrayAccessFormPaths.length; idx++) {
|
123
|
+
var arrayPath = config.arrayAccessFormPaths[idx];
|
124
|
+
if( typeof arrayPath === "string" ) {
|
125
|
+
if(arrayPath == path)
|
126
|
+
break;
|
127
|
+
}
|
128
|
+
else
|
129
|
+
if( arrayPath instanceof RegExp) {
|
130
|
+
if(arrayPath.test(path))
|
131
|
+
break;
|
132
|
+
}
|
133
|
+
else
|
134
|
+
if( typeof arrayPath === "function") {
|
135
|
+
if(arrayPath(obj, childName, path))
|
136
|
+
break;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
if(idx!=config.arrayAccessFormPaths.length) {
|
140
|
+
obj[childName] = [obj[childName]];
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
function fromXmlDateTime(prop) {
|
146
|
+
// Implementation based up on http://stackoverflow.com/questions/8178598/xml-datetime-to-javascript-date-object
|
147
|
+
// Improved to support full spec and optional parts
|
148
|
+
var bits = prop.split(/[-T:+Z]/g);
|
149
|
+
|
150
|
+
var d = new Date(bits[0], bits[1]-1, bits[2]);
|
151
|
+
var secondBits = bits[5].split("\.");
|
152
|
+
d.setHours(bits[3], bits[4], secondBits[0]);
|
153
|
+
if(secondBits.length>1)
|
154
|
+
d.setMilliseconds(secondBits[1]);
|
155
|
+
|
156
|
+
// Get supplied time zone offset in minutes
|
157
|
+
if(bits[6] && bits[7]) {
|
158
|
+
var offsetMinutes = bits[6] * 60 + Number(bits[7]);
|
159
|
+
var sign = /\d\d-\d\d:\d\d$/.test(prop)? '-' : '+';
|
160
|
+
|
161
|
+
// Apply the sign
|
162
|
+
offsetMinutes = 0 + (sign == '-'? -1 * offsetMinutes : offsetMinutes);
|
163
|
+
|
164
|
+
// Apply offset and local timezone
|
165
|
+
d.setMinutes(d.getMinutes() - offsetMinutes - d.getTimezoneOffset())
|
166
|
+
}
|
167
|
+
else
|
168
|
+
if(prop.indexOf("Z", prop.length - 1) !== -1) {
|
169
|
+
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()));
|
170
|
+
}
|
171
|
+
|
172
|
+
// d is now a local time equivalent to the supplied time
|
173
|
+
return d;
|
174
|
+
}
|
175
|
+
|
176
|
+
function checkFromXmlDateTimePaths(value, childName, fullPath) {
|
177
|
+
if(config.datetimeAccessFormPaths.length > 0) {
|
178
|
+
var path = fullPath.split("\.#")[0];
|
179
|
+
var idx = 0;
|
180
|
+
for(; idx < config.datetimeAccessFormPaths.length; idx++) {
|
181
|
+
var dtPath = config.datetimeAccessFormPaths[idx];
|
182
|
+
if( typeof dtPath === "string" ) {
|
183
|
+
if(dtPath == path)
|
184
|
+
break;
|
185
|
+
}
|
186
|
+
else
|
187
|
+
if( dtPath instanceof RegExp) {
|
188
|
+
if(dtPath.test(path))
|
189
|
+
break;
|
190
|
+
}
|
191
|
+
else
|
192
|
+
if( typeof dtPath === "function") {
|
193
|
+
if(dtPath(obj, childName, path))
|
194
|
+
break;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
if(idx!=config.datetimeAccessFormPaths.length) {
|
198
|
+
return fromXmlDateTime(value);
|
199
|
+
}
|
200
|
+
else
|
201
|
+
return value;
|
202
|
+
}
|
203
|
+
else
|
204
|
+
return value;
|
205
|
+
}
|
206
|
+
|
207
|
+
function parseDOMChildren( node, path ) {
|
208
|
+
if(node.nodeType == DOMNodeTypes.DOCUMENT_NODE) {
|
209
|
+
var result = new Object;
|
210
|
+
var nodeChildren = node.childNodes;
|
211
|
+
// Alternative for firstElementChild which is not supported in some environments
|
212
|
+
for(var cidx=0; cidx <nodeChildren.length; cidx++) {
|
213
|
+
var child = nodeChildren.item(cidx);
|
214
|
+
if(child.nodeType == DOMNodeTypes.ELEMENT_NODE) {
|
215
|
+
var childName = getNodeLocalName(child);
|
216
|
+
result[childName] = parseDOMChildren(child, childName);
|
217
|
+
}
|
218
|
+
}
|
219
|
+
return result;
|
220
|
+
}
|
221
|
+
else
|
222
|
+
if(node.nodeType == DOMNodeTypes.ELEMENT_NODE) {
|
223
|
+
var result = new Object;
|
224
|
+
result.__cnt=0;
|
225
|
+
|
226
|
+
var nodeChildren = node.childNodes;
|
227
|
+
|
228
|
+
// Children nodes
|
229
|
+
for(var cidx=0; cidx <nodeChildren.length; cidx++) {
|
230
|
+
var child = nodeChildren.item(cidx); // nodeChildren[cidx];
|
231
|
+
var childName = getNodeLocalName(child);
|
232
|
+
|
233
|
+
if(child.nodeType!= DOMNodeTypes.COMMENT_NODE) {
|
234
|
+
result.__cnt++;
|
235
|
+
if(result[childName] == null) {
|
236
|
+
result[childName] = parseDOMChildren(child, path+"."+childName);
|
237
|
+
toArrayAccessForm(result, childName, path+"."+childName);
|
238
|
+
}
|
239
|
+
else {
|
240
|
+
if(result[childName] != null) {
|
241
|
+
if( !(result[childName] instanceof Array)) {
|
242
|
+
result[childName] = [result[childName]];
|
243
|
+
toArrayAccessForm(result, childName, path+"."+childName);
|
244
|
+
}
|
245
|
+
}
|
246
|
+
(result[childName])[result[childName].length] = parseDOMChildren(child, path+"."+childName);
|
247
|
+
}
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
// Attributes
|
252
|
+
for(var aidx=0; aidx <node.attributes.length; aidx++) {
|
253
|
+
var attr = node.attributes.item(aidx); // [aidx];
|
254
|
+
result.__cnt++;
|
255
|
+
result[config.attributePrefix+attr.name]=attr.value;
|
256
|
+
}
|
257
|
+
|
258
|
+
// Node namespace prefix
|
259
|
+
var nodePrefix = getNodePrefix(node);
|
260
|
+
if(nodePrefix!=null && nodePrefix!="") {
|
261
|
+
result.__cnt++;
|
262
|
+
result.__prefix=nodePrefix;
|
263
|
+
}
|
264
|
+
|
265
|
+
if(result["#text"]!=null) {
|
266
|
+
result.__text = result["#text"];
|
267
|
+
if(result.__text instanceof Array) {
|
268
|
+
result.__text = result.__text.join("\n");
|
269
|
+
}
|
270
|
+
if(config.escapeMode)
|
271
|
+
result.__text = unescapeXmlChars(result.__text);
|
272
|
+
if(config.stripWhitespaces)
|
273
|
+
result.__text = result.__text.trim();
|
274
|
+
delete result["#text"];
|
275
|
+
if(config.arrayAccessForm=="property")
|
276
|
+
delete result["#text_asArray"];
|
277
|
+
result.__text = checkFromXmlDateTimePaths(result.__text, childName, path+"."+childName);
|
278
|
+
}
|
279
|
+
if(result["#cdata-section"]!=null) {
|
280
|
+
result.__cdata = result["#cdata-section"];
|
281
|
+
delete result["#cdata-section"];
|
282
|
+
if(config.arrayAccessForm=="property")
|
283
|
+
delete result["#cdata-section_asArray"];
|
284
|
+
}
|
285
|
+
|
286
|
+
if( result.__cnt == 1 && result.__text!=null ) {
|
287
|
+
result = result.__text;
|
288
|
+
}
|
289
|
+
else
|
290
|
+
if( result.__cnt == 0 && config.emptyNodeForm=="text" ) {
|
291
|
+
result = '';
|
292
|
+
}
|
293
|
+
else
|
294
|
+
if ( result.__cnt > 1 && result.__text!=null && config.skipEmptyTextNodesForObj) {
|
295
|
+
if( (config.stripWhitespaces && result.__text=="") || (result.__text.trim()=="")) {
|
296
|
+
delete result.__text;
|
297
|
+
}
|
298
|
+
}
|
299
|
+
delete result.__cnt;
|
300
|
+
|
301
|
+
if( config.enableToStringFunc && (result.__text!=null || result.__cdata!=null )) {
|
302
|
+
result.toString = function() {
|
303
|
+
return (this.__text!=null? this.__text:'')+( this.__cdata!=null ? this.__cdata:'');
|
304
|
+
};
|
305
|
+
}
|
306
|
+
|
307
|
+
return result;
|
308
|
+
}
|
309
|
+
else
|
310
|
+
if(node.nodeType == DOMNodeTypes.TEXT_NODE || node.nodeType == DOMNodeTypes.CDATA_SECTION_NODE) {
|
311
|
+
return node.nodeValue;
|
312
|
+
}
|
313
|
+
}
|
314
|
+
|
315
|
+
function startTag(jsonObj, element, attrList, closed) {
|
316
|
+
var resultStr = "<"+ ( (jsonObj!=null && jsonObj.__prefix!=null)? (jsonObj.__prefix+":"):"") + element;
|
317
|
+
if(attrList!=null) {
|
318
|
+
for(var aidx = 0; aidx < attrList.length; aidx++) {
|
319
|
+
var attrName = attrList[aidx];
|
320
|
+
var attrVal = jsonObj[attrName];
|
321
|
+
if(config.escapeMode)
|
322
|
+
attrVal=escapeXmlChars(attrVal);
|
323
|
+
resultStr+=" "+attrName.substr(config.attributePrefix.length)+"='"+attrVal+"'";
|
324
|
+
}
|
325
|
+
}
|
326
|
+
if(!closed)
|
327
|
+
resultStr+=">";
|
328
|
+
else
|
329
|
+
resultStr+="/>";
|
330
|
+
return resultStr;
|
331
|
+
}
|
332
|
+
|
333
|
+
function endTag(jsonObj,elementName) {
|
334
|
+
return "</"+ (jsonObj.__prefix!=null? (jsonObj.__prefix+":"):"")+elementName+">";
|
335
|
+
}
|
336
|
+
|
337
|
+
function endsWith(str, suffix) {
|
338
|
+
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
339
|
+
}
|
340
|
+
|
341
|
+
function jsonXmlSpecialElem ( jsonObj, jsonObjField ) {
|
342
|
+
if((config.arrayAccessForm=="property" && endsWith(jsonObjField.toString(),("_asArray")))
|
343
|
+
|| jsonObjField.toString().indexOf(config.attributePrefix)==0
|
344
|
+
|| jsonObjField.toString().indexOf("__")==0
|
345
|
+
|| (jsonObj[jsonObjField] instanceof Function) )
|
346
|
+
return true;
|
347
|
+
else
|
348
|
+
return false;
|
349
|
+
}
|
350
|
+
|
351
|
+
function jsonXmlElemCount ( jsonObj ) {
|
352
|
+
var elementsCnt = 0;
|
353
|
+
if(jsonObj instanceof Object ) {
|
354
|
+
for( var it in jsonObj ) {
|
355
|
+
if(jsonXmlSpecialElem ( jsonObj, it) )
|
356
|
+
continue;
|
357
|
+
elementsCnt++;
|
358
|
+
}
|
359
|
+
}
|
360
|
+
return elementsCnt;
|
361
|
+
}
|
362
|
+
|
363
|
+
function parseJSONAttributes ( jsonObj ) {
|
364
|
+
var attrList = [];
|
365
|
+
if(jsonObj instanceof Object ) {
|
366
|
+
for( var ait in jsonObj ) {
|
367
|
+
if(ait.toString().indexOf("__")== -1 && ait.toString().indexOf(config.attributePrefix)==0) {
|
368
|
+
attrList.push(ait);
|
369
|
+
}
|
370
|
+
}
|
371
|
+
}
|
372
|
+
return attrList;
|
373
|
+
}
|
374
|
+
|
375
|
+
function parseJSONTextAttrs ( jsonTxtObj ) {
|
376
|
+
var result ="";
|
377
|
+
|
378
|
+
if(jsonTxtObj.__cdata!=null) {
|
379
|
+
result+="<![CDATA["+jsonTxtObj.__cdata+"]]>";
|
380
|
+
}
|
381
|
+
|
382
|
+
if(jsonTxtObj.__text!=null) {
|
383
|
+
if(config.escapeMode)
|
384
|
+
result+=escapeXmlChars(jsonTxtObj.__text);
|
385
|
+
else
|
386
|
+
result+=jsonTxtObj.__text;
|
387
|
+
}
|
388
|
+
return result;
|
389
|
+
}
|
390
|
+
|
391
|
+
function parseJSONTextObject ( jsonTxtObj ) {
|
392
|
+
var result ="";
|
393
|
+
|
394
|
+
if( jsonTxtObj instanceof Object ) {
|
395
|
+
result+=parseJSONTextAttrs ( jsonTxtObj );
|
396
|
+
}
|
397
|
+
else
|
398
|
+
if(jsonTxtObj!=null) {
|
399
|
+
if(config.escapeMode)
|
400
|
+
result+=escapeXmlChars(jsonTxtObj);
|
401
|
+
else
|
402
|
+
result+=jsonTxtObj;
|
403
|
+
}
|
404
|
+
|
405
|
+
return result;
|
406
|
+
}
|
407
|
+
|
408
|
+
function parseJSONArray ( jsonArrRoot, jsonArrObj, attrList ) {
|
409
|
+
var result = "";
|
410
|
+
if(jsonArrRoot.length == 0) {
|
411
|
+
result+=startTag(jsonArrRoot, jsonArrObj, attrList, true);
|
412
|
+
}
|
413
|
+
else {
|
414
|
+
for(var arIdx = 0; arIdx < jsonArrRoot.length; arIdx++) {
|
415
|
+
result+=startTag(jsonArrRoot[arIdx], jsonArrObj, parseJSONAttributes(jsonArrRoot[arIdx]), false);
|
416
|
+
result+=parseJSONObject(jsonArrRoot[arIdx]);
|
417
|
+
result+=endTag(jsonArrRoot[arIdx],jsonArrObj);
|
418
|
+
}
|
419
|
+
}
|
420
|
+
return result;
|
421
|
+
}
|
422
|
+
|
423
|
+
function parseJSONObject ( jsonObj ) {
|
424
|
+
var result = "";
|
425
|
+
|
426
|
+
var elementsCnt = jsonXmlElemCount ( jsonObj );
|
427
|
+
|
428
|
+
if(elementsCnt > 0) {
|
429
|
+
for( var it in jsonObj ) {
|
430
|
+
|
431
|
+
if(jsonXmlSpecialElem ( jsonObj, it) )
|
432
|
+
continue;
|
433
|
+
|
434
|
+
var subObj = jsonObj[it];
|
435
|
+
|
436
|
+
var attrList = parseJSONAttributes( subObj )
|
437
|
+
|
438
|
+
if(subObj == null || subObj == undefined) {
|
439
|
+
result+=startTag(subObj, it, attrList, true);
|
440
|
+
}
|
441
|
+
else
|
442
|
+
if(subObj instanceof Object) {
|
443
|
+
|
444
|
+
if(subObj instanceof Array) {
|
445
|
+
result+=parseJSONArray( subObj, it, attrList );
|
446
|
+
}
|
447
|
+
else if(subObj instanceof Date) {
|
448
|
+
result+=startTag(subObj, it, attrList, false);
|
449
|
+
result+=subObj.toISOString();
|
450
|
+
result+=endTag(subObj,it);
|
451
|
+
}
|
452
|
+
else {
|
453
|
+
var subObjElementsCnt = jsonXmlElemCount ( subObj );
|
454
|
+
if(subObjElementsCnt > 0 || subObj.__text!=null || subObj.__cdata!=null) {
|
455
|
+
result+=startTag(subObj, it, attrList, false);
|
456
|
+
result+=parseJSONObject(subObj);
|
457
|
+
result+=endTag(subObj,it);
|
458
|
+
}
|
459
|
+
else {
|
460
|
+
result+=startTag(subObj, it, attrList, true);
|
461
|
+
}
|
462
|
+
}
|
463
|
+
}
|
464
|
+
else {
|
465
|
+
result+=startTag(subObj, it, attrList, false);
|
466
|
+
result+=parseJSONTextObject(subObj);
|
467
|
+
result+=endTag(subObj,it);
|
468
|
+
}
|
469
|
+
}
|
470
|
+
}
|
471
|
+
result+=parseJSONTextObject(jsonObj);
|
472
|
+
|
473
|
+
return result;
|
474
|
+
}
|
475
|
+
|
476
|
+
this.parseXmlString = function(xmlDocStr) {
|
477
|
+
var isIEParser = window.ActiveXObject || "ActiveXObject" in window;
|
478
|
+
if (xmlDocStr === undefined) {
|
479
|
+
return null;
|
480
|
+
}
|
481
|
+
var xmlDoc;
|
482
|
+
if (window.DOMParser) {
|
483
|
+
var parser=new window.DOMParser();
|
484
|
+
var parsererrorNS = null;
|
485
|
+
// IE9+ now is here
|
486
|
+
if(!isIEParser) {
|
487
|
+
try {
|
488
|
+
parsererrorNS = parser.parseFromString("INVALID", "text/xml").childNodes[0].namespaceURI;
|
489
|
+
}
|
490
|
+
catch(err) {
|
491
|
+
parsererrorNS = null;
|
492
|
+
}
|
493
|
+
}
|
494
|
+
try {
|
495
|
+
xmlDoc = parser.parseFromString( xmlDocStr, "text/xml" );
|
496
|
+
if( parsererrorNS!= null && xmlDoc.getElementsByTagNameNS(parsererrorNS, "parsererror").length > 0) {
|
497
|
+
//throw new Error('Error parsing XML: '+xmlDocStr);
|
498
|
+
xmlDoc = null;
|
499
|
+
}
|
500
|
+
}
|
501
|
+
catch(err) {
|
502
|
+
xmlDoc = null;
|
503
|
+
}
|
504
|
+
}
|
505
|
+
else {
|
506
|
+
// IE :(
|
507
|
+
if(xmlDocStr.indexOf("<?")==0) {
|
508
|
+
xmlDocStr = xmlDocStr.substr( xmlDocStr.indexOf("?>") + 2 );
|
509
|
+
}
|
510
|
+
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
|
511
|
+
xmlDoc.async="false";
|
512
|
+
xmlDoc.loadXML(xmlDocStr);
|
513
|
+
}
|
514
|
+
return xmlDoc;
|
515
|
+
};
|
516
|
+
|
517
|
+
this.asArray = function(prop) {
|
518
|
+
if(prop instanceof Array)
|
519
|
+
return prop;
|
520
|
+
else
|
521
|
+
return [prop];
|
522
|
+
};
|
523
|
+
|
524
|
+
this.toXmlDateTime = function(dt) {
|
525
|
+
if(dt instanceof Date)
|
526
|
+
return dt.toISOString();
|
527
|
+
else
|
528
|
+
if(typeof(dt) === 'number' )
|
529
|
+
return new Date(dt).toISOString();
|
530
|
+
else
|
531
|
+
return null;
|
532
|
+
};
|
533
|
+
|
534
|
+
this.asDateTime = function(prop) {
|
535
|
+
if(typeof(prop) == "string") {
|
536
|
+
return fromXmlDateTime(prop);
|
537
|
+
}
|
538
|
+
else
|
539
|
+
return prop;
|
540
|
+
};
|
541
|
+
|
542
|
+
this.xml2json = function (xmlDoc) {
|
543
|
+
return parseDOMChildren ( xmlDoc );
|
544
|
+
};
|
545
|
+
|
546
|
+
this.xml_str2json = function (xmlDocStr) {
|
547
|
+
var xmlDoc = this.parseXmlString(xmlDocStr);
|
548
|
+
if(xmlDoc!=null)
|
549
|
+
return this.xml2json(xmlDoc);
|
550
|
+
else
|
551
|
+
return null;
|
552
|
+
};
|
553
|
+
|
554
|
+
this.json2xml_str = function (jsonObj) {
|
555
|
+
return parseJSONObject ( jsonObj );
|
556
|
+
};
|
557
|
+
|
558
|
+
this.json2xml = function (jsonObj) {
|
559
|
+
var xmlDocStr = this.json2xml_str (jsonObj);
|
560
|
+
return this.parseXmlString(xmlDocStr);
|
561
|
+
};
|
562
|
+
|
563
|
+
this.getVersion = function () {
|
564
|
+
return VERSION;
|
565
|
+
};
|
566
|
+
|
567
|
+
}
|
File without changes
|
File without changes
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/404.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#= require angular
|
2
|
+
#= require angular-rails-templates
|
3
|
+
#= require_tree ./templates
|
4
|
+
#= require_tree ./includes
|
5
|
+
#= require_self
|
6
|
+
#= require_tree ./directives
|
7
|
+
#= require_tree ./services
|
8
|
+
#= require_tree ./controllers
|
9
|
+
|
10
|
+
@zt_module = angular.module('zt', [
|
11
|
+
'templates',
|
12
|
+
])
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Zwr
|
2
|
+
module Angular
|
3
|
+
class DirectiveGenerator < Rails::Generators::NamedBase
|
4
|
+
def copy_files
|
5
|
+
ang_file_name = file_name.gsub("_","-")
|
6
|
+
dir_class = file_name.gsub("-","_").camelize(:lower)
|
7
|
+
create_file "app/assets/javascripts/directives/#{ang_file_name}.js.coffee", <<-FILE.strip_heredoc
|
8
|
+
@#{application_name}.directive '#{dir_class}', ->
|
9
|
+
ret =
|
10
|
+
restrict: 'AE' # also possible class C
|
11
|
+
transclude: true # set to false if ignoring content
|
12
|
+
scope:
|
13
|
+
cmd: '&#{dir_class}' # isolate scope of a function, passed as a value
|
14
|
+
# of the attribute with the name of the directive
|
15
|
+
disabled: '=' # isolate scope of a model (both ways), passed with an
|
16
|
+
# attribute disabled="XXX", where XXX is a variable of
|
17
|
+
# the scope
|
18
|
+
glyph: '@' # isolate scope of a variable (in only), passed with
|
19
|
+
# an attribute disabled="123"
|
20
|
+
templateUrl: "#{ang_file_name}.html"
|
21
|
+
FILE
|
22
|
+
create_file "app/assets/javascripts/templates/#{ang_file_name}.html.haml", <<-FILE.strip_heredoc
|
23
|
+
.#{ang_file_name}
|
24
|
+
%span(ng-transclude)
|
25
|
+
FILE
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Zwr
|
2
|
+
module Angular
|
3
|
+
class PageGenerator < Rails::Generators::NamedBase
|
4
|
+
def copy_files
|
5
|
+
ang_file_name = file_name.gsub("_","-")
|
6
|
+
dir_class = file_name.gsub("-","_").camelize(:lower)
|
7
|
+
create_file "app/assets/javascripts/templates/#{ang_file_name}.html.haml"
|
8
|
+
create_file "app/assets/javascripts/controllers/#{ang_file_name}.js.coffee", <<-FILE.strip_heredoc
|
9
|
+
@#{application_name}.controller '#{dir_class}', [
|
10
|
+
'$scope', '$routeParams', '$location', '$window', '$timeout',
|
11
|
+
($scope, $routeParams, $location, $window, $timeout) ->
|
12
|
+
$scope.item = null
|
13
|
+
$scope.error_message = null
|
14
|
+
$scope.something = ->
|
15
|
+
boo
|
16
|
+
service.init(decodeURIComponent($routeParams.tagName))
|
17
|
+
.then($scope._rememberItem,$scope._errorHandler)
|
18
|
+
]
|
19
|
+
FILE
|
20
|
+
gsub_file 'app/assets/javascripts/app.js.coffee', 'otherwise({',
|
21
|
+
%[when('/#{ang_file_name}/:siteName', {\n templateUrl: '#{ang_file_name}.html',\n }).\n otherwise({]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Zwr
|
2
|
+
module Angular
|
3
|
+
class ServiceGenerator < Rails::Generators::NamedBase
|
4
|
+
def copy_files
|
5
|
+
# we want all services to end with the word service. So add it,
|
6
|
+
# unless it is already there
|
7
|
+
service_name = file_name.gsub(/[_-]service$/,"")
|
8
|
+
ang_file_name = service_name.gsub("_","-")
|
9
|
+
service_class = service_name.gsub("-","_").camelize(:lower) + "Service"
|
10
|
+
create_file "app/assets/javascripts/services/#{ang_file_name}.js.coffee", <<-FILE.strip_heredoc
|
11
|
+
@#{application_name}.service '#{service_class}', [
|
12
|
+
'$http', '$q', 'localStorageService',
|
13
|
+
($http, $q, localStorageService) ->
|
14
|
+
service =
|
15
|
+
constructor: ->
|
16
|
+
@my_variable = null
|
17
|
+
service
|
18
|
+
method: ->
|
19
|
+
me = this
|
20
|
+
$http.get('./my_var.json').then (server_response) ->
|
21
|
+
me.my_variable = server_response.data
|
22
|
+
quick: ->
|
23
|
+
$q.when @my_variable
|
24
|
+
service.constructor()
|
25
|
+
]
|
26
|
+
FILE
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/zwr.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
module Zwr
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
module
|
7
|
-
|
2
|
+
if defined?(Rails)
|
3
|
+
require 'zwr/railtie'
|
4
|
+
require 'zwr/version'
|
5
|
+
|
6
|
+
module ZwrAssets
|
7
|
+
module Rails
|
8
|
+
class Engine < ::Rails::Engine
|
9
|
+
end
|
8
10
|
end
|
9
|
-
end
|
10
|
-
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if defined?(Mongoid)
|
15
|
+
require 'zwr/zwr_mongoid.rb'
|
16
|
+
end
|
11
17
|
end
|
data/lib/zwr/app_template.rb
CHANGED
@@ -125,8 +125,9 @@ file 'app/assets/stylesheets/application.css.scss', tpl('application.css.scss')
|
|
125
125
|
remove_file 'db/seeds.rb'
|
126
126
|
file 'db/seeds.rb', "Dir[Rails.root.join('db/seeds/*.rb')].each { |file| load file }"
|
127
127
|
|
128
|
-
initializer '
|
129
|
-
|
128
|
+
initializer 'zwr.rb', <<-FILE.strip_heredoc
|
129
|
+
MDParser = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
|
130
|
+
FILE
|
130
131
|
|
131
132
|
file 'db/seeds/.keep'
|
132
133
|
|
@@ -12,5 +12,5 @@
|
|
12
12
|
%input#search_control.form-control(type="search" placeholder="Search" ng-change="handle_search_criteria_change()" ng-model="criteria.criteria_text")
|
13
13
|
%span.glyphicon.glyphicon-search(ng-click="handle_search_button_click()")
|
14
14
|
.col-sm-6
|
15
|
-
%h1#second_page_title
|
16
|
-
%p This
|
15
|
+
%h1#second_page_title Second page!
|
16
|
+
%p This is the second page.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Document
|
3
|
+
module ClassMethods
|
4
|
+
def all_full_json
|
5
|
+
collection.find.to_json
|
6
|
+
end
|
7
|
+
def find_full_json(criteria)
|
8
|
+
if criteria.is_a? String
|
9
|
+
criteria = {_id: BSON::ObjectId.from_string(criteria)}
|
10
|
+
end
|
11
|
+
collection.find(criteria).first.to_json
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/zwr.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'zwr'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.6'
|
4
4
|
s.date = '2014-11-17'
|
5
5
|
s.summary = "All the Zwr needs"
|
6
6
|
s.description = "A gem in which I jam what I commonly use."
|
@@ -12,4 +12,4 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.license = 'MIT'
|
13
13
|
|
14
14
|
s.add_dependency "railties", "~> 4.0", ">= 3.1"
|
15
|
-
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zwr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zeljko
|
@@ -46,8 +46,22 @@ files:
|
|
46
46
|
- app/assets/images/logo.png
|
47
47
|
- app/assets/images/logo.xcf
|
48
48
|
- app/assets/images/logo_transparent.png
|
49
|
+
- app/assets/javascripts/controllers/.keep
|
50
|
+
- app/assets/javascripts/directives/.keep
|
51
|
+
- app/assets/javascripts/includes/.keep
|
52
|
+
- app/assets/javascripts/includes/angular-local-storage.js
|
53
|
+
- app/assets/javascripts/includes/xml2json.js
|
54
|
+
- app/assets/javascripts/services/.keep
|
55
|
+
- app/assets/javascripts/templates/.keep
|
56
|
+
- app/assets/javascripts/templates/404.html
|
57
|
+
- app/assets/javascripts/zwr.js.coffee
|
49
58
|
- app/assets/stylesheets/zwr.css.scss.erb
|
50
59
|
- bin/zwr
|
60
|
+
- lib/generators/zwr/angular/directive_generator.rb
|
61
|
+
- lib/generators/zwr/angular/include_generator.rb
|
62
|
+
- lib/generators/zwr/angular/page_generator.rb
|
63
|
+
- lib/generators/zwr/angular/service_generator.rb
|
64
|
+
- lib/generators/zwr/angular/template_generator.rb
|
51
65
|
- lib/tasks/loc.rake
|
52
66
|
- lib/tasks/zwr.rake
|
53
67
|
- lib/zwr.rb
|
@@ -63,6 +77,7 @@ files:
|
|
63
77
|
- lib/zwr/templates/home_controller.rb
|
64
78
|
- lib/zwr/templates/index.html.haml
|
65
79
|
- lib/zwr/version.rb
|
80
|
+
- lib/zwr/zwr_mongoid.rb
|
66
81
|
- zwr.gemspec
|
67
82
|
homepage: http://rubygems.org/gems/zwr
|
68
83
|
licenses:
|