joosy 1.2.0.alpha.68 → 1.2.0.alpha.70

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 007fa5ba359b8c5f4c5e52a53b483a285149c575
4
- data.tar.gz: 15ac5b0c7eaf9eb93b08b487b0e493fcd8ec7075
3
+ metadata.gz: 0c0650d2b49ebccea7dfe767a26b0dc38db9871d
4
+ data.tar.gz: 936ce56008fbf989e1283776d5755af3a9aae82e
5
5
  SHA512:
6
- metadata.gz: b33c07dd76c9a907ff66ce830a55f321b3ae54f9d9e5598e0d5c48aeab9d98c9a4ddfbe11a766fbff3c6b80173c22b90716bbabbdcf6fa1b8328361989a8148f
7
- data.tar.gz: 9548d59875b23556613071537c1c09893ac777a7782dfb1fa2284e5de26c0ab3ceffb88f8b60aac3564c76eca419e992ab35529f96a7dce4cd6208782959deb2
6
+ metadata.gz: 0a3a635da761bc635707176b166d5d8418b211efaff7f0985386a75370128c94c2faf5fc66f6792ed0f2a3b4a7899600fc1acb456bfd05971152e4ce83c80128
7
+ data.tar.gz: ba2f0bcb06ca85faa460ab4f428cbd847d907e989199dcd73f285693925ff3232b3b06ade4b2bfee2b6db522377fde198344279c8aae09f2d054c5763f22afea
data/Gruntfile.coffee CHANGED
@@ -1,5 +1,4 @@
1
- require 'sugar'
2
-
1
+ moment = require 'moment'
3
2
  semver = require 'semver'
4
3
 
5
4
  module.exports = (grunt) ->
@@ -8,11 +7,17 @@ module.exports = (grunt) ->
8
7
  #
9
8
  testemOptions = (vendor, specs) ->
10
9
  return {
11
- src: Array.create([
10
+ src: grunt.util._([
11
+ [
12
12
  'bower_components/sinonjs/sinon.js',
13
13
  'bower_components/sugar/release/sugar-full.min.js',
14
14
  'spec/helpers/*.coffee'
15
- ], vendor, 'joosy.coffee', specs)
15
+ ],
16
+ vendor,
17
+ 'joosy.coffee',
18
+ specs
19
+ ]).flatten()
20
+
16
21
  assets:
17
22
  setup: ->
18
23
  grunt.grill.assetter('development').environment
@@ -101,7 +106,7 @@ module.exports = (grunt) ->
101
106
  #
102
107
  grunt.registerTask 'default', 'testem'
103
108
 
104
- grunt.registerTask 'build', ['bowerize', 'grill:compile']
109
+ grunt.registerTask 'compile', ['bowerize', 'grill:compile']
105
110
 
106
111
  grunt.registerTask 'test', ->
107
112
  grunt.task.run 'coffeelint'
@@ -109,7 +114,7 @@ module.exports = (grunt) ->
109
114
 
110
115
  grunt.registerTask 'publish', [
111
116
  'test',
112
- 'build',
117
+ 'compile',
113
118
  'ensureCommits',
114
119
  'gh-pages',
115
120
  'release',
@@ -169,7 +174,7 @@ module.exports = (grunt) ->
169
174
 
170
175
  date = (version) ->
171
176
  return undefined unless version
172
- Date.create(grunt.file.read "doc/#{version}/DATE").format "{d} {Month} {yyyy}"
177
+ moment(grunt.file.read "doc/#{version}/DATE").format "D MMMM YYYY"
173
178
 
174
179
  args = ['source', '--output-dir', destination]
175
180
  grunt.file.delete destination if grunt.file.exists destination
@@ -183,9 +188,9 @@ module.exports = (grunt) ->
183
188
  versions.push version if semver.valid(version)
184
189
 
185
190
  versions = versions.sort(semver.rcompare)
186
- edge = versions.filter((x) -> x.has('-')).first()
187
- stable = versions.filter((x) -> !x.has('-')).first()
188
- versions = versions.remove edge, stable
191
+ edge = versions.filter((x) -> x.indexOf('-') != -1)[0]
192
+ stable = versions.filter((x) -> x.indexOf('-') == -1)[0]
193
+ versions = grunt.util._(versions).without edge, stable
189
194
 
190
195
  versions = {
191
196
  edge:
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "joosy",
3
- "version": "1.2.0-alpha.68",
3
+ "version": "1.2.0-alpha.70",
4
4
  "main": "build/joosy.js",
5
5
  "ignore": [
6
6
  "lib",
@@ -62,60 +62,46 @@
62
62
  };
63
63
 
64
64
  Base.build = function(data) {
65
- var id, klass, shim, _base, _base1;
65
+ var id, klass, _base, _base1, _base2;
66
66
  if (data == null) {
67
67
  data = {};
68
68
  }
69
- klass = this.prototype.__entityName;
70
- (_base = Joosy.Resources.Base).identity || (_base.identity = {});
71
- (_base1 = Joosy.Resources.Base.identity)[klass] || (_base1[klass] = {});
72
- shim = this.__makeShim(this.prototype);
73
69
  if (Object.isNumber(data) || Object.isString(data)) {
74
70
  id = data;
75
71
  data = {};
76
- data[shim.__primaryKey] = id;
72
+ data[this.prototype.__primaryKey] = id;
77
73
  }
78
- if (Joosy.Resources.Base.identity) {
79
- id = data[shim.__primaryKey];
80
- if ((id != null) && Joosy.Resources.Base.identity[klass][id]) {
81
- shim = Joosy.Resources.Base.identity[klass][id];
82
- shim.load(data);
83
- } else {
84
- Joosy.Resources.Base.identity[klass][id] = shim;
85
- this.apply(shim, [data]);
74
+ klass = this.prototype.__entityName;
75
+ id = data[this.prototype.__primaryKey];
76
+ if ((klass != null) && (id != null)) {
77
+ if ((_base = Joosy.Resources.Base).identity == null) {
78
+ _base.identity = {};
86
79
  }
80
+ if ((_base1 = Joosy.Resources.Base.identity)[klass] == null) {
81
+ _base1[klass] = {};
82
+ }
83
+ if ((_base2 = Joosy.Resources.Base.identity[klass])[id] == null) {
84
+ _base2[id] = new this({
85
+ id: id
86
+ });
87
+ }
88
+ return Joosy.Resources.Base.identity[klass][id].load(data);
87
89
  } else {
88
- this.apply(shim, [data]);
90
+ return new this(data);
89
91
  }
90
- return shim;
91
92
  };
92
93
 
93
94
  Base.grab = function(form) {
94
95
  return this.build({}).grab(form);
95
96
  };
96
97
 
97
- Base.__makeShim = function(proto) {
98
- var key, shim, value;
99
- shim = function() {
100
- return shim.__call.apply(shim, arguments);
101
- };
102
- if (shim.__proto__) {
103
- shim.__proto__ = proto;
104
- } else {
105
- for (key in proto) {
106
- value = proto[key];
107
- shim[key] = value;
108
- }
109
- }
110
- shim.constructor = this;
111
- return shim;
112
- };
113
-
114
98
  function Base(data) {
115
99
  if (data == null) {
116
100
  data = {};
117
101
  }
118
- this.__fillData(data, false);
102
+ return Base.__super__.constructor.call(this, function() {
103
+ return this.__fillData(data, false);
104
+ });
119
105
  }
120
106
 
121
107
  Base.prototype.id = function() {
@@ -231,21 +217,14 @@
231
217
  };
232
218
 
233
219
  Base.prototype.__prepareData = function(data) {
234
- var bl, name, _i, _len, _ref;
220
+ var name;
235
221
  if (Object.isObject(data) && Object.keys(data).length === 1 && this.__entityName) {
236
222
  name = this.__entityName.camelize(false);
237
223
  if (data[name]) {
238
224
  data = data[name];
239
225
  }
240
226
  }
241
- if (this.__beforeLoads != null) {
242
- _ref = this.__beforeLoads;
243
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
244
- bl = _ref[_i];
245
- data = bl.call(this, data);
246
- }
247
- }
248
- return data;
227
+ return this.__applyBeforeLoads(data);
249
228
  };
250
229
 
251
230
  Base.prototype.__map = function(data, name, klass) {
@@ -260,9 +239,13 @@
260
239
  return data;
261
240
  };
262
241
 
242
+ Base.prototype.toString = function() {
243
+ return "<Resource " + this.__entityName + "> " + (JSON.stringify(this.data));
244
+ };
245
+
263
246
  return Base;
264
247
 
265
- })(Joosy.Module);
248
+ })(Joosy.Function);
266
249
 
