diff --git a/js/id/behavior/drag.js b/js/id/behavior/drag.js index d88e8a44a..cd6f607bf 100644 --- a/js/id/behavior/drag.js +++ b/js/id/behavior/drag.js @@ -14,7 +14,7 @@ * Delegation is supported via the `delegate` function. */ -iD.behavior.drag = function () { +iD.behavior.drag = function() { function d3_eventCancel() { d3.event.stopPropagation(); d3.event.preventDefault(); @@ -50,21 +50,21 @@ iD.behavior.drag = function () { moved = 0; var w = d3.select(window) - .on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove) - .on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true); + .on(touchId !== null ? "touchmove.drag-" + touchId : "mousemove.drag", dragmove) + .on(touchId !== null ? "touchend.drag-" + touchId : "mouseup.drag", dragend, true); if (origin) { offset = origin.apply(target, arguments); - offset = [ offset[0] - origin_[0], offset[1] - origin_[1] ]; + offset = [offset[0] - origin_[0], offset[1] - origin_[1]]; } else { - offset = [ 0, 0 ]; + offset = [0, 0]; } - if (touchId == null) d3_eventCancel(); + if (touchId === null) d3_eventCancel(); function point() { var p = target.parentNode; - return touchId != null ? d3.touches(p).filter(function (p) { + return touchId !== null ? d3.touches(p).filter(function(p) { return p.identifier === touchId; })[0] : d3.mouse(p); } @@ -103,8 +103,8 @@ iD.behavior.drag = function () { if (d3.event.target === eventTarget) w.on("click.drag", click, true); } - w.on(touchId != null ? "touchmove.drag-" + touchId : "mousemove.drag", null) - .on(touchId != null ? "touchend.drag-" + touchId : "mouseup.drag", null); + w.on(touchId !== null ? "touchmove.drag-" + touchId : "mousemove.drag", null) + .on(touchId !== null ? "touchend.drag-" + touchId : "mouseup.drag", null); } function click() { diff --git a/js/id/behavior/draw.js b/js/id/behavior/draw.js index 656eb7988..a4fb53a1a 100644 --- a/js/id/behavior/draw.js +++ b/js/id/behavior/draw.js @@ -1,24 +1,41 @@ iD.behavior.Draw = function(context) { - var event = d3.dispatch('move', 'click', 'clickWay', 'clickNode', 'undo', 'cancel', 'finish'), + var event = d3.dispatch('move', 'click', 'clickWay', + 'clickNode', 'undo', 'cancel', 'finish'), keybinding = d3.keybinding('draw'), - hover = iD.behavior.Hover(); + hover = iD.behavior.Hover(), + closeTolerance = 4, + tolerance = 12; function datum() { - if (d3.event.altKey) { - return {}; - } else { - return d3.event.target.__data__ || {}; - } + if (d3.event.altKey) return {}; + else return d3.event.target.__data__ || {}; } function mousedown() { - var selection = d3.select(this); - selection.on('mousemove.draw', null); - d3.select(window) - .on('mouseup.draw', function() { - selection.on('mousemove.draw', mousemove); + function point() { + var p = target.node().parentNode; + return touchId !== null ? d3.touches(p).filter(function(p) { + return p.identifier === touchId; + })[0] : d3.mouse(p); + } + + var target = d3.select(this), + touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null, + time = +new Date(), + pos = point(); + + target.on('mousemove.draw', null); + + d3.select(window).on('mouseup.draw', function() { + target.on('mousemove.draw', mousemove); + if (iD.geo.dist(pos, point()) < closeTolerance || + (iD.geo.dist(pos, point()) < tolerance && + (+new Date() - time) < 500)) { + click(); + } }); + } function mousemove() { @@ -77,8 +94,7 @@ iD.behavior.Draw = function(context) { selection .on('mousedown.draw', mousedown) - .on('mousemove.draw', mousemove) - .on('click.draw', click); + .on('mousemove.draw', mousemove); d3.select(document) .call(keybinding) @@ -93,8 +109,7 @@ iD.behavior.Draw = function(context) { selection .on('mousedown.draw', null) - .on('mousemove.draw', null) - .on('click.draw', null); + .on('mousemove.draw', null); d3.select(window).on('mouseup.draw', null); diff --git a/js/id/behavior/select.js b/js/id/behavior/select.js index b5276a4d0..f7a388396 100644 --- a/js/id/behavior/select.js +++ b/js/id/behavior/select.js @@ -1,4 +1,5 @@ iD.behavior.Select = function(context) { + function click() { var datum = d3.select(d3.event.target).datum(); if (datum instanceof iD.Entity) { diff --git a/test/spec/modes/add_point.js b/test/spec/modes/add_point.js index 38a614198..62291f8ee 100644 --- a/test/spec/modes/add_point.js +++ b/test/spec/modes/add_point.js @@ -1,7 +1,7 @@ -describe("iD.modes.AddPoint", function () { +describe("iD.modes.AddPoint", function() { var context; - beforeEach(function () { + beforeEach(function() { var container = d3.select(document.createElement('div')); context = iD() @@ -15,20 +15,22 @@ describe("iD.modes.AddPoint", function () { }); describe("clicking the map", function () { - it("adds a node", function () { - happen.click(context.surface().node(), {}); + it("adds a node", function() { + happen.mousedown(context.surface().node(), {}); + happen.mouseup(window, {}); expect(context.changes().created).to.have.length(1); }); - it("selects the node", function () { - happen.click(context.surface().node(), {}); + it("selects the node", function() { + happen.mousedown(context.surface().node(), {}); + happen.mouseup(window, {}); expect(context.mode().id).to.equal('select'); expect(context.mode().selection()).to.eql([context.changes().created[0].id]); }); }); - describe("pressing ⎋", function () { - it("exits to browse mode", function () { + describe("pressing ⎋", function() { + it("exits to browse mode", function() { happen.keydown(document, {keyCode: 27}); expect(context.mode().id).to.equal('browse'); });