Commit 258e1720 authored by Pascal Hartig's avatar Pascal Hartig

Ember: Soft-upgrade 1.6 dependencies

parent 12b68729
...@@ -6,13 +6,14 @@ ...@@ -6,13 +6,14 @@
DS.LSSerializer = DS.JSONSerializer.extend({ DS.LSSerializer = DS.JSONSerializer.extend({
serializeHasMany: function(record, json, relationship) { serializeHasMany: function(record, json, relationship) {
var key = relationship.key, var key = relationship.key;
relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship); var payloadKey = this.keyForRelationship ? this.keyForRelationship(key, "hasMany") : key;
var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship);
if (relationshipType === 'manyToNone' || if (relationshipType === 'manyToNone' ||
relationshipType === 'manyToMany' || relationshipType === 'manyToMany' ||
relationshipType === 'manyToOne') { relationshipType === 'manyToOne') {
json[key] = record.get(key).mapBy('id'); json[payloadKey] = record.get(key).mapBy('id');
// TODO support for polymorphic manyToNone and manyToMany relationships // TODO support for polymorphic manyToNone and manyToMany relationships
} }
}, },
...@@ -84,12 +85,9 @@ ...@@ -84,12 +85,9 @@
* @param {Array} payload returned JSONs * @param {Array} payload returned JSONs
*/ */
extractArray: function(store, type, payload) { extractArray: function(store, type, payload) {
var serializer = this; return payload.map(function(json) {
return this.extractSingle(store, type, json);
return payload.map(function(record) { }, this);
var extracted = serializer.extractSingle(store, type, record);
return serializer.normalize(type, record);
});
} }
}); });
...@@ -104,9 +102,9 @@ ...@@ -104,9 +102,9 @@
@param {Object|String|Integer|null} id @param {Object|String|Integer|null} id
*/ */
find: function(store, type, id, opts) { find: function(store, type, id, opts) {
var adapter = this;
var allowRecursive = true; var allowRecursive = true;
var namespace = this._namespaceForType(type); var namespace = this._namespaceForType(type);
var record = Ember.A(namespace.records[id]);
/** /**
* In the case where there are relationships, this method is called again * In the case where there are relationships, this method is called again
...@@ -120,44 +118,51 @@ ...@@ -120,44 +118,51 @@
allowRecursive = opts.allowRecursive; allowRecursive = opts.allowRecursive;
} }
return new Ember.RSVP.Promise(function(resolve, reject) {
var record = Ember.A(namespace.records[id]);
if (!record || !record.hasOwnProperty('id')) { if (!record || !record.hasOwnProperty('id')) {
store.dematerializeRecord(store.typeMapFor(type).idToRecord[id]); return Ember.RSVP.reject(new Error("Couldn't find record of"
reject(); + " type '" + type.typeKey
return; + "' for the id '" + id + "'."));
} }
if (allowRecursive) { if (allowRecursive) {
adapter.loadRelationships(type, record).then(function(finalRecord) { return this.loadRelationships(type, record);
resolve(finalRecord);
});
} else { } else {
resolve(record); return Ember.RSVP.resolve(record);
} }
});
}, },
findMany: function (store, type, ids) { findMany: function (store, type, ids, opts) {
var adapter = this;
var namespace = this._namespaceForType(type); var namespace = this._namespaceForType(type);
var adapter = this,
allowRecursive = true,
results = [], record;
return new Ember.RSVP.Promise(function(resolve, reject) { /**
var results = []; * In the case where there are relationships, this method is called again
* for each relation. Given the relations have references to the main
* object, we use allowRecursive to avoid going further into infinite
* recursiveness.
*
* Concept from ember-indexdb-adapter
*/
if (opts && typeof opts.allowRecursive !== 'undefined') {
allowRecursive = opts.allowRecursive;
}
for (var i = 0; i < ids.length; i++) { for (var i = 0; i < ids.length; i++) {
results.push(Ember.copy(namespace.records[ids[i]])); record = namespace.records[ids[i]];
if (!record || !record.hasOwnProperty('id')) {
return Ember.RSVP.reject(new Error("Couldn't find record of type '" + type.typeKey
+ "' for the id '" + ids[i] + "'."));
}
results.push(Ember.copy(record));
} }
resolve(results); if (results.get('length') && allowRecursive) {
}).then(function(records) { return this.loadRelationshipsForMany(type, results);
if (records.get('length')) {
return adapter.loadRelationshipsForMany(type, records);
} else { } else {
return records; return Ember.RSVP.resolve(results);
} }
});
}, },
// Supports queries that look like this: // Supports queries that look like this:
...@@ -175,33 +180,34 @@ ...@@ -175,33 +180,34 @@
// //
// { complete: true, name: /foo|bar/ } // { complete: true, name: /foo|bar/ }
findQuery: function (store, type, query, recordArray) { findQuery: function (store, type, query, recordArray) {
var namespace = this._namespaceForType(type), var namespace = this._namespaceForType(type);
results = this.query(namespace.records, query); var results = this.query(namespace.records, query);
if (results.get('length')) { if (results.get('length')) {
results = this.loadRelationshipsForMany(type, results); return this.loadRelationshipsForMany(type, results);
return Ember.RSVP.resolve(results);
} else { } else {
return Ember.RSVP.reject(); return Ember.RSVP.reject();
} }
}, },
query: function (records, query) { query: function (records, query) {
var results = [], var results = [], record;
id, record, property, test, push;
for (id in records) { function recordMatchesQuery(record) {
record = records[id]; return Ember.keys(query).every(function(property) {
for (property in query) { var test = query[property];
test = query[property];
push = false;
if (Object.prototype.toString.call(test) === '[object RegExp]') { if (Object.prototype.toString.call(test) === '[object RegExp]') {
push = test.test(record[property]); return test.test(record[property]);
} else { } else {
push = record[property] === test; return record[property] === test;
} }
});
} }
if (push) {
results.push(record); for (var id in records) {
record = records[id];
if (recordMatchesQuery(record)) {
results.push(Ember.copy(record));
} }
} }
return results; return results;
...@@ -218,8 +224,8 @@ ...@@ -218,8 +224,8 @@
}, },
createRecord: function (store, type, record) { createRecord: function (store, type, record) {
var namespaceRecords = this._namespaceForType(type), var namespaceRecords = this._namespaceForType(type);
recordHash = record.serialize({includeId: true}); var recordHash = record.serialize({includeId: true});
namespaceRecords.records[recordHash.id] = recordHash; namespaceRecords.records[recordHash.id] = recordHash;
...@@ -228,8 +234,8 @@ ...@@ -228,8 +234,8 @@
}, },
updateRecord: function (store, type, record) { updateRecord: function (store, type, record) {
var namespaceRecords = this._namespaceForType(type), var namespaceRecords = this._namespaceForType(type);
id = record.get('id'); var id = record.get('id');
namespaceRecords.records[id] = record.serialize({ includeId: true }); namespaceRecords.records[id] = record.serialize({ includeId: true });
...@@ -238,8 +244,8 @@ ...@@ -238,8 +244,8 @@
}, },
deleteRecord: function (store, type, record) { deleteRecord: function (store, type, record) {
var namespaceRecords = this._namespaceForType(type), var namespaceRecords = this._namespaceForType(type);
id = record.get('id'); var id = record.get('id');
delete namespaceRecords.records[id]; delete namespaceRecords.records[id];
...@@ -263,8 +269,8 @@ ...@@ -263,8 +269,8 @@
}, },
persistData: function(type, data) { persistData: function(type, data) {
var modelNamespace = this.modelNamespace(type), var modelNamespace = this.modelNamespace(type);
localStorageData = this.loadData(); var localStorageData = this.loadData();
localStorageData[modelNamespace] = data; localStorageData[modelNamespace] = data;
...@@ -272,10 +278,10 @@ ...@@ -272,10 +278,10 @@
}, },
_namespaceForType: function (type) { _namespaceForType: function (type) {
var namespace = this.modelNamespace(type), var namespace = this.modelNamespace(type);
storage = localStorage.getItem(this.adapterNamespace()); var storage = this.loadData();
return storage ? JSON.parse(storage)[namespace] || {records: {}} : {records: {}}; return storage[namespace] || {records: {}};
}, },
modelNamespace: function(type) { modelNamespace: function(type) {
...@@ -326,27 +332,29 @@ ...@@ -326,27 +332,29 @@
* @param {Object} record * @param {Object} record
*/ */
loadRelationships: function(type, record) { loadRelationships: function(type, record) {
var adapter = this; var adapter = this,
resultJSON = {},
return new Ember.RSVP.Promise(function(resolve, reject) {
var resultJSON = {},
typeKey = type.typeKey, typeKey = type.typeKey,
relationshipNames, relationships, relationshipNames, relationships,
relationshipPromises = []; relationshipPromises = [];
/**
* Create a chain of promises, so the relationships are
* loaded sequentially. Think of the variable
* `recordPromise` as of the accumulator in a left fold.
*/
var recordPromise = Ember.RSVP.resolve(record);
relationshipNames = Ember.get(type, 'relationshipNames'); relationshipNames = Ember.get(type, 'relationshipNames');
relationships = relationshipNames.belongsTo; relationships = relationshipNames.belongsTo
relationships = relationships.concat(relationshipNames.hasMany); .concat(relationshipNames.hasMany);
relationships.forEach(function(relationName) { relationships.forEach(function(relationName) {
var relationModel = type.typeForRelationship(relationName), var relationModel = type.typeForRelationship(relationName);
relationEmbeddedId = record[relationName], var relationEmbeddedId = record[relationName];
relationProp = adapter.relationshipProperties(type, relationName), var relationProp = adapter.relationshipProperties(type, relationName);
relationType = relationProp.kind, var relationType = relationProp.kind;
/** var foreignAdapter = type.store.adapterFor(relationModel);
* This is the relationship field.
*/
promise, embedPromise;
var opts = {allowRecursive: false}; var opts = {allowRecursive: false};
...@@ -364,28 +372,24 @@ ...@@ -364,28 +372,24 @@
* In this case, cart belongsTo customer and its id is present in the * In this case, cart belongsTo customer and its id is present in the
* main payload. We find each of these records and add them to _embedded. * main payload. We find each of these records and add them to _embedded.
*/ */
if (relationEmbeddedId) { if (relationEmbeddedId && foreignAdapter === adapter)
if (relationType == 'belongsTo' || relationType == 'hasOne') { {
promise = adapter.find(null, relationModel, relationEmbeddedId, opts) recordPromise = recordPromise.then(function(recordPayload) {
var promise;
if (relationType === 'belongsTo' || relationType === 'hasOne') {
promise = adapter.find(null, relationModel, relationEmbeddedId, opts);
} else if (relationType == 'hasMany') { } else if (relationType == 'hasMany') {
promise = adapter.findMany(null, relationModel, relationEmbeddedId, opts) promise = adapter.findMany(null, relationModel, relationEmbeddedId, opts);
} }
embedPromise = new Ember.RSVP.Promise(function(resolve, reject) { return promise.then(function(relationRecord) {
promise.then(function(relationRecord) { return adapter.addEmbeddedPayload(recordPayload, relationName, relationRecord);
var finalPayload = adapter.addEmbeddedPayload(record, relationName, relationRecord)
resolve(finalPayload);
}); });
}); });
relationshipPromises.push(embedPromise);
} }
}); });
Ember.RSVP.all(relationshipPromises).then(function() { return recordPromise;
resolve(record);
});
});
}, },
...@@ -427,13 +431,13 @@ ...@@ -427,13 +431,13 @@
* @param {Object} relationshipRecord * @param {Object} relationshipRecord
*/ */
addEmbeddedPayload: function(payload, relationshipName, relationshipRecord) { addEmbeddedPayload: function(payload, relationshipName, relationshipRecord) {
var objectHasId = (relationshipRecord && relationshipRecord.id), var objectHasId = (relationshipRecord && relationshipRecord.id);
arrayHasIds = (relationshipRecord.length && relationshipRecord.everyBy("id")), var arrayHasIds = (relationshipRecord.length && relationshipRecord.everyBy("id"));
isValidRelationship = (objectHasId || arrayHasIds); var isValidRelationship = (objectHasId || arrayHasIds);
if (isValidRelationship) { if (isValidRelationship) {
if (!payload['_embedded']) { if (!payload['_embedded']) {
payload['_embedded'] = {} payload['_embedded'] = {};
} }
payload['_embedded'][relationshipName] = relationshipRecord; payload['_embedded'][relationshipName] = relationshipRecord;
...@@ -467,47 +471,24 @@ ...@@ -467,47 +471,24 @@
* @param {Object} recordsArray * @param {Object} recordsArray
*/ */
loadRelationshipsForMany: function(type, recordsArray) { loadRelationshipsForMany: function(type, recordsArray) {
var adapter = this; var adapter = this,
promise = Ember.RSVP.resolve([]);
return new Ember.RSVP.Promise(function(resolve, reject) {
var recordsWithRelationships = [],
recordsToBeLoaded = [],
promises = [];
/** /**
* Some times Ember puts some stuff in arrays. We want to clean it so * Create a chain of promises, so the records are loaded sequentially.
* we know exactly what to iterate over. * Think of the variable promise as of the accumulator in a left fold.
*/ */
for (var i in recordsArray) { recordsArray.forEach(function(record) {
if (recordsArray.hasOwnProperty(i)) { promise = promise.then(function(records) {
recordsToBeLoaded.push(recordsArray[i]); return adapter.loadRelationships(type, record)
} .then(function(loadedRecord) {
} records.push(loadedRecord);
return records;
var loadNextRecord = function(record) { });
/**
* Removes the first item from recordsToBeLoaded
*/
recordsToBeLoaded = recordsToBeLoaded.slice(1);
var promise = adapter.loadRelationships(type, record);
promise.then(function(recordWithRelationships) {
recordsWithRelationships.push(recordWithRelationships);
if (recordsToBeLoaded[0]) {
loadNextRecord(recordsToBeLoaded[0]);
} else {
resolve(recordsWithRelationships);
}
}); });
}
/**
* We start by the first record
*/
loadNextRecord(recordsToBeLoaded[0]);
}); });
return promise;
}, },
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright 2008-2011 Apple Inc. All rights reserved. * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
* @license Licensed under MIT license * @license Licensed under MIT license
* See https://raw.github.com/emberjs/ember.js/master/LICENSE * See https://raw.github.com/emberjs/ember.js/master/LICENSE
* @version 1.6.0 * @version 1.6.1
*/ */
...@@ -2518,7 +2518,7 @@ define("ember-metal/core", ...@@ -2518,7 +2518,7 @@ define("ember-metal/core",
@class Ember @class Ember
@static @static
@version 1.6.0 @version 1.6.1
*/ */
if ('undefined' === typeof Ember) { if ('undefined' === typeof Ember) {
...@@ -2545,10 +2545,10 @@ define("ember-metal/core", ...@@ -2545,10 +2545,10 @@ define("ember-metal/core",
/** /**
@property VERSION @property VERSION
@type String @type String
@default '1.6.0' @default '1.6.1'
@static @static
*/ */
Ember.VERSION = '1.6.0'; Ember.VERSION = '1.6.1';
/** /**
Standard environmental variables. You can define these in a global `EmberENV` Standard environmental variables. You can define these in a global `EmberENV`
...@@ -39379,7 +39379,7 @@ define("ember-routing/system/router", ...@@ -39379,7 +39379,7 @@ define("ember-routing/system/router",
} else if (error.name === 'TransitionAborted') { } else if (error.name === 'TransitionAborted') {
// just ignore TransitionAborted here // just ignore TransitionAborted here
} else { } else {
throw error; logError(error);
} }
return error; return error;
...@@ -39522,16 +39522,7 @@ define("ember-routing/system/router", ...@@ -39522,16 +39522,7 @@ define("ember-routing/system/router",
return; return;
} }
var errorArgs = ['Error while processing route: ' + transition.targetName]; logError(error, 'Error while processing route: ' + transition.targetName);
if (error) {
if (error.message) { errorArgs.push(error.message); }
if (error.stack) { errorArgs.push(error.stack); }
if (typeof error === "string") { errorArgs.push(error); }
}
Ember.Logger.error.apply(this, errorArgs);
}, },
loading: function(transition, originRoute) { loading: function(transition, originRoute) {
...@@ -39562,6 +39553,21 @@ define("ember-routing/system/router", ...@@ -39562,6 +39553,21 @@ define("ember-routing/system/router",
} }
}; };
function logError(error, initialMessage) {
var errorArgs = [];
if (initialMessage) { errorArgs.push(initialMessage); }
if (error) {
if (error.message) { errorArgs.push(error.message); }
if (error.stack) { errorArgs.push(error.stack); }
if (typeof error === "string") { errorArgs.push(error); }
}
Ember.Logger.error.apply(this, errorArgs);
}
function findChildRouteName(parentRoute, originatingChildRoute, name) { function findChildRouteName(parentRoute, originatingChildRoute, name) {
var router = parentRoute.router, var router = parentRoute.router,
childName, childName,
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment