diff --git a/js/id/core/graph.js b/js/id/core/graph.js
index eae11cc15..f9966be7a 100644
--- a/js/id/core/graph.js
+++ b/js/id/core/graph.js
@@ -225,21 +225,10 @@ iD.Graph.prototype = {
return this;
},
- // get all objects that intersect an extent.
- intersects: function(extent) {
- var items = [];
- for (var i in this.entities) {
- var entity = this.entities[i];
- if (entity && this.hasAllChildren(entity) && entity.intersects(extent, this)) {
- items.push(entity);
- }
- }
- return items;
- },
-
hasAllChildren: function(entity) {
// we're only checking changed entities, since we assume fetched data
// must have all children present
+ var i;
if (this.entities.hasOwnProperty(entity.id)) {
if (entity.type === 'way') {
for (i = 0; i < entity.nodes.length; i++) {
diff --git a/js/id/core/history.js b/js/id/core/history.js
index 9e5daa88e..a8d49cbde 100644
--- a/js/id/core/history.js
+++ b/js/id/core/history.js
@@ -1,5 +1,5 @@
iD.History = function(context) {
- var stack, index, tree;
+ var stack, index, tree,
imagery_used = 'Bing',
dispatch = d3.dispatch('change', 'undone', 'redone'),
lock = false;
diff --git a/js/id/core/tree.js b/js/id/core/tree.js
index 7570ba8ed..8c3635c32 100644
--- a/js/id/core/tree.js
+++ b/js/id/core/tree.js
@@ -2,7 +2,10 @@ iD.Tree = function(graph) {
var rtree = new RTree(),
m = 1000 * 1000 * 100,
- head = graph;
+ head = graph,
+ queuedCreated = [],
+ queuedModified = [],
+ x, y, dx, dy;
function extentRectangle(extent) {
x = m * extent[0][0],
@@ -29,7 +32,7 @@ iD.Tree = function(graph) {
rebase: function(entities) {
for (var i = 0; i < entities.length; i++) {
- insert(graph.entities[entities[i]]);
+ insert(graph.entity(entities[i]), true);
}
return tree;
},
@@ -49,8 +52,21 @@ iD.Tree = function(graph) {
}
});
- d3.values(diff.addParents(modified)).map(reinsert);
- diff.created().forEach(insert);
+ var created = diff.created().concat(queuedCreated);
+ modified = d3.values(diff.addParents(modified)).concat(queuedModified);
+ queuedCreated = [];
+ queuedModified = [];
+
+ modified.forEach(function(d) {
+ if (head.hasAllChildren(d)) reinsert(d);
+ else queuedModified.push(d);
+ });
+
+ created.forEach(function(d) {
+ if (head.hasAllChildren(d)) insert(d);
+ else queuedCreated.push(d);
+ });
+
diff.deleted().forEach(remove);
graph = head;
diff --git a/test/index.html b/test/index.html
index fe81a4ec5..7862c53a5 100644
--- a/test/index.html
+++ b/test/index.html
@@ -133,6 +133,7 @@
+
@@ -172,6 +173,7 @@
+
diff --git a/test/spec/core/tree.js b/test/spec/core/tree.js
new file mode 100644
index 000000000..d279bc0f3
--- /dev/null
+++ b/test/spec/core/tree.js
@@ -0,0 +1,18 @@
+describe("iD.Tree", function() {
+ var tree;
+
+ beforeEach(function() {
+ tree = iD.Tree(iD.Graph());
+ });
+
+ describe("intersects", function() {
+ it("excludes entities with missing children, adds them when all are present", function() {
+ var way = iD.Way({id: 'w1', nodes: ['n']});
+ var g = tree.base().replace(way);
+ expect(tree.intersects(iD.geo.Extent([0, 0], [1, 1]), g)).to.eql([]);
+ var node = iD.Node({id: 'n', loc: [0.5, 0.5]});
+ g = tree.base().replace(node);
+ expect(tree.intersects(iD.geo.Extent([0, 0], [1, 1]), g)).to.eql([way, node]);
+ });
+ });
+});