spine-rails 0.0.1 → 0.0.2

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.
data/.gitignore CHANGED
@@ -1,4 +1,6 @@
1
- *.gem
1
+ *.swp
2
+ *.swo
3
+ .#*
2
4
  .bundle
3
- Gemfile.lock
4
- pkg/*
5
+ .DS_Store
6
+ *~
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in spine-rails.gemspec
4
4
  gemspec
5
+ # Rails is already being pulled in through gemspec
6
+ # gem "rails", :git => "git://github.com/rails/rails.git"
7
+ gem "rack", :git => "git://github.com/rack/rack.git"
8
+ gem "sprockets", :git => "git://github.com/sstephenson/sprockets.git"
9
+ gem "i18n", "0.6.0beta1"
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ daemons (1.1.3)
5
+ eventmachine (0.12.10)
6
+ json (1.5.2)
7
+ rack (1.3.0)
8
+ shotgun (0.9)
9
+ rack (>= 1.0)
10
+ sinatra (1.2.6)
11
+ rack (~> 1.1)
12
+ tilt (< 2.0, >= 1.2.2)
13
+ thin (1.2.11)
14
+ daemons (>= 1.0.9)
15
+ eventmachine (>= 0.12.6)
16
+ rack (>= 1.0.0)
17
+ tilt (1.3.2)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ json
24
+ shotgun
25
+ sinatra (~> 1.0)
26
+ thin
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ # require "spec/rake/spectask"
5
+ # desc "Run all examples"
6
+ # Spec::Rake::SpecTask.new(:spec) do |t|
7
+ # t.ruby_opts = ['-r test/unit']
8
+ # t.spec_opts = %w[--color]
9
+ # end
10
+ task :default => :spec
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  http://www.JSON.org/json2.js
3
- 2011-02-23
3
+ 2009-09-29
4
4
 
5
5
  Public Domain.
6
6
 
@@ -146,7 +146,7 @@
146
146
  redistribute.
147
147
  */
148
148
 
149
- /*jslint evil: true, strict: false, regexp: false */
149
+ /*jslint evil: true, strict: false */
150
150
 
151
151
  /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
152
152
  call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
@@ -159,13 +159,15 @@
159
159
  // Create a JSON object only if one does not already exist. We create the
160
160
  // methods in a closure to avoid creating global variables.
161
161
 
