mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 13:38:26 +02:00
@@ -3,7 +3,9 @@ iD.Entity = function(attrs) {
|
||||
if (this instanceof iD.Entity) return;
|
||||
|
||||
// Create the appropriate subtype.
|
||||
if (attrs && attrs.type) {
|
||||
if (attrs && attrs.id) {
|
||||
return iD.Entity[iD.Entity.id.type(attrs.id)].apply(this, arguments);
|
||||
} else if (attrs && attrs.type) {
|
||||
return iD.Entity[attrs.type].apply(this, arguments);
|
||||
}
|
||||
|
||||
@@ -31,7 +33,7 @@ iD.Entity.id.type = function(id) {
|
||||
|
||||
// A function suitable for use as the second argument to d3.selection#data().
|
||||
iD.Entity.key = function(entity) {
|
||||
return entity.id + ',' + entity.v;
|
||||
return entity.id + 'v' + (entity.v || 0);
|
||||
};
|
||||
|
||||
iD.Entity.areaPath = d3.geo.path()
|
||||
|
||||
+4
-18
@@ -263,28 +263,14 @@ iD.Graph.prototype = {
|
||||
|
||||
// Obliterates any existing entities
|
||||
load: function(entities) {
|
||||
|
||||
var base = this.base(),
|
||||
i, entity, prefix;
|
||||
var base = this.base();
|
||||
this.entities = Object.create(base.entities);
|
||||
|
||||
for (i in entities) {
|
||||
entity = entities[i];
|
||||
prefix = i[0];
|
||||
|
||||
if (entity === 'undefined') {
|
||||
this.entities[i] = undefined;
|
||||
} else if (prefix == 'n') {
|
||||
this.entities[i] = new iD.Node(entity);
|
||||
|
||||
} else if (prefix == 'w') {
|
||||
this.entities[i] = new iD.Way(entity);
|
||||
|
||||
} else if (prefix == 'r') {
|
||||
this.entities[i] = new iD.Relation(entity);
|
||||
}
|
||||
for (var i in entities) {
|
||||
this.entities[i] = entities[i];
|
||||
this._updateCalculated(base.entities[i], this.entities[i]);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
+61
-9
@@ -187,33 +187,85 @@ iD.History = function(context) {
|
||||
toJSON: function() {
|
||||
if (stack.length <= 1) return;
|
||||
|
||||
var allEntities = {};
|
||||
|
||||
var s = stack.map(function(i) {
|
||||
var x = { entities: i.graph.entities };
|
||||
var modified = [], deleted = [];
|
||||
|
||||
_.forEach(i.graph.entities, function(entity, id) {
|
||||
if (entity) {
|
||||
var key = iD.Entity.key(entity);
|
||||
allEntities[key] = entity;
|
||||
modified.push(key);
|
||||
} else {
|
||||
deleted.push(id);
|
||||
}
|
||||
});
|
||||
|
||||
var x = {};
|
||||
|
||||
if (modified.length) x.modified = modified;
|
||||
if (deleted.length) x.deleted = deleted;
|
||||
if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
|
||||
if (i.annotation) x.annotation = i.annotation;
|
||||
|
||||
return x;
|
||||
});
|
||||
|
||||
return JSON.stringify({
|
||||
version: 2,
|
||||
entities: _.values(allEntities),
|
||||
stack: s,
|
||||
nextIDs: iD.Entity.id.next,
|
||||
index: index
|
||||
}, function includeUndefined(key, value) {
|
||||
if (typeof value === 'undefined') return 'undefined';
|
||||
return value;
|
||||
});
|
||||
},
|
||||
|
||||
fromJSON: function(json) {
|
||||
|
||||
var h = JSON.parse(json);
|
||||
|
||||
iD.Entity.id.next = h.nextIDs;
|
||||
index = h.index;
|
||||
stack = h.stack.map(function(d) {
|
||||
d.graph = iD.Graph(stack[0].graph).load(d.entities);
|
||||
return d;
|
||||
});
|
||||
|
||||
if (h.version === 2) {
|
||||
var allEntities = {};
|
||||
|
||||
h.entities.forEach(function(entity) {
|
||||
allEntities[iD.Entity.key(entity)] = iD.Entity(entity);
|
||||
});
|
||||
|
||||
stack = h.stack.map(function(d) {
|
||||
var entities = {}, entity;
|
||||
|
||||
d.modified && d.modified.forEach(function(key) {
|
||||
entity = allEntities[key];
|
||||
entities[entity.id] = entity;
|
||||
});
|
||||
|
||||
d.deleted && d.deleted.forEach(function(id) {
|
||||
entities[id] = undefined;
|
||||
});
|
||||
|
||||
return {
|
||||
graph: iD.Graph(stack[0].graph).load(entities),
|
||||
annotation: d.annotation,
|
||||
imageryUsed: d.imageryUsed
|
||||
};
|
||||
});
|
||||
} else { // original version
|
||||
stack = h.stack.map(function(d) {
|
||||
var entities = {};
|
||||
|
||||
for (var i in d.entities) {
|
||||
var entity = d.entities[i];
|
||||
entities[i] = entity === 'undefined' ? undefined : iD.Entity(entity);
|
||||
}
|
||||
|
||||
d.graph = iD.Graph(stack[0].graph).load(entities);
|
||||
return d;
|
||||
});
|
||||
}
|
||||
|
||||
stack[0].graph.inherited = false;
|
||||
dispatch.change();
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
describe('iD.Entity', function () {
|
||||
it("returns a subclass of the appropriate type", function () {
|
||||
expect(iD.Entity({type: 'way'})).be.an.instanceOf(iD.Way);
|
||||
expect(iD.Entity({type: 'node'})).be.an.instanceOf(iD.Node);
|
||||
expect(iD.Entity({type: 'way'})).be.an.instanceOf(iD.Way);
|
||||
expect(iD.Entity({type: 'relation'})).be.an.instanceOf(iD.Relation);
|
||||
expect(iD.Entity({id: 'n1'})).be.an.instanceOf(iD.Node);
|
||||
expect(iD.Entity({id: 'w1'})).be.an.instanceOf(iD.Way);
|
||||
expect(iD.Entity({id: 'r1'})).be.an.instanceOf(iD.Relation);
|
||||
});
|
||||
|
||||
if (iD.debug) {
|
||||
|
||||
+125
-2
@@ -252,7 +252,6 @@ describe("iD.History", function () {
|
||||
});
|
||||
|
||||
describe("#save", function() {
|
||||
|
||||
it("doesn't do anything if it doesn't have the lock", function() {
|
||||
var key = history._getKey('saved_history');
|
||||
context.storage(key, null);
|
||||
@@ -270,7 +269,7 @@ describe("iD.History", function () {
|
||||
history.perform(iD.actions.AddEntity(node));
|
||||
history.save();
|
||||
var saved = JSON.parse(context.storage(history._getKey('saved_history')));
|
||||
expect(saved.stack[1].entities.n.id).to.eql('n');
|
||||
expect(saved.stack[1].modified[0]).to.eql('nv0');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -290,4 +289,128 @@ describe("iD.History", function () {
|
||||
expect(history.graph().hasEntity('n2')).to.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe("#toJSON", function() {
|
||||
it("generates v2 JSON", function() {
|
||||
var node = iD.Node({id: 'n-1'});
|
||||
history.merge({n1: iD.Node({id: 'n1'})});
|
||||
history.perform(iD.actions.AddEntity(node));
|
||||
var json = JSON.parse(history.toJSON());
|
||||
expect(json.version).to.eql(2);
|
||||
expect(json.entities).to.eql([node]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#fromJSON", function() {
|
||||
it("restores from v1 JSON (creation)", function() {
|
||||
var json = {
|
||||
"stack": [
|
||||
{"entities": {}},
|
||||
{"entities": {"n-1": {"loc": [1, 2], "id": "n-1"}}, "imageryUsed": ["Bing"], "annotation": "Added a point."}
|
||||
],
|
||||
"nextIDs": {"node": -2, "way": -1, "relation": -1},
|
||||
"index": 1
|
||||
};
|
||||
history.fromJSON(JSON.stringify(json));
|
||||
expect(history.graph().entity('n-1')).to.eql(iD.Node({id: 'n-1', loc: [1, 2]}));
|
||||
expect(history.undoAnnotation()).to.eql("Added a point.");
|
||||
expect(history.imageryUsed()).to.eql(["Bing"]);
|
||||
expect(iD.Entity.id.next).to.eql({node: -2, way: -1, relation: -1});
|
||||
});
|
||||
|
||||
it("restores from v1 JSON (modification)", function() {
|
||||
var json = {
|
||||
"stack": [
|
||||
{"entities": {}},
|
||||
{"entities": {"n-1": {"loc": [1, 2], "id": "n-1"}}, "imageryUsed": ["Bing"], "annotation": "Added a point."},
|
||||
{"entities": {"n-1": {"loc": [2, 3], "id": "n-1", "v": 1}}, "imageryUsed": ["Bing"], "annotation": "Moved a point."}
|
||||
],
|
||||
"nextIDs": {"node": -2, "way": -1, "relation": -1},
|
||||
"index": 2
|
||||
};
|
||||
history.fromJSON(JSON.stringify(json));
|
||||
expect(history.graph().entity('n-1')).to.eql(iD.Node({id: 'n-1', loc: [2, 3], v: 1}));
|
||||
expect(history.undoAnnotation()).to.eql("Moved a point.");
|
||||
expect(history.imageryUsed()).to.eql(["Bing"]);
|
||||
expect(iD.Entity.id.next).to.eql({node: -2, way: -1, relation: -1});
|
||||
});
|
||||
|
||||
it("restores from v1 JSON (deletion)", function() {
|
||||
var json = {
|
||||
"stack": [
|
||||
{"entities": {}},
|
||||
{"entities": {"n1": "undefined"}, "imageryUsed": ["Bing"], "annotation": "Deleted a point."}
|
||||
],
|
||||
"nextIDs": {"node": -1, "way": -2, "relation": -3},
|
||||
"index": 1
|
||||
};
|
||||
history.fromJSON(JSON.stringify(json));
|
||||
history.merge({n1: iD.Node({id: 'n1'})});
|
||||
expect(history.graph().hasEntity('n1')).to.be.undefined;
|
||||
expect(history.undoAnnotation()).to.eql("Deleted a point.");
|
||||
expect(history.imageryUsed()).to.eql(["Bing"]);
|
||||
expect(iD.Entity.id.next).to.eql({node: -1, way: -2, relation: -3});
|
||||
});
|
||||
|
||||
it("restores from v2 JSON (creation)", function() {
|
||||
var json = {
|
||||
"version": 2,
|
||||
"entities": [
|
||||
{"loc": [1, 2], "id": "n-1"}
|
||||
],
|
||||
"stack": [
|
||||
{},
|
||||
{"modified": ["n-1v0"], "imageryUsed": ["Bing"], "annotation": "Added a point."}
|
||||
],
|
||||
"nextIDs": {"node": -2, "way": -1, "relation": -1},
|
||||
"index": 1
|
||||
};
|
||||
history.fromJSON(JSON.stringify(json));
|
||||
expect(history.graph().entity('n-1')).to.eql(iD.Node({id: 'n-1', loc: [1, 2]}));
|
||||
expect(history.undoAnnotation()).to.eql("Added a point.");
|
||||
expect(history.imageryUsed()).to.eql(["Bing"]);
|
||||
expect(iD.Entity.id.next).to.eql({node: -2, way: -1, relation: -1});
|
||||
});
|
||||
|
||||
it("restores from v2 JSON (modification)", function() {
|
||||
var json = {
|
||||
"version": 2,
|
||||
"entities": [
|
||||
{"loc": [1, 2], "id": "n-1"},
|
||||
{"loc": [2, 3], "id": "n-1", "v": 1}
|
||||
],
|
||||
"stack": [
|
||||
{},
|
||||
{"modified": ["n-1v0"], "imageryUsed": ["Bing"], "annotation": "Added a point."},
|
||||
{"modified": ["n-1v1"], "imageryUsed": ["Bing"], "annotation": "Moved a point."}
|
||||
],
|
||||
"nextIDs": {"node": -2, "way": -1, "relation": -1},
|
||||
"index": 2
|
||||
};
|
||||
history.fromJSON(JSON.stringify(json));
|
||||
expect(history.graph().entity('n-1')).to.eql(iD.Node({id: 'n-1', loc: [2, 3], v: 1}));
|
||||
expect(history.undoAnnotation()).to.eql("Moved a point.");
|
||||
expect(history.imageryUsed()).to.eql(["Bing"]);
|
||||
expect(iD.Entity.id.next).to.eql({node: -2, way: -1, relation: -1});
|
||||
});
|
||||
|
||||
it("restores from v2 JSON (deletion)", function() {
|
||||
var json = {
|
||||
"version": 2,
|
||||
"entities": [],
|
||||
"stack": [
|
||||
{},
|
||||
{"deleted": ["n1"], "imageryUsed": ["Bing"], "annotation": "Deleted a point."}
|
||||
],
|
||||
"nextIDs": {"node": -1, "way": -2, "relation": -3},
|
||||
"index": 1
|
||||
};
|
||||
history.fromJSON(JSON.stringify(json));
|
||||
history.merge({n1: iD.Node({id: 'n1'})});
|
||||
expect(history.graph().hasEntity('n1')).to.be.undefined;
|
||||
expect(history.undoAnnotation()).to.eql("Deleted a point.");
|
||||
expect(history.imageryUsed()).to.eql(["Bing"]);
|
||||
expect(iD.Entity.id.next).to.eql({node: -1, way: -2, relation: -3});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user