From fc0a15e6c47f5a4ced2a1965df7ae59138ceb32b Mon Sep 17 00:00:00 2001 From: tyr Date: Thu, 20 Feb 2014 15:27:29 +0100 Subject: [PATCH] fix duplicate objects after restoring data from localStorage This makes sure that the originals of changed entities get merged into the base of the stack after restoring the data from JSON. This is necessary, because the stack will only have elements for the current viewport after a restart and previously *modified* objects will now be falsely detected as *created* ones. Also removed some ineffective code. --- js/id/core/history.js | 23 +++++++++++++++++++---- test/spec/core/history.js | 4 ++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/js/id/core/history.js b/js/id/core/history.js index e4f76aae8..7325dbbb0 100644 --- a/js/id/core/history.js +++ b/js/id/core/history.js @@ -199,9 +199,19 @@ iD.History = function(context) { return x; }); + // make sure that the originals of changed entities get merged into + // the base of the stack after restoring the data from JSON. + var base = stack[0], + baseEntities = {}; + _.forEach(allEntities, function(entity) { + if (entity.id in base.graph.entities && !base.graph.entities.hasOwnProperty(entity.id)) + baseEntities[entity.id] = base.graph.entities[entity.id]; + }); + return JSON.stringify({ - version: 2, + version: 3, entities: _.values(allEntities), + baseEntities: _.values(baseEntities), stack: s, nextIDs: iD.Entity.id.next, index: index @@ -214,13 +224,20 @@ 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) + stack[0].graph.rebase(h.baseEntities, _.pluck(stack, 'graph')); + } + stack = h.stack.map(function(d) { var entities = {}, entity; @@ -292,8 +309,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 diff --git a/test/spec/core/history.js b/test/spec/core/history.js index 0df9fc5d8..6c7a21496 100644 --- a/test/spec/core/history.js +++ b/test/spec/core/history.js @@ -229,12 +229,12 @@ describe("iD.History", function () { }); describe("#toJSON", function() { - it("generates v2 JSON", function() { + it("generates v3 JSON", function() { var node = iD.Node({id: 'n-1'}); history.merge([iD.Node({id: 'n1'})]); history.perform(iD.actions.AddEntity(node)); var json = JSON.parse(history.toJSON()); - expect(json.version).to.eql(2); + expect(json.version).to.eql(3); expect(json.entities).to.eql([node]); }); });