267
250
  }).call(this);
268
251
  (function() {
@@ -511,12 +494,9 @@
511
494
  };
512
495
 
513
496
  REST.prototype.at = function() {
514
- var args, _ref1,
515
- _this = this;
497
+ var args, _ref1;
516
498
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
517
- return (_ref1 = this.constructor).__atWrapper.apply(_ref1, [function(callback) {
518
- return Object.tap(_this.constructor.__makeShim(_this), callback);
519
- }].concat(__slice.call(args)));
499
+ return new ((_ref1 = this.constructor).at.apply(_ref1, args))(this.data);
520
500
  };
521
501
 
522
502
  REST.prototype.__collection = function() {
data/build/joosy.js CHANGED
@@ -107,6 +107,9 @@
107
107
 
108
108
  }).call(this);
109
109
  (function() {
110
+ var __hasProp = {}.hasOwnProperty,
111
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
112
+
110
113
  Joosy.Module = (function() {
111
114
  function Module() {}
112
115
 
@@ -207,6 +210,33 @@
207
210
 
208
211
  })();
209
212
 
213
+ Joosy.Function = (function(_super) {
214
+ __extends(Function, _super);
215
+
216
+ function Function(setup) {
217
+ var key, shim, value;
218
+ shim = function() {
219
+ return shim.__call.apply(shim, arguments);
220
+ };
221
+ if (shim.__proto__) {
222
+ shim.__proto__ = this;
223
+ } else {
224
+ for (key in this) {
225
+ value = this[key];
226
+ shim[key] = value;
227
+ }
228
+ }
229
+ shim.constructor = this.constructor;
230
+ if (setup != null) {
231
+ setup.call(shim);
232
+ }
233
+ return shim;
234
+ }
235
+
236
+ return Function;
237
+
238
+ })(Joosy.Module);
239
+
210
240
  if ((typeof define !== "undefined" && define !== null ? define.amd : void 0) != null) {
211
241
  define('joosy/module', function() {
212
242
  return Joosy.Module;
@@ -1263,7 +1293,24 @@
1263
1293
  return filters.each(function(filter) {
1264
1294
  var camelized;
1265
1295
  camelized = _this.__registerFilterCollector(filter);
1266
- return _this.prototype["__run" + camelized + "s"] = function() {
1296
+ _this.prototype["__run" + camelized + "s"] = function() {
1297
+ var callback, params, _i, _len, _ref, _results;
1298
+ params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1299
+ if (!this["__" + filter + "s"]) {
1300
+ return;
1301
+ }
1302
+ _ref = this["__" + filter + "s"];
1303
+ _results = [];
1304
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1305
+ callback = _ref[_i];
1306
+ if (typeof callback !== 'function') {
1307
+ callback = this[callback];
1308
+ }
1309
+ _results.push(callback.apply(this, params));
1310
+ }
1311
+ return _results;
1312
+ };
1313
+ _this.prototype["__confirm" + camelized + "s"] = function() {
1267
1314
  var params,
1268
1315
  _this = this;
1269
1316
  params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
@@ -1271,12 +1318,28 @@
1271
1318
  return true;
1272
1319
  }
1273
1320
  return this["__" + filter + "s"].reduce(function(flag, callback) {
1274
- if (!Object.isFunction(callback)) {
1321
+ if (typeof callback !== 'function') {
1275
1322
  callback = _this[callback];
1276
1323
  }
1277
1324
  return flag && callback.apply(_this, params) !== false;
1278
1325
  }, true);
1279
1326
  };
1327
+ return _this.prototype["__apply" + camelized + "s"] = function() {
1328
+ var callback, data, params, _i, _len, _ref;
1329
+ data = arguments[0], params = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
1330
+ if (!this["__" + filter + "s"]) {
1331
+ return data;
1332
+ }
1333
+ _ref = this["__" + filter + "s"];
1334
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1335
+ callback = _ref[_i];
1336
+ if (typeof callback !== 'function') {
1337
+ callback = this[callback];
1338
+ }
1339
+ data = callback.apply(this, [data].concat(params));
1340
+ }
1341
+ return data;
1342
+ };
1280
1343
  });
1281
1344
  };
1282
1345
  return this.registerSequencedFilters = function() {
@@ -1783,7 +1846,7 @@
1783
1846
  this.params = params;
1784
1847
  this.previous = previous;
1785
1848
  this.layoutShouldChange = ((_ref = this.previous) != null ? _ref.__layoutClass : void 0) !== this.__layoutClass;
1786
- this.halted = !this.__runBeforeLoads();
1849
+ this.halted = !this.__confirmBeforeLoads();
1787
1850
  this.layout = (function() {
1788
1851
  var _ref1, _ref2;
1789
1852
  switch (false) {
@@ -2203,6 +2266,131 @@
2203
2266
  });
2204
2267
  }
2205
2268
 
2269
+ }).call(this);
2270
+ (function() {
2271
+ var __hasProp = {}.hasOwnProperty,
2272
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
2273
+
2274
+ Joosy.Resources.Array = (function(_super) {
2275
+ __extends(Array, _super);
2276
+
2277
+ Joosy.Module.include.call(Array, Joosy.Modules.Events);
2278
+
2279
+ function Array() {
2280
+ var entry, _i, _len, _ref;
2281
+ _ref = this.slice.call(arguments, 0);
2282
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2283
+ entry = _ref[_i];
2284
+ this.push(entry);
2285
+ }
2286
+ }
2287
+
2288
+ Array.prototype.get = function(index) {
2289
+ return this[index];
2290
+ };
2291
+
2292
+ Array.prototype.set = function(index, value) {
2293
+ this[index] = value;
2294
+ this.trigger('changed');
2295
+ return this.length;
2296
+ };
2297
+
2298
+ Array.prototype.push = function() {
2299
+ var result;
2300
+ result = Array.__super__.push.apply(this, arguments);
2301
+ this.trigger('changed');
2302
+ return result;
2303
+ };
2304
+
2305
+ Array.prototype.pop = function() {
2306
+ var result;
2307
+ result = Array.__super__.pop.apply(this, arguments);
2308
+ this.trigger('changed');
2309
+ return result;
2310
+ };
2311
+
2312
+ Array.prototype.shift = function() {
2313
+ var result;
2314
+ result = Array.__super__.shift.apply(this, arguments);
2315
+ this.trigger('changed');
2316
+ return result;
2317
+ };
2318
+
2319
+ Array.prototype.unshift = function() {
2320
+ var result;
2321
+ result = Array.__super__.unshift.apply(this, arguments);
2322
+ this.trigger('changed');
2323
+ return result;
2324
+ };
2325
+
2326
+ Array.prototype.splice = function() {
2327
+ var result;
2328
+ result = Array.__super__.splice.apply(this, arguments);
2329
+ this.trigger('changed');
2330
+ return result;
2331
+ };
2332
+
2333
+ return Array;
2334
+
2335
+ })(Array);
2336
+
2337
+ if ((typeof define !== "undefined" && define !== null ? define.amd : void 0) != null) {
2338
+ define('joosy/resources/array', function() {
2339
+ return Joosy.Resources.Array;
2340
+ });
2341
+ }
2342
+
2343
+ }).call(this);
2344
+ (function() {
2345
+ var __hasProp = {}.hasOwnProperty,
2346
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
2347
+
2348
+ Joosy.Resources.Scalar = (function(_super) {
2349
+ __extends(Scalar, _super);
2350
+
2351
+ Scalar.include(Joosy.Modules.Events);
2352
+
2353
+ function Scalar(value) {
2354
+ return Scalar.__super__.constructor.call(this, function() {
2355
+ return this.value = value;
2356
+ });
2357
+ }
2358
+
2359
+ Scalar.prototype.__call = function() {
2360
+ if (arguments.length > 0) {
2361
+ return this.set(arguments[0]);
2362
+ } else {
2363
+ return this.get();
2364
+ }
2365
+ };
2366
+
2367
+ Scalar.prototype.get = function() {
2368
+ return this.value;
2369
+ };
2370
+
2371
+ Scalar.prototype.set = function(value) {
2372
+ this.value = value;
2373
+ return this.trigger('changed');
2374
+ };
2375
+
2376
+ Scalar.prototype.valueOf = function() {
2377
+ return this.value.valueOf();
2378
+ };
2379
+
2380
+ Scalar.prototype.toString = function() {
2381
+ return this.value.toString();
2382
+ };
2383
+
2384
+ return Scalar;
2385
+
2386
+ })(Joosy.Function);
2387
+
2388
+ if ((typeof define !== "undefined" && define !== null ? define.amd : void 0) != null) {
2389
+ define('joosy/resources/scalar', function() {
2390
+ return Joosy.Resources.Scalar;
2391
+ });
2392
+ }
2393
+
2206
2394
  }).call(this);
2207
2395
  (function() {
2208
2396
  var __hasProp = {}.hasOwnProperty,
@@ -2213,6 +2401,10 @@
2213
2401
 
2214
2402
  Watcher.include(Joosy.Modules.Events);
2215
2403
 
2404
+ Watcher.include(Joosy.Modules.Filters);
2405
+
2406
+ Watcher.registerPlainFilters('beforeLoad');
2407
+
2216
2408
  Watcher.cache = function(cacheKey) {
2217
2409
  return this.prototype.__cacheKey = cacheKey;
2218
2410
  };
@@ -2221,21 +2413,14 @@
2221
2413
  return this.prototype.__fetcher = fetcher;
2222
2414
  };
2223
2415
 
2224
- Watcher.beforeLoad = function(action) {
2225
- if (!this.prototype.hasOwnProperty('__beforeLoads')) {
2226
- this.prototype.__beforeLoads = [].concat(this.__super__.__beforeLoads || []);
2227
- }
2228
- return this.prototype.__beforeLoads.push(action);
2229
- };
2230
-
2231
- function Watcher(cacheKey, fetcher) {
2416
+ function Watcher(callback, cacheKey, fetcher) {
2232
2417
  if (cacheKey == null) {
2233
2418
  cacheKey = false;
2234
2419
  }
2235
2420
  if (fetcher == null) {
2236
2421
  fetcher = false;
2237
2422
  }
2238
- if (Object.isFunction(cacheKey)) {
2423
+ if (typeof cacheKey === 'function') {
2239
2424
  fetcher = cacheKey;
2240
2425
  cacheKey = void 0;
2241
2426
  }
@@ -2245,30 +2430,20 @@
2245
2430
  if (cacheKey) {
2246
2431
  this.__cacheKey = cacheKey;
2247
2432
  }
2248
- }
2249
-
2250
- Watcher.prototype.load = function(callback) {
2251
- var _this = this;
2252
- if (this.__cacheKey && localStorage[this.__cacheKey]) {
2253
- this.data = this.prepare(JSON.parse(localStorage[this.__cacheKey]));
2254
- this.trigger('changed');
2433
+ if (this.__cacheKey && localStorage && localStorage[this.__cacheKey]) {
2434
+ this.data = this.__applyBeforeLoads(JSON.parse(localStorage[this.__cacheKey]));
2435
+ if (typeof callback === "function") {
2436
+ callback(this);
2437
+ }
2255
2438
  this.refresh();
2256
- return typeof callback === "function" ? callback(this) : void 0;
2257
2439
  } else {
2258
- return this.__fetcher(function(result) {
2259
- if (_this.__cacheKey) {
2260
- localStorage[_this.__cacheKey] = JSON.stringify(result);
2261
- }
2262
- _this.data = _this.prepare(result);
2263
- _this.trigger('changed');
2264
- return typeof callback === "function" ? callback(_this) : void 0;
2265
- });
2440
+ this.refresh(callback);
2266
2441
  }
2267
- };
2442
+ }
2268
2443
 
2269
- Watcher.prototype.clone = function() {
2444
+ Watcher.prototype.clone = function(callback) {
2270
2445
  var copy;
2271
- copy = new this.constructor(this.__cacheKey, this.__fetcher);
2446
+ copy = new this.constructor(callback, this.__cacheKey, this.__fetcher);
2272
2447
  copy.data = Object.clone(this.data, true);
2273
2448
  copy.trigger('changed');
2274
2449
  return copy;
@@ -2277,25 +2452,15 @@
2277
2452
  Watcher.prototype.refresh = function(callback) {
2278
2453
  var _this = this;
2279
2454
  return this.__fetcher(function(result) {
2280
- if (_this.__cacheKey) {
2455
+ if (_this.__cacheKey && localStorage) {
2281
2456
  localStorage[_this.__cacheKey] = JSON.stringify(result);
2282
2457
  }
2283
- _this.data = _this.prepare(result);
2284
- _this.trigger('changed');
2285
- return typeof callback === "function" ? callback(_this) : void 0;
2286
- });
2287
- };
2288
-
2289
- Watcher.prototype.prepare = function(data) {
2290
- var bl, _i, _len, _ref;
2291
- if (this.__beforeLoads != null) {
2292
- _ref = this.__beforeLoads;
2293
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2294
- bl = _ref[_i];
2295
- data = bl.call(this, data);
2458
+ _this.data = _this.__applyBeforeLoads(result);
2459
+ if (typeof callback === "function") {
2460
+ callback(_this);
2296
2461
  }
2297
- }
2298
- return data;
2462
+ return _this.trigger('changed');
2463
+ });
2299
2464
  };
2300
2465
 
2301
2466
  return Watcher;
data/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "keywords": [
5
5
  "joosy"
6
6
  ],
7
- "version": "1.2.0-alpha.68",
7
+ "version": "1.2.0-alpha.70",
8
8
  "author": "Boris Staal <boris@staal.io>",
9
9
  "homepage": "http://joosy.ws/",
10
10
  "repository": {
@@ -15,16 +15,15 @@
15
15
  "node": ">=0.4.0"
16
16
  },
17
17
  "dependencies": {
18
- "grill": "~1.0.0-alpha.12"
18
+ "grill": ">=1.0.0-alpha.19",
19
+ "moment": "~2.1.0"
19
20
  },
20
21
  "devDependencies": {
21
- "coffee-script": "~1.6.3",
22
- "sugar": "~1.3.8",
23
22
  "bower": "~1.2.1",
24
23
  "semver": "~2.1.0",
25
24
  "grunt-coffeelint": "0.0.6",
26
25
  "grunt-release": "~0.3.5",
27
- "grunt-contrib-testem": ">=0.4.0",
26
+ "grunt-contrib-testem": ">=0.5.2",
28
27
  "grunt-gh-pages": "git+https://github.com/inossidabile/grunt-gh-pages.git"
29
28
  }
30
29
  }
@@ -25,7 +25,7 @@
25
25
  # @param [Function] action `(Object) -> Object` to call
26
26
  #
27
27
  #
28
- class Joosy.Resources.Base extends Joosy.Module
28
+ class Joosy.Resources.Base extends Joosy.Function
29
29
  @include Joosy.Modules.Log
30
30
  @include Joosy.Modules.Events
31
31
  @include Joosy.Modules.Filters
@@ -122,31 +122,22 @@ class Joosy.Resources.Base extends Joosy.Module
122
122
  # @return [Joosy.Resources.Base]
123
123
  #
124
124
  @build: (data={}) ->
125
- klass = @::__entityName
126
-
127
- Joosy.Resources.Base.identity ||= {}
128
- Joosy.Resources.Base.identity[klass] ||= {}
129
-
130
- shim = @__makeShim(@::)
131
-
132
125
  if Object.isNumber(data) || Object.isString(data)
133
126
  id = data
134
127
  data = {}
135
- data[shim.__primaryKey] = id
128
+ data[@::__primaryKey] = id
129
+
130
+ klass = @::__entityName
131
+ id = data[@::__primaryKey]
136
132
 
137
- if Joosy.Resources.Base.identity
138
- id = data[shim.__primaryKey]
133
+ if klass? && id?
134
+ Joosy.Resources.Base.identity ?= {}
135
+ Joosy.Resources.Base.identity[klass] ?= {}
136
+ Joosy.Resources.Base.identity[klass][id] ?= new @ id: id
139
137
 
140
- if id? && Joosy.Resources.Base.identity[klass][id]
141
- shim = Joosy.Resources.Base.identity[klass][id]
142
- shim.load data
143
- else
144
- Joosy.Resources.Base.identity[klass][id] = shim
145
- @apply shim, [data]
138
+ Joosy.Resources.Base.identity[klass][id].load data
146
139
  else
147
- @apply shim, [data]
148
-
149
- shim
140
+ new @ data
150
141
 
151
142
  #
152
143
  # Creates new instance of Resource using values from form
@@ -156,25 +147,6 @@ class Joosy.Resources.Base extends Joosy.Module
156
147
  @grab: (form) ->
157
148
  @build({}).grab form
158
149
 
159
- #
160
- # Makes base shim-function for making instances through build or making instance clones
161
- #
162
- # @param [Object] proto Any function or object whose properties will be inherited by a new function
163
- #
164
- @__makeShim: (proto) ->
165
- shim = ->
166
- shim.__call.apply shim, arguments
167
-
168
- if shim.__proto__
169
- shim.__proto__ = proto
170
- else
171
- for key, value of proto
172
- shim[key] = value
173
-
174
- shim.constructor = @
175
-
176
- shim
177
-
178
150
  #
179
151
  # Should NOT be called directly, use {::build} instead
180
152
  #
@@ -182,7 +154,8 @@ class Joosy.Resources.Base extends Joosy.Module
182
154
  # @param [Object] data Data to store
183
155
  #
184
156
  constructor: (data={}) ->
185
- @__fillData data, false
157
+ return super ->
158
+ @__fillData data, false
186
159
 
187
160
  id: ->
188
161
  @data?[@__primaryKey]
@@ -312,10 +285,7 @@ class Joosy.Resources.Base extends Joosy.Module
312
285
  name = @__entityName.camelize(false)
313
286
  data = data[name] if data[name]
314
287
 
315
- if @__beforeLoads?
316
- data = bl.call(this, data) for bl in @__beforeLoads
317
-
318
- data
288
+ @__applyBeforeLoads data
319
289
 
320
290
  __map: (data, name, klass) ->
321
291
  if Object.isArray data[name]
@@ -325,3 +295,6 @@ class Joosy.Resources.Base extends Joosy.Module
325
295
  else if Object.isObject data[name]
326
296
  data[name] = klass.build data[name]
327
297
  data
298
+
299
+ toString: ->
300
+ "<Resource #{@__entityName}> #{JSON.stringify(@data)}"
@@ -54,7 +54,7 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
54
54
 
55
55
 
56
56
  #
57
- # Creates the proxy of current resource instance binded as a child of given entity
57
+ # Creates the proxy of current resource instance binded as a children of given entity
58
58
  #
59
59
  # @param [Array] args Array of parent entities. Can be a string or another REST resource.
60
60
  #
@@ -64,9 +64,7 @@ class Joosy.Resources.REST extends Joosy.Resources.Base
64
64
  # @note accepts both array notation (comment.at(['admin', @blog, @post])) and args notation (comment.at('admin', @blog, @post))
65
65
  #
66
66
  at: (args...) ->
67
- @constructor.__atWrapper (callback) =>
68
- Object.tap @constructor.__makeShim(@), callback
69
- , args...
67
+ new (@constructor.at args...) @data
70
68
 
71
69
  #
72
70
  # Implements `@collection` default behavior.
@@ -112,9 +112,9 @@ class Joosy.Module
112
112
 
113
113
  for key, value of object
114
114
  if key != 'included' && key != 'extended'
115
- this::[key] = value
115
+ @::[key] = value
116
116
 
117
- object.included?.apply this
117
+ object.included?.apply @
118
118
  null
119
119
 
120
120
  #
@@ -131,6 +131,34 @@ class Joosy.Module
131
131
  object.extended?.apply this
132
132
  null
133
133
 
134
+ #
135
+ # Class allowing to emulate Fn-based instances in JS
136
+ #
137
+ # @example
138
+ # class Foo extends Joosy.Module.Function
139
+ # constructor: (value)
140
+ # return super ->
141
+ # @value = value
142
+ #
143
+ # __call: -> @value
144
+ #
145
+ # foo = new Foo 'test'
146
+ # typeof(foo) # 'function'
147
+ # foo() # 'test'
148
+ #
149
+ class Joosy.Function extends Joosy.Module
150
+ constructor: (setup) ->
151
+ shim = -> shim.__call.apply shim, arguments
152
+
153
+ if shim.__proto__
154
+ shim.__proto__ = @
155
+ else
156
+ shim[key] = value for key, value of @
157
+
158
+ shim.constructor = @constructor
159
+ setup?.call(shim)
160
+ return shim
161
+
134
162
  # AMD wrapper
135
163
  if define?.amd?
136
164
  define 'joosy/module', -> Joosy.Module
@@ -18,7 +18,7 @@ Joosy.Modules.Filters =
18
18
  #
19
19
  # # private
20
20
  #
21
- # @__runBeforeLoads() # Runs filters registered as beforeLoad
21
+ # @__confirmBeforeLoads() # Runs filters registered as beforeLoad
22
22
  # @__runAfterLoads() # Runs filters registered as afterLoad
23
23
  # @__runAfterUnloads() # Runs filters registered as afterUnload
24
24
  #
@@ -36,13 +36,29 @@ Joosy.Modules.Filters =
36
36
  camelized = @__registerFilterCollector filter
37
37
 
38
38
  @::["__run#{camelized}s"] = (params...) ->
39
+ return unless @["__#{filter}s"]
40
+
41
+ for callback in @["__#{filter}s"]
42
+ callback = @[callback] unless typeof(callback) == 'function'
43
+ callback.apply(@, params)
44
+
45
+ @::["__confirm#{camelized}s"] = (params...) ->
39
46
  return true unless @["__#{filter}s"]
40
47
 
41
48
  @["__#{filter}s"].reduce (flag, callback) =>
42
- callback = @[callback] unless Object.isFunction callback
49
+ callback = @[callback] unless typeof(callback) == 'function'
43
50
  flag && callback.apply(@, params) != false
44
51
  , true
45
52
 
53
+ @::["__apply#{camelized}s"] = (data, params...) ->
54
+ return data unless @["__#{filter}s"]
55
+
56
+ for callback in @["__#{filter}s"]
57
+ callback = @[callback] unless typeof(callback) == 'function'
58
+ data = callback.apply(@, [data].concat params)
59
+
60
+ data
61
+
46
62
  @registerSequencedFilters = (filters...) =>
47
63
  filters.each (filter) =>
48
64
  camelized = @__registerFilterCollector filter
@@ -33,7 +33,7 @@ class Joosy.Page extends Joosy.Widget
33
33
  constructor: (@params, @previous) ->
34
34
  @layoutShouldChange = @previous?.__layoutClass != @__layoutClass
35
35
 
36
- @halted = !@__runBeforeLoads()
36
+ @halted = !@__confirmBeforeLoads()
37
37
  @layout = switch
38
38
  when @layoutShouldChange && @__layoutClass
39
39
  new @__layoutClass(params, @previous?.layout)
@@ -0,0 +1,43 @@
1
+ class Joosy.Resources.Array extends Array
2
+
3
+ Joosy.Module.include.call @, Joosy.Modules.Events
4
+
5
+ constructor: ->
6
+ @push entry for entry in @slice.call(arguments, 0)
7
+
8
+ get: (index) ->
9
+ @[index]
10
+
11
+ set: (index, value) ->
12
+ @[index] = value
13
+ @trigger 'changed'
14
+ @length
15
+
16
+ push: ->
17
+ result = super
18
+ @trigger 'changed'
19
+ result
20
+
21
+ pop: ->
22
+ result = super
23
+ @trigger 'changed'
24
+ result
25
+
26
+ shift: ->
27
+ result = super
28
+ @trigger 'changed'
29
+ result
30
+
31
+ unshift: ->
32
+ result = super
33
+ @trigger 'changed'
34
+ result
35
+
36
+ splice: ->
37
+ result = super
38
+ @trigger 'changed'
39
+ result
40
+
41
+ # AMD wrapper
42
+ if define?.amd?
43
+ define 'joosy/resources/array', -> Joosy.Resources.Array
@@ -0,0 +1,29 @@
1
+ class Joosy.Resources.Scalar extends Joosy.Function
2
+
3
+ @include Joosy.Modules.Events
4
+
5
+ constructor: (value) ->
6
+ return super ->
7
+ @value = value
8
+
9
+ __call: ->
10
+ if arguments.length > 0
11
+ @set arguments[0]
12
+ else
13
+ @get()
14
+
15
+ get: ->
16
+ @value
17
+
18
+ set: (@value) ->
19
+ @trigger 'changed'
20
+
21
+ valueOf: ->
22
+ @value.valueOf()
23
+
24
+ toString: ->
25
+ @value.toString()
26
+
27
+ # AMD wrapper
28
+ if define?.amd?
29
+ define 'joosy/resources/scalar', -> Joosy.Resources.Scalar
@@ -1,54 +1,40 @@
1
- #### !!!UNSPECED ####
2
1
  class Joosy.Resources.Watcher extends Joosy.Module
2
+
3
3
  @include Joosy.Modules.Events
4
+ @include Joosy.Modules.Filters
5
+
6
+ @registerPlainFilters 'beforeLoad'
4
7
 
5
8
  @cache: (cacheKey) -> @::__cacheKey = cacheKey
6
9
  @fetcher: (fetcher) -> @::__fetcher = fetcher
7
10
 
8
- @beforeLoad: (action) ->
9
- unless @::hasOwnProperty '__beforeLoads'
10
- @::__beforeLoads = [].concat @.__super__.__beforeLoads || []
11
- @::__beforeLoads.push action
12
-
13
- constructor: (cacheKey=false, fetcher=false) ->
14
- if Object.isFunction(cacheKey)
11
+ constructor: (callback, cacheKey=false, fetcher=false) ->
12
+ if typeof(cacheKey) == 'function'
15
13
  fetcher = cacheKey
16
14
  cacheKey = undefined
17
15
 
18
- @__fetcher = fetcher if fetcher
16
+ @__fetcher = fetcher if fetcher
19
17
  @__cacheKey = cacheKey if cacheKey
20
18
 
21
- load: (callback) ->
22
- if @__cacheKey && localStorage[@__cacheKey]
23
- @data = @prepare(JSON.parse localStorage[@__cacheKey])
24
- @trigger 'changed'
25
- @refresh()
19
+ if @__cacheKey && localStorage && localStorage[@__cacheKey]
20
+ @data = @__applyBeforeLoads(JSON.parse localStorage[@__cacheKey])
26
21
  callback? @
22
+ @refresh()
27
23
  else
28
- @__fetcher (result) =>
29
- localStorage[@__cacheKey] = JSON.stringify(result) if @__cacheKey
30
- @data = @prepare result
31
- @trigger 'changed'
32
- callback? @
33
-
34
- clone: ->
35
- copy = new @constructor(@__cacheKey, @__fetcher)
24
+ @refresh callback
25
+
26
+ clone: (callback) ->
27
+ copy = new @constructor(callback, @__cacheKey, @__fetcher)
36
28
  copy.data = Object.clone(@data, true)
37
29
  copy.trigger 'changed'
38
30
  copy
39
31
 
40
32
  refresh: (callback) ->
41
33
  @__fetcher (result) =>
42
- localStorage[@__cacheKey] = JSON.stringify(result) if @__cacheKey
43
- @data = @prepare result
44
- @trigger 'changed'
34
+ localStorage[@__cacheKey] = JSON.stringify(result) if @__cacheKey && localStorage
35
+ @data = @__applyBeforeLoads result
45
36
  callback? @
46
-
47
- prepare: (data) ->
48
- if @__beforeLoads?
49
- data = bl.call(this, data) for bl in @__beforeLoads
50
-
51
- data
37
+ @trigger 'changed'
52
38
 
53
39
  # AMD wrapper
54
40
  if define?.amd?
@@ -41,7 +41,7 @@ describe "Joosy.Modules.Filters", ->
41
41
  @Filters.afterLoad callbacks[1]
42
42
  @Filters.afterUnload callbacks[2]
43
43
 
44
- @filters.__runBeforeLoads 1, 2
44
+ @filters.__confirmBeforeLoads 1, 2
45
45
  @filters.__runAfterLoads 1, 2
46
46
  @filters.__runAfterUnloads 1, 2
47
47
 
@@ -60,7 +60,7 @@ describe "Joosy.Modules.Filters", ->
60
60
  callbacks[0].returns true
61
61
  callbacks[1].returns true
62
62
 
63
- expect(@filters.__runBeforeLoads()).toBeTruthy()
63
+ expect(@filters.__confirmBeforeLoads()).toBeTruthy()
64
64
 
65
65
  expect(callbacks[0].callCount).toEqual 1
66
66
  expect(callbacks[1].callCount).toEqual 1
@@ -74,7 +74,7 @@ describe "Joosy.Modules.Filters", ->
74
74
  callbacks[0].returns true
75
75
  callbacks[1].returns false
76
76
 
77
- expect(@filters.__runBeforeLoads()).toBeFalsy()
77
+ expect(@filters.__confirmBeforeLoads()).toBeFalsy()
78
78
 
79
79
  expect(callbacks[0].callCount).toEqual 1
80
80
  expect(callbacks[1].callCount).toEqual 1
@@ -87,7 +87,7 @@ describe "Joosy.Modules.Filters", ->
87
87
  @Filters.afterLoad 'callback1'
88
88
  @Filters.afterUnload 'callback2'
89
89
 
90
- @filters.__runBeforeLoads()
90
+ @filters.__confirmBeforeLoads()
91
91
  @filters.__runAfterLoads()
92
92
  @filters.__runAfterUnloads()
93
93
 
@@ -187,48 +187,4 @@ describe "Joosy.Modules.Filters", ->
187
187
  complete()
188
188
 
189
189
  @filters.__runBeforeLoads ['test'], ->
190
- expect(spies).toBeSequenced()
191
-
192
- # describe "chaining", ->
193
-
194
- # it "evaluates", ->
195
- # callbacks = 0.upto(1).map =>
196
- # callback = sinon.stub()
197
- # @Filters.beforeLoad callback
198
- # callback
199
-
200
- # callbacks[0].returns true
201
- # callbacks[1].returns true
202
-
203
- # expect(@filters.__runBeforeLoads()).toBeTruthy()
204
-
205
- # expect(callbacks[0].callCount).toEqual 1
206
- # expect(callbacks[1].callCount).toEqual 1
207
-
208
- # it "breaks on false", ->
209
- # callbacks = 0.upto(2).map =>
210
- # callback = sinon.stub()
211
- # @Filters.beforeLoad callback
212
- # callback
213
-
214
- # callbacks[0].returns true
215
- # callbacks[1].returns false
216
-
217
- # expect(@filters.__runBeforeLoads()).toBeFalsy()
218
-
219
- # expect(callbacks[0].callCount).toEqual 1
220
- # expect(callbacks[1].callCount).toEqual 1
221
- # expect(callbacks[2].callCount).toEqual 0
222
-
223
- # it "accepts method names as callbacks", ->
224
- # @filters['callback' + i] = sinon.spy() for i in 0.upto(2)
225
-
226
- # @Filters.beforeLoad 'callback0'
227
- # @Filters.afterLoad 'callback1'
228
- # @Filters.afterUnload 'callback2'
229
-
230
- # @filters.__runBeforeLoads()
231
- # @filters.__runAfterLoads()
232
- # @filters.__runAfterUnloads()
233
-
234
- # expect(@filters['callback' + i].callCount).toEqual 1 for i in 0.upto(2)
190
+ expect(spies).toBeSequenced()
@@ -35,8 +35,8 @@ describe "Joosy.Page", ->
35
35
  Joosy.Router.navigate.restore()
36
36
 
37
37
  it "respects beforeFilters cancelation", ->
38
- sinon.stub @Page.prototype, '__runBeforeLoads'
39
- @Page::__runBeforeLoads.returns(false)
38
+ sinon.stub @Page.prototype, '__confirmBeforeLoads'
39
+ @Page::__confirmBeforeLoads.returns(false)
40
40
 
41
41
  new @Page $('#application')
42
42
 
@@ -31,6 +31,8 @@ describe "Joosy", ->
31
31
  'joosy/modules/renderer',
32
32
  'joosy/modules/time_manager',
33
33
  'joosy/page',
34
+ 'joosy/resources/array',
35
+ 'joosy/resources/scalar',
34
36
  'joosy/resources/watcher',
35
37
  'joosy/router',
36
38
  'joosy/templaters/jst',
@@ -148,6 +148,7 @@ describe "Joosy.Resources.Base", ->
148
148
  it "handles nested bi-directional reference", ->
149
149
  biDirectionTestNode = TestNode.build
150
150
  id: 1
151
- children: [{id: 2, parent: {id: 1}}]
151
+ yolo: true
152
+ children: [{id: 2, parent: {id: 1, yolo: true}}]
152
153
 
153
154
  expect(biDirectionTestNode).toEqual(biDirectionTestNode('children').at(0)('parent'))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joosy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0.alpha.68
4
+ version: 1.2.0.alpha.70
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boris Staal
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-08-30 00:00:00.000000000 Z
13
+ date: 2013-09-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sprockets
@@ -85,6 +85,8 @@ files:
85
85
  - source/joosy/modules/time_manager.coffee
86
86
  - source/joosy/modules/widgets_manager.coffee
87
87
  - source/joosy/page.coffee
88
+ - source/joosy/resources/array.coffee
89
+ - source/joosy/resources/scalar.coffee
88
90
  - source/joosy/resources/watcher.coffee
89
91
  - source/joosy/router.coffee
90
92
  - source/joosy/templaters/jst.coffee