mes 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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
+ })();