162
- var JSON;
163
- if (!JSON) {
164
- JSON = {};
162
+ if (!this.JSON) {
163
+ this.JSON = {};
165
164
  }
166
165
 
166
+ if (this.module)
167
+ module.exports = JSON;
168
+
167
169
  (function () {
168
- "use strict";
170
+
169
171
 
170
172
  function f(n) {
171
173
  // Format integers to have at least two digits.
@@ -177,19 +179,19 @@ if (!JSON) {
177
179
  Date.prototype.toJSON = function (key) {
178
180
 
179
181
  return isFinite(this.valueOf()) ?
180
- this.getUTCFullYear() + '-' +
181
- f(this.getUTCMonth() + 1) + '-' +
182
- f(this.getUTCDate()) + 'T' +
183
- f(this.getUTCHours()) + ':' +
184
- f(this.getUTCMinutes()) + ':' +
185
- f(this.getUTCSeconds()) + 'Z' : null;
182
+ this.getUTCFullYear() + '-' +
183
+ f(this.getUTCMonth() + 1) + '-' +
184
+ f(this.getUTCDate()) + 'T' +
185
+ f(this.getUTCHours()) + ':' +
186
+ f(this.getUTCMinutes()) + ':' +
187
+ f(this.getUTCSeconds()) + 'Z' : null;
186
188
  };
187
189
 
188
- String.prototype.toJSON =
189
- Number.prototype.toJSON =
190
- Boolean.prototype.toJSON = function (key) {
191
- return this.valueOf();
192
- };
190
+ String.prototype.toJSON =
191
+ Number.prototype.toJSON =
192
+ Boolean.prototype.toJSON = function (key) {
193
+ return this.valueOf();
194
+ };
193
195
  }
194
196
 
195
197
  var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
@@ -216,11 +218,13 @@ if (!JSON) {
216
218
  // sequences.
217
219
 
218
220
  escapable.lastIndex = 0;
219
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
220
- var c = meta[a];
221
- return typeof c === 'string' ? c :
222
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
223
- }) + '"' : '"' + string + '"';
221
+ return escapable.test(string) ?
222
+ '"' + string.replace(escapable, function (a) {
223
+ var c = meta[a];
224
+ return typeof c === 'string' ? c :
225
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
226
+ }) + '"' :
227
+ '"' + string + '"';
224
228
  }
225
229
 
226
230
 
@@ -303,9 +307,11 @@ if (!JSON) {
303
307
  // Join all of the elements together, separated with commas, and wrap them in
304
308
  // brackets.
305
309
 
306
- v = partial.length === 0 ? '[]' : gap ?
307
- '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
308
- '[' + partial.join(',') + ']';
310
+ v = partial.length === 0 ? '[]' :
311
+ gap ? '[\n' + gap +
312
+ partial.join(',\n' + gap) + '\n' +
313
+ mind + ']' :
314
+ '[' + partial.join(',') + ']';
309
315
  gap = mind;
310
316
  return v;
311
317
  }
@@ -315,8 +321,8 @@ if (!JSON) {
315
321
  if (rep && typeof rep === 'object') {
316
322
  length = rep.length;
317
323
  for (i = 0; i < length; i += 1) {
318
- if (typeof rep[i] === 'string') {
319
- k = rep[i];
324
+ k = rep[i];
325
+ if (typeof k === 'string') {
320
326
  v = str(k, value);
321
327
  if (v) {
322
328
  partial.push(quote(k) + (gap ? ': ' : ':') + v);
@@ -328,7 +334,7 @@ if (!JSON) {
328
334
  // Otherwise, iterate through all of the keys in the object.
329
335
 
330
336
  for (k in value) {
331
- if (Object.prototype.hasOwnProperty.call(value, k)) {
337
+ if (Object.hasOwnProperty.call(value, k)) {
332
338
  v = str(k, value);
333
339
  if (v) {
334
340
  partial.push(quote(k) + (gap ? ': ' : ':') + v);
@@ -340,9 +346,9 @@ if (!JSON) {
340
346
  // Join all of the member texts together, separated with commas,
341
347
  // and wrap them in braces.
342
348
 
343
- v = partial.length === 0 ? '{}' : gap ?
344
- '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
345
- '{' + partial.join(',') + '}';
349
+ v = partial.length === 0 ? '{}' :
350
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
351
+ mind + '}' : '{' + partial.join(',') + '}';
346
352
  gap = mind;
347
353
  return v;
348
354
  }
@@ -383,7 +389,7 @@ if (!JSON) {
383
389
  rep = replacer;
384
390
  if (replacer && typeof replacer !== 'function' &&
385
391
  (typeof replacer !== 'object' ||
386
- typeof replacer.length !== 'number')) {
392
+ typeof replacer.length !== 'number')) {
387
393
  throw new Error('JSON.stringify');
388
394
  }
389
395
 
@@ -413,7 +419,7 @@ if (!JSON) {
413
419
  var k, v, value = holder[key];
414
420
  if (value && typeof value === 'object') {
415
421
  for (k in value) {
416
- if (Object.prototype.hasOwnProperty.call(value, k)) {
422
+ if (Object.hasOwnProperty.call(value, k)) {
417
423
  v = walk(value, k);
418
424
  if (v !== undefined) {
419
425
  value[k] = v;
@@ -431,7 +437,6 @@ if (!JSON) {
431
437
  // Unicode characters with escape sequences. JavaScript handles many characters
432
438
  // incorrectly, either silently deleting them, or treating them as line endings.
433
439
 
434
- text = String(text);
435
440
  cx.lastIndex = 0;
436
441
  if (cx.test(text)) {
437
442
  text = text.replace(cx, function (a) {
@@ -453,10 +458,10 @@ if (!JSON) {
453
458
  // we look to see that the remaining characters are only whitespace or ']' or
454
459
  // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
455
460
 
456
- if (/^[\],:{}\s]*$/
457
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
458
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
459
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
461
+ if (/^[\],:{}\s]*$/.
462
+ test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
463
+ replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
464
+ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
460
465
 
461
466
  // In the third stage we use the eval function to compile the text into a
462
467
  // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
@@ -0,0 +1,717 @@
1
+ (function() {
2
+ var $, Controller, Events, Log, Model, Module, Spine, guid, isArray, isBlank, makeArray, moduleKeywords;
3
+ var __slice = Array.prototype.slice, __indexOf = Array.prototype.indexOf || function(item) {
4
+ for (var i = 0, l = this.length; i < l; i++) {
5
+ if (this[i] === item) return i;
6
+ }
7
+ return -1;
8
+ }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
9
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
10
+ function ctor() { this.constructor = child; }
11
+ ctor.prototype = parent.prototype;
12
+ child.prototype = new ctor;
13
+ child.__super__ = parent.prototype;
14
+ return child;
15
+ };
16
+ Events = {
17
+ bind: function(ev, callback) {
18
+ var calls, evs, name, _i, _len;
19
+ evs = ev.split(' ');
20
+ calls = this.hasOwnProperty('_callbacks') && this._callbacks || (this._callbacks = {});
21
+ for (_i = 0, _len = evs.length; _i < _len; _i++) {
22
+ name = evs[_i];
23
+ calls[name] || (calls[name] = []);
24
+ calls[name].push(callback);
25
+ }
26
+ return this;
27
+ },
28
+ trigger: function() {
29
+ var args, callback, ev, list, _i, _len, _ref;
30
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
31
+ ev = args.shift();
32
+ list = this.hasOwnProperty('_callbacks') && ((_ref = this._callbacks) != null ? _ref[ev] : void 0);
33
+ if (!list) {
34
+ return false;
35
+ }
36
+ for (_i = 0, _len = list.length; _i < _len; _i++) {
37
+ callback = list[_i];
38
+ if (callback.apply(this, args) === false) {
39
+ break;
40
+ }
41
+ }
42
+ return true;
43
+ },
44
+ unbind: function(ev, callback) {
45
+ var cb, i, list, _len, _ref;
46
+ if (!ev) {
47
+ this._callbacks = {};
48
+ return this;
49
+ }
50
+ list = (_ref = this._callbacks) != null ? _ref[ev] : void 0;
51
+ if (!list) {
52
+ return this;
53
+ }
54
+ if (!callback) {
55
+ delete this._callbacks[ev];
56
+ return this;
57
+ }
58
+ for (i = 0, _len = list.length; i < _len; i++) {
59
+ cb = list[i];
60
+ if (cb === callback) {
61
+ list = list.slice();
62
+ list.splice(i, 1);
63
+ this._callbacks[ev] = list;
64
+ break;
65
+ }
66
+ }
67
+ return this;
68
+ }
69
+ };
70
+ Log = {
71
+ trace: true,
72
+ logPrefix: '(App)',
73
+ log: function() {
74
+ var args;
75
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
76
+ if (!this.trace) {
77
+ return;
78
+ }
79
+ if (typeof console === 'undefined') {
80
+ return;
81
+ }
82
+ if (this.logPrefix) {
83
+ args.unshift(this.logPrefix);
84
+ }
85
+ console.log.apply(console, args);
86
+ return this;
87
+ }
88
+ };
89
+ moduleKeywords = ['included', 'extended'];
90
+ Module = (function() {
91
+ Module.include = function(obj) {
92
+ var included, key, value;
93
+ if (!obj) {
94
+ throw 'include(obj) requires obj';
95
+ }
96
+ for (key in obj) {
97
+ value = obj[key];
98
+ if (__indexOf.call(moduleKeywords, key) < 0) {
99
+ this.prototype[key] = value;
100
+ }
101
+ }
102
+ included = obj.included;
103
+ if (included) {
104
+ included.apply(this);
105
+ }
106
+ return this;
107
+ };
108
+ Module.extend = function(obj) {
109
+ var extended, key, value;
110
+ if (!obj) {
111
+ throw 'extend(obj) requires obj';
112
+ }
113
+ for (key in obj) {
114
+ value = obj[key];
115
+ if (__indexOf.call(moduleKeywords, key) < 0) {
116
+ this[key] = value;
117
+ }
118
+ }
119
+ extended = obj.extended;
120
+ if (extended) {
121
+ extended.apply(this);
122
+ }
123
+ return this;
124
+ };
125
+ Module.proxy = function(func) {
126
+ return __bind(function() {
127
+ return func.apply(this, arguments);
128
+ }, this);
129
+ };
130
+ Module.prototype.proxy = function(func) {
131
+ return __bind(function() {
132
+ return func.apply(this, arguments);
133
+ }, this);
134
+ };
135
+ function Module() {
136
+ if (typeof this.init === "function") {
137
+ this.init.apply(this, arguments);
138
+ }
139
+ }
140
+ return Module;
141
+ })();
142
+ Model = (function() {
143
+ __extends(Model, Module);
144
+ Model.extend(Events);
145
+ Model.records = {};
146
+ Model.attributes = [];
147
+ Model.configure = function() {
148
+ var attributes, name;
149
+ name = arguments[0], attributes = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
150
+ this.className = name;
151
+ this.records = {};
152
+ if (attributes.length) {
153
+ this.attributes = attributes;
154
+ }
155
+ this.attributes && (this.attributes = makeArray(this.attributes));
156
+ this.attributes || (this.attributes = []);
157
+ this.unbind();
158
+ return this;
159
+ };
160
+ Model.toString = function() {
161
+ return "" + this.className + "(" + (this.attributes.join(", ")) + ")";
162
+ };
163
+ Model.find = function(id) {
164
+ var record;
165
+ record = this.records[id];
166
+ if (!record) {
167
+ throw 'Unknown record';
168
+ }
169
+ return record.clone();
170
+ };
171
+ Model.exists = function(id) {
172
+ try {
173
+ return this.find(id);
174
+ } catch (e) {
175
+ return false;
176
+ }
177
+ };
178
+ Model.refresh = function(values, options) {
179
+ var record, _i, _len, _ref;
180
+ if (options == null) {
181
+ options = {};
182
+ }
183
+ if (options.clear) {
184
+ this.records = {};
185
+ }
186
+ _ref = this.fromJSON(values);
187
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
188
+ record = _ref[_i];
189
+ record.newRecord = false;
190
+ record.id || (record.id = guid());
191
+ this.records[record.id] = record;
192
+ }
193
+ this.trigger('refresh');
194
+ return this;
195
+ };
196
+ Model.select = function(callback) {
197
+ var id, record, result;
198
+ result = (function() {
199
+ var _ref, _results;
200
+ _ref = this.records;
201
+ _results = [];
202
+ for (id in _ref) {
203
+ record = _ref[id];
204
+ if (callback(record)) {
205
+ _results.push(record);
206
+ }
207
+ }
208
+ return _results;
209
+ }).call(this);
210
+ return this.cloneArray(result);
211
+ };
212
+ Model.findByAttribute = function(name, value) {
213
+ var id, record, _ref;
214
+ _ref = this.records;
215
+ for (id in _ref) {
216
+ record = _ref[id];
217
+ if (record[name] === value) {
218
+ return record.clone();
219
+ }
220
+ }
221
+ return null;
222
+ };
223
+ Model.findAllByAttribute = function(name, value) {
224
+ return this.select(function(item) {
225
+ return item[name] === value;
226
+ });
227
+ };
228
+ Model.each = function(callback) {
229
+ var key, value, _ref, _results;
230
+ _ref = this.records;
231
+ _results = [];
232
+ for (key in _ref) {
233
+ value = _ref[key];
234
+ _results.push(callback(value.clone()));
235
+ }
236
+ return _results;
237
+ };
238
+ Model.all = function() {
239
+ return this.cloneArray(this.recordsValues());
240
+ };
241
+ Model.first = function() {
242
+ var record;
243
+ record = this.recordsValues()[0];
244
+ return record != null ? record.clone() : void 0;
245
+ };
246
+ Model.last = function() {
247
+ var record, values;
248
+ values = this.recordsValues();
249
+ record = values[values.length - 1];
250
+ return record != null ? record.clone() : void 0;
251
+ };
252
+ Model.count = function() {
253
+ return this.recordsValues().length;
254
+ };
255
+ Model.deleteAll = function() {
256
+ var key, value, _ref, _results;
257
+ _ref = this.records;
258
+ _results = [];
259
+ for (key in _ref) {
260
+ value = _ref[key];
261
+ _results.push(delete this.records[key]);
262
+ }
263
+ return _results;
264
+ };
265
+ Model.destroyAll = function() {
266
+ var key, value, _ref, _results;
267
+ _ref = this.records;
268
+ _results = [];
269
+ for (key in _ref) {
270
+ value = _ref[key];
271
+ _results.push(this.records[key].destroy());
272
+ }
273
+ return _results;
274
+ };
275
+ Model.update = function(id, atts) {
276
+ return this.find(id).updateAttributes(atts);
277
+ };
278
+ Model.create = function(atts) {
279
+ var record;
280
+ record = new this(atts);
281
+ return record.save();
282
+ };
283
+ Model.destroy = function(id) {
284
+ return this.find(id).destroy();
285
+ };
286
+ Model.change = function(callbackOrParams) {
287
+ if (typeof callbackOrParams === 'function') {
288
+ return this.bind('change', callbackOrParams);
289
+ } else {
290
+ return this.trigger('change', callbackOrParams);
291
+ }
292
+ };
293
+ Model.fetch = function(callbackOrParams) {
294
+ if (typeof callbackOrParams === 'function') {
295
+ return this.bind('fetch', callbackOrParams);
296
+ } else {
297
+ return this.trigger('fetch', callbackOrParams);
298
+ }
299
+ };
300
+ Model.toJSON = function() {
301
+ return this.recordsValues();
302
+ };
303
+ Model.fromJSON = function(objects) {
304
+ var value, _i, _len, _results;
305
+ if (!objects) {
306
+ return;
307
+ }
308
+ if (typeof objects === 'string') {
309
+ objects = JSON.parse(objects);
310
+ }
311
+ if (isArray(objects)) {
312
+ _results = [];
313
+ for (_i = 0, _len = objects.length; _i < _len; _i++) {
314
+ value = objects[_i];
315
+ _results.push(new this(value));
316
+ }
317
+ return _results;
318
+ } else {
319
+ return new this(objects);
320
+ }
321
+ };
322
+ Model.recordsValues = function() {
323
+ var key, result, value, _ref;
324
+ result = [];
325
+ _ref = this.records;
326
+ for (key in _ref) {
327
+ value = _ref[key];
328
+ result.push(value);
329
+ }
330
+ return result;
331
+ };
332
+ Model.cloneArray = function(array) {
333
+ var value, _i, _len, _results;
334
+ _results = [];
335
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
336
+ value = array[_i];
337
+ _results.push(value.clone());
338
+ }
339
+ return _results;
340
+ };
341
+ Model.prototype.newRecord = true;
342
+ function Model(atts) {
343
+ Model.__super__.constructor.apply(this, arguments);
344
+ this.ids = [];
345
+ if (atts) {
346
+ this.load(atts);
347
+ }
348
+ }
349
+ Model.prototype.isNew = function() {
350
+ return this.newRecord;
351
+ };
352
+ Model.prototype.isValid = function() {
353
+ return !this.validate();
354
+ };
355
+ Model.prototype.validate = function() {};
356
+ Model.prototype.load = function(atts) {
357
+ var key, value, _results;
358
+ _results = [];
359
+ for (key in atts) {
360
+ value = atts[key];
361
+ _results.push(this[key] = value);
362
+ }
363
+ return _results;
364
+ };
365
+ Model.prototype.attributes = function() {
366
+ var key, result, _i, _len, _ref;
367
+ result = {};
368
+ _ref = this.constructor.attributes;
369
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
370
+ key = _ref[_i];
371
+ result[key] = this[key];
372
+ }
373
+ result.id = this.id;
374
+ return result;
375
+ };
376
+ Model.prototype.eql = function(rec) {
377
+ var _ref, _ref2;
378
+ return rec && rec.constructor === this.constructor && (rec.id === this.id || (_ref = this.id, __indexOf.call(rec.ids, _ref) >= 0) || (_ref2 = rec.id, __indexOf.call(this.ids, _ref2) >= 0));
379
+ };
380
+ Model.prototype.save = function() {
381
+ var error;
382
+ error = this.validate();
383
+ if (error) {
384
+ this.trigger('error', this, error);
385
+ return false;
386
+ }
387
+ this.trigger('beforeSave', this);
388
+ if (this.newRecord) {
389
+ this.create();
390
+ } else {
391
+ this.update();
392
+ }
393
+ this.trigger('save', this);
394
+ return this;
395
+ };
396
+ Model.prototype.updateAttribute = function(name, value) {
397
+ this[name] = value;
398
+ return this.save();
399
+ };
400
+ Model.prototype.updateAttributes = function(atts) {
401
+ this.load(atts);
402
+ return this.save();
403
+ };
404
+ Model.prototype.changeID = function(id) {
405
+ var records;
406
+ this.ids.push(this.id);
407
+ records = this.constructor.records;
408
+ records[id] = records[this.id];
409
+ delete records[this.id];
410
+ this.id = id;
411
+ return this.save();
412
+ };
413
+ Model.prototype.destroy = function() {
414
+ this.trigger('beforeDestroy', this);
415
+ delete this.constructor.records[this.id];
416
+ this.destroyed = true;
417
+ this.trigger('destroy', this);
418
+ this.trigger('change', this, 'destroy');
419
+ this.unbind();
420
+ return this;
421
+ };
422
+ Model.prototype.dup = function(newRecord) {
423
+ var result;
424
+ result = new this.constructor(this.attributes());
425
+ if (newRecord === false) {
426
+ result.newRecord = this.newRecord;
427
+ } else {
428
+ delete result.id;
429
+ }
430
+ return result;
431
+ };
432
+ Model.prototype.clone = function() {
433
+ return Object.create(this);
434
+ };
435
+ Model.prototype.reload = function() {
436
+ var original;
437
+ if (this.newRecord) {
438
+ return this;
439
+ }
440
+ original = this.constructor.find(this.id);
441
+ this.load(original.attributes());
442
+ return original;
443
+ };
444
+ Model.prototype.toJSON = function() {
445
+ return this.attributes();
446
+ };
447
+ Model.prototype.toString = function() {
448
+ return "<" + this.constructor.className + " (" + (JSON.stringify(this)) + ")>";
449
+ };
450
+ Model.prototype.exists = function() {
451
+ return this.id && this.id in this.constructor.records;
452
+ };
453
+ Model.prototype.update = function() {
454
+ var clone, records;
455
+ this.trigger('beforeUpdate', this);
456
+ records = this.constructor.records;
457
+ records[this.id].load(this.attributes());
458
+ clone = records[this.id].clone();
459
+ this.trigger('update', clone);
460
+ return this.trigger('change', clone, 'update');
461
+ };
462
+ Model.prototype.create = function() {
463
+ var clone, records;
464
+ this.trigger('beforeCreate', this);
465
+ if (!this.id) {
466
+ this.id = guid();
467
+ }
468
+ this.newRecord = false;
469
+ records = this.constructor.records;
470
+ records[this.id] = this.dup(false);
471
+ clone = records[this.id].clone();
472
+ this.trigger('create', clone);
473
+ return this.trigger('change', clone, 'create');
474
+ };
475
+ Model.prototype.bind = function(events, callback) {
476
+ var binder, unbinder;
477
+ this.constructor.bind(events, binder = __bind(function(record) {
478
+ if (record && this.eql(record)) {
479
+ return callback.apply(this, arguments);
480
+ }
481
+ }, this));
482
+ this.constructor.bind('unbind', unbinder = __bind(function(record) {
483
+ if (record && this.eql(record)) {
484
+ this.constructor.unbind(events, binder);
485
+ return this.constructor.unbind('unbind', unbinder);
486
+ }
487
+ }, this));
488
+ return binder;
489
+ };
490
+ Model.prototype.trigger = function() {
491
+ var _ref;
492
+ return (_ref = this.constructor).trigger.apply(_ref, arguments);
493
+ };
494
+ Model.prototype.unbind = function() {
495
+ return this.trigger('unbind', this);
496
+ };
497
+ return Model;
498
+ })();
499
+ Controller = (function() {
500
+ __extends(Controller, Module);
501
+ Controller.include(Events);
502
+ Controller.include(Log);
503
+ Controller.prototype.eventSplitter = /^(\w+)\s*(.*)$/;
504
+ Controller.prototype.tag = 'div';
505
+ function Controller(options) {
506
+ this.release = __bind(this.release, this);
507
+ var key, value, _ref;
508
+ this.options = options;
509
+ _ref = this.options;
510
+ for (key in _ref) {
511
+ value = _ref[key];
512
+ this[key] = value;
513
+ }
514
+ if (!this.el) {
515
+ this.el = document.createElement(this.tag);
516
+ }
517
+ this.el = $(this.el);
518
+ if (this.className) {
519
+ this.el.addClass(this.className);
520
+ }
521
+ this.release(function() {
522
+ return this.el.remove();
523
+ });
524
+ if (!this.events) {
525
+ this.events = this.constructor.events;
526
+ }
527
+ if (!this.elements) {
528
+ this.elements = this.constructor.elements;
529
+ }
530
+ if (this.events) {
531
+ this.delegateEvents();
532
+ }
533
+ if (this.elements) {
534
+ this.refreshElements();
535
+ }
536
+ Controller.__super__.constructor.apply(this, arguments);
537
+ }
538
+ Controller.prototype.release = function(callback) {
539
+ if (typeof callback === 'function') {
540
+ return this.bind('release', callback);
541
+ } else {
542
+ return this.trigger('release');
543
+ }
544
+ };
545
+ Controller.prototype.$ = function(selector) {
546
+ return $(selector, this.el);
547
+ };
548
+ Controller.prototype.delegateEvents = function() {
549
+ var eventName, key, match, method, selector, _ref, _results;
550
+ _ref = this.events;
551
+ _results = [];
552
+ for (key in _ref) {
553
+ method = _ref[key];
554
+ if (typeof method !== 'function') {
555
+ method = this.proxy(this[method]);
556
+ }
557
+ match = key.match(this.eventSplitter);
558
+ eventName = match[1];
559
+ selector = match[2];
560
+ _results.push(selector === '' ? this.el.bind(eventName, method) : this.el.delegate(selector, eventName, method));
561
+ }
562
+ return _results;
563
+ };
564
+ Controller.prototype.refreshElements = function() {
565
+ var key, value, _ref, _results;
566
+ _ref = this.elements;
567
+ _results = [];
568
+ for (key in _ref) {
569
+ value = _ref[key];
570
+ _results.push(this[value] = this.$(key));
571
+ }
572
+ return _results;
573
+ };
574
+ Controller.prototype.delay = function(func, timeout) {
575
+ return setTimeout(this.proxy(func), timeout || 0);
576
+ };
577
+ Controller.prototype.html = function(element) {
578
+ this.el.html(element.el || element);
579
+ this.refreshElements();
580
+ return this.el;
581
+ };
582
+ Controller.prototype.append = function() {
583
+ var e, elements, _ref;
584
+ elements = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
585
+ elements = (function() {
586
+ var _i, _len, _results;
587
+ _results = [];
588
+ for (_i = 0, _len = elements.length; _i < _len; _i++) {
589
+ e = elements[_i];
590
+ _results.push(e.el || e);
591
+ }
592
+ return _results;
593
+ })();
594
+ (_ref = this.el).append.apply(_ref, elements);
595
+ this.refreshElements();
596
+ return this.el;
597
+ };
598
+ Controller.prototype.appendTo = function(element) {
599
+ this.el.appendTo(element.el || element);
600
+ this.refreshElements();
601
+ return this.el;
602
+ };
603
+ Controller.prototype.prepend = function() {
604
+ var e, elements, _ref;
605
+ elements = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
606
+ elements = (function() {
607
+ var _i, _len, _results;
608
+ _results = [];
609
+ for (_i = 0, _len = elements.length; _i < _len; _i++) {
610
+ e = elements[_i];
611
+ _results.push(e.el || e);
612
+ }
613
+ return _results;
614
+ })();
615
+ (_ref = this.el).prepend.apply(_ref, elements);
616
+ this.refreshElements();
617
+ return this.el;
618
+ };
619
+ Controller.prototype.replace = function(element) {
620
+ var previous, _ref;
621
+ _ref = [this.el, element.el || element], previous = _ref[0], this.el = _ref[1];
622
+ previous.replaceWith(this.el);
623
+ this.delegateEvents();
624
+ this.refreshElements();
625
+ return this.el;
626
+ };
627
+ return Controller;
628
+ })();
629
+ $ = this.jQuery || this.Zepto || function(element) {
630
+ return element;
631
+ };
632
+ if (typeof Object.create !== 'function') {
633
+ Object.create = function(o) {
634
+ var Func;
635
+ Func = function() {};
636
+ Func.prototype = o;
637
+ return new Func();
638
+ };
639
+ }
640
+ isArray = function(value) {
641
+ return Object.prototype.toString.call(value) === '[object Array]';
642
+ };
643
+ isBlank = function(value) {
644
+ var key;
645
+ if (!value) {
646
+ return true;
647
+ }
648
+ for (key in value) {
649
+ return false;
650
+ }
651
+ return true;
652
+ };
653
+ makeArray = function(args) {
654
+ return Array.prototype.slice.call(args, 0);
655
+ };
656
+ guid = function() {
657
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
658
+ var r, v;
659
+ r = Math.random() * 16 | 0;
660
+ v = c === 'x' ? r : r & 3 | 8;
661
+ return v.toString(16);
662
+ }).toUpperCase();
663
+ };
664
+ Spine = this.Spine = {};
665
+ if (typeof module !== "undefined" && module !== null) {
666
+ module.exports = Spine;
667
+ }
668
+ Spine.version = '0.0.9';
669
+ Spine.isArray = isArray;
670
+ Spine.isBlank = isBlank;
671
+ Spine.$ = $;
672
+ Spine.Events = Events;
673
+ Spine.Log = Log;
674
+ Spine.Module = Module;
675
+ Spine.Controller = Controller;
676
+ Spine.Model = Model;
677
+ Module.extend.call(Spine, Events);
678
+ Module.create = Module.sub = Controller.create = Controller.sub = Model.sub = function(instances, statics) {
679
+ var result;
680
+ result = (function() {
681
+ __extends(result, this);
682
+ function result() {
683
+ result.__super__.constructor.apply(this, arguments);
684
+ }
685
+ return result;
686
+ }).call(this);
687
+ if (instances) {
688
+ result.include(instances);
689
+ }
690
+ if (statics) {
691
+ result.extend(statics);
692
+ }
693
+ if (typeof result.unbind === "function") {
694
+ result.unbind();
695
+ }
696
+ return result;
697
+ };
698
+ Model.setup = function(name, attributes) {
699
+ var Instance;
700
+ if (attributes == null) {
701
+ attributes = [];
702
+ }
703
+ Instance = (function() {
704
+ __extends(Instance, this);
705
+ function Instance() {
706
+ Instance.__super__.constructor.apply(this, arguments);
707
+ }
708
+ return Instance;
709
+ }).call(this);
710
+ Instance.configure.apply(Instance, [name].concat(__slice.call(attributes)));
711
+ return Instance;
712
+ };
713
+ Module.init = Controller.init = Model.init = function(a1, a2, a3, a4, a5) {
714
+ return new this(a1, a2, a3, a4, a5);
715
+ };
716
+ Spine.Class = Module;
717
+ }).call(this);