mes 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c4b7d220cd39d368676fff018bdd8bf833fa3aa9
4
- data.tar.gz: 58984aa27fba40caeb0838149348e68e003b60e4
3
+ metadata.gz: b9c790f758d22852d0b798477c13a53b2d9eb22c
4
+ data.tar.gz: eb07badc0518821eb8fb45960ea7b4ce766eea48
5
5
  SHA512:
6
- metadata.gz: 9dc6901e775e3f06adad0d6a8f0403f8b821e5359ee5023ea7111618c98811ef88bea104ed737e50deeeb601dd713989d0cfd5c129a6a2aac741439d18ac5c04
7
- data.tar.gz: d6f52795be717eb81b556e9759f5e3e24658df4e639a889464b8bbab8f8782c51199d3924bacd4ab63bfd1a78e84bd3922b3f59b34ddfede320de3efc2b42f7e
6
+ metadata.gz: 0a477386773a838b44395ffd6e4c4267554d7181f7742cc6e9893bcb492ead7496c2b96b799445bc63750bebc1eb973f81fe405a5ecb887fe541b90c704eb86f
7
+ data.tar.gz: ab89cc0220c3f0a46f2723fe2f73cddf926bf738b2ea9e40cf388d157aba63cd26c15bfa98908c3cd4686aca9db8f89671f904bad66cfdd564cf1c54d8bafadf
@@ -13,8 +13,7 @@ module MiddlemanEmberScaffold
13
13
  directory(src, destination_root)
14
14
  Dir.chdir(destination_root)
15
15
  run_bundle
16
- #puts 'Building scaffold....'
17
- #puts %x['cd #{destination_root}; middleman build']
16
+ bundle_command('exec middleman build')
18
17
  end
19
18
 
20
19
 
@@ -1,12 +1,11 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "middleman", "3.0.14"
3
+ gem "middleman", "3.2.1"
4
4
  gem 'json', '~> 1.7.7'
5
5
  gem "middleman-livereload"
6
- gem 'ember-source', '1.0.0.rc5'
7
- gem 'handlebars-source', '1.0.0.rc4'
8
- gem 'ember-data-source'
9
- gem "middleman-emblem", "~> 1.1.1"
6
+ gem 'ember-source', '1.2.0.1'
7
+ gem 'handlebars-source', '1.1.2'
8
+ gem "middleman-emblem", "~> 1.1.5"
10
9
  gem 'bootstrap-sass', '~> 2.3.1.0', :require => false
11
10
  gem 'middleman-emberscript', '~> 1.0.0'
12
11
 
@@ -99,7 +99,6 @@ configure :build do
99
99
 
100
100
  FileUtils.cp(::Handlebars::Source.bundled_path, "#{root}/vendor/javascripts/")
101
101
  FileUtils.cp(::Ember::Source.bundled_path_for("ember.js"), "#{root}/vendor/javascripts/")
102
- FileUtils.cp(::Ember::Data::Source.bundled_path_for("ember-data.js"), "#{root}/vendor/javascripts/")
103
102
  sprockets.append_path "#{root}/vendor/javascripts/"
104
103
 
105
104
 
@@ -3,7 +3,7 @@
3
3
  #= require "utils"
4
4
  #= require "handlebars"
5
5
  #= require "ember"
6
- #= require "ember-data"
6
+ #= require "ember-model"
7
7
  #= require "underscore"
8
8
  #= require "bootstrap-modalmanager"
9
9
  #= require "bootstrap-modal"
