mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-22 16:19:48 +02:00
Merge pull request #2135 from tyrasd/master
fix duplicate objects after restoring data from localStorage
This commit is contained in:
+19
-5
@@ -174,7 +174,9 @@ iD.History = function(context) {
|
||||
toJSON: function() {
|
||||
if (stack.length <= 1) return;
|
||||
|
||||
var allEntities = {};
|
||||
var allEntities = {},
|
||||
baseEntities = {},
|
||||
base = stack[0];
|
||||
|
||||
var s = stack.map(function(i) {
|
||||
var modified = [], deleted = [];
|
||||
@@ -187,6 +189,10 @@ iD.History = function(context) {
|
||||
} else {
|
||||
deleted.push(id);
|
||||
}
|
||||
// make sure that the originals of changed or deleted entities get merged
|
||||
// into the base of the stack after restoring the data from JSON.
|
||||
if (id in base.graph.entities && !base.graph.entities.hasOwnProperty(id))
|
||||
baseEntities[id] = base.graph.entities[id];
|
||||
});
|
||||
|
||||
var x = {};
|
||||
@@ -200,8 +206,9 @@ iD.History = function(context) {
|
||||
});
|
||||
|
||||
return JSON.stringify({
|
||||
version: 2,
|
||||
version: 3,
|
||||
entities: _.values(allEntities),
|
||||
baseEntities: _.values(baseEntities),
|
||||
stack: s,
|
||||
nextIDs: iD.Entity.id.next,
|
||||
index: index
|
||||
@@ -214,13 +221,22 @@ iD.History = function(context) {
|
||||
iD.Entity.id.next = h.nextIDs;
|
||||
index = h.index;
|
||||
|
||||
if (h.version === 2) {
|
||||
if (h.version === 2 || h.version === 3) {
|
||||
var allEntities = {};
|
||||
|
||||
h.entities.forEach(function(entity) {
|
||||
allEntities[iD.Entity.key(entity)] = iD.Entity(entity);
|
||||
});
|
||||
|
||||
if (h.version === 3) {
|
||||
// this merges originals for changed entities into the base of
|
||||
// the stack even if the current stack doesn't have them (for
|
||||
// example when iD has been restarted in a different region)
|
||||
var baseEntities = h.baseEntities.map(iD.Entity);
|
||||
stack[0].graph.rebase(baseEntities, _.pluck(stack, 'graph'));
|
||||
tree.rebase(baseEntities);
|
||||
}
|
||||
|
||||
stack = h.stack.map(function(d) {
|
||||
var entities = {}, entity;
|
||||
|
||||
@@ -292,8 +308,6 @@ iD.History = function(context) {
|
||||
|
||||
var json = context.storage(getKey('saved_history'));
|
||||
if (json) history.fromJSON(json);
|
||||
|
||||
context.storage(getKey('saved_history', null));
|
||||
},
|
||||
|
||||
_getKey: getKey
|
||||
|
||||
@@ -229,13 +229,19 @@ describe("iD.History", function () {
|
||||
});
|
||||
|
||||
describe("#toJSON", function() {
|
||||
it("generates v2 JSON", function() {
|
||||
var node = iD.Node({id: 'n-1'});
|
||||
history.merge([iD.Node({id: 'n1'})]);
|
||||
history.perform(iD.actions.AddEntity(node));
|
||||
it("generates v3 JSON", function() {
|
||||
var node_1 = iD.Node({id: 'n-1'}),
|
||||
node1 = iD.Node({id: 'n1'}),
|
||||
node2 = iD.Node({id: 'n2'}),
|
||||
node3 = iD.Node({id: 'n3'});
|
||||
history.merge([node1, node2, node3]);
|
||||
history.perform(iD.actions.AddEntity(node_1)); // addition
|
||||
history.perform(iD.actions.ChangeTags('n2', {k: 'v'})); // modification
|
||||
history.perform(iD.actions.DeleteNode('n3')); // deletion
|
||||
var json = JSON.parse(history.toJSON());
|
||||
expect(json.version).to.eql(2);
|
||||
expect(json.entities).to.eql([node]);
|
||||
expect(json.version).to.eql(3);
|
||||
expect(json.entities).to.eql([node_1, node2.update({tags: {k: 'v'}})]);
|
||||
expect(json.baseEntities).to.eql([node2, node3]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -350,5 +356,71 @@ describe("iD.History", function () {
|
||||
expect(history.imageryUsed()).to.eql(["Bing"]);
|
||||
expect(iD.Entity.id.next).to.eql({node: -1, way: -2, relation: -3});
|
||||
});
|
||||
|
||||
it("restores from v3 JSON (creation)", function() {
|
||||
var json = {
|
||||
"version": 3,
|
||||
"entities": [
|
||||
{"loc": [1, 2], "id": "n-1"}
|
||||
],
|
||||
"baseEntities": [],
|
||||
"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});
|
||||
expect(history.difference().created().length).to.eql(1);
|
||||
});
|
||||
|
||||
it("restores from v3 JSON (modification)", function() {
|
||||
var json = {
|
||||
"version": 3,
|
||||
"entities": [
|
||||
{"loc": [1, 2], "id": "n-1"},
|
||||
{"loc": [2, 3], "id": "n-1", "v": 1}
|
||||
],
|
||||
"baseEntities": [{"loc": [1, 2], "id": "n-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});
|
||||
expect(history.difference().modified().length).to.eql(1);
|
||||
});
|
||||
|
||||
it("restores from v3 JSON (deletion)", function() {
|
||||
var json = {
|
||||
"version": 3,
|
||||
"entities": [],
|
||||
"baseEntities": [{"loc": [1, 2], "id": "n1"}],
|
||||
"stack": [
|
||||
{},
|
||||
{"deleted": ["n1"], "imageryUsed": ["Bing"], "annotation": "Deleted a point."}
|
||||
],
|
||||
"nextIDs": {"node": -1, "way": -2, "relation": -3},
|
||||
"index": 1
|
||||
};
|
||||
history.fromJSON(JSON.stringify(json));
|
||||
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});
|
||||
expect(history.difference().deleted().length).to.eql(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user