zwr 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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:
|