@@ -0,0 +1,1693 @@
1
+ (function() {
2
+
3
+ var VERSION = '0.0.10';
4
+
5
+ if (Ember.libraries) {
6
+ Ember.libraries.register('Ember Model', VERSION);
7
+ }
8
+
9
+
10
+ })();
11
+
12
+ (function() {
13
+
14
+ function mustImplement(message) {
15
+ var fn = function() {
16
+ var className = this.constructor.toString();
17
+
18
+ throw new Error(message.replace('{{className}}', className));
19
+ };
20
+ fn.isUnimplemented = true;
21
+ return fn;
22
+ }
23
+
24
+ Ember.Adapter = Ember.Object.extend({
25
+ find: mustImplement('{{className}} must implement find'),
26
+ findQuery: mustImplement('{{className}} must implement findQuery'),
27
+ findMany: mustImplement('{{className}} must implement findMany'),
28
+ findAll: mustImplement('{{className}} must implement findAll'),
29
+ createRecord: mustImplement('{{className}} must implement createRecord'),
30
+ saveRecord: mustImplement('{{className}} must implement saveRecord'),
31
+ deleteRecord: mustImplement('{{className}} must implement deleteRecord'),
32
+
33
+ load: function(record, id, data) {
34
+ record.load(id, data);
35
+ }
36
+ });
37
+
38
+
39
+ })();
40
+
41
+ (function() {
42
+
43
+ var get = Ember.get;
44
+
45
+ Ember.FixtureAdapter = Ember.Adapter.extend({
46
+ _findData: function(klass, id) {
47
+ var fixtures = klass.FIXTURES,
48
+ idAsString = id.toString(),
49
+ primaryKey = get(klass, 'primaryKey'),
50
+ data = Ember.A(fixtures).find(function(el) { return (el[primaryKey]).toString() === idAsString; });
51
+
52
+ return data;
53
+ },
54
+
55
+ find: function(record, id) {
56
+ var data = this._findData(record.constructor, id);
57
+
58
+ return new Ember.RSVP.Promise(function(resolve, reject) {
59
+ Ember.run.later(this, function() {
60
+ Ember.run(record, record.load, id, data);
61
+ resolve(record);
62
+ }, 0);
63
+ });
64
+ },
65
+
66
+ findMany: function(klass, records, ids) {
67
+ var fixtures = klass.FIXTURES,
68
+ requestedData = [];
69
+
70
+ for (var i = 0, l = ids.length; i < l; i++) {
71
+ requestedData.push(this._findData(klass, ids[i]));
72
+ }
73
+
74
+ return new Ember.RSVP.Promise(function(resolve, reject) {
75
+ Ember.run.later(this, function() {
76
+ Ember.run(records, records.load, klass, requestedData);
77
+ resolve(records);
78
+ }, 0);
79
+ });
80
+ },
81
+
82
+ findAll: function(klass, records) {
83
+ var fixtures = klass.FIXTURES;
84
+
85
+ return new Ember.RSVP.Promise(function(resolve, reject) {
86
+ Ember.run.later(this, function() {
87
+ Ember.run(records, records.load, klass, fixtures);
88
+ resolve(records);
89
+ }, 0);
90
+ });
91
+ },
92
+
93
+ createRecord: function(record) {
94
+ var klass = record.constructor,
95
+ fixtures = klass.FIXTURES;
96
+
97
+ return new Ember.RSVP.Promise(function(resolve, reject) {
98
+ Ember.run.later(this, function() {
99
+ fixtures.push(klass.findFromCacheOrLoad(record.toJSON()));
100
+ record.didCreateRecord();
101
+ resolve(record);
102
+ }, 0);
103
+ });
104
+ },
105
+
106
+ saveRecord: function(record) {
107
+ return new Ember.RSVP.Promise(function(resolve, reject) {
108
+ Ember.run.later(this, function() {
109
+ record.didSaveRecord();
110
+ resolve(record);
111
+ }, 0);
112
+ });
113
+ },
114
+
115
+ deleteRecord: function(record) {
116
+ return new Ember.RSVP.Promise(function(resolve, reject) {
117
+ Ember.run.later(this, function() {
118
+ record.didDeleteRecord();
119
+ resolve(record);
120
+ }, 0);
121
+ });
122
+ }
123
+ });
124
+
125
+
126
+ })();
127
+
128
+ (function() {
129
+
130
+ var get = Ember.get,
131
+ set = Ember.set;
132
+
133
+ Ember.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, {
134
+ isLoaded: false,
135
+ isLoading: Ember.computed.not('isLoaded'),
136
+
137
+ load: function(klass, data) {
138
+ set(this, 'content', this.materializeData(klass, data));
139
+ this.notifyLoaded();
140
+ },
141
+
142
+ loadForFindMany: function(klass) {
143
+ var content = get(this, '_ids').map(function(id) { return klass.cachedRecordForId(id); });
144
+ set(this, 'content', Ember.A(content));
145
+ this.notifyLoaded();
146
+ },
147
+
148
+ notifyLoaded: function() {
149
+ set(this, 'isLoaded', true);
150
+ this.trigger('didLoad');
151
+ },
152
+
153
+ materializeData: function(klass, data) {
154
+ return Ember.A(data.map(function(el) {
155
+ return klass.findFromCacheOrLoad(el); // FIXME
156
+ }));
157
+ },
158
+
159
+ reload: function() {
160
+ var modelClass = this.get('modelClass'),
161
+ self = this,
162
+ promises;
163
+
164
+ set(this, 'isLoaded', false);
165
+ if (modelClass._findAllRecordArray === this) {
166
+ return modelClass.adapter.findAll(modelClass, this);
167
+ } else if (this._query) {
168
+ return modelClass.adapter.findQuery(modelClass, this, this._query);
169
+ } else {
170
+ promises = this.map(function(record) {
171
+ return record.reload();
172
+ });
173
+ return Ember.RSVP.all(promises).then(function(data) {
174
+ self.notifyLoaded();
175
+ });
176
+ }
177
+ }
178
+ });
179
+
180
+
181
+ })();
182
+
183
+ (function() {
184
+
185
+ var get = Ember.get;
186
+
187
+ Ember.FilteredRecordArray = Ember.RecordArray.extend({
188
+ init: function() {
189
+ if (!get(this, 'modelClass')) {
190
+ throw new Error('FilteredRecordArrays must be created with a modelClass');
191
+ }
192
+ if (!get(this, 'filterFunction')) {
193
+ throw new Error('FilteredRecordArrays must be created with a filterFunction');
194
+ }
195
+ if (!get(this, 'filterProperties')) {
196
+ throw new Error('FilteredRecordArrays must be created with filterProperties');
197
+ }
198
+
199
+ var modelClass = get(this, 'modelClass');
200
+ modelClass.registerRecordArray(this);
201
+
202
+ this.registerObservers();
203
+ this.updateFilter();
204
+
205
+ this._super();
206
+ },
207
+
208
+ updateFilter: function() {
209
+ var self = this,
210
+ results = [];
211
+ get(this, 'modelClass').forEachCachedRecord(function(record) {
212
+ if (self.filterFunction(record)) {
213
+ results.push(record);
214
+ }
215
+ });
216
+ this.set('content', Ember.A(results));
217
+ },
218
+
219
+ updateFilterForRecord: function(record) {
220
+ var results = get(this, 'content');
221
+ if (this.filterFunction(record) && !results.contains(record)) {
222
+ results.pushObject(record);
223
+ }
224
+ },
225
+
226
+ registerObservers: function() {
227
+ var self = this;
228
+ get(this, 'modelClass').forEachCachedRecord(function(record) {
229
+ self.registerObserversOnRecord(record);
230
+ });
231
+ },
232
+
233
+ registerObserversOnRecord: function(record) {
234
+ var self = this,
235
+ filterProperties = get(this, 'filterProperties');
236
+
237
+ for (var i = 0, l = get(filterProperties, 'length'); i < l; i++) {
238
+ record.addObserver(filterProperties[i], self, 'updateFilterForRecord');
239
+ }
240
+ }
241
+ });
242
+
243
+ })();
244
+
245
+ (function() {
246
+
247
+ var get = Ember.get, set = Ember.set;
248
+
249
+ Ember.ManyArray = Ember.RecordArray.extend({
250
+ _records: null,
251
+ originalContent: [],
252
+
253
+ isDirty: function() {
254
+ var originalContent = get(this, 'originalContent'),
255
+ originalContentLength = get(originalContent, 'length'),
256
+ content = get(this, 'content'),
257
+ contentLength = get(content, 'length');
258
+
259
+ if (originalContentLength !== contentLength) { return true; }
260
+
261
+ var isDirty = false;
262
+
263
+ for (var i = 0, l = contentLength; i < l; i++) {
264
+ if (!originalContent.contains(content[i])) {
265
+ isDirty = true;
266
+ break;
267
+ }
268
+ }
269
+
270
+ return isDirty;
271
+ }.property('content.[]', 'originalContent'),
272
+
273
+ objectAtContent: function(idx) {
274
+ var content = get(this, 'content');
275
+
276
+ if (!content.length) { return; }
277
+
278
+ return this.materializeRecord(idx);
279
+ },
280
+
281
+ save: function() {
282
+ // TODO: loop over dirty records only
283
+ return Ember.RSVP.all(this.map(function(record) {
284
+ return record.save();
285
+ }));
286
+ },
287
+
288
+ replaceContent: function(index, removed, added) {
289
+ added = Ember.EnumerableUtils.map(added, function(record) {
290
+ return record._reference;
291
+ }, this);
292
+
293
+ this._super(index, removed, added);
294
+ },
295
+
296
+ _contentWillChange: function() {
297
+ var content = get(this, 'content');
298
+ if (content) {
299
+ content.removeArrayObserver(this);
300
+ this._setupOriginalContent(content);
301
+ }
302
+ }.observesBefore('content'),
303
+
304
+ _contentDidChange: function() {
305
+ var content = get(this, 'content');
306
+ if (content) {
307
+ content.addArrayObserver(this);
308
+ this.arrayDidChange(content, 0, 0, get(content, 'length'));
309
+ }
310
+ }.observes('content'),
311
+
312
+ arrayWillChange: function(item, idx, removedCnt, addedCnt) {},
313
+
314
+ arrayDidChange: function(item, idx, removedCnt, addedCnt) {
315
+ var parent = get(this, 'parent'), relationshipKey = get(this, 'relationshipKey'),
316
+ isDirty = get(this, 'isDirty');
317
+
318
+ if (isDirty) {
319
+ parent._relationshipBecameDirty(relationshipKey);
320
+ } else {
321
+ parent._relationshipBecameClean(relationshipKey);
322
+ }
323
+ },
324
+
325
+ _setupOriginalContent: function(content) {
326
+ content = content || get(this, 'content');
327
+ if (content) {
328
+ set(this, 'originalContent', content.slice());
329
+ }
330
+ },
331
+
332
+ init: function() {
333
+ this._super();
334
+ this._setupOriginalContent();
335
+ this._contentDidChange();
336
+ }
337
+ });
338
+
339
+ Ember.HasManyArray = Ember.ManyArray.extend({
340
+ materializeRecord: function(idx) {
341
+ var klass = get(this, 'modelClass'),
342
+ content = get(this, 'content'),
343
+ reference = content.objectAt(idx),
344
+ record;
345
+
346
+ if (reference.record) {
347
+ record = reference.record;
348
+ } else {
349
+ record = klass.find(reference.id);
350
+ }
351
+
352
+ return record;
353
+ },
354
+
355
+ toJSON: function() {
356
+ var ids = [], content = this.get('content');
357
+
358
+ content.forEach(function(reference) {
359
+ if (reference.id) {
360
+ ids.push(reference.id);
361
+ }
362
+ });
363
+
364
+ return ids;
365
+ }
366
+ });
367
+
368
+ Ember.EmbeddedHasManyArray = Ember.ManyArray.extend({
369
+ create: function(attrs) {
370
+ var klass = get(this, 'modelClass'),
371
+ record = klass.create(attrs);
372
+
373
+ this.pushObject(record);
374
+
375
+ return record; // FIXME: inject parent's id
376
+ },
377
+
378
+ materializeRecord: function(idx) {
379
+ var klass = get(this, 'modelClass'),
380
+ primaryKey = get(klass, 'primaryKey'),
381
+ content = get(this, 'content'),
382
+ reference = content.objectAt(idx),
383
+ attrs = reference.data;
384
+
385
+ if (reference.record) {
386
+ return reference.record;
387
+ } else {
388
+ var record = klass.create({ _reference: reference });
389
+ reference.record = record;
390
+ if (attrs) {
391
+ record.load(attrs[primaryKey], attrs);
392
+ }
393
+ return record;
394
+ }
395
+ },
396
+
397
+ toJSON: function() {
398
+ return this.map(function(record) {
399
+ return record.toJSON();
400
+ });
401
+ }
402
+ });
403
+
404
+
405
+ })();
406
+
407
+ (function() {
408
+
409
+ var get = Ember.get,
410
+ set = Ember.set,
411
+ setProperties = Ember.setProperties,
412
+ meta = Ember.meta,
413
+ underscore = Ember.String.underscore;
414
+
415
+ function contains(array, element) {
416
+ for (var i = 0, l = array.length; i < l; i++) {
417
+ if (array[i] === element) { return true; }
418
+ }
419
+ return false;
420
+ }
421
+
422
+ function concatUnique(toArray, fromArray) {
423
+ var e;
424
+ for (var i = 0, l = fromArray.length; i < l; i++) {
425
+ e = fromArray[i];
426
+ if (!contains(toArray, e)) { toArray.push(e); }
427
+ }
428
+ return toArray;
429
+ }
430
+
431
+ function hasCachedValue(object, key) {
432
+ var objectMeta = meta(object, false);
433
+ if (objectMeta) {
434
+ return key in objectMeta.cache;
435
+ }
436
+ }
437
+
438
+ Ember.run.queues.push('data');
439
+
440
+ Ember.Model = Ember.Object.extend(Ember.Evented, {
441
+ isLoaded: true,
442
+ isLoading: Ember.computed.not('isLoaded'),
443
+ isNew: true,
444
+ isDeleted: false,
445
+ _dirtyAttributes: null,
446
+
447
+ /**
448
+ Called when attribute is accessed.
449
+
450
+ @method getAttr
451
+ @param key {String} key which is being accessed
452
+ @param value {Object} value, which will be returned from getter by default
453
+ */
454
+ getAttr: function(key, value) {
455
+ return value;
456
+ },
457
+
458
+ isDirty: function() {
459
+ var dirtyAttributes = get(this, '_dirtyAttributes');
460
+ return dirtyAttributes && dirtyAttributes.length !== 0 || false;
461
+ }.property('_dirtyAttributes.length'),
462
+
463
+ _relationshipBecameDirty: function(name) {
464
+ var dirtyAttributes = get(this, '_dirtyAttributes');
465
+ if (!dirtyAttributes.contains(name)) { dirtyAttributes.pushObject(name); }
466
+ },
467
+
468
+ _relationshipBecameClean: function(name) {
469
+ var dirtyAttributes = get(this, '_dirtyAttributes');
470
+ dirtyAttributes.removeObject(name);
471
+ },
472
+
473
+ dataKey: function(key) {
474
+ var camelizeKeys = get(this.constructor, 'camelizeKeys');
475
+ var meta = this.constructor.metaForProperty(key);
476
+ if (meta.options && meta.options.key) {
477
+ return camelizeKeys ? underscore(meta.options.key) : meta.options.key;
478
+ }
479
+ return camelizeKeys ? underscore(key) : key;
480
+ },
481
+
482
+ init: function() {
483
+ this._createReference();
484
+ if (!this._dirtyAttributes) {
485
+ set(this, '_dirtyAttributes', []);
486
+ }
487
+ this._super();
488
+ },
489
+
490
+ _createReference: function() {
491
+ var reference = this._reference,
492
+ id = this.getPrimaryKey();
493
+
494
+ if (!reference) {
495
+ reference = this.constructor._getOrCreateReferenceForId(id);
496
+ reference.record = this;
497
+ this._reference = reference;
498
+ } else if (reference.id !== id) {
499
+ reference.id = id;
500
+ this.constructor._cacheReference(reference);
501
+ }
502
+
503
+ if (!reference.id) {
504
+ reference.id = id;
505
+ }
506
+
507
+ return reference;
508
+ },
509
+
510
+ getPrimaryKey: function() {
511
+ return get(this, get(this.constructor, 'primaryKey'));
512
+ },
513
+
514
+ load: function(id, hash) {
515
+ var data = {};
516
+ data[get(this.constructor, 'primaryKey')] = id;
517
+ set(this, '_data', Ember.merge(data, hash));
518
+
519
+ // eagerly load embedded data
520
+ var relationships = this.constructor._relationships || [], meta = Ember.meta(this), relationshipKey, relationship, relationshipMeta, relationshipData, relationshipType;
521
+ for (var i = 0, l = relationships.length; i < l; i++) {
522
+ relationshipKey = relationships[i];
523
+ relationship = meta.descs[relationshipKey];
524
+ relationshipMeta = relationship.meta();
525
+
526
+ if (relationshipMeta.options.embedded) {
527
+ relationshipType = relationshipMeta.type;
528
+ if (typeof relationshipType === "string") {
529
+ relationshipType = Ember.get(Ember.lookup, relationshipType);
530
+ }
531
+
532
+ relationshipData = data[relationshipKey];
533
+ if (relationshipData) {
534
+ relationshipType.load(relationshipData);
535
+ }
536
+ }
537
+ }
538
+
539
+ set(this, 'isLoaded', true);
540
+ set(this, 'isNew', false);
541
+ this._createReference();
542
+ this.trigger('didLoad');
543
+ },
544
+
545
+ didDefineProperty: function(proto, key, value) {
546
+ if (value instanceof Ember.Descriptor) {
547
+ var meta = value.meta();
548
+ var klass = proto.constructor;
549
+
550
+ if (meta.isAttribute) {
551
+ if (!klass._attributes) { klass._attributes = []; }
552
+ klass._attributes.push(key);
553
+ } else if (meta.isRelationship) {
554
+ if (!klass._relationships) { klass._relationships = []; }
555
+ klass._relationships.push(key);
556
+ meta.relationshipKey = key;
557
+ }
558
+ }
559
+ },
560
+
561
+ serializeHasMany: function(key, meta) {
562
+ return this.get(key).toJSON();
563
+ },
564
+
565
+ serializeBelongsTo: function(key, meta) {
566
+ if (meta.options.embedded) {
567
+ var record = this.get(key);
568
+ return record ? record.toJSON() : null;
569
+ } else {
570
+ var primaryKey = get(meta.getType(), 'primaryKey');
571
+ return this.get(key + '.' + primaryKey);
572
+ }
573
+ },
574
+
575
+ toJSON: function() {
576
+ var key, meta,
577
+ json = {},
578
+ attributes = this.constructor.getAttributes(),
579
+ relationships = this.constructor.getRelationships(),
580
+ properties = attributes ? this.getProperties(attributes) : {},
581
+ rootKey = get(this.constructor, 'rootKey');
582
+
583
+ for (key in properties) {
584
+ meta = this.constructor.metaForProperty(key);
585
+ if (meta.type && meta.type.serialize) {
586
+ json[this.dataKey(key)] = meta.type.serialize(properties[key]);
587
+ } else if (meta.type && Ember.Model.dataTypes[meta.type]) {
588
+ json[this.dataKey(key)] = Ember.Model.dataTypes[meta.type].serialize(properties[key]);
589
+ } else {
590
+ json[this.dataKey(key)] = properties[key];
591
+ }
592
+ }
593
+
594
+ if (relationships) {
595
+ var data, relationshipKey;
596
+
597
+ for(var i = 0; i < relationships.length; i++) {
598
+ key = relationships[i];
599
+ meta = this.constructor.metaForProperty(key);
600
+ relationshipKey = meta.options.key || key;
601
+
602
+ if (meta.kind === 'belongsTo') {
603
+ data = this.serializeBelongsTo(key, meta);
604
+ } else {
605
+ data = this.serializeHasMany(key, meta);
606
+ }
607
+
608
+ json[relationshipKey] = data;
609
+
610
+ }
611
+ }
612
+
613
+ if (rootKey) {
614
+ var jsonRoot = {};
615
+ jsonRoot[rootKey] = json;
616
+ return jsonRoot;
617
+ } else {
618
+ return json;
619
+ }
620
+ },
621
+
622
+ save: function() {
623
+ var adapter = this.constructor.adapter;
624
+ set(this, 'isSaving', true);
625
+ if (get(this, 'isNew')) {
626
+ return adapter.createRecord(this);
627
+ } else if (get(this, 'isDirty')) {
628
+ return adapter.saveRecord(this);
629
+ } else { // noop, return a resolved promise
630
+ var self = this,
631
+ promise = new Ember.RSVP.Promise(function(resolve, reject) {
632
+ resolve(self);
633
+ });
634
+ set(this, 'isSaving', false);
635
+ return promise;
636
+ }
637
+ },
638
+
639
+ reload: function() {
640
+ this.getWithDefault('_dirtyAttributes', []).clear();
641
+ return this.constructor.reload(this.get(get(this.constructor, 'primaryKey')));
642
+ },
643
+
644
+ revert: function() {
645
+ this.getWithDefault('_dirtyAttributes', []).clear();
646
+ this.notifyPropertyChange('_data');
647
+ },
648
+
649
+ didCreateRecord: function() {
650
+ var primaryKey = get(this.constructor, 'primaryKey'),
651
+ id = get(this, primaryKey);
652
+
653
+ set(this, 'isNew', false);
654
+
655
+ set(this, '_dirtyAttributes', []);
656
+ this.constructor.addToRecordArrays(this);
657
+ this.trigger('didCreateRecord');
658
+ this.didSaveRecord();
659
+ },
660
+
661
+ didSaveRecord: function() {
662
+ set(this, 'isSaving', false);
663
+ this.trigger('didSaveRecord');
664
+ if (this.get('isDirty')) { this._copyDirtyAttributesToData(); }
665
+ },
666
+
667
+ deleteRecord: function() {
668
+ return this.constructor.adapter.deleteRecord(this);
669
+ },
670
+
671
+ didDeleteRecord: function() {
672
+ this.constructor.removeFromRecordArrays(this);
673
+ set(this, 'isDeleted', true);
674
+ this.trigger('didDeleteRecord');
675
+ },
676
+
677
+ _copyDirtyAttributesToData: function() {
678
+ if (!this._dirtyAttributes) { return; }
679
+ var dirtyAttributes = this._dirtyAttributes,
680
+ data = get(this, '_data'),
681
+ key;
682
+
683
+ if (!data) {
684
+ data = {};
685
+ set(this, '_data', data);
686
+ }
687
+ for (var i = 0, l = dirtyAttributes.length; i < l; i++) {
688
+ // TODO: merge Object.create'd object into prototype
689
+ key = dirtyAttributes[i];
690
+ data[this.dataKey(key)] = this.cacheFor(key);
691
+ }
692
+ set(this, '_dirtyAttributes', []);
693
+ },
694
+
695
+ dataDidChange: Ember.observer(function() {
696
+ this._reloadHasManys();
697
+ }, '_data'),
698
+
699
+ _registerHasManyArray: function(array) {
700
+ if (!this._hasManyArrays) { this._hasManyArrays = Ember.A([]); }
701
+
702
+ this._hasManyArrays.pushObject(array);
703
+ },
704
+
705
+ _reloadHasManys: function() {
706
+ if (!this._hasManyArrays) { return; }
707
+ var i, j;
708
+ for (i = 0; i < this._hasManyArrays.length; i++) {
709
+ var array = this._hasManyArrays[i],
710
+ hasManyContent = this._getHasManyContent(get(array, 'key'), get(array, 'modelClass'), get(array, 'embedded'));
711
+ for (j = 0; j < array.get('length'); j++) {
712
+ if (array.objectAt(j).get('isNew')) {
713
+ hasManyContent.addObject(array.objectAt(j)._reference);
714
+ }
715
+ }
716
+ set(array, 'content', hasManyContent);
717
+ }
718
+ },
719
+
720
+ _getHasManyContent: function(key, type, embedded) {
721
+ var content = get(this, '_data.' + key);
722
+
723
+ if (content) {
724
+ var mapFunction, primaryKey, reference;
725
+ if (embedded) {
726
+ primaryKey = get(type, 'primaryKey');
727
+ mapFunction = function(attrs) {
728
+ reference = type._getOrCreateReferenceForId(attrs[primaryKey]);
729
+ reference.data = attrs;
730
+ return reference;
731
+ };
732
+ } else {
733
+ mapFunction = function(id) { return type._getOrCreateReferenceForId(id); };
734
+ }
735
+ content = Ember.EnumerableUtils.map(content, mapFunction);
736
+ }
737
+
738
+ return Ember.A(content || []);
739
+ }
740
+ });
741
+
742
+ Ember.Model.reopenClass({
743
+ primaryKey: 'id',
744
+
745
+ adapter: Ember.Adapter.create(),
746
+
747
+ _clientIdCounter: 1,
748
+
749
+ getAttributes: function() {
750
+ this.proto(); // force class "compilation" if it hasn't been done.
751
+ var attributes = this._attributes || [];
752
+ if (typeof this.superclass.getAttributes === 'function') {
753
+ attributes = this.superclass.getAttributes().concat(attributes);
754
+ }
755
+ return attributes;
756
+ },
757
+
758
+ getRelationships: function() {
759
+ this.proto(); // force class "compilation" if it hasn't been done.
760
+ var relationships = this._relationships || [];
761
+ if (typeof this.superclass.getRelationships === 'function') {
762
+ relationships = this.superclass.getRelationships().concat(relationships);
763
+ }
764
+ return relationships;
765
+ },
766
+
767
+ fetch: function(id) {
768
+ if (!arguments.length) {
769
+ return this._findFetchAll(true);
770
+ } else if (Ember.isArray(id)) {
771
+ return this._findFetchMany(id, true);
772
+ } else if (typeof id === 'object') {
773
+ return this._findFetchQuery(id, true);
774
+ } else {
775
+ return this._findFetchById(id, true);
776
+ }
777
+ },
778
+
779
+ find: function(id) {
780
+ if (!arguments.length) {
781
+ return this._findFetchAll(false);
782
+ } else if (Ember.isArray(id)) {
783
+ return this._findFetchMany(id, false);
784
+ } else if (typeof id === 'object') {
785
+ return this._findFetchQuery(id, false);
786
+ } else {
787
+ return this._findFetchById(id, false);
788
+ }
789
+ },
790
+
791
+ findQuery: function(params) {
792
+ return this._findFetchQuery(params, false);
793
+ },
794
+
795
+ fetchQuery: function(params) {
796
+ return this._findFetchQuery(params, true);
797
+ },
798
+
799
+ _findFetchQuery: function(params, isFetch) {
800
+ var records = Ember.RecordArray.create({modelClass: this, _query: params});
801
+
802
+ var promise = this.adapter.findQuery(this, records, params);
803
+
804
+ return isFetch ? promise : records;
805
+ },
806
+
807
+ findMany: function(ids) {
808
+ return this._findFetchMany(ids, false);
809
+ },
810
+
811
+ fetchMany: function(ids) {
812
+ return this._findFetchMany(ids, true);
813
+ },
814
+
815
+ _findFetchMany: function(ids, isFetch) {
816
+ Ember.assert("findFetchMany requires an array", Ember.isArray(ids));
817
+
818
+ var records = Ember.RecordArray.create({_ids: ids, modelClass: this}),
819
+ deferred;
820
+
821
+ if (!this.recordArrays) { this.recordArrays = []; }
822
+ this.recordArrays.push(records);
823
+
824
+ if (this._currentBatchIds) {
825
+ concatUnique(this._currentBatchIds, ids);
826
+ this._currentBatchRecordArrays.push(records);
827
+ } else {
828
+ this._currentBatchIds = concatUnique([], ids);
829
+ this._currentBatchRecordArrays = [records];
830
+ }
831
+
832
+ if (isFetch) {
833
+ deferred = Ember.Deferred.create();
834
+ Ember.set(deferred, 'resolveWith', records);
835
+
836
+ if (!this._currentBatchDeferreds) { this._currentBatchDeferreds = []; }
837
+ this._currentBatchDeferreds.push(deferred);
838
+ }
839
+
840
+ Ember.run.scheduleOnce('data', this, this._executeBatch);
841
+
842
+ return isFetch ? deferred : records;
843
+ },
844
+
845
+ findAll: function() {
846
+ return this._findFetchAll(false);
847
+ },
848
+
849
+ fetchAll: function() {
850
+ return this._findFetchAll(true);
851
+ },
852
+
853
+ _findFetchAll: function(isFetch) {
854
+ var self = this;
855
+
856
+ if (this._findAllRecordArray) {
857
+ if (isFetch) {
858
+ return new Ember.RSVP.Promise(function(resolve) {
859
+ resolve(self._findAllRecordArray);
860
+ });
861
+ } else {
862
+ return this._findAllRecordArray;
863
+ }
864
+ }
865
+
866
+ var records = this._findAllRecordArray = Ember.RecordArray.create({modelClass: this});
867
+
868
+ var promise = this.adapter.findAll(this, records);
869
+
870
+ // Remove the cached record array if the promise is rejected
871
+ if (promise.then) {
872
+ promise.then(null, function() {
873
+ self._findAllRecordArray = null;
874
+ return Ember.RSVP.reject.apply(null, arguments);
875
+ });
876
+ }
877
+
878
+ return isFetch ? promise : records;
879
+ },
880
+
881
+ findById: function(id) {
882
+ return this._findFetchById(id, false);
883
+ },
884
+
885
+ fetchById: function(id) {
886
+ return this._findFetchById(id, true);
887
+ },
888
+
889
+ _findFetchById: function(id, isFetch) {
890
+ var record = this.cachedRecordForId(id),
891
+ isLoaded = get(record, 'isLoaded'),
892
+ adapter = get(this, 'adapter'),
893
+ deferredOrPromise;
894
+
895
+ if (isLoaded) {
896
+ if (isFetch) {
897
+ return new Ember.RSVP.Promise(function(resolve, reject) {
898
+ resolve(record);
899
+ });
900
+ } else {
901
+ return record;
902
+ }
903
+ }
904
+
905
+ deferredOrPromise = this._fetchById(record, id);
906
+
907
+ return isFetch ? deferredOrPromise : record;
908
+ },
909
+
910
+ _currentBatchIds: null,
911
+ _currentBatchRecordArrays: null,
912
+ _currentBatchDeferreds: null,
913
+
914
+ reload: function(id) {
915
+ var record = this.cachedRecordForId(id);
916
+ record.set('isLoaded', false);
917
+ return this._fetchById(record, id);
918
+ },
919
+
920
+ _fetchById: function(record, id) {
921
+ var adapter = get(this, 'adapter'),
922
+ deferred;
923
+
924
+ if (adapter.findMany && !adapter.findMany.isUnimplemented) {
925
+ if (this._currentBatchIds) {
926
+ if (!contains(this._currentBatchIds, id)) { this._currentBatchIds.push(id); }
927
+ } else {
928
+ this._currentBatchIds = [id];
929
+ this._currentBatchRecordArrays = [];
930
+ }
931
+
932
+ deferred = Ember.Deferred.create();
933
+
934
+ //Attached the record to the deferred so we can resolove it later.
935
+ Ember.set(deferred, 'resolveWith', record);
936
+
937
+ if (!this._currentBatchDeferreds) { this._currentBatchDeferreds = []; }
938
+ this._currentBatchDeferreds.push(deferred);
939
+
940
+ Ember.run.scheduleOnce('data', this, this._executeBatch);
941
+
942
+ return deferred;
943
+ } else {
944
+ return adapter.find(record, id);
945
+ }
946
+ },
947
+
948
+ _executeBatch: function() {
949
+ var batchIds = this._currentBatchIds,
950
+ batchRecordArrays = this._currentBatchRecordArrays,
951
+ batchDeferreds = this._currentBatchDeferreds,
952
+ self = this,
953
+ requestIds = [],
954
+ promise,
955
+ i;
956
+
957
+ this._currentBatchIds = null;
958
+ this._currentBatchRecordArrays = null;
959
+ this._currentBatchDeferreds = null;
960
+
961
+ for (i = 0; i < batchIds.length; i++) {
962
+ if (!this.cachedRecordForId(batchIds[i]).get('isLoaded')) {
963
+ requestIds.push(batchIds[i]);
964
+ }
965
+ }
966
+
967
+ if (batchIds.length === 1) {
968
+ promise = get(this, 'adapter').find(this.cachedRecordForId(batchIds[0]), batchIds[0]);
969
+ } else {
970
+ var recordArray = Ember.RecordArray.create({_ids: batchIds});
971
+ if (requestIds.length === 0) {
972
+ promise = new Ember.RSVP.Promise(function(resolve, reject) { resolve(recordArray); });
973
+ recordArray.notifyLoaded();
974
+ } else {
975
+ promise = get(this, 'adapter').findMany(this, recordArray, requestIds);
976
+ }
977
+ }
978
+
979
+ promise.then(function() {
980
+ for (var i = 0, l = batchRecordArrays.length; i < l; i++) {
981
+ batchRecordArrays[i].loadForFindMany(self);
982
+ }
983
+
984
+ if (batchDeferreds) {
985
+ for (i = 0, l = batchDeferreds.length; i < l; i++) {
986
+ var resolveWith = Ember.get(batchDeferreds[i], 'resolveWith');
987
+ batchDeferreds[i].resolve(resolveWith);
988
+ }
989
+ }
990
+ }).then(null, function(errorXHR) {
991
+ if (batchDeferreds) {
992
+ for (var i = 0, l = batchDeferreds.length; i < l; i++) {
993
+ batchDeferreds[i].reject(errorXHR);
994
+ }
995
+ }
996
+ });
997
+ },
998
+
999
+ getCachedReferenceRecord: function(id){
1000
+ var ref = this._getReferenceById(id);
1001
+ if(ref) return ref.record;
1002
+ return undefined;
1003
+ },
1004
+
1005
+ cachedRecordForId: function(id) {
1006
+ var record = this.getCachedReferenceRecord(id);
1007
+
1008
+ if (!record) {
1009
+ var primaryKey = get(this, 'primaryKey'),
1010
+ attrs = {isLoaded: false};
1011
+ attrs[primaryKey] = id;
1012
+ record = this.create(attrs);
1013
+ var sideloadedData = this.sideloadedData && this.sideloadedData[id];
1014
+ if (sideloadedData) {
1015
+ record.load(id, sideloadedData);
1016
+ }
1017
+ }
1018
+
1019
+ return record;
1020
+ },
1021
+
1022
+
1023
+ addToRecordArrays: function(record) {
1024
+ if (this._findAllRecordArray) {
1025
+ this._findAllRecordArray.pushObject(record);
1026
+ }
1027
+ if (this.recordArrays) {
1028
+ this.recordArrays.forEach(function(recordArray) {
1029
+ if (recordArray instanceof Ember.FilteredRecordArray) {
1030
+ recordArray.registerObserversOnRecord(record);
1031
+ recordArray.updateFilter();
1032
+ } else {
1033
+ recordArray.pushObject(record);
1034
+ }
1035
+ });
1036
+ }
1037
+ },
1038
+
1039
+ unload: function (record) {
1040
+ this.removeFromRecordArrays(record);
1041
+ var primaryKey = record.get(get(this, 'primaryKey'));
1042
+ this.removeFromCache(primaryKey);
1043
+ },
1044
+
1045
+ clearCache: function () {
1046
+ this.sideloadedData = undefined;
1047
+ this._referenceCache = undefined;
1048
+ },
1049
+
1050
+ removeFromCache: function (key) {
1051
+ if (this.sideloadedData && this.sideloadedData[key]) {
1052
+ delete this.sideloadedData[key];
1053
+ }
1054
+ if(this._referenceCache && this._referenceCache[key]) {
1055
+ delete this._referenceCache[key];
1056
+ }
1057
+ },
1058
+
1059
+ removeFromRecordArrays: function(record) {
1060
+ if (this._findAllRecordArray) {
1061
+ this._findAllRecordArray.removeObject(record);
1062
+ }
1063
+ if (this.recordArrays) {
1064
+ this.recordArrays.forEach(function(recordArray) {
1065
+ recordArray.removeObject(record);
1066
+ });
1067
+ }
1068
+ },
1069
+
1070
+ // FIXME
1071
+ findFromCacheOrLoad: function(data) {
1072
+ var record;
1073
+ if (!data[get(this, 'primaryKey')]) {
1074
+ record = this.create({isLoaded: false});
1075
+ } else {
1076
+ record = this.cachedRecordForId(data[get(this, 'primaryKey')]);
1077
+ }
1078
+ // set(record, 'data', data);
1079
+ record.load(data[get(this, 'primaryKey')], data);
1080
+ return record;
1081
+ },
1082
+
1083
+ registerRecordArray: function(recordArray) {
1084
+ if (!this.recordArrays) { this.recordArrays = []; }
1085
+ this.recordArrays.push(recordArray);
1086
+ },
1087
+
1088
+ unregisterRecordArray: function(recordArray) {
1089
+ if (!this.recordArrays) { return; }
1090
+ Ember.A(this.recordArrays).removeObject(recordArray);
1091
+ },
1092
+
1093
+ forEachCachedRecord: function(callback) {
1094
+ if (!this._referenceCache) { return; }
1095
+ var ids = Object.keys(this._referenceCache);
1096
+ ids.map(function(id) {
1097
+ return this._getReferenceById(id).record;
1098
+ }, this).forEach(callback);
1099
+ },
1100
+
1101
+ load: function(hashes) {
1102
+ if (Ember.typeOf(hashes) !== 'array') { hashes = [hashes]; }
1103
+
1104
+ if (!this.sideloadedData) { this.sideloadedData = {}; }
1105
+
1106
+ for (var i = 0, l = hashes.length; i < l; i++) {
1107
+ var hash = hashes[i],
1108
+ primaryKey = hash[get(this, 'primaryKey')],
1109
+ record = this.getCachedReferenceRecord(primaryKey);
1110
+
1111
+ if (record) {
1112
+ record.load(primaryKey, hash);
1113
+ } else {
1114
+ this.sideloadedData[primaryKey] = hash;
1115
+ }
1116
+ }
1117
+ },
1118
+
1119
+ _getReferenceById: function(id) {
1120
+ if (!this._referenceCache) { this._referenceCache = {}; }
1121
+ return this._referenceCache[id];
1122
+ },
1123
+
1124
+ _getOrCreateReferenceForId: function(id) {
1125
+ var reference = this._getReferenceById(id);
1126
+
1127
+ if (!reference) {
1128
+ reference = this._createReference(id);
1129
+ }
1130
+
1131
+ return reference;
1132
+ },
1133
+
1134
+ _createReference: function(id) {
1135
+ if (!this._referenceCache) { this._referenceCache = {}; }
1136
+
1137
+ Ember.assert('The id ' + id + ' has alread been used with another record of type ' + this.toString() + '.', !id || !this._referenceCache[id]);
1138
+
1139
+ var reference = {
1140
+ id: id,
1141
+ clientId: this._clientIdCounter++
1142
+ };
1143
+
1144
+ this._cacheReference(reference);
1145
+
1146
+ return reference;
1147
+ },
1148
+
1149
+ _cacheReference: function(reference) {
1150
+ if (!this._referenceCache) { this._referenceCache = {}; }
1151
+
1152
+ // if we're creating an item, this process will be done
1153
+ // later, once the object has been persisted.
1154
+ if (reference.id) {
1155
+ this._referenceCache[reference.id] = reference;
1156
+ }
1157
+ }
1158
+ });
1159
+
1160
+
1161
+ })();
1162
+
1163
+ (function() {
1164
+
1165
+ var get = Ember.get;
1166
+
1167
+ Ember.hasMany = function(type, options) {
1168
+ options = options || {};
1169
+
1170
+ var meta = { type: type, isRelationship: true, options: options, kind: 'hasMany' },
1171
+ key = options.key;
1172
+
1173
+ return Ember.computed(function() {
1174
+ if (typeof type === "string") {
1175
+ type = Ember.get(Ember.lookup, type);
1176
+ }
1177
+
1178
+ return this.getHasMany(key, type, meta);
1179
+ }).property().meta(meta);
1180
+ };
1181
+
1182
+ Ember.Model.reopen({
1183
+ getHasMany: function(key, type, meta) {
1184
+ var embedded = meta.options.embedded,
1185
+ collectionClass = embedded ? Ember.EmbeddedHasManyArray : Ember.HasManyArray;
1186
+
1187
+ var collection = collectionClass.create({
1188
+ parent: this,
1189
+ modelClass: type,
1190
+ content: this._getHasManyContent(key, type, embedded),
1191
+ embedded: embedded,
1192
+ key: key,
1193
+ relationshipKey: meta.relationshipKey
1194
+ });
1195
+
1196
+ this._registerHasManyArray(collection);
1197
+
1198
+ return collection;
1199
+ }
1200
+ });
1201
+
1202
+
1203
+ })();
1204
+
1205
+ (function() {
1206
+
1207
+ var get = Ember.get,
1208
+ set = Ember.set;
1209
+
1210
+ function getType() {
1211
+ if (typeof this.type === "string") {
1212
+ this.type = Ember.get(Ember.lookup, this.type);
1213
+ }
1214
+ return this.type;
1215
+ }
1216
+
1217
+ Ember.belongsTo = function(type, options) {
1218
+ options = options || {};
1219
+
1220
+ var meta = { type: type, isRelationship: true, options: options, kind: 'belongsTo', getType: getType },
1221
+ relationshipKey = options.key;
1222
+
1223
+ return Ember.computed(function(key, value, oldValue) {
1224
+ type = meta.getType();
1225
+
1226
+ var dirtyAttributes = get(this, '_dirtyAttributes'),
1227
+ createdDirtyAttributes = false;
1228
+
1229
+ if (!dirtyAttributes) {
1230
+ dirtyAttributes = [];
1231
+ createdDirtyAttributes = true;
1232
+ }
1233
+
1234
+ if (arguments.length > 1) {
1235
+ if (value) {
1236
+ Ember.assert(Ember.String.fmt('Attempted to set property of type: %@ with a value of type: %@',
1237
+ [value.constructor, type]),
1238
+ value instanceof type);
1239
+
1240
+ if (oldValue !== value) {
1241
+ dirtyAttributes.pushObject(key);
1242
+ } else {
1243
+ dirtyAttributes.removeObject(key);
1244
+ }
1245
+
1246
+ if (createdDirtyAttributes) {
1247
+ set(this, '_dirtyAttributes', dirtyAttributes);
1248
+ }
1249
+ }
1250
+ return value === undefined ? null : value;
1251
+ } else {
1252
+ return this.getBelongsTo(relationshipKey, type, meta);
1253
+ }
1254
+ }).property('_data').meta(meta);
1255
+ };
1256
+
1257
+ Ember.Model.reopen({
1258
+ getBelongsTo: function(key, type, meta) {
1259
+ var idOrAttrs = get(this, '_data.' + key),
1260
+ record;
1261
+
1262
+ if (Ember.isNone(idOrAttrs)) {
1263
+ return null;
1264
+ }
1265
+
1266
+ if (meta.options.embedded) {
1267
+ var primaryKey = get(type, 'primaryKey'),
1268
+ id = idOrAttrs[primaryKey];
1269
+ record = type.create({ isLoaded: false, id: id });
1270
+ record.load(id, idOrAttrs);
1271
+ } else {
1272
+ record = type.find(idOrAttrs);
1273
+ }
1274
+
1275
+ return record;
1276
+ }
1277
+ });
1278
+
1279
+
1280
+ })();
1281
+
1282
+ (function() {
1283
+
1284
+ var get = Ember.get,
1285
+ set = Ember.set,
1286
+ meta = Ember.meta;
1287
+
1288
+ Ember.Model.dataTypes = {};
1289
+
1290
+ Ember.Model.dataTypes[Date] = {
1291
+ deserialize: function(string) {
1292
+ if (!string) { return null; }
1293
+ return new Date(string);
1294
+ },
1295
+ serialize: function (date) {
1296
+ if (!date) { return null; }
1297
+ return date.toISOString();
1298
+ },
1299
+ isEqual: function(obj1, obj2) {
1300
+ if (obj1 instanceof Date) { obj1 = this.serialize(obj1); }
1301
+ if (obj2 instanceof Date) { obj2 = this.serialize(obj2); }
1302
+ return obj1 === obj2;
1303
+ }
1304
+ };
1305
+
1306
+ Ember.Model.dataTypes[Number] = {
1307
+ deserialize: function(string) {
1308
+ if (!string && string !== 0) { return null; }
1309
+ return Number(string);
1310
+ },
1311
+ serialize: function (number) {
1312
+ if (!number && number !== 0) { return null; }
1313
+ return Number(number);
1314
+ }
1315
+ };
1316
+
1317
+ function deserialize(value, type) {
1318
+ if (type && type.deserialize) {
1319
+ return type.deserialize(value);
1320
+ } else if (type && Ember.Model.dataTypes[type]) {
1321
+ return Ember.Model.dataTypes[type].deserialize(value);
1322
+ } else {
1323
+ return value;
1324
+ }
1325
+ }
1326
+
1327
+ function serialize(value, type) {
1328
+ if (type && type.serialize) {
1329
+ return type.serialize(value);
1330
+ } else if (type && Ember.Model.dataTypes[type]) {
1331
+ return Ember.Model.dataTypes[type].serialize(value);
1332
+ } else {
1333
+ return value;
1334
+ }
1335
+ }
1336
+
1337
+ Ember.attr = function(type, options) {
1338
+ return Ember.computed(function(key, value) {
1339
+ var data = get(this, '_data'),
1340
+ dataKey = this.dataKey(key),
1341
+ dataValue = data && get(data, dataKey),
1342
+ beingCreated = meta(this).proto === this,
1343
+ dirtyAttributes = get(this, '_dirtyAttributes'),
1344
+ createdDirtyAttributes = false;
1345
+
1346
+ if (!dirtyAttributes) {
1347
+ dirtyAttributes = [];
1348
+ createdDirtyAttributes = true;
1349
+ }
1350
+
1351
+ if (arguments.length === 2) {
1352
+ if (beingCreated) {
1353
+ if (!data) {
1354
+ data = {};
1355
+ set(this, '_data', data);
1356
+ }
1357
+ dataValue = data[dataKey] = value;
1358
+ }
1359
+
1360
+ if (dataValue !== serialize(value, type)) {
1361
+ dirtyAttributes.pushObject(key);
1362
+ } else {
1363
+ dirtyAttributes.removeObject(key);
1364
+ }
1365
+
1366
+ if (createdDirtyAttributes) {
1367
+ set(this, '_dirtyAttributes', dirtyAttributes);
1368
+ }
1369
+
1370
+ return value;
1371
+ }
1372
+
1373
+ return this.getAttr(key, deserialize(dataValue, type));
1374
+ }).property('_data').meta({isAttribute: true, type: type, options: options});
1375
+ };
1376
+
1377
+
1378
+ })();
1379
+
1380
+ (function() {
1381
+
1382
+ var get = Ember.get;
1383
+
1384
+ Ember.RESTAdapter = Ember.Adapter.extend({
1385
+ find: function(record, id) {
1386
+ var url = this.buildURL(record.constructor, id),
1387
+ self = this;
1388
+
1389
+ return this.ajax(url).then(function(data) {
1390
+ self.didFind(record, id, data);
1391
+ return record;
1392
+ });
1393
+ },
1394
+
1395
+ didFind: function(record, id, data) {
1396
+ var rootKey = get(record.constructor, 'rootKey'),
1397
+ dataToLoad = rootKey ? data[rootKey] : data;
1398
+
1399
+ record.load(id, dataToLoad);
1400
+ },
1401
+
1402
+ findAll: function(klass, records) {
1403
+ var url = this.buildURL(klass),
1404
+ self = this;
1405
+
1406
+ return this.ajax(url).then(function(data) {
1407
+ self.didFindAll(klass, records, data);
1408
+ return records;
1409
+ });
1410
+ },
1411
+
1412
+ didFindAll: function(klass, records, data) {
1413
+ var collectionKey = get(klass, 'collectionKey'),
1414
+ dataToLoad = collectionKey ? data[collectionKey] : data;
1415
+
1416
+ records.load(klass, dataToLoad);
1417
+ },
1418
+
1419
+ findQuery: function(klass, records, params) {
1420
+ var url = this.buildURL(klass),
1421
+ self = this;
1422
+
1423
+ return this.ajax(url, params).then(function(data) {
1424
+ self.didFindQuery(klass, records, params, data);
1425
+ return records;
1426
+ });
1427
+ },
1428
+
1429
+ didFindQuery: function(klass, records, params, data) {
1430
+ var collectionKey = get(klass, 'collectionKey'),
1431
+ dataToLoad = collectionKey ? data[collectionKey] : data;
1432
+
1433
+ records.load(klass, dataToLoad);
1434
+ },
1435
+
1436
+ createRecord: function(record) {
1437
+ var url = this.buildURL(record.constructor),
1438
+ self = this;
1439
+
1440
+ return this.ajax(url, record.toJSON(), "POST").then(function(data) {
1441
+ self.didCreateRecord(record, data);
1442
+ return record;
1443
+ });
1444
+ },
1445
+
1446
+ didCreateRecord: function(record, data) {
1447
+ var rootKey = get(record.constructor, 'rootKey'),
1448
+ primaryKey = get(record.constructor, 'primaryKey'),
1449
+ dataToLoad = rootKey ? data[rootKey] : data;
1450
+ record.load(dataToLoad[primaryKey], dataToLoad);
1451
+ record.didCreateRecord();
1452
+ },
1453
+
1454
+ saveRecord: function(record) {
1455
+ var primaryKey = get(record.constructor, 'primaryKey'),
1456
+ url = this.buildURL(record.constructor, get(record, primaryKey)),
1457
+ self = this;
1458
+
1459
+ return this.ajax(url, record.toJSON(), "PUT").then(function(data) { // TODO: Some APIs may or may not return data
1460
+ self.didSaveRecord(record, data);
1461
+ return record;
1462
+ });
1463
+ },
1464
+
1465
+ didSaveRecord: function(record, data) {
1466
+ record.didSaveRecord();
1467
+ },
1468
+
1469
+ deleteRecord: function(record) {
1470
+ var primaryKey = get(record.constructor, 'primaryKey'),
1471
+ url = this.buildURL(record.constructor, get(record, primaryKey)),
1472
+ self = this;
1473
+
1474
+ return this.ajax(url, record.toJSON(), "DELETE").then(function(data) { // TODO: Some APIs may or may not return data
1475
+ self.didDeleteRecord(record, data);
1476
+ });
1477
+ },
1478
+
1479
+ didDeleteRecord: function(record, data) {
1480
+ record.didDeleteRecord();
1481
+ },
1482
+
1483
+ ajax: function(url, params, method, settings) {
1484
+ return this._ajax(url, params, (method || "GET"), settings);
1485
+ },
1486
+
1487
+ buildURL: function(klass, id) {
1488
+ var urlRoot = get(klass, 'url');
1489
+ if (!urlRoot) { throw new Error('Ember.RESTAdapter requires a `url` property to be specified'); }
1490
+
1491
+ if (!Ember.isEmpty(id)) {
1492
+ return urlRoot + "/" + id + ".json";
1493
+ } else {
1494
+ return urlRoot + ".json";
1495
+ }
1496
+ },
1497
+
1498
+ ajaxSettings: function(url, method) {
1499
+ return {
1500
+ url: url,
1501
+ type: method,
1502
+ dataType: "json"
1503
+ };
1504
+ },
1505
+
1506
+ _ajax: function(url, params, method, settings) {
1507
+ if (!settings) {
1508
+ settings = this.ajaxSettings(url, method);
1509
+ }
1510
+
1511
+ return new Ember.RSVP.Promise(function(resolve, reject) {
1512
+ if (params) {
1513
+ if (method === "GET") {
1514
+ settings.data = params;
1515
+ } else {
1516
+ settings.contentType = "application/json; charset=utf-8";
1517
+ settings.data = JSON.stringify(params);
1518
+ }
1519
+ }
1520
+
1521
+ settings.success = function(json) {
1522
+ Ember.run(null, resolve, json);
1523
+ };
1524
+
1525
+ settings.error = function(jqXHR, textStatus, errorThrown) {
1526
+ // https://github.com/ebryn/ember-model/issues/202
1527
+ if (jqXHR) {
1528
+ jqXHR.then = null;
1529
+ }
1530
+
1531
+ Ember.run(null, reject, jqXHR);
1532
+ };
1533
+
1534
+
1535
+ Ember.$.ajax(settings);
1536
+ });
1537
+ }
1538
+ });
1539
+
1540
+
1541
+ })();
1542
+
1543
+ (function() {
1544
+
1545
+ var get = Ember.get;
1546
+
1547
+ Ember.LoadPromise = Ember.Object.extend(Ember.DeferredMixin, {
1548
+ init: function() {
1549
+ this._super.apply(this, arguments);
1550
+
1551
+ var target = get(this, 'target');
1552
+
1553
+ if (get(target, 'isLoaded') && !get(target, 'isNew')) {
1554
+ this.resolve(target);
1555
+ } else {
1556
+ target.one('didLoad', this, function() {
1557
+ this.resolve(target);
1558
+ });
1559
+ }
1560
+ }
1561
+ });
1562
+
1563
+ Ember.loadPromise = function(target) {
1564
+ if (Ember.isNone(target)) {
1565
+ return null;
1566
+ } else if (target.then) {
1567
+ return target;
1568
+ } else {
1569
+ return Ember.LoadPromise.create({target: target});
1570
+ }
1571
+ };
1572
+
1573
+
1574
+ })();
1575
+
1576
+ (function() {
1577
+
1578
+ // This is a debug adapter for the Ember Extension, don't let the fact this is called an "adapter" confuse you.
1579
+ // Most copied from: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/debug/debug_adapter.js
1580
+
1581
+ if (!Ember.DataAdapter) { return; }
1582
+
1583
+ var get = Ember.get, capitalize = Ember.String.capitalize, underscore = Ember.String.underscore;
1584
+
1585
+ var DebugAdapter = Ember.DataAdapter.extend({
1586
+ getFilters: function() {
1587
+ return [
1588
+ { name: 'isNew', desc: 'New' },
1589
+ { name: 'isModified', desc: 'Modified' },
1590
+ { name: 'isClean', desc: 'Clean' }
1591
+ ];
1592
+ },
1593
+
1594
+ detect: function(klass) {
1595
+ return klass !== Ember.Model && Ember.Model.detect(klass);
1596
+ },
1597
+
1598
+ columnsForType: function(type) {
1599
+ var columns = [], count = 0, self = this;
1600
+ type.getAttributes().forEach(function(name, meta) {
1601
+ if (count++ > self.attributeLimit) { return false; }
1602
+ var desc = capitalize(underscore(name).replace('_', ' '));
1603
+ columns.push({ name: name, desc: desc });
1604
+ });
1605
+ return columns;
1606
+ },
1607
+
1608
+ getRecords: function(type) {
1609
+ var records = [];
1610
+ type.forEachCachedRecord(function(record) { records.push(record); });
1611
+ return records;
1612
+ },
1613
+
1614
+ getRecordColumnValues: function(record) {
1615
+ var self = this, count = 0,
1616
+ columnValues = { id: get(record, 'id') };
1617
+
1618
+ record.constructor.getAttributes().forEach(function(key) {
1619
+ if (count++ > self.attributeLimit) {
1620
+ return false;
1621
+ }
1622
+ var value = get(record, key);
1623
+ columnValues[key] = value;
1624
+ });
1625
+ return columnValues;
1626
+ },
1627
+
1628
+ getRecordKeywords: function(record) {
1629
+ var keywords = [], keys = Ember.A(['id']);
1630
+ record.constructor.getAttributes().forEach(function(key) {
1631
+ keys.push(key);
1632
+ });
1633
+ keys.forEach(function(key) {
1634
+ keywords.push(get(record, key));
1635
+ });
1636
+ return keywords;
1637
+ },
1638
+
1639
+ getRecordFilterValues: function(record) {
1640
+ return {
1641
+ isNew: record.get('isNew'),
1642
+ isModified: record.get('isDirty') && !record.get('isNew'),
1643
+ isClean: !record.get('isDirty')
1644
+ };
1645
+ },
1646
+
1647
+ getRecordColor: function(record) {
1648
+ var color = 'black';
1649
+ if (record.get('isNew')) {
1650
+ color = 'green';
1651
+ } else if (record.get('isDirty')) {
1652
+ color = 'blue';
1653
+ }
1654
+ return color;
1655
+ },
1656
+
1657
+ observeRecord: function(record, recordUpdated) {
1658
+ var releaseMethods = Ember.A(), self = this,
1659
+ keysToObserve = Ember.A(['id', 'isNew', 'isDirty']);
1660
+
1661
+ record.constructor.getAttributes().forEach(function(key) {
1662
+ keysToObserve.push(key);
1663
+ });
1664
+
1665
+ keysToObserve.forEach(function(key) {
1666
+ var handler = function() {
1667
+ recordUpdated(self.wrapRecord(record));
1668
+ };
1669
+ Ember.addObserver(record, key, handler);
1670
+ releaseMethods.push(function() {
1671
+ Ember.removeObserver(record, key, handler);
1672
+ });
1673
+ });
1674
+
1675
+ var release = function() {
1676
+ releaseMethods.forEach(function(fn) { fn(); } );
1677
+ };
1678
+
1679
+ return release;
1680
+ }
1681
+ });
1682
+
1683
+ Ember.onLoad('Ember.Application', function(Application) {
1684
+ Application.initializer({
1685
+ name: "dataAdapter",
1686
+
1687
+ initialize: function(container, application) {
1688
+ application.register('dataAdapter:main', DebugAdapter);
1689
+ }
1690
+ });
1691
+ });
1692
+
1693
+ })();