From 47ea2d82a656cd806888f64d347c05832d78c6c6 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 13 Dec 2012 16:45:05 -0500 Subject: [PATCH 01/16] Indentation and jshint --- js/id/ui/inspector.js | 2 +- js/id/ui/layerswitcher.js | 56 +++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index c8c9d502c..5f7f7de6d 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -48,7 +48,7 @@ iD.Inspector = function() { var inspectorwrap = selection .append('ul').attr('class', 'inspector-inner tag-wrap fillL2'); - inspectorwrap.append('h4').text('Edit tags') + inspectorwrap.append('h4').text('Edit tags'); inspectorwrap .data(['tag', 'value', '']) diff --git a/js/id/ui/layerswitcher.js b/js/id/ui/layerswitcher.js index e5f1a8b32..f79ab169c 100644 --- a/js/id/ui/layerswitcher.js +++ b/js/id/ui/layerswitcher.js @@ -48,36 +48,36 @@ iD.layerswitcher = function(map) { var opa = content .append('div') - .attr('class', 'opacity-options-wrapper fillL2') + .attr('class', 'opacity-options-wrapper fillL2'); - opa.append('h4').text('Layers') + opa.append('h4').text('Layers'); - opa.append('ul') - .attr('class', 'opacity-options') - .selectAll('div.opacity') - .data(opacities) - .enter() - .append('li') - .attr('data-original-title', function(d) { - return (d * 100) + "% opacity"; - }) - .on('click.set-opacity', function(d) { - d3.select('#tile-g') - .transition() - .style('opacity', d) - .attr('data-opacity', d); - d3.selectAll('.opacity-options li') - .classed('selected', false); - d3.select(this) - .classed('selected', true); - }) - .html("
") - .call(bootstrap.tooltip().placement('top')) - .append('div') - .attr('class', 'opacity') - .style('opacity', function(d) { - return d; - }); + opa.append('ul') + .attr('class', 'opacity-options') + .selectAll('div.opacity') + .data(opacities) + .enter() + .append('li') + .attr('data-original-title', function(d) { + return (d * 100) + "% opacity"; + }) + .on('click.set-opacity', function(d) { + d3.select('#tile-g') + .transition() + .style('opacity', d) + .attr('data-opacity', d); + d3.selectAll('.opacity-options li') + .classed('selected', false); + d3.select(this) + .classed('selected', true); + }) + .html("
") + .call(bootstrap.tooltip().placement('top')) + .append('div') + .attr('class', 'opacity') + .style('opacity', function(d) { + return d; + }); // Make sure there is an active selection by default d3.select('.opacity-options li').classed('selected', true); From 9461fe794c129e12a6801e79ea5c15d9546327ca Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 13 Dec 2012 17:00:34 -0500 Subject: [PATCH 02/16] Fix dragging selected features. Fixes #271 --- js/id/modes/drag_features.js | 1 + js/id/modes/select.js | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/js/id/modes/drag_features.js b/js/id/modes/drag_features.js index 7a38883ed..8d2eeda18 100644 --- a/js/id/modes/drag_features.js +++ b/js/id/modes/drag_features.js @@ -4,6 +4,7 @@ iD.modes._dragFeatures = function(mode) { var dragbehavior = d3.behavior.drag() .origin(function(entity) { var p = mode.map.projection(entity.loc); + d3.event.sourceEvent.stopPropagation(); return { x: p[0], y: p[1] }; }) .on('drag', function(entity) { diff --git a/js/id/modes/select.js b/js/id/modes/select.js index daf5c9016..45eeaf8ed 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -11,8 +11,6 @@ iD.modes.Select = function (entity) { return { x: p[0], y: p[1] }; }) .on('drag', function(entity) { - if (!mode.map.dragEnable()) return; - d3.event.sourceEvent.stopPropagation(); if (!dragging) { @@ -32,7 +30,7 @@ iD.modes.Select = function (entity) { }); }) .on('dragend', function () { - if (!mode.map.dragEnable() || !dragging) return; + if (!dragging) return; dragging = undefined; mode.map.redraw(); }); @@ -53,6 +51,8 @@ iD.modes.Select = function (entity) { target = mode.map.surface.selectAll("*") .filter(function (d) { return d === entity; }); + iD.modes._dragFeatures(mode); + d3.select('.inspector-wrap') .style('display', 'block') .style('opacity', 1) @@ -99,6 +99,7 @@ iD.modes.Select = function (entity) { .on('touchstart.drag', null); } + mode.map.surface.on('mousedown.latedrag', null); mode.map.surface.on("click.browse", null); mode.map.keybinding().on('⌫.browse', null); From c4298dd13582f5073171f800101c164bff6da4b1 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 13 Dec 2012 17:34:23 -0500 Subject: [PATCH 03/16] Simplify inspector --- js/id/ui/inspector.js | 111 ++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index 5f7f7de6d..9f47c4be5 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -55,40 +55,58 @@ iD.Inspector = function() { .enter(); function removeTag(d) { - var tags = pad(grabtags()); - delete tags[d.key]; - draw(tags); + draw(grabtags().filter(function(t) { return t.key !== d.key; })); } function draw(data) { - var tr = inspectorwrap.selectAll('li') - .data(d3.entries(data), function(d) { return [d.key, d.value]; }); - tr.exit().remove(); - var row = tr.enter().append('li').attr('class','tag-row'); - var inputs = row.append('div').attr('class','input-wrap').selectAll('input') - .data(function(d) { return [d, d]; }); - inputs.enter().append('input') + + var li = inspectorwrap.selectAll('li') + .data(data, function(d) { return [d.key, d.value]; }); + + li.exit().remove(); + + var row = li.enter().append('li').attr('class','tag-row'); + var inputs = row.append('div').attr('class','input-wrap'); + + function setValue(d, i) { d.value = this.value; } + + function emptyTag(d) { return d.key === ''; } + + function pushMore(d, i) { + if (d3.event.keyCode === 9) { + var tags = grabtags(); + if (i == tags.length - 1 && !tags.filter(emptyTag).length) { + draw(tags.concat([{ key: '', value: '' }])); + } + } + } + + function bindTypeahead(d, i) { + var selection = d3.select(this); + selection.call(d3.typeahead() + .data(function(selection, callback) { + taginfo.values(selection.datum().key, function(err, data) { + callback(data.data); + }); + })); + } + + inputs.append('input') .property('type', 'text') - .attr('class', function(d, i) { - return i ? 'value' : 'key'; - }) - .property('value', function(d, i) { return d[i ? 'value' : 'key']; }) - .on('keyup.update', function(d, i) { - d[i ? 'value' : 'key'] = this.value; - update(); - }) - .each(function(d, i) { - if (!i) return; - var selection = d3.select(this); - selection.call(d3.typeahead() - .data(function(selection, callback) { - update(); - taginfo.values(selection.datum().key, function(err, data) { - callback(data.data); - }); - })); - }); + .attr('class', 'key') + .property('value', function(d, i) { return d.key; }) + .on('keyup.update', setValue); + + inputs.append('input') + .property('type', 'text') + .attr('class', 'value') + .property('value', function(d, i) { return d.value; }) + .on('keyup.update', setValue) + .on('keydown.push-more', pushMore) + .each(bindTypeahead); + row.append('button').attr('class','remove minor').on('click', removeTag); + row.append('button').attr('class', 'tag-help minor').append('a') .text('?') .attr('target', '_blank') @@ -98,36 +116,21 @@ iD.Inspector = function() { }); } - // Remove any blank key-values - function clean(x) { - for (var i in x) { - // undefined is cast to a string as an object key - if (!i || i === 'undefined') delete x[i]; - } - return x; - } - - // Add a blank row for new tags - function pad(x) { - if (!x['']) x[''] = ''; - return x; - } - function grabtags() { - var grabbed = {}; - function grab(d) { if (d.key !== undefined) grabbed[d.key] = d.value; } - inspectorwrap.selectAll('input').each(grab); + var grabbed = []; + function grab(d) { grabbed.push(d); } + inspectorwrap.selectAll('li').each(grab); return grabbed; } - // fill values and add blank field if necessary - function update() { - draw(pad(grabtags())); + function unentries(entries) { + return d3.nest() + .key(function(d) { return d.key; }) + .rollup(function(v) { return v[0].value; }) + .map(entries); } - var data = _.clone(entity.tags); - draw(data); - update(); + draw(d3.entries(_.clone(entity.tags))); selection.select('input').node().focus(); @@ -139,7 +142,7 @@ iD.Inspector = function() { .attr('class', 'apply wide action') .html("Apply") .on('click', function(entity) { - event.changeTags(entity, clean(grabtags())); + event.changeTags(entity, unentries(grabtags())); event.close(entity); }); selection.append('button') From 4a5663df9267cbf8e7e8a145ea1b68b99a7209bb Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 13 Dec 2012 18:28:16 -0500 Subject: [PATCH 04/16] Show local editing users --- js/id/id.js | 31 ++++++++++++++++++++++++++++--- js/id/ui/inspector.js | 10 ++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/js/id/id.js b/js/id/id.js index 071c0773d..296a2bdae 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -36,14 +36,36 @@ window.iD = function(container) { .call(bootstrap.tooltip().placement('bottom')) .on('click', function (mode) { controller.enter(mode); }); - map.on('move.disable-buttons', function() { + function disableTooHigh() { if (map.zoom() < 16) { buttons.attr('disabled', 'disabled'); controller.enter(iD.modes.Browse()); } else { buttons.attr('disabled', null); } - }); + } + + var showUsers = _.debounce(function() { + var users = {}, + entities = map.history().graph().entities; + for (var i in entities) { + users[entities[i].user] = true; + if (Object.keys(users).length > 10) break; + } + var u = Object.keys(users); + var l = d3.select('#user-list') + .selectAll('a.user-link').data(u); + l.enter().append('a') + .attr('class', 'user-link') + .attr('href', function(d) { + return 'http://api06.dev.openstreetmap.org/user/' + d; + }) + .text(String); + l.exit().remove(); + }, 1000); + + map.on('move.disable-buttons', disableTooHigh) + .on('move.show-users', showUsers); buttons.append('span') .attr('class', function(d) { @@ -143,12 +165,15 @@ window.iD = function(container) { .attr('class', 'inspector-wrap fillL') .style('display', 'none'); - this.append('div') + var about = this.append('div') .attr('id', 'about') .html("code " + "report a bug" + " "); + about.append('div') + .attr('id', 'user-list'); + history.on('change.buttons', function() { var undo = history.undoAnnotation(), redo = history.redoAnnotation(); diff --git a/js/id/ui/inspector.js b/js/id/ui/inspector.js index 9f47c4be5..681436072 100644 --- a/js/id/ui/inspector.js +++ b/js/id/ui/inspector.js @@ -137,14 +137,16 @@ iD.Inspector = function() { selection.append('div') .attr('class', 'inspector-buttons').call(drawbuttons); + function apply(entity) { + event.changeTags(entity, unentries(grabtags())); + event.close(entity); + } + function drawbuttons(selection) { selection.append('button') .attr('class', 'apply wide action') .html("Apply") - .on('click', function(entity) { - event.changeTags(entity, unentries(grabtags())); - event.close(entity); - }); + .on('click', apply); selection.append('button') .attr('class', 'delete wide action fr') .html("Delete") From a58a07277a484aa047e49db1b9d68c0897d58dd6 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Sat, 8 Dec 2012 16:03:16 -0800 Subject: [PATCH 05/16] Simplify d3.keybinding Remove window.__onfocus property; it triggers mocha's leak detection. Calculate modifiers using the even properties instead. --- js/lib/d3.keybinding.js | 53 +++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/js/lib/d3.keybinding.js b/js/lib/d3.keybinding.js index 12f7a33fd..3311e845d 100644 --- a/js/lib/d3.keybinding.js +++ b/js/lib/d3.keybinding.js @@ -93,42 +93,27 @@ d3.keybinding = function() { while(++i < 91) _keys.keys[String.fromCharCode(i).toLowerCase()] = i; var pairs = d3.entries(_keys.keys), - key_shortcuts = pairs.map(function(d) { - return d.key; - }), - mods = d3.entries(_keys.mods), - mod_shortcuts = mods.map(function(d) { - return d.key; - }), - event = d3.dispatch.apply(d3, key_shortcuts), - modifiers = []; - - function keydown() { - var tagName = d3.select(d3.event.target).node().tagName; - if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') { - return; - } - - modifiers = modifiers.concat(mods.filter(function(d) { - return d.value === d3.event.keyCode; - }).map(function(d) { return d.key; })); - - pairs.filter(function(d) { - return d.value === d3.event.keyCode; - }).forEach(function(d) { - event[d.key](d3.event, modifiers.slice().sort().join('')); - }); - } - - function keyup() { - modifiers = []; - } + event = d3.dispatch.apply(d3, d3.keys(_keys.keys)); function keys(selection) { - d3.select(window).on('focus', keyup); - selection - .on('keyup', keyup) - .on('keydown', keydown); + selection.on('keydown', function () { + var tagName = d3.select(d3.event.target).node().tagName; + if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') { + return; + } + + var modifiers = ''; + if (d3.event.shiftKey) modifiers += '⇧'; + if (d3.event.ctrlKey) modifiers += '⌃'; + if (d3.event.altKey) modifiers += '⌥'; + if (d3.event.metaKey) modifiers += '⌘'; + + pairs.filter(function(d) { + return d.value === d3.event.keyCode; + }).forEach(function(d) { + event[d.key](d3.event, modifiers); + }); + }); } return d3.rebind(keys, event, 'on'); From c5dbebc063226df751924942c65db6d67e40dbec Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Sat, 8 Dec 2012 16:04:03 -0800 Subject: [PATCH 06/16] Move keybinding to map --- js/id/id.js | 4 +--- js/id/renderer/map.js | 4 +++- test/index.html | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/js/id/id.js b/js/id/id.js index 296a2bdae..8a65570e4 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -191,7 +191,7 @@ window.iD = function(container) { map.size(m.size()); }; - var keybinding = d3.keybinding() + map.keybinding() .on('a', function(evt, mods) { controller.enter(iD.modes.AddArea()); }) @@ -205,8 +205,6 @@ window.iD = function(container) { if (mods === '⇧⌘') history.redo(); if (mods === '⌘') history.undo(); }); - d3.select(document).call(keybinding); - map.keybinding(keybinding); var hash = iD.Hash().map(map); diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index e74d3e61c..fd5caf5d3 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -4,7 +4,7 @@ iD.Map = function() { dispatch = d3.dispatch('move'), selection = null, hover = null, translateStart, - keybinding, + keybinding = d3.keybinding(), projection = d3.geo.mercator().scale(1024), zoom = d3.behavior.zoom() .translate(projection.translate()) @@ -63,6 +63,8 @@ iD.Map = function() { map.size(this.size()); map.surface = surface; + + d3.select(document).call(keybinding); } function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; } diff --git a/test/index.html b/test/index.html index 7e5abcda2..5db9e7245 100644 --- a/test/index.html +++ b/test/index.html @@ -20,6 +20,7 @@ + From d192d8bed5aee4080a225e36a4662a17103522c8 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Sat, 8 Dec 2012 10:37:21 -0800 Subject: [PATCH 07/16] Smaller test data --- test/data/map.xml | 5449 --------------------------------------- test/data/node.xml | 13 + test/data/way.xml | 58 + test/spec/connection.js | 12 +- 4 files changed, 77 insertions(+), 5455 deletions(-) delete mode 100644 test/data/map.xml create mode 100644 test/data/node.xml create mode 100644 test/data/way.xml diff --git a/test/data/map.xml b/test/data/map.xml deleted file mode 100644 index 4b0ccd4c4..000000000 --- a/test/data/map.xml +++ /dev/null @@ -1,5449 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/data/node.xml b/test/data/node.xml new file mode 100644 index 000000000..9e6640dc4 --- /dev/null +++ b/test/data/node.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/test/data/way.xml b/test/data/way.xml new file mode 100644 index 000000000..e8e2ed5eb --- /dev/null +++ b/test/data/way.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/connection.js b/test/spec/connection.js index 7a0bbacbe..70f018322 100644 --- a/test/spec/connection.js +++ b/test/spec/connection.js @@ -24,11 +24,11 @@ describe('Connection', function() { describe('#loadFromURL', function() { it('loads test data', function(done) { - c.loadFromURL('data/map.xml', done); + c.loadFromURL('data/node.xml', done); }); it('returns a graph', function(done) { - c.loadFromURL('data/map.xml', function(err, graph) { + c.loadFromURL('data/node.xml', function(err, graph) { expect(err).to.not.be.ok; expect(graph).to.be.instanceOf(iD.Graph); done(); @@ -36,15 +36,15 @@ describe('Connection', function() { }); it('parses a node', function(done) { - c.loadFromURL('data/map.xml', function(err, graph) { - expect(graph.entity('n1193811')).to.be.instanceOf(iD.Entity); + c.loadFromURL('data/node.xml', function(err, graph) { + expect(graph.entity('n356552551')).to.be.instanceOf(iD.Entity); done(); }); }); it('parses a way', function(done) { - c.loadFromURL('data/map.xml', function(err, graph) { - expect(graph.entity('w53471')).to.be.instanceOf(iD.Entity); + c.loadFromURL('data/way.xml', function(err, graph) { + expect(graph.entity('w19698713')).to.be.instanceOf(iD.Entity); done(); }); }); From c37aa11408f6a4c38203904b2f5472ae29d1c23a Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Sun, 9 Dec 2012 10:23:18 -0800 Subject: [PATCH 08/16] Start testing modes --- js/id/modes/select.js | 9 ++++++--- test/index.html | 7 +++++++ test/index_packaged.html | 5 +++++ test/spec/modes/add_place.js | 39 ++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 test/spec/modes/add_place.js diff --git a/js/id/modes/select.js b/js/id/modes/select.js index 45eeaf8ed..e5f208992 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -1,8 +1,11 @@ iD.modes.Select = function (entity) { var mode = { - button: '' - }, - inspector = iD.Inspector(), + id: 'select', + button: '', + entity: entity + }; + + var inspector = iD.Inspector(), dragging, target; var dragWay = d3.behavior.drag() diff --git a/test/index.html b/test/index.html index 5db9e7245..4edfc5197 100644 --- a/test/index.html +++ b/test/index.html @@ -21,6 +21,7 @@ + @@ -64,6 +65,7 @@ + @@ -100,14 +102,19 @@ + + + + + diff --git a/test/index_packaged.html b/test/index_packaged.html index 8271e3886..7222f3ae4 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -39,14 +39,19 @@ + + + + + diff --git a/test/spec/modes/add_place.js b/test/spec/modes/add_place.js new file mode 100644 index 000000000..71cbfccd6 --- /dev/null +++ b/test/spec/modes/add_place.js @@ -0,0 +1,39 @@ +describe("iD.modes.AddPlace", function () { + var container, map, history, controller, mode; + + beforeEach(function () { + container = d3.select('body').append('div'); + map = iD.Map(); + history = iD.History(); + controller = iD.Controller(map, history); + + container.call(map); + + mode = iD.modes.AddPlace(); + controller.enter(mode); + }); + + afterEach(function() { + container.remove(); + }); + + describe("clicking the map", function () { + it("adds a node", function () { + happen.click(map.surface.node(), {}); + expect(history.changes().created).to.have.length(1); + }); + + it("selects the node", function () { + happen.click(map.surface.node(), {}); + expect(controller.mode.id).to.equal('select'); + expect(controller.mode.entity).to.equal(history.changes().created[0]); + }); + }); + + describe("pressing ⎋", function () { + it("exits to browse mode", function () { + happen.keydown(document, {keyCode: 27}); + expect(controller.mode.id).to.equal('browse'); + }); + }); +}); From 304a9c360383ab2a8fce46b22c7f9830e0dfc160 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 13 Dec 2012 13:33:15 -0800 Subject: [PATCH 09/16] Add symbol for delete key --- js/id/modes/draw_area.js | 14 ++++++++++---- js/id/modes/draw_line.js | 17 +++++++++++------ js/lib/d3.keybinding.js | 4 ++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index ae5925ea0..3640131cd 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -97,22 +97,28 @@ iD.modes.DrawArea = function(wayId) { map.surface.on('mousemove.drawarea', mousemove); map.surface.on('click.drawarea', click); - map.keybinding().on('⎋.drawarea', esc) + + map.keybinding() + .on('⎋.drawarea', esc) .on('⌫.drawarea', backspace) - .on('delete.drawarea', del) + .on('⌦.drawarea', del) .on('↩.drawarea', ret); }; mode.exit = function() { mode.map.hint(false); mode.map.fastEnable(true); + mode.map.surface .on('mousemove.drawarea', null) .on('click.drawarea', null); - mode.map.keybinding().on('⎋.drawarea', null) + + mode.map.keybinding() + .on('⎋.drawarea', null) .on('⌫.drawarea', null) - .on('delete.drawarea', null) + .on('⌦.drawarea', null) .on('↩.drawarea', null); + window.setTimeout(function() { mode.map.dblclickEnable(true); }, 1000); diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index 09789c8f7..2320354f9 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -108,23 +108,28 @@ iD.modes.DrawLine = function(wayId, direction) { controller.enter(iD.modes.Browse()); } - map.keybinding().on('⎋.drawline', esc) + map.keybinding() + .on('⎋.drawline', esc) .on('⌫.drawline', backspace) - .on('delete.drawline', del) + .on('⌦.drawline', del) .on('↩.drawline', ret); }; mode.exit = function() { - mode.map.hint(false); - mode.map.fastEnable(true); + mode.map + .hint(false) + .fastEnable(true); mode.map.surface .on('mousemove.drawline', null) .on('click.drawline', null); - mode.map.keybinding().on('⎋.drawline', null) + + mode.map.keybinding() + .on('⎋.drawline', null) .on('⌫.drawline', null) - .on('delete.drawline', null) + .on('⌦.drawline', null) .on('↩.drawline', null); + window.setTimeout(function() { mode.map.dblclickEnable(true); }, 1000); diff --git a/js/lib/d3.keybinding.js b/js/lib/d3.keybinding.js index 3311e845d..01256aa20 100644 --- a/js/lib/d3.keybinding.js +++ b/js/lib/d3.keybinding.js @@ -39,8 +39,8 @@ d3.keybinding = function() { '⇞': 36, home: 36, // Insert key, or ins ins: 45, insert: 45, - // Delete key, on Mac: ⌫ (Delete) - del: 46, 'delete': 46, + // Delete key, on Mac: ⌦ (Delete) + '⌦': 46, del: 46, 'delete': 46, // Left Arrow Key, or ← '←': 37, left: 37, 'arrow-left': 37, // Up Arrow Key, or ↑ From 150dcf471e30873cc2ed7b28c99dc90b10adf60f Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 13 Dec 2012 13:37:46 -0800 Subject: [PATCH 10/16] Chain --- js/id/modes/draw_area.js | 10 ++++++---- js/id/modes/draw_line.js | 12 ++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index 3640131cd..12f04d283 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -95,8 +95,9 @@ iD.modes.DrawArea = function(wayId) { controller.enter(iD.modes.Browse()); } - map.surface.on('mousemove.drawarea', mousemove); - map.surface.on('click.drawarea', click); + map.surface + .on('mousemove.drawarea', mousemove) + .on('click.drawarea', click); map.keybinding() .on('⎋.drawarea', esc) @@ -106,8 +107,9 @@ iD.modes.DrawArea = function(wayId) { }; mode.exit = function() { - mode.map.hint(false); - mode.map.fastEnable(true); + mode.map + .hint(false) + .fastEnable(true); mode.map.surface .on('mousemove.drawarea', null) diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index 2320354f9..b9b8e4409 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -24,11 +24,11 @@ iD.modes.DrawLine = function(wayId, direction) { iD.actions.AddNode(node), iD.actions.AddWayNode(wayId, node.id, index)); - map.surface.on('mousemove.drawline', function() { + function mousemove() { history.replace(iD.actions.Move(node.id, map.mouseCoordinates())); - }); + } - map.surface.on('click.drawline', function() { + function click() { var datum = d3.select(d3.event.target).datum() || {}; if (datum.id === tailId) { @@ -72,7 +72,7 @@ iD.modes.DrawLine = function(wayId, direction) { controller.enter(iD.modes.DrawLine(wayId, direction)); } - }); + } function esc() { history.replace( @@ -108,6 +108,10 @@ iD.modes.DrawLine = function(wayId, direction) { controller.enter(iD.modes.Browse()); } + map.surface + .on('mousemove.drawline', mousemove) + .on('click.drawline', click); + map.keybinding() .on('⎋.drawline', esc) .on('⌫.drawline', backspace) From 15c5f5d866ac37316ba35b17fa0b83266d574df2 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 13 Dec 2012 13:39:21 -0800 Subject: [PATCH 11/16] Follow rename --- js/id/modes/add_line.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/id/modes/add_line.js b/js/id/modes/add_line.js index bf5172b4a..baa4364bc 100644 --- a/js/id/modes/add_line.js +++ b/js/id/modes/add_line.js @@ -15,7 +15,7 @@ iD.modes.AddLine = function() { map.dblclickEnable(false) .hint('Click on the map to start drawing an road, path, or route.'); - map.surface.on('click.addroad', function() { + map.surface.on('click.addline', function() { var datum = d3.select(d3.event.target).datum() || {}, way = iD.Way({ tags: { highway: 'residential' } }), direction = 'forward'; @@ -62,7 +62,7 @@ iD.modes.AddLine = function() { controller.enter(iD.modes.DrawLine(way.id, direction)); }); - map.keybinding().on('⎋.addroad', function() { + map.keybinding().on('⎋.addline', function() { controller.exit(); }); }; @@ -70,8 +70,8 @@ iD.modes.AddLine = function() { mode.exit = function() { mode.map.dblclickEnable(true); mode.map.hint(false); - mode.map.surface.on('click.addroad', null); - mode.map.keybinding().on('⎋.addroad', null); + mode.map.surface.on('click.addline', null); + mode.map.keybinding().on('⎋.addline', null); }; return mode; From ee3f5cc768d726b034a3f84619d7e7bb9f41d34b Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 13 Dec 2012 13:58:24 -0800 Subject: [PATCH 12/16] Move -> MoveNode, in preparation for MoveWay --- index.html | 2 +- js/id/actions/{move.js => move_node.js} | 6 +++--- js/id/modes/drag_features.js | 4 ++-- js/id/modes/draw_area.js | 2 +- js/id/modes/draw_line.js | 2 +- test/index.html | 4 ++-- test/index_packaged.html | 2 +- test/spec/actions/move.js | 8 -------- test/spec/actions/move_node.js | 8 ++++++++ 9 files changed, 19 insertions(+), 19 deletions(-) rename js/id/actions/{move.js => move_node.js} (64%) delete mode 100644 test/spec/actions/move.js create mode 100644 test/spec/actions/move_node.js diff --git a/index.html b/index.html index 122569faa..9de339471 100644 --- a/index.html +++ b/index.html @@ -53,7 +53,7 @@ - + diff --git a/js/id/actions/move.js b/js/id/actions/move_node.js similarity index 64% rename from js/id/actions/move.js rename to js/id/actions/move_node.js index 21870c8d4..9204fcb67 100644 --- a/js/id/actions/move.js +++ b/js/id/actions/move_node.js @@ -1,8 +1,8 @@ // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as -iD.actions.Move = function(entityId, loc) { +iD.actions.MoveNode = function(nodeId, loc) { return function(graph) { - var entity = graph.entity(entityId); - return graph.replace(entity.update({loc: loc})); + var node = graph.entity(nodeId); + return graph.replace(node.update({loc: loc})); }; }; diff --git a/js/id/modes/drag_features.js b/js/id/modes/drag_features.js index 8d2eeda18..d20119080 100644 --- a/js/id/modes/drag_features.js +++ b/js/id/modes/drag_features.js @@ -21,11 +21,11 @@ iD.modes._dragFeatures = function(mode) { } else { dragging = entity; mode.history.perform( - iD.actions.Move(dragging.id, loc)); + iD.actions.MoveNode(dragging.id, loc)); } } - mode.history.replace(iD.actions.Move(dragging.id, loc)); + mode.history.replace(iD.actions.MoveNode(dragging.id, loc)); }) .on('dragend', function (entity) { if (!dragging) return; diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index 12f04d283..c31544e5c 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -24,7 +24,7 @@ iD.modes.DrawArea = function(wayId) { iD.actions.AddWayNode(way.id, node.id, -1)); function mousemove() { - history.replace(iD.actions.Move(node.id, map.mouseCoordinates())); + history.replace(iD.actions.MoveNode(node.id, map.mouseCoordinates())); } function click() { diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index b9b8e4409..74c16095f 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -25,7 +25,7 @@ iD.modes.DrawLine = function(wayId, direction) { iD.actions.AddWayNode(wayId, node.id, index)); function mousemove() { - history.replace(iD.actions.Move(node.id, map.mouseCoordinates())); + history.replace(iD.actions.MoveNode(node.id, map.mouseCoordinates())); } function click() { diff --git a/test/index.html b/test/index.html index 4edfc5197..f66c872d4 100644 --- a/test/index.html +++ b/test/index.html @@ -54,7 +54,7 @@ - + @@ -94,7 +94,7 @@ - + diff --git a/test/index_packaged.html b/test/index_packaged.html index 7222f3ae4..1c197a5b7 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -31,7 +31,7 @@ - + diff --git a/test/spec/actions/move.js b/test/spec/actions/move.js deleted file mode 100644 index 5e4163af7..000000000 --- a/test/spec/actions/move.js +++ /dev/null @@ -1,8 +0,0 @@ -describe("iD.actions.Move", function () { - it("changes an entity's location", function () { - var entity = iD.Entity(), - loc = [2, 3], - graph = iD.actions.Move(entity.id, loc)(iD.Graph([entity])); - expect(graph.entity(entity.id).loc).to.eql(loc); - }); -}); diff --git a/test/spec/actions/move_node.js b/test/spec/actions/move_node.js new file mode 100644 index 000000000..5e7c8f663 --- /dev/null +++ b/test/spec/actions/move_node.js @@ -0,0 +1,8 @@ +describe("iD.actions.MoveNode", function () { + it("changes a node's location", function () { + var node = iD.Node(), + loc = [2, 3], + graph = iD.actions.MoveNode(node.id, loc)(iD.Graph([node])); + expect(graph.entity(node.id).loc).to.eql(loc); + }); +}); From 209b87f7e84fc0f6531eadce7ab42fce9ba5e288 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 13 Dec 2012 14:01:43 -0800 Subject: [PATCH 13/16] Extract MoveWay action --- index.html | 1 + js/id/actions/move_way.js | 14 ++++++++++++++ js/id/modes/select.js | 10 +--------- test/index.html | 2 ++ test/index_packaged.html | 1 + test/spec/actions/move_way.js | 21 +++++++++++++++++++++ 6 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 js/id/actions/move_way.js create mode 100644 test/spec/actions/move_way.js diff --git a/index.html b/index.html index 9de339471..51ddec95d 100644 --- a/index.html +++ b/index.html @@ -54,6 +54,7 @@ + diff --git a/js/id/actions/move_way.js b/js/id/actions/move_way.js new file mode 100644 index 000000000..0ef14e4f3 --- /dev/null +++ b/js/id/actions/move_way.js @@ -0,0 +1,14 @@ +iD.actions.MoveWay = function(wayId, dxdy, projection) { + return function(graph) { + var way = graph.entity(wayId); + + _.uniq(way.nodes).forEach(function(id) { + var node = graph.entity(id), + start = projection(node.loc), + end = projection.invert([start[0] + dxdy[0], start[1] + dxdy[1]]); + graph = iD.actions.MoveNode(id, end)(graph); + }); + + return graph; + }; +}; diff --git a/js/id/modes/select.js b/js/id/modes/select.js index e5f208992..c0553ac61 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -22,15 +22,7 @@ iD.modes.Select = function (entity) { mode.history.perform(iD.actions.Noop()); } - _.uniq(_.pluck(entity.nodes, 'id')) - .forEach(function(id) { - var node = mode.history.graph().entity(id), - start = mode.map.projection(node.loc), - end = mode.map.projection.invert([ - start[0] + d3.event.dx, - start[1] + d3.event.dy]); - mode.history.replace(iD.actions.Move(id, end)); - }); + mode.history.replace(iD.actions.MoveWay(entity.id, [d3.event.dx, d3.event.dy], mode.map.projection)); }) .on('dragend', function () { if (!dragging) return; diff --git a/test/index.html b/test/index.html index f66c872d4..c583acee9 100644 --- a/test/index.html +++ b/test/index.html @@ -55,6 +55,7 @@ + @@ -95,6 +96,7 @@ + diff --git a/test/index_packaged.html b/test/index_packaged.html index 1c197a5b7..2fdd8ab0f 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -32,6 +32,7 @@ + diff --git a/test/spec/actions/move_way.js b/test/spec/actions/move_way.js new file mode 100644 index 000000000..71c703e7f --- /dev/null +++ b/test/spec/actions/move_way.js @@ -0,0 +1,21 @@ +describe("iD.actions.MoveWay", function () { + it("moves all nodes in a way by the given amount", function () { + var node1 = iD.Node({loc: [0, 0]}), + node2 = iD.Node({loc: [5, 10]}), + way = iD.Way({nodes: [node1.id, node2.id]}), + dxdy = [2, 3], + projection = d3.geo.mercator(), + graph = iD.actions.MoveWay(way.id, dxdy, projection)(iD.Graph([node1, node2, way])); + expect(graph.entity(node1.id).loc).to.eql([1.4400000000000002, -2.1594885414215783]); + expect(graph.entity(node2.id).loc).to.eql([6.440000000000008, 7.866329874099955]); + }); + + it("moves repeated nodes only once", function () { + var node = iD.Node({loc: [0, 0]}), + way = iD.Way({nodes: [node.id, node.id]}), + dxdy = [2, 3], + projection = d3.geo.mercator(), + graph = iD.actions.MoveWay(way.id, dxdy, projection)(iD.Graph([node, way])); + expect(graph.entity(node.id).loc).to.eql([1.4400000000000002, -2.1594885414215783]); + }); +}); From 9eb455257341954669c7f1e370ef965f41a6edbd Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 13 Dec 2012 14:07:39 -0800 Subject: [PATCH 14/16] Revert unintended changes in c93cd4 --- js/id/modes/select.js | 45 +++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/js/id/modes/select.js b/js/id/modes/select.js index c0553ac61..a94e54103 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -1,7 +1,7 @@ iD.modes.Select = function (entity) { var mode = { id: 'select', - button: '', + button: 'browse', entity: entity }; @@ -17,8 +17,7 @@ iD.modes.Select = function (entity) { d3.event.sourceEvent.stopPropagation(); if (!dragging) { - dragging = iD.util.trueObj([entity.id].concat( - _.pluck(mode.history.graph().parentWays(entity.id), 'id'))); + dragging = true; mode.history.perform(iD.actions.Noop()); } @@ -31,19 +30,25 @@ iD.modes.Select = function (entity) { }); function remove() { - switch (entity.type) { - case 'way': - mode.history.perform(iD.actions.DeleteWay(entity.id)); - break; - case 'node': - mode.history.perform(iD.actions.DeleteNode(entity.id)); + if (entity.type === 'way') { + mode.history.perform( + iD.actions.DeleteWay(entity.id), + 'deleted a way'); + } else if (entity.type === 'node') { + var parents = mode.history.graph().parentWays(entity.id), + operations = [iD.actions.DeleteNode(entity.id)]; + parents.forEach(function(parent) { + if (_.uniq(parent.nodes).length === 1) operations.push(iD.actions.DeleteWay(parent.id)); + }); + mode.history.perform.apply(mode.history, + operations.concat(['deleted a node'])); } mode.controller.exit(); } mode.enter = function () { - target = mode.map.surface.selectAll("*") + target = mode.map.surface.selectAll('*') .filter(function (d) { return d === entity; }); iD.modes._dragFeatures(mode); @@ -55,11 +60,23 @@ iD.modes.Select = function (entity) { .call(inspector); inspector.on('changeTags', function(d, tags) { - mode.history.perform(iD.actions.ChangeEntityTags(d.id, tags)); + mode.history.perform( + iD.actions.ChangeEntityTags(d.id, tags), + 'changed tags'); + }).on('changeWayDirection', function(d) { - mode.history.perform(iD.actions.ReverseWay(d)); + mode.history.perform( + iD.actions.ReverseWay(d.id), + 'reversed a way'); + + }).on('splitWay', function(d) { + mode.history.perform( + iD.actions.SplitWay(d.id), + 'split a way on a node'); + }).on('remove', function() { remove(); + }).on('close', function() { mode.controller.exit(); }); @@ -68,7 +85,7 @@ iD.modes.Select = function (entity) { target.call(dragWay); } - mode.map.surface.on("click.browse", function () { + mode.map.surface.on('click.browse', function () { var datum = d3.select(d3.event.target).datum(); if (datum instanceof iD.Entity) { mode.controller.enter(iD.modes.Select(datum)); @@ -94,8 +111,8 @@ iD.modes.Select = function (entity) { .on('touchstart.drag', null); } - mode.map.surface.on('mousedown.latedrag', null); mode.map.surface.on("click.browse", null); + mode.map.surface.on('mousedown.latedrag', null); mode.map.keybinding().on('⌫.browse', null); mode.map.selection(null); From 070ee74ff6653739d3b676b089c0d073b3a868a1 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 13 Dec 2012 14:16:58 -0800 Subject: [PATCH 15/16] Remove unused --- js/id/renderer/map.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index fd5caf5d3..11484b3bc 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -12,7 +12,6 @@ iD.Map = function() { .scaleExtent([1024, 256 * Math.pow(2, 24)]) .on('zoom', zoomPan), dblclickEnabled = true, - dragging = false, fastEnabled = true, notice, background = iD.Background() From a1383d01b059b55674865ab0efe2d72c24dfd26b Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Fri, 14 Dec 2012 11:30:13 -0500 Subject: [PATCH 16/16] Add npm package --- package.json | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 000000000..5c991f29b --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "iD", + "version": "0.0.0", + "description": "a new editor for openstreetmap", + "main": "iD.js", + "directories": { + "doc": "docs", + "test": "test" + }, + "scripts": { + "test": "mocha-phantomjs test/index.html" + }, + "repository": { + "type": "git", + "url": "git://github.com/systemed/iD.git" + }, + "keywords": [ + "editor", + "openstreetmap" + ], + "license": "BSD", + "devDependencies": { + "uglify-js": "~2.2.2", + "mocha-phantomjs": "~1.1.1" + } +}