From 54863c679f88d310370e595d16442f7a011b93fa Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Mon, 28 Jan 2013 15:43:05 -0500 Subject: [PATCH 01/12] Update screenshot --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 770629f39..711cb5418 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://secure.travis-ci.org/systemed/iD.png)](https://travis-ci.org/systemed/iD) -[![](https://raw.github.com/systemed/iD/master/screenshot.jpg)](http://geowiki.com/iD/) +[![](http://ideditor.com/img/editor.png)](http://geowiki.com/iD/) [Try the online demo of the most recent code.](http://geowiki.com/iD/) and [open issues for bugs and ideas!](https://github.com/systemed/iD/issues) From aa21e4b30182c4118fad8225f20a341251453c99 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Mon, 28 Jan 2013 15:56:37 -0500 Subject: [PATCH 02/12] Undo cancels drags --- js/id/behavior/drag.js | 19 ++++++++++++++++++- js/id/behavior/drag_node.js | 3 ++- js/id/behavior/drag_way.js | 3 ++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/js/id/behavior/drag.js b/js/id/behavior/drag.js index 29f033c1c..9a7ed4fdc 100644 --- a/js/id/behavior/drag.js +++ b/js/id/behavior/drag.js @@ -23,7 +23,8 @@ iD.behavior.drag = function () { var event = d3.dispatch("start", "move", "end"), origin = null, selector = '', - filter = null; + filter = null, + keybinding = d3.keybinding('drag'); event.of = function(thiz, argumentz) { return function(e1) { @@ -135,6 +136,9 @@ iD.behavior.drag = function () { drag.off = function(selection) { selection.on("mousedown.drag" + selector, null) .on("touchstart.drag" + selector, null); + keybinding + .on('⌘+Z', null) + .on('⌃+Z', null); }; drag.delegate = function(_) { @@ -155,5 +159,18 @@ iD.behavior.drag = function () { return drag; }; + drag.cancel = function() { + d3.select(window) + .on("mousemove.drag", null) + .on("mouseup.drag", null); + return drag; + }; + + keybinding + .on('⌘+Z', drag.cancel) + .on('⌃+Z', drag.cancel); + + d3.select(document).call(keybinding); + return d3.rebind(drag, event, "on"); }; diff --git a/js/id/behavior/drag_node.js b/js/id/behavior/drag_node.js index e104c795f..084c81895 100644 --- a/js/id/behavior/drag_node.js +++ b/js/id/behavior/drag_node.js @@ -14,7 +14,8 @@ iD.behavior.DragNode = function(mode) { .on('move', function(entity) { d3.event.sourceEvent.stopPropagation(); history.replace( - iD.actions.MoveNode(entity.id, projection.invert(d3.event.point))); + iD.actions.MoveNode(entity.id, projection.invert(d3.event.point)), + 'moved a node'); }) .on('end', function() { history.replace( diff --git a/js/id/behavior/drag_way.js b/js/id/behavior/drag_way.js index 47045f5ac..6de8ca252 100644 --- a/js/id/behavior/drag_way.js +++ b/js/id/behavior/drag_way.js @@ -17,7 +17,8 @@ iD.behavior.DragWay = function(mode) { .on('move', function(entity) { d3.event.sourceEvent.stopPropagation(); history.replace( - iD.actions.MoveWay(entity.id, d3.event.delta, projection)); + iD.actions.MoveWay(entity.id, d3.event.delta, projection), + 'moved a way'); }) .on('end', function() { history.replace( From 6ae683dedc086a7c512d2ad74dcd912ac9a92cde Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Mon, 28 Jan 2013 16:18:49 -0500 Subject: [PATCH 03/12] Hints for keybindings. Refs #517 --- css/app.css | 11 +++++++++++ js/id/id.js | 24 +++++++++++++++--------- js/id/modes/add_area.js | 3 ++- js/id/modes/add_line.js | 3 ++- js/id/modes/add_point.js | 3 ++- js/id/modes/browse.js | 3 ++- 6 files changed, 34 insertions(+), 13 deletions(-) diff --git a/css/app.css b/css/app.css index e83c7152f..19d6660cd 100644 --- a/css/app.css +++ b/css/app.css @@ -1110,6 +1110,17 @@ div.typeahead a:first-child { left: 30px; } +.tooltip .keyhint { + float: right; + background: #eee; + font-size: 10px; + padding: 0 4px; + background:#aaa; + color:#fff; + border-radius: 2px; + margin-left: 4px; +} + .tail { pointer-events:none; position: absolute; diff --git a/js/id/id.js b/js/id/id.js index 770cbde43..ab6dd37f2 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -21,6 +21,10 @@ window.iD = function(container) { return; } + function hintprefix(x, y) { + return '' + x + ' ' + y; + } + var m = container.append('div') .attr('id', 'map') .call(map); @@ -40,8 +44,10 @@ window.iD = function(container) { .enter().append('button') .attr('tabindex', -1) .attr('class', function (mode) { return mode.title + ' add-button col3'; }) - .attr('data-original-title', function (mode) { return mode.description; }) - .call(bootstrap.tooltip().placement('bottom')) + .attr('data-original-title', function (mode) { + return hintprefix(mode.key, mode.description); + }) + .call(bootstrap.tooltip().placement('bottom').html(true)) .on('click.editor', function (mode) { controller.enter(mode); }); function disableTooHigh() { @@ -82,7 +88,7 @@ window.iD = function(container) { var undo_buttons = limiter.append('div') .attr('class', 'button-wrap joined col1'), - undo_tooltip = bootstrap.tooltip().placement('bottom'); + undo_tooltip = bootstrap.tooltip().placement('bottom').html(true); undo_buttons.append('button') .attr({ id: 'undo', 'class': 'col6' }) @@ -201,12 +207,12 @@ window.iD = function(container) { limiter.select('#undo') .property('disabled', !undo) - .attr('data-original-title', undo) + .attr('data-original-title', hintprefix('⌘Z', undo)) .call(refreshTooltip); limiter.select('#redo') .property('disabled', !redo) - .attr('data-original-title', redo) + .attr('data-original-title', hintprefix('⌘⇧Z', redo)) .call(refreshTooltip); }); @@ -215,16 +221,16 @@ window.iD = function(container) { }); var keybinding = d3.keybinding('main') - .on('M', function() { if (map.editable()) controller.enter(iD.modes.Browse()); }) - .on('P', function() { if (map.editable()) controller.enter(iD.modes.AddPoint()); }) - .on('L', function() { if (map.editable()) controller.enter(iD.modes.AddLine()); }) - .on('A', function() { if (map.editable()) controller.enter(iD.modes.AddArea()); }) .on('⌘+Z', function() { history.undo(); }) .on('⌃+Z', function() { history.undo(); }) .on('⌘+⇧+Z', function() { history.redo(); }) .on('⌃+⇧+Z', function() { history.redo(); }) .on('⌫', function() { d3.event.preventDefault(); }); + [iD.modes.Browse(), iD.modes.AddPoint(), iD.modes.AddLine(), iD.modes.AddArea()].forEach(function(m) { + keybinding.on(m.key, function() { if (map.editable()) controller.enter(m); }); + }); + d3.select(document) .call(keybinding); diff --git a/js/id/modes/add_area.js b/js/id/modes/add_area.js index e00031723..cbfdffbd0 100644 --- a/js/id/modes/add_area.js +++ b/js/id/modes/add_area.js @@ -3,7 +3,8 @@ iD.modes.AddArea = function() { id: 'add-area', button: 'area', title: 'Area', - description: 'Add parks, buildings, lakes, or other areas to the map.' + description: 'Add parks, buildings, lakes, or other areas to the map.', + key: 'a' }; var behavior, diff --git a/js/id/modes/add_line.js b/js/id/modes/add_line.js index ad446a0f0..f9d52a9a0 100644 --- a/js/id/modes/add_line.js +++ b/js/id/modes/add_line.js @@ -3,7 +3,8 @@ iD.modes.AddLine = function() { id: 'add-line', button: 'line', title: 'Line', - description: 'Lines can be highways, streets, pedestrian paths, or even canals.' + description: 'Lines can be highways, streets, pedestrian paths, or even canals.', + key: 'l' }; var behavior, diff --git a/js/id/modes/add_point.js b/js/id/modes/add_point.js index 89f7aa536..1a51c314d 100644 --- a/js/id/modes/add_point.js +++ b/js/id/modes/add_point.js @@ -2,7 +2,8 @@ iD.modes.AddPoint = function() { var mode = { id: 'add-point', title: 'Point', - description: 'Restaurants, monuments, and postal boxes are points.' + description: 'Restaurants, monuments, and postal boxes are points.', + key: 'p' }; var behavior; diff --git a/js/id/modes/browse.js b/js/id/modes/browse.js index 4b2ea448f..90726b6bc 100644 --- a/js/id/modes/browse.js +++ b/js/id/modes/browse.js @@ -3,7 +3,8 @@ iD.modes.Browse = function() { button: 'browse', id: 'browse', title: 'Move', - description: 'Pan and zoom the map' + description: 'Pan and zoom the map', + key: 'b' }; var behaviors; From 73fd21fefb088b19ed65e4b1da8d9d08252a4d38 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Mon, 28 Jan 2013 16:25:54 -0500 Subject: [PATCH 04/12] Replace gray dot with marker icon. Fixes #474 --- icons/unknown.png | Bin 278 -> 1476 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/unknown.png b/icons/unknown.png index a47dd947dd41e3f45ba73b52034bd90abdd3c23d..404602aa4de44786ef78c6551f51c3e23a3ec3da 100644 GIT binary patch literal 1476 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#X$M%Ak65bF}s3+fyE>< zB%&n3*T*V3KUXg?B|j-uuOhbqsG5Pnrosxy%uOvxRH(?!$t$+1uvG%9umZ9{!um=I zU?nBlwn`Dc0SeCfMX3s=dWL#NN_Jcd3JNwwDQQ+gE^bimK%T8qMoCG5mA-y?dAVM> zv0i>ry1t>MrKP@sk-m|UE>MMTab;dfVufyAu`tKo-FP)SbBnaEtPap}qq8Pro9uK;KZ$Kp$>0P@@gdk5<0FM2bZyT0xdlb3#l;|NOrh$L#n9CwYzfWFEP=ZWO&DEQ z1VY{p&2h+5P;FET_|%F_903oK!3=nis1-PUM7U(;rsjb|#n8+~AFBkCC&BX0`8oMT z!3BxQsdi?jrpCa~L>ETa0k$dwEs=+y_)3i1SltFNa%`2Fun>D}<9SD1g#C<>qU z)av}_{MqZ@_;)ON!5hJ|aR%QF)*CvWlcr`W@l*NrrP+B7@W4v%HFamrI&$L|i{Iz45v8$bT8BvmJYEg;$@?_^@=V5Pw#uY>3ai-4;iV@a2?qh#&dz>sguq|97Sr jmh8KA%Ta#k>hJu2F7G+w=fBYeRL*+3`njxgN@xNAqdD_9 delta 231 zcmV}LP=Bz2nYy#2xN$nAs2rD8FWQhbW?9;ba!ELWdL_~cP?pe zYja~^aAhuUa%Y?FJQ@H10Fy~XK~y-6)svwPgFp~OA5E*Mz(Imo$^U;2as)|n2v9XO zYxW8U2^c0>vpX|4xxFhSaR!f5>MIPMYfUqI12s^3YXL?{^KJq&Yk&@@fR|SVbUxcQ z@RLv5Oybr#n+fWSc$JeHl~_SXOa002ovPDHLkV1l>YTL=IE From 7ffda8c7d32a3bd83afb756e9fefad8b433780bb Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Mon, 28 Jan 2013 16:31:57 -0500 Subject: [PATCH 05/12] Use nicer transitions on buttons like layerswitcher and geocoder. Refs #449 --- css/app.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/css/app.css b/css/app.css index 19d6660cd..36b09e392 100644 --- a/css/app.css +++ b/css/app.css @@ -255,6 +255,9 @@ button { height:40px; cursor:url(../img/cursor-pointer.png) 6 1, auto; border-radius:4px; + -webkit-transition: background 100ms; + -moz-transition: background 100ms; + transition: background 100ms; } button:hover { From 859ae1c1cc6aa52ab9be722094fa24f6dd66ab00 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 28 Jan 2013 16:38:54 -0500 Subject: [PATCH 06/12] DrawWay#cancel shouldn't unconditionally delete the way Fixes #514. --- js/id/behavior/draw_way.js | 4 ++-- js/id/modes/add_area.js | 15 +++++++++------ js/id/modes/add_line.js | 16 +++++++++------- js/id/modes/draw_area.js | 4 ++-- js/id/modes/draw_line.js | 4 ++-- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/js/id/behavior/draw_way.js b/js/id/behavior/draw_way.js index a9f1f5c91..649d79e55 100644 --- a/js/id/behavior/draw_way.js +++ b/js/id/behavior/draw_way.js @@ -1,4 +1,4 @@ -iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) { +iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { var map = mode.map, history = mode.history, controller = mode.controller, @@ -129,7 +129,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) { // Cancel the draw operation and return to browse, deleting everything drawn. drawWay.cancel = function() { - history.perform(iD.actions.DeleteWay(wayId), 'cancelled drawing'); + history.perform(d3.functor(baseGraph), 'cancelled drawing'); controller.enter(iD.modes.Browse()); }; diff --git a/js/id/modes/add_area.js b/js/id/modes/add_area.js index cbfdffbd0..d1a3efb08 100644 --- a/js/id/modes/add_area.js +++ b/js/id/modes/add_area.js @@ -16,18 +16,20 @@ iD.modes.AddArea = function() { controller = mode.controller; function startFromNode(node) { - var way = iD.Way({tags: defaultTags}); + var graph = history.graph(), + way = iD.Way({tags: defaultTags}); history.perform( iD.actions.AddWay(way), iD.actions.AddWayNode(way.id, node.id), iD.actions.AddWayNode(way.id, node.id)); - controller.enter(iD.modes.DrawArea(way.id)); + controller.enter(iD.modes.DrawArea(way.id, graph)); } function startFromWay(other, loc, index) { - var node = iD.Node({loc: loc}), + var graph = history.graph(), + node = iD.Node({loc: loc}), way = iD.Way({tags: defaultTags}); history.perform( @@ -37,11 +39,12 @@ iD.modes.AddArea = function() { iD.actions.AddWayNode(way.id, node.id), iD.actions.AddWayNode(other.id, node.id, index)); - controller.enter(iD.modes.DrawArea(way.id)); + controller.enter(iD.modes.DrawArea(way.id, graph)); } function start(loc) { - var node = iD.Node({loc: loc}), + var graph = history.graph(), + node = iD.Node({loc: loc}), way = iD.Way({tags: defaultTags}); history.perform( @@ -50,7 +53,7 @@ iD.modes.AddArea = function() { iD.actions.AddWayNode(way.id, node.id), iD.actions.AddWayNode(way.id, node.id)); - controller.enter(iD.modes.DrawArea(way.id)); + controller.enter(iD.modes.DrawArea(way.id, graph)); } behavior = iD.behavior.AddWay(mode) diff --git a/js/id/modes/add_line.js b/js/id/modes/add_line.js index f9d52a9a0..bf419d2bb 100644 --- a/js/id/modes/add_line.js +++ b/js/id/modes/add_line.js @@ -21,10 +21,10 @@ iD.modes.AddLine = function() { isLine = parent && parent.geometry(graph) === 'line'; if (isLine && parent.first() === node.id) { - controller.enter(iD.modes.DrawLine(parent.id, 'backward')); + controller.enter(iD.modes.DrawLine(parent.id, 'backward', graph)); } else if (isLine && parent.last() === node.id) { - controller.enter(iD.modes.DrawLine(parent.id, 'forward')); + controller.enter(iD.modes.DrawLine(parent.id, 'forward', graph)); } else { var way = iD.Way({tags: defaultTags}); @@ -33,12 +33,13 @@ iD.modes.AddLine = function() { iD.actions.AddWay(way), iD.actions.AddWayNode(way.id, node.id)); - controller.enter(iD.modes.DrawLine(way.id, 'forward')); + controller.enter(iD.modes.DrawLine(way.id, 'forward', graph)); } } function startFromWay(other, loc, index) { - var node = iD.Node({loc: loc}), + var graph = history.graph(), + node = iD.Node({loc: loc}), way = iD.Way({tags: defaultTags}); history.perform( @@ -47,11 +48,12 @@ iD.modes.AddLine = function() { iD.actions.AddWayNode(way.id, node.id), iD.actions.AddWayNode(other.id, node.id, index)); - controller.enter(iD.modes.DrawLine(way.id, 'forward')); + controller.enter(iD.modes.DrawLine(way.id, 'forward', graph)); } function start(loc) { - var node = iD.Node({loc: loc}), + var graph = history.graph(), + node = iD.Node({loc: loc}), way = iD.Way({tags: defaultTags}); history.perform( @@ -59,7 +61,7 @@ iD.modes.AddLine = function() { iD.actions.AddWay(way), iD.actions.AddWayNode(way.id, node.id)); - controller.enter(iD.modes.DrawLine(way.id, 'forward')); + controller.enter(iD.modes.DrawLine(way.id, 'forward', graph)); } behavior = iD.behavior.AddWay(mode) diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index 9e2bd6a32..721452bae 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -1,4 +1,4 @@ -iD.modes.DrawArea = function(wayId) { +iD.modes.DrawArea = function(wayId, baseGraph) { var mode = { button: 'area', id: 'draw-area' @@ -29,7 +29,7 @@ iD.modes.DrawArea = function(wayId) { behavior.add(loc, annotation); } - behavior = iD.behavior.DrawWay(wayId, headId, tailId, index, mode) + behavior = iD.behavior.DrawWay(wayId, headId, tailId, index, mode, baseGraph) .on('addHead', addHeadTail) .on('addTail', addHeadTail) .on('addNode', addNode) diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index 7980b0549..289d91c14 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -1,4 +1,4 @@ -iD.modes.DrawLine = function(wayId, direction) { +iD.modes.DrawLine = function(wayId, direction, baseGraph) { var mode = { button: 'line', id: 'draw-line' @@ -38,7 +38,7 @@ iD.modes.DrawLine = function(wayId, direction) { behavior.add(loc, annotation); } - behavior = iD.behavior.DrawWay(wayId, headId, tailId, index, mode) + behavior = iD.behavior.DrawWay(wayId, headId, tailId, index, mode, baseGraph) .on('addHead', addHead) .on('addTail', addTail) .on('addNode', addNode) From 7acca8e6d29a12bbdb608d0eff90e3086f6869f6 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Mon, 28 Jan 2013 16:41:25 -0500 Subject: [PATCH 07/12] Reformat success page. Fixes #532 --- css/app.css | 30 +++++++++++++++++++----------- js/id/connection.js | 5 +++++ js/id/ui/save.js | 2 +- js/id/ui/success.js | 21 +++++++++++++++------ 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/css/app.css b/css/app.css index 36b09e392..5deef6b50 100644 --- a/css/app.css +++ b/css/app.css @@ -994,6 +994,14 @@ div.typeahead a:first-child { text-align: center; } +/* Success +------------------------------------------------------- */ +a.success-action { + display:inline-block; + padding:10px; + margin:10px; +} + /* Notices ------------------------------------------------------- */ @@ -1056,17 +1064,17 @@ div.typeahead a:first-child { } .tooltip-inner { - text-align: left; - width: 200px; - font-size: 11px; - font-weight: bold; - line-height: 20px; - padding: 5px 10px; - color: #333; - background-color: white; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; + text-align: left; + width: 200px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + padding: 5px 10px; + color: #333; + background-color: white; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } .tooltip-arrow { diff --git a/js/id/connection.js b/js/id/connection.js index 53c96bd96..0460b09ab 100644 --- a/js/id/connection.js +++ b/js/id/connection.js @@ -10,6 +10,10 @@ iD.Connection = function() { loadedTiles = {}, oauth = iD.OAuth().url(url); + function changesetUrl(changesetId) { + return url + '/browse/changeset/' + changesetId; + } + function bboxUrl(b) { return url + '/api/0.6/map?bbox=' + [b[0][0],b[1][1],b[1][0],b[0][1]]; } @@ -325,6 +329,7 @@ iD.Connection = function() { }; connection.bboxFromAPI = bboxFromAPI; + connection.changesetUrl = changesetUrl; connection.loadFromURL = loadFromURL; connection.loadTiles = _.debounce(loadTiles, 100); connection.userDetails = userDetails; diff --git a/js/id/ui/save.js b/js/id/ui/save.js index 21af956d9..50f9891f7 100644 --- a/js/id/ui/save.js +++ b/js/id/ui/save.js @@ -37,7 +37,7 @@ iD.ui.save = function() { id: changeset_id, comment: e.comment }) - .call(iD.ui.success() + .call(iD.ui.success(connection) .on('cancel', function() { modal.remove(); })); diff --git a/js/id/ui/success.js b/js/id/ui/success.js index d135f7d80..8cc6e328b 100644 --- a/js/id/ui/success.js +++ b/js/id/ui/success.js @@ -1,4 +1,4 @@ -iD.ui.success = function() { +iD.ui.success = function(connection) { var event = d3.dispatch('cancel', 'save'); function success(selection) { @@ -9,22 +9,31 @@ iD.ui.success = function() { var section = body.append('div').attr('class','modal-section fillD'); header.append('h2').text('You Just Edited OpenStreetMap!'); - header.append('p').text('You just improved the world\'s best free map'); var m = ''; if (changeset.comment) { m = '"' + changeset.comment.substring(0, 20) + '" '; } - var message = 'Edited OpenStreetMap! ' + m + - 'http://osm.org/browse/changeset/' + changeset.id; + var message = (m || 'Edited OSM!') + + connection.changesetUrl(changeset.id); - section.append('a') + header.append('a') + .attr('href', function(d) { + return connection.changesetUrl(changeset.id); + }) + .attr('target', '_blank') + .attr('class', 'success-action') + .text('View on OSM'); + + header.append('a') + .attr('target', '_blank') .attr('href', function(d) { return 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message); }) - .text('Tweet: ' + message); + .attr('class', 'success-action') + .text('Tweet'); var buttonwrap = section.append('div') .attr('class', 'buttons cf'); From 3c99d36a768a2e17a4b9bea0aefd39592d57b197 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 28 Jan 2013 16:54:38 -0500 Subject: [PATCH 08/12] Fix differenced redraw artifacts during pan/zoom Fixes #543. --- js/id/renderer/map.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index bc4ca8e03..60ad3de39 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -165,24 +165,33 @@ iD.Map = function() { } function resetTransform() { - if (!surface.style(transformProp)) return; + if (!surface.style(transformProp)) return false; surface.style(transformProp, ''); tilegroup.style(transformProp, ''); + return true; } function redraw(difference) { - resetTransform(); + // If we are in the middle of a zoom/pan, we can't do differenced redraws. + // It would result in artifacts where differenced entities are redrawn with + // one transform and unchanged entities with another. + if (resetTransform()) + difference = undefined; + surface.attr('data-zoom', ~~map.zoom()); tilegroup.call(background); + if (map.editable()) { connection.loadTiles(projection, dimensions); drawVector(difference); } else { editOff(); } + transformStart = [ projection.scale(), projection.translate().slice()]; + return map; } From d998b000d55f7a8e36665c2d4c551539c78b314a Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Mon, 28 Jan 2013 17:02:07 -0500 Subject: [PATCH 09/12] Fix midpoint dragging, break multiple touch drags --- js/id/behavior/drag.js | 16 ++++++++++++---- js/id/behavior/drag_midpoint.js | 12 ++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/js/id/behavior/drag.js b/js/id/behavior/drag.js index 9a7ed4fdc..d88e8a44a 100644 --- a/js/id/behavior/drag.js +++ b/js/id/behavior/drag.js @@ -24,7 +24,8 @@ iD.behavior.drag = function () { origin = null, selector = '', filter = null, - keybinding = d3.keybinding('drag'); + keybinding = d3.keybinding('drag'), + event_, target; event.of = function(thiz, argumentz) { return function(e1) { @@ -40,9 +41,9 @@ iD.behavior.drag = function () { }; function mousedown() { - var target = this, - event_ = event.of(target, arguments), - eventTarget = d3.event.target, + target = this, + event_ = event.of(target, arguments); + var eventTarget = d3.event.target, touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null, offset, origin_ = point(), @@ -166,6 +167,13 @@ iD.behavior.drag = function () { return drag; }; + drag.target = function() { + if (!arguments.length) return target; + target = arguments[0]; + event_ = event.of(target, Array.prototype.slice.call(arguments, 1)); + return drag; + }; + keybinding .on('⌘+Z', drag.cancel) .on('⌃+Z', drag.cancel); diff --git a/js/id/behavior/drag_midpoint.js b/js/id/behavior/drag_midpoint.js index 5445003b8..9f73a7115 100644 --- a/js/id/behavior/drag_midpoint.js +++ b/js/id/behavior/drag_midpoint.js @@ -1,8 +1,7 @@ iD.behavior.DragMidpoint = function(mode) { var history = mode.history, - projection = mode.map.projection; - - return iD.behavior.drag() + projection = mode.map.projection, + behavior = iD.behavior.drag() .delegate(".midpoint") .origin(function(d) { return projection(d.loc); @@ -21,15 +20,20 @@ iD.behavior.DragMidpoint = function(mode) { } } history.perform.apply(history, args); + var node = d3.selectAll('.node.vertex') + .filter(function(data) { return data.id === d.node.id; }); + behavior.target(node.node(), node.datum()); + }) .on('move', function(d) { d3.event.sourceEvent.stopPropagation(); history.replace( - iD.actions.MoveNode(d.node.id, projection.invert(d3.event.point))); + iD.actions.MoveNode(d.id, projection.invert(d3.event.point))); }) .on('end', function() { history.replace( iD.actions.Noop(), 'added a node to a way'); }); + return behavior; }; From 5d73e45b50452d932013b533e065096fadeaadea Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 28 Jan 2013 17:26:06 -0500 Subject: [PATCH 10/12] Fix exiting draw mode via other means (fixes #503) --- js/id/behavior/draw_way.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/js/id/behavior/draw_way.js b/js/id/behavior/draw_way.js index 649d79e55..0e5bcf4fd 100644 --- a/js/id/behavior/draw_way.js +++ b/js/id/behavior/draw_way.js @@ -4,6 +4,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { controller = mode.controller, event = d3.dispatch('add', 'addHead', 'addTail', 'addNode', 'addWay'), way = mode.history.graph().entity(wayId), + finished = false, hover, draw; var node = iD.Node({loc: map.mouseCoordinates()}), @@ -56,6 +57,9 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { }; drawWay.off = function(surface) { + if (!finished) + history.pop(); + map.fastEnable(true) .minzoom(0) .tail(false); @@ -86,6 +90,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { ReplaceTemporaryNode(node), annotation); + finished = true; controller.enter(mode); }; @@ -99,6 +104,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { ReplaceTemporaryNode(newNode), annotation); + finished = true; controller.enter(mode); }; @@ -111,6 +117,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { ReplaceTemporaryNode(newNode), annotation); + finished = true; controller.enter(mode); }; @@ -118,6 +125,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { // nodes to be valid, it's selected. Otherwise, return to browse mode. drawWay.finish = function() { history.pop(); + finished = true; var way = history.graph().entity(wayId); if (way) { @@ -129,7 +137,11 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) { // Cancel the draw operation and return to browse, deleting everything drawn. drawWay.cancel = function() { - history.perform(d3.functor(baseGraph), 'cancelled drawing'); + history.perform( + d3.functor(baseGraph), + 'cancelled drawing'); + + finished = true; controller.enter(iD.modes.Browse()); }; From 8fe9da4710e6de4ad0459000569bab46b82f3253 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 28 Jan 2013 17:29:21 -0500 Subject: [PATCH 11/12] Mode name and shortcut key should match --- js/id/modes/browse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/id/modes/browse.js b/js/id/modes/browse.js index 90726b6bc..9782bac27 100644 --- a/js/id/modes/browse.js +++ b/js/id/modes/browse.js @@ -2,7 +2,7 @@ iD.modes.Browse = function() { var mode = { button: 'browse', id: 'browse', - title: 'Move', + title: 'Browse', description: 'Pan and zoom the map', key: 'b' }; From 541ff96af67c8baf1bfcd680c2b114cccc977b52 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Mon, 28 Jan 2013 17:46:25 -0500 Subject: [PATCH 12/12] Close modals with esc or backspace --- js/id/ui/modal.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/js/id/ui/modal.js b/js/id/ui/modal.js index 498f1e241..2e58166cb 100644 --- a/js/id/ui/modal.js +++ b/js/id/ui/modal.js @@ -1,6 +1,13 @@ iD.ui.modal = function(blocking) { + var animate = d3.select('div.modal').empty(); + var keybinding = d3.keybinding('modal') + .on('⌫', close) + .on('⎋', close); + + d3.select(document).call(keybinding); + d3.select('div.modal').transition() .style('opacity', 0).remove(); @@ -30,5 +37,10 @@ iD.ui.modal = function(blocking) { shaded.style('opacity', 1); } + function close() { + shaded.remove(); + keybinding.off(); + } + return shaded; };