spine-rails 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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);