From 1a2b897d06328d84f333da2ce2fc6de074e2a567 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Tue, 15 Jan 2013 17:23:00 -0500 Subject: [PATCH 01/35] Fix closing inspector after delete --- js/id/modes/select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/id/modes/select.js b/js/id/modes/select.js index a1fde48ef..c85172a4a 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -138,7 +138,7 @@ iD.modes.Select = function (entity) { mode.exit = function () { var surface = mode.map.surface; - changeTags(entity, inspector.tags()); + entity && changeTags(entity, inspector.tags()); d3.select('.inspector-wrap') .style('display', 'none') .html(''); From b303cb796f2547aec6780f8091573ffcee319199 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 15 Jan 2013 18:31:52 -0500 Subject: [PATCH 02/35] Rename apply to close. Fixes #325 --- js/id/ui/inspector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index da022e8c8..f0db48166 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -81,7 +81,7 @@ iD.ui.inspector = function() { function drawButtons(selection) { selection.append('button') .attr('class', 'apply wide action') - .html("Apply") + .html("Close") .on('click', apply); selection.append('button') From cc59b048e1bbea0495d6224f8ddfee68c0fbbde5 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Tue, 15 Jan 2013 23:06:58 -0800 Subject: [PATCH 03/35] Fix reloading of tiles from API after save. --- js/id/connection.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/id/connection.js b/js/id/connection.js index 101c7a9c8..531d89d54 100644 --- a/js/id/connection.js +++ b/js/id/connection.js @@ -16,6 +16,7 @@ iD.Connection = function() { function bboxFromAPI(box, tile, callback) { function done(err, parsed) { loadedTiles[tile.toString()] = true; + delete inflight[tile.toString()]; callback(err, parsed); } inflight[tile.toString()] = loadFromURL(bboxUrl(box), done); From 0a1e16a31923bff08fb34fb4dc61d18800a8deec Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 16 Jan 2013 11:31:36 -0500 Subject: [PATCH 04/35] Nodes with changed parents added to difference --- js/id/graph/graph.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/js/id/graph/graph.js b/js/id/graph/graph.js index d1f5e4cc7..5e5792346 100644 --- a/js/id/graph/graph.js +++ b/js/id/graph/graph.js @@ -128,11 +128,19 @@ iD.Graph.prototype = { }, difference: function (graph) { - var result = [], entity, id; + var result = [], entity, oldentity, id; for (id in this.entities) { entity = this.entities[id]; - if (entity !== graph.entities[id]) { + oldentity = graph.entities[id]; + if (entity !== oldentity) { + if (entity.type === 'way') { + result = oldentity + ? result + .concat(_.difference(entity.nodes, oldentity.nodes)) + .concat(_.difference(oldentity.nodes, entity.nodes)) + : result.concat(entity.nodes); + } result.push(id); } } @@ -141,6 +149,7 @@ iD.Graph.prototype = { entity = graph.entities[id]; if (entity && !this.entities.hasOwnProperty(id)) { result.push(id); + if (entity.type === 'way') result = result.concat(entity.nodes); } } From fc272199c780ce1c8eff458dbf2010e9ca349acd Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 16 Jan 2013 11:34:50 -0500 Subject: [PATCH 05/35] Fix difference --- js/id/graph/graph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/id/graph/graph.js b/js/id/graph/graph.js index 5e5792346..9b6de7219 100644 --- a/js/id/graph/graph.js +++ b/js/id/graph/graph.js @@ -134,7 +134,7 @@ iD.Graph.prototype = { entity = this.entities[id]; oldentity = graph.entities[id]; if (entity !== oldentity) { - if (entity.type === 'way') { + if (entity && entity.type === 'way') { result = oldentity ? result .concat(_.difference(entity.nodes, oldentity.nodes)) From a980695ee7c72e909529faf4cddd921ffc9aa69e Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 16 Jan 2013 12:20:35 -0500 Subject: [PATCH 06/35] Avoid creating lines with < 2 nodes (or areas < 3) --- js/id/modes/add_area.js | 6 ++---- js/id/modes/add_line.js | 9 +++------ js/id/modes/draw_area.js | 14 ++++++++++---- js/id/modes/draw_line.js | 16 +++++++++++----- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/js/id/modes/add_area.js b/js/id/modes/add_area.js index 33facb041..6977f2e15 100644 --- a/js/id/modes/add_area.js +++ b/js/id/modes/add_area.js @@ -23,8 +23,7 @@ iD.modes.AddArea = function() { history.perform( iD.actions.AddWay(way), iD.actions.AddWayNode(way.id, datum.id), - iD.actions.AddWayNode(way.id, datum.id), - 'started an area'); + iD.actions.AddWayNode(way.id, datum.id)); } else { // start from a new node @@ -33,8 +32,7 @@ iD.modes.AddArea = function() { iD.actions.AddWay(way), iD.actions.AddNode(node), iD.actions.AddWayNode(way.id, node.id), - iD.actions.AddWayNode(way.id, node.id), - 'started an area'); + iD.actions.AddWayNode(way.id, node.id)); } controller.enter(iD.modes.DrawArea(way.id)); diff --git a/js/id/modes/add_line.js b/js/id/modes/add_line.js index bc87238ca..60f376181 100644 --- a/js/id/modes/add_line.js +++ b/js/id/modes/add_line.js @@ -33,8 +33,7 @@ iD.modes.AddLine = function() { } else { history.perform( iD.actions.AddWay(way), - iD.actions.AddWayNode(way.id, datum.id), - 'started a line'); + iD.actions.AddWayNode(way.id, datum.id)); } } else if (datum.type === 'way') { @@ -46,8 +45,7 @@ iD.modes.AddLine = function() { iD.actions.AddWay(way), iD.actions.AddNode(node), iD.actions.AddWayNode(datum.id, node.id, choice.index), - iD.actions.AddWayNode(way.id, node.id), - 'started a line'); + iD.actions.AddWayNode(way.id, node.id)); } else { // begin a new way @@ -56,8 +54,7 @@ iD.modes.AddLine = function() { history.perform( iD.actions.AddWay(way), iD.actions.AddNode(node), - iD.actions.AddWayNode(way.id, node.id), - 'started a line'); + iD.actions.AddWayNode(way.id, node.id)); } controller.enter(iD.modes.DrawLine(way.id, direction)); diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index d868a7620..75b84af65 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -42,22 +42,28 @@ iD.modes.DrawArea = function(wayId) { var datum = d3.select(d3.event.target).datum() || {}; if (datum.id === tailId || datum.id === headId) { - history.replace(iD.actions.DeleteNode(node.id)); - controller.enter(iD.modes.Select(way)); + if (way.nodes.length > 3) { + history.replace(iD.actions.DeleteNode(node.id)); + controller.enter(iD.modes.Select(way)); + } else { + // Areas with less than 3 nodes gets deleted + history.replace(iD.actions.DeleteWay(way.id)); + controller.enter(iD.modes.Browse()); + } } else if (datum.type === 'node' && datum.id !== node.id) { // connect the way to an existing node history.replace( iD.actions.DeleteNode(node.id), iD.actions.AddWayNode(way.id, datum.id, -1), - 'added to an area'); + way.nodes.length > 2 ? 'added to an area' : ''); controller.enter(iD.modes.DrawArea(wayId)); } else { history.replace( iD.actions.Noop(), - 'added to an area'); + way.nodes.length > 2 ? 'added to an area' : ''); controller.enter(iD.modes.DrawArea(wayId)); } diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index 9c3d4b38e..700944b18 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -42,12 +42,18 @@ iD.modes.DrawLine = function(wayId, direction) { if (datum.id === tailId) { // connect the way in a loop - history.replace( - iD.actions.DeleteNode(node.id), - iD.actions.AddWayNode(wayId, tailId, index), - 'added to a line'); + if (way.nodes.length > 2) { + history.replace( + iD.actions.DeleteNode(node.id), + iD.actions.AddWayNode(wayId, tailId, index), + 'added to a line'); - controller.enter(iD.modes.Select(way)); + controller.enter(iD.modes.Select(way)); + + } else { + history.replace(iD.actions.DeleteWay(way.id)); + controller.enter(iD.modes.Browse()); + } } else if (datum.id === headId) { // finish the way From 4808a8ec9dfe33844640991cc98050a0c8db868a Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 12:29:59 -0500 Subject: [PATCH 07/35] Improve test coverage of ui elements --- test/index.html | 7 +++++++ test/spec/ui/confirm.js | 11 +++++++++++ test/spec/ui/flash.js | 13 +++++++++++++ test/spec/ui/modal.js | 8 ++++++++ 4 files changed, 39 insertions(+) create mode 100644 test/spec/ui/confirm.js create mode 100644 test/spec/ui/flash.js create mode 100644 test/spec/ui/modal.js diff --git a/test/index.html b/test/index.html index 072439887..88b7ff2ea 100644 --- a/test/index.html +++ b/test/index.html @@ -55,6 +55,9 @@ + + + @@ -152,6 +155,10 @@ + + + + diff --git a/test/spec/ui/confirm.js b/test/spec/ui/confirm.js new file mode 100644 index 000000000..a9380e1cc --- /dev/null +++ b/test/spec/ui/confirm.js @@ -0,0 +1,11 @@ +describe("iD.ui.confirm", function () { + it('can be instantiated', function () { + var confirm = iD.ui.confirm(); + expect(confirm).to.be.ok; + }); + it('can be dismissed', function () { + var confirm = iD.ui.confirm(); + happen.click(confirm.select('button').node()); + expect(confirm.node().parentNode).to.be.null; + }); +}); diff --git a/test/spec/ui/flash.js b/test/spec/ui/flash.js new file mode 100644 index 000000000..0426d1734 --- /dev/null +++ b/test/spec/ui/flash.js @@ -0,0 +1,13 @@ +describe("iD.ui.flash", function () { + it('can be instantiated', function () { + var flash = iD.ui.flash(); + expect(flash).to.be.ok; + }); + it('leaves after 1000 ms', function (done) { + var flash = iD.ui.flash(); + window.setTimeout(function() { + expect(flash.node().parentNode).to.be.null; + done(); + }, 1200); + }); +}); diff --git a/test/spec/ui/modal.js b/test/spec/ui/modal.js new file mode 100644 index 000000000..32a42878a --- /dev/null +++ b/test/spec/ui/modal.js @@ -0,0 +1,8 @@ +describe("iD.ui.modal", function () { + it('can be instantiated', function () { + var modal = iD.ui.modal() + .select('.content') + .text('foo'); + expect(modal).to.be.ok; + }); +}); From 110d60d739d544a4ef2d9a3382523ac093d45cda Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 12:35:58 -0500 Subject: [PATCH 08/35] Test new polygon intersection utils --- test/spec/util.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/spec/util.js b/test/spec/util.js index e6663ade2..3ac1cdda2 100644 --- a/test/spec/util.js +++ b/test/spec/util.js @@ -61,5 +61,36 @@ describe('Util', function() { expect(iD.util.geo.dist(a, b)).to.eql(5); }); }); + + describe('#pointInPolygon', function() { + it('says a point in a polygon is on a polygon', function() { + var poly = [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]; + var point = [0.5, 0.5]; + expect(iD.util.geo.pointInPolygon(point, poly)).to.be.true; + }); + it('says a point outside of a polygon is outside', function() { + var poly = [ + [0, 0], + [0, 1], + [1, 1], + [1, 0], + [0, 0]]; + var point = [0.5, 1.5]; + expect(iD.util.geo.pointInPolygon(point, poly)).to.be.false; + }); + }); + + describe('#polygonContainsPolygon', function() { + it('says a polygon in a polygon is in', function() { + var outer = [[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]]; + var inner = [[1, 1], [1, 2], [2, 2], [2, 1], [1, 1]]; + expect(iD.util.geo.polygonContainsPolygon(outer, inner)).to.be.true; + }); + it('says a polygon outside of a polygon is out', function() { + var outer = [[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]]; + var inner = [[1, 1], [1, 9], [2, 2], [2, 1], [1, 1]]; + expect(iD.util.geo.polygonContainsPolygon(outer, inner)).to.be.false; + }); + }); }); }); From 87c341d7e0518cd75b339e481a02f8fba4650989 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 12:39:35 -0500 Subject: [PATCH 09/35] Fix jshint problems. --- js/id/graph/graph.js | 4 ++-- js/id/renderer/map.js | 2 +- js/id/svg.js | 4 ++-- js/id/svg/lines.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/id/graph/graph.js b/js/id/graph/graph.js index 9b6de7219..ee15d68c9 100644 --- a/js/id/graph/graph.js +++ b/js/id/graph/graph.js @@ -135,8 +135,8 @@ iD.Graph.prototype = { oldentity = graph.entities[id]; if (entity !== oldentity) { if (entity && entity.type === 'way') { - result = oldentity - ? result + result = oldentity ? + result .concat(_.difference(entity.nodes, oldentity.nodes)) .concat(_.difference(oldentity.nodes, entity.nodes)) : result.concat(entity.nodes); diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 3f64886b6..ea4b901f8 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -113,7 +113,7 @@ iD.Map = function() { if (Math.log(d3.event.scale / Math.LN2 - 8) < minzoom + 1) { iD.flash() .select('.content') - .text('Cannot zoom out further in current mode.') + .text('Cannot zoom out further in current mode.'); return map.zoom(16); } var fast = (d3.event.scale === projection.scale() && fastEnabled); diff --git a/js/id/svg.js b/js/id/svg.js index fd648f5db..5860126e9 100644 --- a/js/id/svg.js +++ b/js/id/svg.js @@ -2,13 +2,13 @@ iD.svg = { RoundProjection: function (projection) { return function (d) { return iD.util.geo.roundCoords(projection(d)); - } + }; }, PointTransform: function (projection) { projection = iD.svg.RoundProjection(projection); return function (entity) { return 'translate(' + projection(entity.loc) + ')'; - } + }; } }; diff --git a/js/id/svg/lines.js b/js/id/svg/lines.js index 3a64c1b28..925d8c968 100644 --- a/js/id/svg/lines.js +++ b/js/id/svg/lines.js @@ -97,5 +97,5 @@ iD.svg.Lines = function() { // adding longer text than necessary, since overflow is hidden return (new Array(Math.floor(lengths[d.id] * 1.1))).join(arrowtext); }); - } + }; }; From a9de2500aaff8b5ba074bdd85a3db0f89afd11af Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 16 Jan 2013 12:43:29 -0500 Subject: [PATCH 10/35] Fix undo right after drawing line or area --- js/id/modes/draw_area.js | 2 +- js/id/modes/draw_line.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index 75b84af65..88d61d323 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -43,7 +43,7 @@ iD.modes.DrawArea = function(wayId) { if (datum.id === tailId || datum.id === headId) { if (way.nodes.length > 3) { - history.replace(iD.actions.DeleteNode(node.id)); + history.undo(); controller.enter(iD.modes.Select(way)); } else { // Areas with less than 3 nodes gets deleted diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index 700944b18..a59e3a7e9 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -57,7 +57,7 @@ iD.modes.DrawLine = function(wayId, direction) { } else if (datum.id === headId) { // finish the way - history.replace(iD.actions.DeleteNode(node.id)); + history.undo(); controller.enter(iD.modes.Select(way)); From e3775844c83e86afcf0d29bae73f72fe428182fd Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 12:52:06 -0500 Subject: [PATCH 11/35] Refactor lines, keep non-scoped fns out of scope --- js/id/svg/lines.js | 54 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/js/id/svg/lines.js b/js/id/svg/lines.js index 925d8c968..02f33a707 100644 --- a/js/id/svg/lines.js +++ b/js/id/svg/lines.js @@ -1,16 +1,38 @@ iD.svg.Lines = function() { - var arrowtext = '►\u3000\u3000', - alength; + var arrowtext = '►\u3000\u3000', + alength; + + function drawPaths(group, lines, filter, classes, lineString) { + var paths = group.selectAll('path') + .filter(filter) + .data(lines, iD.Entity.key); + + paths.enter() + .append('path') + .attr('class', classes); + + paths + .order() + .attr('d', lineString) + .call(iD.svg.TagClasses()); + + paths.exit() + .remove(); + + return paths; + } return function(surface, graph, entities, filter, projection) { + if (!alength) { var arrow = surface.append('text').text(arrowtext); alength = arrow.node().getComputedTextLength(); arrow.remove(); } - var lines = []; + var lines = [], + lineStrings = {}; for (var i = 0; i < entities.length; i++) { var entity = entities[i]; @@ -19,8 +41,6 @@ iD.svg.Lines = function() { } } - var lineStrings = {}; - function lineString(entity) { if (lineStrings[entity.id] !== undefined) { return lineStrings[entity.id]; @@ -31,32 +51,12 @@ iD.svg.Lines = function() { 'M' + nodes.map(iD.svg.RoundProjection(projection)).join('L')); } - function drawPaths(group, lines, filter, classes) { - var paths = group.selectAll('path') - .filter(filter) - .data(lines, iD.Entity.key); - - paths.enter() - .append('path') - .attr('class', classes); - - paths - .order() - .attr('d', lineString) - .call(iD.svg.TagClasses()); - - paths.exit() - .remove(); - - return paths; - } - var casing = surface.select('.layer-casing'), stroke = surface.select('.layer-stroke'), defs = surface.select('defs'), text = surface.select('.layer-text'), - casings = drawPaths(casing, lines, filter, 'way line casing'), - strokes = drawPaths(stroke, lines, filter, 'way line stroke'); + casings = drawPaths(casing, lines, filter, 'way line casing', lineString), + strokes = drawPaths(stroke, lines, filter, 'way line stroke', lineString); // Determine the lengths of oneway paths var lengths = {}, From 6aae64bd6216ddc7ebb70d89008b41ed3215284d Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 13:06:01 -0500 Subject: [PATCH 12/35] Add waystack, fix bridge coloring --- css/map.css | 3 --- js/id/svg/lines.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/css/map.css b/css/map.css index 590cc114e..f110c0129 100644 --- a/css/map.css +++ b/css/map.css @@ -252,9 +252,6 @@ path.casing.tag-highway-secondary_link { stroke:#444; } -path.stroke.tag-bridge-yes { - stroke:#eee; -} path.casing.tag-bridge-yes { stroke-width: 14; stroke: #000; diff --git a/js/id/svg/lines.js b/js/id/svg/lines.js index 02f33a707..164613d0d 100644 --- a/js/id/svg/lines.js +++ b/js/id/svg/lines.js @@ -3,6 +3,36 @@ iD.svg.Lines = function() { var arrowtext = '►\u3000\u3000', alength; + var highway_stack = { + motorway: 0, + motorway_link: 1, + trunk: 2, + trunk_link: 3, + primary: 4, + primary_link: 5, + secondary: 6, + tertiary: 7, + unclassified: 8, + residential: 9, + service: 10, + footway: 11 + }; + + function waystack(a, b) { + if (!a || !b || !a.tags || !b.tags) return 0; + if (a.tags.layer !== undefined && b.tags.layer !== undefined) { + return a.tags.layer - b.tags.layer; + } + if (a.tags.bridge) return 1; + if (b.tags.bridge) return -1; + var as = 0, bs = 0; + if (a.tags.highway && b.tags.highway) { + as -= highway_stack[a.tags.highway]; + bs -= highway_stack[b.tags.highway]; + } + return as - bs; + } + function drawPaths(group, lines, filter, classes, lineString) { var paths = group.selectAll('path') .filter(filter) @@ -41,6 +71,8 @@ iD.svg.Lines = function() { } } + lines.sort(waystack); + function lineString(entity) { if (lineStrings[entity.id] !== undefined) { return lineStrings[entity.id]; From 8def2e0999d17c6d85bfe9b9aab4d9f84dcffc02 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 13:07:30 -0500 Subject: [PATCH 13/35] Remove style and references to it --- index.html | 1 - js/id/renderer/style.js | 38 -------------------------------------- test/index.html | 1 - 3 files changed, 40 deletions(-) delete mode 100644 js/id/renderer/style.js diff --git a/index.html b/index.html index 8e86da888..b106c35b7 100644 --- a/index.html +++ b/index.html @@ -31,7 +31,6 @@ - diff --git a/js/id/renderer/style.js b/js/id/renderer/style.js deleted file mode 100644 index 734ce10ca..000000000 --- a/js/id/renderer/style.js +++ /dev/null @@ -1,38 +0,0 @@ -iD.Style = {}; - -// all styling that is done outside of CSS in iD. -// -// Since SVG does not support z-index, we sort roads manually with d3's `sort` -// and the `waystack` fn. -// -// This also chooses kosher CSS classes for ways, and images for points - -iD.Style.highway_stack = { - motorway: 0, - motorway_link: 1, - trunk: 2, - trunk_link: 3, - primary: 4, - primary_link: 5, - secondary: 6, - tertiary: 7, - unclassified: 8, - residential: 9, - service: 10, - footway: 11 -}; - -iD.Style.waystack = function(a, b) { - if (!a || !b) return 0; - if (a.tags.layer !== undefined && b.tags.layer !== undefined) { - return a.tags.layer - b.tags.layer; - } - if (a.tags.bridge) return 1; - if (b.tags.bridge) return -1; - var as = 0, bs = 0; - if (a.tags.highway && b.tags.highway) { - as -= iD.Style.highway_stack[a.tags.highway]; - bs -= iD.Style.highway_stack[b.tags.highway]; - } - return as - bs; -}; diff --git a/test/index.html b/test/index.html index 88b7ff2ea..f8d570f36 100644 --- a/test/index.html +++ b/test/index.html @@ -37,7 +37,6 @@ - From cb8dedf2c064930ff51873757517a3338f5626cf Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 16 Jan 2013 13:16:59 -0500 Subject: [PATCH 14/35] Fix element drag mousedown is listening to --- js/id/renderer/map.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index ea4b901f8..9b8817f35 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -29,14 +29,14 @@ iD.Map = function() { var supersurface = selection.append('div') .style('position', 'absolute') + .on('mousedown.drag', function() { + translateStart = projection.translate(); + }) .call(zoom); surface = supersurface.append('svg') .on('mouseup.reset-transform', resetTransform) .on('touchend.reset-transform', resetTransform) - .on('mousedown.drag', function() { - translateStart = projection.translate(); - }) .on('mousedown.zoom', function() { if (d3.event.button == 2) { d3.event.stopPropagation(); From 852e0216f3c43220cebdee7b871d9785a5e198ab Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 13:18:57 -0500 Subject: [PATCH 15/35] Improve contrast of selected way nodes. Fixes #371 --- css/map.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/css/map.css b/css/map.css index f110c0129..11ba62976 100644 --- a/css/map.css +++ b/css/map.css @@ -81,9 +81,12 @@ g.vertex.hover circle.stroke { transform:scale(1.4, 1.4); } -g.vertex circle.selected { +g.vertex circle.selected.fill { fill: #ffff00; } +g.vertex circle.selected.stroke { + fill: #38380A; +} circle.midpoint { fill:#aaa; From 8151b48d3424c3182c6ede6aecf355a80005f463 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 13:26:20 -0500 Subject: [PATCH 16/35] Request tiles at z15 rather than z16 --- js/id/connection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/id/connection.js b/js/id/connection.js index 531d89d54..71f11e23d 100644 --- a/js/id/connection.js +++ b/js/id/connection.js @@ -202,7 +202,7 @@ iD.Connection = function() { } function loadTiles(projection) { - var scaleExtent = [16, 16], + var scaleExtent = [15, 15], s = projection.scale(), tiles = d3.geo.tile() .scaleExtent(scaleExtent) From 199584fbffa31cc332b2fcaf145a0f1d15b0bcfd Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 13:54:36 -0500 Subject: [PATCH 17/35] Name drawing functions so we can profile them --- js/id/svg/areas.js | 2 +- js/id/svg/lines.js | 2 +- js/id/svg/midpoints.js | 2 +- js/id/svg/points.js | 6 +++++- js/id/svg/surface.js | 2 +- js/id/svg/vertices.js | 6 +++++- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/js/id/svg/areas.js b/js/id/svg/areas.js index 386f5f0c3..b4a8a36f5 100644 --- a/js/id/svg/areas.js +++ b/js/id/svg/areas.js @@ -1,5 +1,5 @@ iD.svg.Areas = function() { - return function(surface, graph, entities, filter, projection) { + return function drawAreas(surface, graph, entities, filter, projection) { var areas = []; for (var i = 0; i < entities.length; i++) { diff --git a/js/id/svg/lines.js b/js/id/svg/lines.js index 164613d0d..3f1b634d7 100644 --- a/js/id/svg/lines.js +++ b/js/id/svg/lines.js @@ -53,7 +53,7 @@ iD.svg.Lines = function() { return paths; } - return function(surface, graph, entities, filter, projection) { + return function drawLines(surface, graph, entities, filter, projection) { if (!alength) { var arrow = surface.append('text').text(arrowtext); diff --git a/js/id/svg/midpoints.js b/js/id/svg/midpoints.js index 185afc696..9c060ea3b 100644 --- a/js/id/svg/midpoints.js +++ b/js/id/svg/midpoints.js @@ -1,5 +1,5 @@ iD.svg.Midpoints = function() { - return function(surface, graph, entities, filter, projection) { + return function drawMidpoints(surface, graph, entities, filter, projection) { var midpoints = []; for (var i = 0; i < entities.length; i++) { diff --git a/js/id/svg/points.js b/js/id/svg/points.js index 9015f1d5d..7a2600814 100644 --- a/js/id/svg/points.js +++ b/js/id/svg/points.js @@ -10,7 +10,7 @@ iD.svg.Points = function() { return 'icons/unknown.png'; } - return function(surface, graph, entities, filter, projection) { + return function drawPoints(surface, graph, entities, filter, projection) { var points = []; for (var i = 0; i < entities.length; i++) { @@ -20,6 +20,10 @@ iD.svg.Points = function() { } } + if (points.length > 100) { + return surface.select('.layer-hit').selectAll('g.point').remove(); + } + var groups = surface.select('.layer-hit').selectAll('g.point') .filter(filter) .data(points, iD.Entity.key); diff --git a/js/id/svg/surface.js b/js/id/svg/surface.js index 5c19a0c65..9fb64ca0e 100644 --- a/js/id/svg/surface.js +++ b/js/id/svg/surface.js @@ -1,5 +1,5 @@ iD.svg.Surface = function() { - return function(selection) { + return function drawSurface(selection) { selection.append('defs') .append('clipPath') .attr('id', 'clip') diff --git a/js/id/svg/vertices.js b/js/id/svg/vertices.js index 36363fbff..700ef5538 100644 --- a/js/id/svg/vertices.js +++ b/js/id/svg/vertices.js @@ -1,5 +1,5 @@ iD.svg.Vertices = function() { - return function(surface, graph, entities, filter, projection) { + return function drawVertices(surface, graph, entities, filter, projection) { var vertices = []; for (var i = 0; i < entities.length; i++) { @@ -9,6 +9,10 @@ iD.svg.Vertices = function() { } } + if (vertices.length > 2000) { + return surface.select('.layer-hit').selectAll('g.vertex').remove(); + } + var groups = surface.select('.layer-hit').selectAll('g.vertex') .filter(filter) .data(vertices, iD.Entity.key); From 0e9e14102ee97e1f91737c0137440ae5ca632e8a Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 13:54:53 -0500 Subject: [PATCH 18/35] Cache fetch results, higher features limit --- js/id/graph/graph.js | 4 +++- js/id/renderer/map.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/js/id/graph/graph.js b/js/id/graph/graph.js index ee15d68c9..74caf7ceb 100644 --- a/js/id/graph/graph.js +++ b/js/id/graph/graph.js @@ -13,6 +13,7 @@ iD.Graph = function(entities) { this.transients = {}; this._parentWays = {}; this._parentRels = {}; + this._fetches = {}; if (iD.debug) { Object.freeze(this); @@ -119,12 +120,13 @@ iD.Graph.prototype = { // Resolve the id references in a way, replacing them with actual objects. fetch: function(id) { + if (this._fetches[id]) return this._fetches[id]; var entity = this.entities[id], nodes = []; if (!entity || !entity.nodes || !entity.nodes.length) return entity; for (var i = 0, l = entity.nodes.length; i < l; i++) { nodes[i] = this.fetch(entity.nodes[i]); } - return iD.Entity(entity, {nodes: nodes}); + return (this._fetches[id] = iD.Entity(entity, {nodes: nodes})); }, difference: function (graph) { diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 9b8817f35..764fa83ae 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -80,7 +80,7 @@ iD.Map = function() { filter = function(d) { return d.midpoint ? d.way in only : d.id in only; }; } - if (all.length > 10000) { + if (all.length > 100000) { editOff(); return; } From 6407fa464c60f04927745e8968866867c081bf3b Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 14:06:11 -0500 Subject: [PATCH 19/35] Run intersection on difference changes, do not use compact. Fixes #334 --- js/id/graph/way.js | 3 ++- js/id/renderer/map.js | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/js/id/graph/way.js b/js/id/graph/way.js index 77858d29a..5c3e1210b 100644 --- a/js/id/graph/way.js +++ b/js/id/graph/way.js @@ -6,7 +6,8 @@ iD.Way = iD.Entity.extend({ return resolver.transient(this, 'extent', function() { var extent = [[-Infinity, Infinity], [Infinity, -Infinity]]; for (var i = 0, l = this.nodes.length; i < l; i++) { - var node = resolver.entity(this.nodes[i]); + var node = this.nodes[i]; + if (node.loc === undefined) node = resolver.entity(node); if (node.loc[0] > extent[0][0]) extent[0][0] = node.loc[0]; if (node.loc[0] < extent[1][0]) extent[1][0] = node.loc[0]; if (node.loc[1] < extent[0][1]) extent[0][1] = node.loc[1]; diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 764fa83ae..9d80676f4 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -65,18 +65,21 @@ iD.Map = function() { var only = {}; for (var j = 0; j < difference.length; j++) { var id = difference[j]; - only[id] = graph.fetch(id); - if (only[id] && only[id].type === 'node') { - var parents = graph.parentWays(only[id]); - for (var k = 0; k < parents.length; k++) { - // Don't re-fetch parents - if (only[parents[k].id] === undefined) { - only[parents[k].id] = graph.fetch(parents[k].id); + var entity = graph.fetch(id); + if (entity && entity.intersects(extent, graph)) { + only[id] = entity; + if (only[id].type === 'node') { + var parents = graph.parentWays(only[id]); + for (var k = 0; k < parents.length; k++) { + // Don't re-fetch parents + if (only[parents[k].id] === undefined) { + only[parents[k].id] = graph.fetch(parents[k].id); + } } } } } - all = _.compact(_.values(only)); + all = _.values(only); filter = function(d) { return d.midpoint ? d.way in only : d.id in only; }; } From 140e6991eda31f53ba820a158ef72d7b58b1de17 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 14:21:20 -0500 Subject: [PATCH 20/35] Stack areas as well as ways. Fixes #409 --- js/id/svg/areas.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/js/id/svg/areas.js b/js/id/svg/areas.js index b4a8a36f5..ff24afecc 100644 --- a/js/id/svg/areas.js +++ b/js/id/svg/areas.js @@ -1,4 +1,31 @@ iD.svg.Areas = function() { + + var area_stack = { + building: 0, + manmade: 1, + natural: 1, + boundary: 2 + }; + + function findKey(a) { + var vals = Object.keys(a.tags).filter(function(k) { + return area_stack[k] !== undefined; + }); + if (vals.length > 0) return area_stack[vals[0]]; + else return -1; + } + + function areastack(a, b) { + if (!a || !b || !a.tags || !b.tags) return 0; + if (a.tags.layer !== undefined && b.tags.layer !== undefined) { + return a.tags.layer - b.tags.layer; + } + var as = 0, bs = 0; + as -= findKey(a); + bs -= findKey(b); + return as - bs; + } + return function drawAreas(surface, graph, entities, filter, projection) { var areas = []; @@ -9,6 +36,8 @@ iD.svg.Areas = function() { } } + areas.sort(areastack); + var lineStrings = {}; function lineString(entity) { From ef1af7a731e51ebbec3e9c639b991e285af4076a Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 14:51:34 -0500 Subject: [PATCH 21/35] Only show tags that appear in greater than a percentage of cases. --- js/id/services/taginfo.js | 25 +++++++++++++++++++++++-- js/id/ui/inspector.js | 8 ++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/js/id/services/taginfo.js b/js/id/services/taginfo.js index 20f1cd09a..3e7de3859 100644 --- a/js/id/services/taginfo.js +++ b/js/id/services/taginfo.js @@ -33,6 +33,21 @@ iD.taginfo = function() { return _.omit(parameters, 'geometry'); } + function popular(parameters) { + var pop_field = 'fraction'; + if (parameters) pop_field = 'count_' + parameters.filter + '_fraction'; + return function(d) { return parseFloat(d[pop_field]) > 0.01; }; + } + + function valKey(d) { return { value: d.key }; } + + function valKeyDescription(d) { + return { + value: d.value, + title: d.description + }; + } + taginfo.keys = function(parameters, callback) { parameters = clean(setSort(setFilter(parameters))); d3.json(endpoint + 'keys/all?' + @@ -41,7 +56,10 @@ iD.taginfo = function() { sortname: 'count_all', sortorder: 'desc', page: 1 - }, parameters)), callback); + }, parameters)), function(err, d) { + if (err) return callback(err); + callback(null, d.data.filter(popular(parameters)).map(valKey)); + }); }; taginfo.values = function(parameters, callback) { @@ -52,7 +70,10 @@ iD.taginfo = function() { sortname: 'count_all', sortorder: 'desc', page: 1 - }, parameters)), callback); + }, parameters)), function(err, d) { + if (err) return callback(err); + callback(null, d.data.filter(popular()).map(valKeyDescription)); + }); }; taginfo.docs = function(parameters, callback) { diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index f0db48166..dcae12d55 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -219,9 +219,7 @@ iD.ui.inspector = function() { geometry: geometry, query: key.property('value') }, function(err, data) { - callback(data.data.map(function (d) { - return {value: d.key}; - })); + if (!err) callback(data); }); }, 500))); @@ -232,9 +230,7 @@ iD.ui.inspector = function() { geometry: geometry, query: value.property('value') }, function(err, data) { - callback(data.data.map(function (d) { - return {value: d.value, title: d.description}; - })); + if (!err) callback(data); }); }, 500))); } From ad6de1437f2bf49eda8f2c8228ea6d40198437d8 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 15:01:21 -0500 Subject: [PATCH 22/35] Prevent typeahead from falling off length of list --- js/lib/d3.typeahead.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/js/lib/d3.typeahead.js b/js/lib/d3.typeahead.js index 554b89a60..08a1a36ec 100644 --- a/js/lib/d3.typeahead.js +++ b/js/lib/d3.typeahead.js @@ -2,7 +2,7 @@ d3.typeahead = function() { var data; var typeahead = function(selection) { - var container, hidden, idx = 0; + var container, hidden, idx = -1; function setup() { var rect = selection.node().getBoundingClientRect(); @@ -20,7 +20,7 @@ d3.typeahead = function() { function hide() { container.remove(); - idx = 0; + idx = -1; hidden = true; } @@ -33,14 +33,17 @@ d3.typeahead = function() { .on('blur.typeahead', slowHide); function key() { + var len = container.selectAll('a').data().length; if (d3.event.keyCode === 40) { - idx++; + idx = Math.min(idx + 1, len - 1); return highlight(); } else if (d3.event.keyCode === 38) { - idx--; + idx = Math.max(idx - 1, 0); return highlight(); } else if (d3.event.keyCode === 13) { - select(container.select('a.selected').datum()); + if (container.select('a.selected').node()) { + select(container.select('a.selected').datum()); + } hide(); } else { update(); From 1c757a7c202a4091fb4291bf265e3114fb3b4e8b Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 17:36:45 -0500 Subject: [PATCH 23/35] Improve background cache logic. Fixes #411 --- js/id/renderer/background.js | 37 +++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/js/id/renderer/background.js b/js/id/renderer/background.js index 76188c79f..f861d2226 100644 --- a/js/id/renderer/background.js +++ b/js/id/renderer/background.js @@ -55,14 +55,36 @@ iD.Background = function() { ups = {}; tiles.forEach(function(d) { - d.push(source(d)); - // this tile has not been loaded yet - if (!cache[d] && - cache[atZoom(d, -1)] && + + // if this tile has already failed, do + // not request it + if (cache[d] !== false) d.push(source(d)); + + // if this tile has failed, try to request its tile above + if (cache[d] === false && + cache[atZoom(d, -1)] !== false && !ups[atZoom(d, -1)]) { + ups[atZoom(d, -1)] = true; tiles.push(atZoom(d, -1)); - } else if (!cache[d]) { + + // if this tile has not finished, req the one above + } else if (cache[d] === undefined && + + // but the tile above is in the cache + cache[atZoom(d, -1)] && + + // and another tile has not already requested the + // tile above + !ups[atZoom(d, -1)]) { + + ups[atZoom(d, -1)] = true; + tiles.push(atZoom(d, -1)); + + // if this tile has not yet completed, try keeping the + // tiles below it + } else if (cache[d] === undefined || + cache[d] === false) { upZoom(d, 1).forEach(function(u) { if (cache[u] && !ups[u]) { ups[u] = true; @@ -79,11 +101,12 @@ iD.Background = function() { image.exit().remove(); function load(d) { - cache[d] = true; + cache[d.slice(0, 3)] = true; d3.select(this).on('load', null); } - function error() { + function error(d) { + cache[d.slice(0, 3)] = false; d3.select(this).remove(); } From d8a587631ba96773dbe7f49ede3714add63f0d8c Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 17:37:57 -0500 Subject: [PATCH 24/35] Fix TypeError from race condition between resetting and using transforms. --- js/id/renderer/map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 9d80676f4..9bb695747 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -123,7 +123,7 @@ iD.Map = function() { projection .translate(d3.event.translate) .scale(d3.event.scale); - if (fast) { + if (fast && translateStart) { var a = d3.event.translate, b = translateStart, translate = 'translate(' + ~~(a[0] - b[0]) + 'px,' + From eecc6b14fb7ded90c9ed79127ab7dc88fcecedf7 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 16 Jan 2013 18:39:12 -0500 Subject: [PATCH 25/35] First shot at tooltips cc @samanbb --- css/app.css | 15 ++++++++++--- index.html | 1 + js/id/modes/add_point.js | 2 +- js/id/renderer/map.js | 10 ++++++++- js/lib/d3.tooltip.js | 46 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 js/lib/d3.tooltip.js diff --git a/css/app.css b/css/app.css index 4aba98318..cafe19774 100644 --- a/css/app.css +++ b/css/app.css @@ -1044,7 +1044,16 @@ div.typeahead a:first-child { } .Browse .tooltip .tooltip-arrow { - left: 30px; - } - + left: 30px; +} +.mouse-tooltip { + opacity:0.5; + background :#fff; + margin-left: 20px; + margin-top: -15px; + padding:5px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} diff --git a/index.html b/index.html index b106c35b7..08c23a46b 100644 --- a/index.html +++ b/index.html @@ -22,6 +22,7 @@ + diff --git a/js/id/modes/add_point.js b/js/id/modes/add_point.js index 37767f3de..4936f1578 100644 --- a/js/id/modes/add_point.js +++ b/js/id/modes/add_point.js @@ -10,7 +10,7 @@ iD.modes.AddPoint = function() { history = mode.history, controller = mode.controller; - map.hint('Click on the map to add a point.'); + map.tooltip('Click on the map to add a point.'); map.surface.on('click.addpoint', function() { var node = iD.Node({loc: map.mouseCoordinates(), _poi: true}); diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 9bb695747..7d3bd8a2a 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -21,6 +21,7 @@ iD.Map = function() { lines = iD.svg.Lines(), areas = iD.svg.Areas(), midpoints = iD.svg.Midpoints(), + tooltip = d3.tooltip(), surface, tilegroup; function map(selection) { @@ -32,7 +33,8 @@ iD.Map = function() { .on('mousedown.drag', function() { translateStart = projection.translate(); }) - .call(zoom); + .call(zoom) + .call(tooltip); surface = supersurface.append('svg') .on('mouseup.reset-transform', resetTransform) @@ -281,6 +283,12 @@ iD.Map = function() { return map; }; + map.tooltip = function (_) { + if (_ === false) tooltip.off(); + else tooltip.text(_); + return map; + }; + map.hint = function (_) { if (_ === false) { d3.select('div.inspector-wrap') diff --git a/js/lib/d3.tooltip.js b/js/lib/d3.tooltip.js new file mode 100644 index 000000000..1be658038 --- /dev/null +++ b/js/lib/d3.tooltip.js @@ -0,0 +1,46 @@ +d3.tooltip = function() { + var text, on = false, container, tooltip_size, container_size, + transformProp = iD.util.prefixCSSProperty('Transform'); + + var tooltip = function(selection) { + function setup() { + var rect = selection.node().getBoundingClientRect(); + container = d3.select(document.body) + .append('div').attr('class', 'mouse-tooltip') + .style({ + position: 'absolute' + }); + + selection + .on('mousemove.tooltip', mousemove); + + container_size = container.size(); + } + + function mousemove() { + if (!on) return; + container.style(transformProp, 'translate(' + + ~~d3.event.x + 'px,' + + ~~d3.event.y + 'px)'); + } + + if (!container) setup(); + }; + + tooltip.text = function(_) { + if (_ === false) { + on = false; + container.style('display', 'none'); + return tooltip; + } else if (container.style('display') == 'none') { + container.style('display', 'block'); + } + on = true; + text = _; + container.text(text); + size = container.size(); + return tooltip; + }; + + return tooltip; +}; From 349935b38191c16150538c559ca942e5e1792f3c Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Wed, 16 Jan 2013 22:32:10 -0800 Subject: [PATCH 26/35] Fix build. --- test/spec/taginfo.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/spec/taginfo.js b/test/spec/taginfo.js index b41c760e0..9efe750ea 100644 --- a/test/spec/taginfo.js +++ b/test/spec/taginfo.js @@ -22,13 +22,12 @@ describe("iD.taginfo", function() { server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/4/keys/all"), [200, { "Content-Type": "application/json" }, - '{"data":[{"count_all":5190337,"key":"amenity"}]}']); + '{"data":[{"count_all":5190337,"key":"amenity","count_undefined_fraction":1}]}']); server.respond(); expect(query(server.requests[0].url)).to.eql( {query: "amen", page: "1", rp: "6", sortname: "count_all", sortorder: "desc"}); - expect(callback).to.have.been.calledWith(null, - {"data":[{"count_all":5190337,"key":"amenity"}]}); + expect(callback).to.have.been.calledWith(null, [{"value":"amenity"}]); }); }); @@ -41,13 +40,12 @@ describe("iD.taginfo", function() { server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/4/key/values"), [200, { "Content-Type": "application/json" }, - '{"data":[{"value":"parking","description":"A place for parking cars"}]}']); + '{"data":[{"value":"parking","description":"A place for parking cars", "fraction":1}]}']); server.respond(); expect(query(server.requests[0].url)).to.eql( {key: "amenity", query: "par", page: "1", rp: "20", sortname: 'count_all', sortorder: 'desc'}); - expect(callback).to.have.been.calledWith(null, - {"data":[{"value":"parking","description":"A place for parking cars"}]}); + expect(callback).to.have.been.calledWith(null, [{"value":"parking","title":"A place for parking cars"}]); }); }); From 48d93f2f38903364c0b71b37e3027d17d09bda71 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Wed, 16 Jan 2013 23:20:56 -0800 Subject: [PATCH 27/35] tag autocomplete can filter keys by element type. --- js/id/services/taginfo.js | 14 ++++++---- test/spec/taginfo.js | 58 ++++++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/js/id/services/taginfo.js b/js/id/services/taginfo.js index 3e7de3859..aa89a37fa 100644 --- a/js/id/services/taginfo.js +++ b/js/id/services/taginfo.js @@ -33,12 +33,16 @@ iD.taginfo = function() { return _.omit(parameters, 'geometry'); } - function popular(parameters) { - var pop_field = 'fraction'; - if (parameters) pop_field = 'count_' + parameters.filter + '_fraction'; + function popularKeys(parameters) { + var pop_field = 'count_all_fraction'; + if (parameters.filter) pop_field = 'count_' + parameters.filter + '_fraction'; return function(d) { return parseFloat(d[pop_field]) > 0.01; }; } + function popularValues(parameters) { + return function(d) { return parseFloat(d['fraction']) > 0.01; }; + } + function valKey(d) { return { value: d.key }; } function valKeyDescription(d) { @@ -58,7 +62,7 @@ iD.taginfo = function() { page: 1 }, parameters)), function(err, d) { if (err) return callback(err); - callback(null, d.data.filter(popular(parameters)).map(valKey)); + callback(null, d.data.filter(popularKeys(parameters)).map(valKey)); }); }; @@ -72,7 +76,7 @@ iD.taginfo = function() { page: 1 }, parameters)), function(err, d) { if (err) return callback(err); - callback(null, d.data.filter(popular()).map(valKeyDescription)); + callback(null, d.data.filter(popularValues()).map(valKeyDescription)); }); }; diff --git a/test/spec/taginfo.js b/test/spec/taginfo.js index 9efe750ea..61f7bcea0 100644 --- a/test/spec/taginfo.js +++ b/test/spec/taginfo.js @@ -1,8 +1,9 @@ describe("iD.taginfo", function() { - var server; + var server, taginfo; beforeEach(function() { server = sinon.fakeServer.create(); + taginfo = iD.taginfo(); }); afterEach(function() { @@ -15,44 +16,81 @@ describe("iD.taginfo", function() { describe("#keys", function() { it("calls the given callback with the results of the keys query", function() { - var taginfo = iD.taginfo(), - callback = sinon.spy(); - + var callback = sinon.spy(); taginfo.keys({query: "amen"}, callback); server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/4/keys/all"), [200, { "Content-Type": "application/json" }, - '{"data":[{"count_all":5190337,"key":"amenity","count_undefined_fraction":1}]}']); + '{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0}]}']); server.respond(); expect(query(server.requests[0].url)).to.eql( {query: "amen", page: "1", rp: "6", sortname: "count_all", sortorder: "desc"}); expect(callback).to.have.been.calledWith(null, [{"value":"amenity"}]); }); + + it("filters only popular nodes", function() { + var callback = sinon.spy(); + taginfo.keys({query: "amen"}, callback); + + server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/4/keys/all"), + [200, { "Content-Type": "application/json" }, + '{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0, "count_nodes_fraction":1.0},\ + {"count_all":1,"key":"amenityother","count_all_fraction":0.0, "count_nodes_fraction":0.0}]}']); + server.respond(); + + expect(callback).to.have.been.calledWith(null, [{"value":"amenity"}]); + }); + + it("filters only popular nodes with an entity type filter", function() { + var callback = sinon.spy(); + + taginfo.keys({query: "amen", filter: "nodes"}, callback); + + server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/4/keys/all"), + [200, { "Content-Type": "application/json" }, + '{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0, "count_nodes_fraction":1.0},\ + {"count_all":1,"key":"amenityother","count_all_fraction":0.0, "count_nodes_fraction":1.0}]}']); + server.respond(); + + expect(callback).to.have.been.calledWith(null, [{"value":"amenity"},{"value":"amenityother"}]); + }); }); describe("#values", function() { it("calls the given callback with the results of the values query", function() { - var taginfo = iD.taginfo(), - callback = sinon.spy(); + var callback = sinon.spy(); taginfo.values({key: "amenity", query: "par"}, callback); server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/4/key/values"), [200, { "Content-Type": "application/json" }, - '{"data":[{"value":"parking","description":"A place for parking cars", "fraction":1}]}']); + '{"data":[{"value":"parking","description":"A place for parking cars", "fraction":0.1}]}']); server.respond(); expect(query(server.requests[0].url)).to.eql( {key: "amenity", query: "par", page: "1", rp: "20", sortname: 'count_all', sortorder: 'desc'}); expect(callback).to.have.been.calledWith(null, [{"value":"parking","title":"A place for parking cars"}]); }); + + it("filters popular values", function() { + var callback = sinon.spy(); + + taginfo.values({key: "amenity", query: "par"}, callback); + + server.respondWith("GET", new RegExp("http://taginfo.openstreetmap.org/api/4/key/values"), + [200, { "Content-Type": "application/json" }, + '{"data":[{"value":"parking","description":"A place for parking cars", "fraction":1.0},\ + {"value":"party","description":"A place for partying", "fraction":0.0}]}']); + server.respond(); + + expect(callback).to.have.been.calledWith(null, [{"value":"parking","title":"A place for parking cars"}]); + }); }); describe("#docs", function() { it("calls the given callback with the results of the docs query", function() { - var taginfo = iD.taginfo(), - callback = sinon.spy(); + var callback = sinon.spy(); taginfo.docs({key: "amenity", value: "parking"}, callback); From 3d10a00284584f78abb0fdae9ae18d68c6c54559 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 17 Jan 2013 10:16:39 -0500 Subject: [PATCH 28/35] Higher-contrast shared vertices --- css/map.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/css/map.css b/css/map.css index 11ba62976..b2929f149 100644 --- a/css/map.css +++ b/css/map.css @@ -65,9 +65,12 @@ g.vertex circle.stroke { fill:#333; } -g.vertex.shared circle { +g.vertex.shared circle.fill { fill:#aff; } +g.vertex.shared circle.stroke { + fill:#044; +} g.vertex.hover circle.fill { -webkit-transform:scale(1.5, 1.5); From cdbe3d616807f59162254af7ca60f00e9dfcfc15 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 17 Jan 2013 10:44:12 -0500 Subject: [PATCH 29/35] Fix removal of elements on undo. Fixes #410 --- js/id/renderer/map.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 9bb695747..c0defee3f 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -62,12 +62,15 @@ iD.Map = function() { all = graph.intersects(extent); filter = d3.functor(true); } else { - var only = {}; + var only = {}, + filterOnly = {}; for (var j = 0; j < difference.length; j++) { - var id = difference[j]; - var entity = graph.fetch(id); + var id = difference[j], + entity = graph.fetch(id); + // Even if the entity is false (deleted), it needs to be + // removed from the surface + only[id] = entity; if (entity && entity.intersects(extent, graph)) { - only[id] = entity; if (only[id].type === 'node') { var parents = graph.parentWays(only[id]); for (var k = 0; k < parents.length; k++) { @@ -79,7 +82,7 @@ iD.Map = function() { } } } - all = _.values(only); + all = _.compact(_.values(only)); filter = function(d) { return d.midpoint ? d.way in only : d.id in only; }; } From b8d9741959ecdf7fb3fe6267cbbccd3fdba477f8 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Thu, 17 Jan 2013 10:48:42 -0500 Subject: [PATCH 30/35] Only update inspector tag list when necessary --- js/id/modes/select.js | 5 +++-- js/id/ui/inspector.js | 26 +++++++++++++++----------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/js/id/modes/select.js b/js/id/modes/select.js index c85172a4a..d091fdc57 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -87,11 +87,12 @@ iD.modes.Select = function (entity) { // Exit mode if selected entity gets undone mode.history.on('change.entity-undone', function() { + var old = entity; entity = mode.history.graph().entity(entity.id); if (!entity) { mode.controller.enter(iD.modes.Browse()); - } else { - d3.select('.inspector-wrap').datum(entity).call(inspector); + } else if(!_.isEqual(entity.tags, old.tags)) { + inspector.tags(entity.tags); } }); diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index dcae12d55..a1aed91ec 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -99,7 +99,8 @@ iD.ui.inspector = function() { tags = [{key: '', value: ''}]; } - var li = tagList.selectAll('li') + var li = tagList.html('') + .selectAll('li') .data(tags, function(d) { return d.key; }); li.exit().remove(); @@ -154,7 +155,6 @@ iD.ui.inspector = function() { if (en.on_node) types.push('point'); if (en.on_way) types.push('line'); en.types = types; - console.log(en); iD.ui.modal() .select('.content') .datum(en) @@ -256,15 +256,19 @@ iD.ui.inspector = function() { event.close(entity); } - inspector.tags = function () { - var tags = {}; - tagList.selectAll('li').each(function() { - var row = d3.select(this), - key = row.selectAll('.key').property('value'), - value = row.selectAll('.value').property('value'); - if (key !== '') tags[key] = value; - }); - return tags; + inspector.tags = function (tags) { + if (!arguments.length) { + var tags = {}; + tagList.selectAll('li').each(function() { + var row = d3.select(this), + key = row.selectAll('.key').property('value'), + value = row.selectAll('.value').property('value'); + if (key !== '') tags[key] = value; + }); + return tags; + } else { + drawTags(tags); + } }; return d3.rebind(inspector, event, 'on'); From fd2ef2a78b48c36ce2c5d49ed46e12cd5500b729 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 17 Jan 2013 12:07:26 -0500 Subject: [PATCH 31/35] Rename tooltip to tail, use tail in modes. --- css/app.css | 9 +++--- index.html | 2 +- js/id/id.js | 4 +-- js/id/modes/add_area.js | 4 +-- js/id/modes/add_line.js | 4 +-- js/id/modes/add_point.js | 4 +-- js/id/modes/draw_area.js | 5 ++-- js/id/modes/draw_line.js | 4 +-- js/id/renderer/map.js | 14 +++++---- js/lib/d3.tail.js | 65 ++++++++++++++++++++++++++++++++++++++++ js/lib/d3.tooltip.js | 46 ---------------------------- 11 files changed, 90 insertions(+), 71 deletions(-) create mode 100644 js/lib/d3.tail.js delete mode 100644 js/lib/d3.tooltip.js diff --git a/css/app.css b/css/app.css index cafe19774..b54ac70f1 100644 --- a/css/app.css +++ b/css/app.css @@ -1047,12 +1047,11 @@ div.typeahead a:first-child { left: 30px; } -.mouse-tooltip { - opacity:0.5; - background :#fff; - margin-left: 20px; +.tail { + position: absolute; + background: rgba(255, 255, 255, 0.7); margin-top: -15px; - padding:5px; + padding: 5px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; diff --git a/index.html b/index.html index 08c23a46b..9db659489 100644 --- a/index.html +++ b/index.html @@ -22,7 +22,7 @@ - + diff --git a/js/id/id.js b/js/id/id.js index 712656cd6..96f4d09d5 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -180,9 +180,9 @@ window.iD = function(container) { .call(redo ? refreshTooltip : undo_tooltip.hide); }); - window.onresize = function() { + d3.select(window).on('resize.map-size', function() { map.size(m.size()); - }; + }); map.keybinding() .on('a', function(evt, mods) { diff --git a/js/id/modes/add_area.js b/js/id/modes/add_area.js index 6977f2e15..a9fcb830e 100644 --- a/js/id/modes/add_area.js +++ b/js/id/modes/add_area.js @@ -12,7 +12,7 @@ iD.modes.AddArea = function() { controller = mode.controller; map.dblclickEnable(false) - .hint('Click on the map to start drawing an area, like a park, lake, or building.'); + .tail('Click on the map to start drawing an area, like a park, lake, or building.'); map.surface.on('click.addarea', function() { var datum = d3.select(d3.event.target).datum() || {}, @@ -47,7 +47,7 @@ iD.modes.AddArea = function() { window.setTimeout(function() { mode.map.dblclickEnable(true); }, 1000); - mode.map.hint(false); + mode.map.tail(false); mode.map.surface.on('click.addarea', null); mode.map.keybinding().on('⎋.addarea', null); }; diff --git a/js/id/modes/add_line.js b/js/id/modes/add_line.js index 60f376181..b83202097 100644 --- a/js/id/modes/add_line.js +++ b/js/id/modes/add_line.js @@ -13,7 +13,7 @@ iD.modes.AddLine = function() { controller = mode.controller; map.dblclickEnable(false) - .hint('Click on the map to start drawing an road, path, or route.'); + .tail('Click on the map to start drawing an road, path, or route.'); map.surface.on('click.addline', function() { var datum = d3.select(d3.event.target).datum() || {}, @@ -67,7 +67,7 @@ iD.modes.AddLine = function() { mode.exit = function() { mode.map.dblclickEnable(true); - mode.map.hint(false); + mode.map.tail(false); mode.map.surface.on('click.addline', null); mode.map.keybinding().on('⎋.addline', null); }; diff --git a/js/id/modes/add_point.js b/js/id/modes/add_point.js index 4936f1578..21d6343e0 100644 --- a/js/id/modes/add_point.js +++ b/js/id/modes/add_point.js @@ -10,7 +10,7 @@ iD.modes.AddPoint = function() { history = mode.history, controller = mode.controller; - map.tooltip('Click on the map to add a point.'); + map.tail('Click on the map to add a point.'); map.surface.on('click.addpoint', function() { var node = iD.Node({loc: map.mouseCoordinates(), _poi: true}); @@ -28,7 +28,7 @@ iD.modes.AddPoint = function() { }; mode.exit = function() { - mode.map.hint(false); + mode.map.tail(false); mode.map.surface.on('click.addpoint', null); mode.map.keybinding().on('⎋.addpoint', null); }; diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index 88d61d323..cdb966351 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -18,8 +18,7 @@ iD.modes.DrawArea = function(wayId) { map.dblclickEnable(false) .fastEnable(false); - map.hint('Click on the map to add points to your area. Finish the ' + - 'area by clicking on your first point'); + map.tail('Click to add points to your area. Click the first point to finish the area.'); history.perform( iD.actions.AddNode(node), @@ -116,7 +115,7 @@ iD.modes.DrawArea = function(wayId) { surface.selectAll('.way, .node') .classed('active', false); - mode.map.hint(false); + mode.map.tail(false); mode.map.fastEnable(true); surface diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index a59e3a7e9..68130d7b8 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -19,7 +19,7 @@ iD.modes.DrawLine = function(wayId, direction) { map.dblclickEnable(false) .fastEnable(false) - .hint('Click to add more points to the line. ' + + .tail('Click to add more points to the line. ' + 'Click on other lines to connect to them, and double-click to ' + 'end the line.'); @@ -152,7 +152,7 @@ iD.modes.DrawLine = function(wayId, direction) { surface.selectAll('.way, .node') .classed('active', false); - mode.map.hint(false); + mode.map.tail(false); mode.map.fastEnable(true); mode.map.minzoom(0); diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index a2f2acfd9..9edb347e4 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -21,7 +21,7 @@ iD.Map = function() { lines = iD.svg.Lines(), areas = iD.svg.Areas(), midpoints = iD.svg.Midpoints(), - tooltip = d3.tooltip(), + tail = d3.tail(), surface, tilegroup; function map(selection) { @@ -33,8 +33,7 @@ iD.Map = function() { .on('mousedown.drag', function() { translateStart = projection.translate(); }) - .call(zoom) - .call(tooltip); + .call(zoom); surface = supersurface.append('svg') .on('mouseup.reset-transform', resetTransform) @@ -46,9 +45,13 @@ iD.Map = function() { }) .call(iD.svg.Surface()); + map.size(selection.size()); map.surface = surface; + supersurface + .call(tail); + d3.select(document).call(keybinding); } @@ -286,9 +289,8 @@ iD.Map = function() { return map; }; - map.tooltip = function (_) { - if (_ === false) tooltip.off(); - else tooltip.text(_); + map.tail = function (_) { + tail.text(_); return map; }; diff --git a/js/lib/d3.tail.js b/js/lib/d3.tail.js new file mode 100644 index 000000000..00627de0a --- /dev/null +++ b/js/lib/d3.tail.js @@ -0,0 +1,65 @@ +d3.tail = function() { + var text = false, + container, + xmargin = 20, + tooltip_size = [0, 0], + selection_size = [0, 0], + transformProp = iD.util.prefixCSSProperty('Transform'); + + var tail = function(selection) { + + d3.select(window).on('resize.tail-size', function() { + selection_size = selection.size(); + }); + + function setup() { + + container = d3.select(document.body) + .append('div').attr('class', 'tail'); + + selection + .on('mousemove.tail', mousemove) + .on('mouseover.tail', mouseover) + .on('mouseout.tail', mouseout); + + selection_size = selection.size(); + + } + + function mousemove() { + if (text === false) return; + var xoffset = ((d3.event.x + tooltip_size[0] + xmargin) > selection_size[0]) ? + -tooltip_size[0] - xmargin : xoffset = xmargin; + container.style(transformProp, 'translate(' + + (~~d3.event.x + xoffset) + 'px,' + + ~~d3.event.y + 'px)'); + } + + function mouseout() { + if (text !== false) container.style('display', 'none'); + } + + function mouseover() { + if (text !== false) container.style('display', 'block'); + } + + if (!container) setup(); + + }; + + tail.text = function(_) { + if (_ === false) { + text = _; + container.style('display', 'none'); + return tail; + } else if (container.style('display') == 'none') { + container.style('display', 'block'); + } + text = _; + container.text(text); + tooltip_size = container.size(); + return tail; + }; + + return tail; +}; diff --git a/js/lib/d3.tooltip.js b/js/lib/d3.tooltip.js deleted file mode 100644 index 1be658038..000000000 --- a/js/lib/d3.tooltip.js +++ /dev/null @@ -1,46 +0,0 @@ -d3.tooltip = function() { - var text, on = false, container, tooltip_size, container_size, - transformProp = iD.util.prefixCSSProperty('Transform'); - - var tooltip = function(selection) { - function setup() { - var rect = selection.node().getBoundingClientRect(); - container = d3.select(document.body) - .append('div').attr('class', 'mouse-tooltip') - .style({ - position: 'absolute' - }); - - selection - .on('mousemove.tooltip', mousemove); - - container_size = container.size(); - } - - function mousemove() { - if (!on) return; - container.style(transformProp, 'translate(' + - ~~d3.event.x + 'px,' + - ~~d3.event.y + 'px)'); - } - - if (!container) setup(); - }; - - tooltip.text = function(_) { - if (_ === false) { - on = false; - container.style('display', 'none'); - return tooltip; - } else if (container.style('display') == 'none') { - container.style('display', 'block'); - } - on = true; - text = _; - container.text(text); - size = container.size(); - return tooltip; - }; - - return tooltip; -}; From d550eda4432ff011500262b426c2bd71aee1e670 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 17 Jan 2013 12:17:45 -0500 Subject: [PATCH 32/35] Remove pointer-events from tooltips to keep them from disappearing. --- css/app.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/css/app.css b/css/app.css index b54ac70f1..932ca3b52 100644 --- a/css/app.css +++ b/css/app.css @@ -1048,8 +1048,10 @@ div.typeahead a:first-child { } .tail { + pointer-events:none; position: absolute; background: rgba(255, 255, 255, 0.7); + max-width: 250px; margin-top: -15px; padding: 5px; -webkit-border-radius: 4px; From e111ea2aa5e4f587cf7f39a15290069e920b080c Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 17 Jan 2013 12:22:11 -0500 Subject: [PATCH 33/35] Gracefully handle Opera, which does not support pointer-events --- js/lib/d3.tail.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/js/lib/d3.tail.js b/js/lib/d3.tail.js index 00627de0a..8046e4a96 100644 --- a/js/lib/d3.tail.js +++ b/js/lib/d3.tail.js @@ -22,6 +22,9 @@ d3.tail = function() { .on('mouseover.tail', mouseover) .on('mouseout.tail', mouseout); + container + .on('mousemove.tail', mousemove); + selection_size = selection.size(); } @@ -36,11 +39,13 @@ d3.tail = function() { } function mouseout() { - if (text !== false) container.style('display', 'none'); + if (d3.event.relatedTarget !== container.node() && + text !== false) container.style('display', 'none'); } function mouseover() { - if (text !== false) container.style('display', 'block'); + if (d3.event.relatedTarget !== container.node() && + text !== false) container.style('display', 'block'); } if (!container) setup(); From ae37003852f8d1ff930bfc188b1e58822eb44c27 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Thu, 17 Jan 2013 12:32:11 -0500 Subject: [PATCH 34/35] prefer taginfo suggestions that startwith input --- js/id/ui/inspector.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index a1aed91ec..3af39c1b7 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -213,13 +213,26 @@ iD.ui.inspector = function() { key = row.selectAll('.key'), value = row.selectAll('.value'); + function sort(value, data) { + var sameletter = [], + other = []; + for (var i = 0; i < data.length; i++) { + if (data[i].value.substring(0, value.length) === value) { + sameletter.push(data[i]); + } else { + other.push(data[i]); + } + } + return sameletter.concat(other); + } + key.call(d3.typeahead() .data(_.debounce(function(_, callback) { taginfo.keys({ geometry: geometry, query: key.property('value') }, function(err, data) { - if (!err) callback(data); + if (!err) callback(sort(key.property('value'), data)); }); }, 500))); @@ -230,7 +243,7 @@ iD.ui.inspector = function() { geometry: geometry, query: value.property('value') }, function(err, data) { - if (!err) callback(data); + if (!err) callback(sort(value.property('value'), data)); }); }, 500))); } From 87c8fbdb2fe7a2b56f2d77ec00deb54b5eea0c55 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 17 Jan 2013 12:49:43 -0500 Subject: [PATCH 35/35] Remove unreachable code in connection. This unfortunately prevents loadFromURL from sharing the queue and cancelling functionality of bboxes --- js/id/connection.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/js/id/connection.js b/js/id/connection.js index 71f11e23d..003750ff2 100644 --- a/js/id/connection.js +++ b/js/id/connection.js @@ -27,8 +27,6 @@ iD.Connection = function() { return callback(null, parse(dom)); } return d3.xml(url).get().on('load', done); - inflight.push(d3.xml(url).get() - .on('load', done)); } function getNodes(obj) {