diff --git a/js/id/graph/graph.js b/js/id/graph/graph.js index 3eea6a59a..d35f616a0 100644 --- a/js/id/graph/graph.js +++ b/js/id/graph/graph.js @@ -1,19 +1,25 @@ iD.Graph = function(other, mutable) { if (!(this instanceof iD.Graph)) return new iD.Graph(other, mutable); - if (_.isArray(other)) { - this.entities = Object.create({}); - for (var i = 0; i < other.length; i++) { - this.entities[other[i].id] = other[i]; - } - } else if (other instanceof iD.Graph) { + if (other instanceof iD.Graph) { + var base = other.base(); + this.entities = _.assign(Object.create(base.entities), other.entities); + this._parentWays = _.assign(Object.create(base.parentWays), other._parentWays); this.rebase(other.base(), other.entities); + } else { - this.entities = Object.create(other || {}); + if (_.isArray(other)) { + this.entities = Object.create({}); + for (var i = 0; i < other.length; i++) { + this.entities[other[i].id] = other[i]; + } + } else { + this.entities = Object.create(other || {}); + } + this._parentWays = Object.create({}); } this.transients = {}; - this._parentWays = {}; this._parentRels = {}; this._childNodes = {}; @@ -100,9 +106,10 @@ iD.Graph.prototype = { }, base: function() { - return Object.getPrototypeOf ? - Object.getPrototypeOf(this.entities) : - this.entities.__proto__; + return { + 'entities': iD.util.getPrototypeOf(this.entities), + 'parentWays': iD.util.getPrototypeOf(this._parentWays) + }; }, // Unlike other graph methods, rebase mutates in place. This is because it @@ -110,7 +117,6 @@ iD.Graph.prototype = { // data into each state. To external consumers, it should appear as if the // graph always contained the newly downloaded data. rebase: function(base, entities) { - this.entities = _.assign(Object.create(base), entities || this.entities); }, replace: function(entity) { diff --git a/js/id/graph/history.js b/js/id/graph/history.js index c9e3e19f5..e5bfd353f 100644 --- a/js/id/graph/history.js +++ b/js/id/graph/history.js @@ -30,11 +30,14 @@ iD.History = function() { }, merge: function (graph) { - var base = stack[0].graph.base(); + var base = stack[0].graph.base(), + mergee = graph.base(); - _.defaults(base, graph.entities); + for (var i in base) { + _.defaults(base[i], mergee[i]); + } - for (var i = 1; i < stack.length; i++) { + for (i = 1; i < stack.length; i++) { stack[i].graph.rebase(base); } }, diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index bc4ca8e03..e27fdc5b9 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -123,7 +123,7 @@ iD.Map = function() { function connectionLoad(err, result) { history.merge(result); - redraw(Object.keys(result.entities)); + redraw(Object.keys(iD.util.getPrototypeOf(result.entities))); } function zoomPan() { diff --git a/js/id/util.js b/js/id/util.js index da31a162b..645d15363 100644 --- a/js/id/util.js +++ b/js/id/util.js @@ -74,3 +74,5 @@ iD.util.getStyle = function(selector) { } } }; + +iD.util.getPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };