diff --git a/css/map.css b/css/map.css
index e3e05a044..8ad55c790 100644
--- a/css/map.css
+++ b/css/map.css
@@ -616,6 +616,14 @@ text.pointlabel {
pointer-events: none;
}
+.layer-halo rect,
+.layer-halo path,
+.layer-label text {
+ -webkit-transition: opacity 100ms linear;
+ transition: opacity 100ms linear;
+ -moz-transition: opacity 100ms linear;
+}
+
.pathlabel .textpath {
dominant-baseline: middle;
}
diff --git a/index.html b/index.html
index d8d7cec9b..ce885c4b7 100644
--- a/index.html
+++ b/index.html
@@ -98,6 +98,7 @@
+
diff --git a/js/id/behavior/add_way.js b/js/id/behavior/add_way.js
index fa038d201..89ba7f1cd 100644
--- a/js/id/behavior/add_way.js
+++ b/js/id/behavior/add_way.js
@@ -32,7 +32,7 @@ iD.behavior.AddWay = function(mode) {
};
addWay.cancel = function() {
- controller.exit();
+ controller.enter(iD.modes.Browse());
};
return d3.rebind(addWay, event, 'on');
diff --git a/js/id/behavior/select.js b/js/id/behavior/select.js
new file mode 100644
index 000000000..cee2cc940
--- /dev/null
+++ b/js/id/behavior/select.js
@@ -0,0 +1,22 @@
+iD.behavior.Select = function(mode) {
+ var controller = mode.controller;
+
+ function click() {
+ var datum = d3.select(d3.event.target).datum();
+ if (datum instanceof iD.Entity) {
+ controller.enter(iD.modes.Select([datum.id]));
+ } else {
+ controller.enter(iD.modes.Browse());
+ }
+ }
+
+ var behavior = function(selection) {
+ selection.on('click.select', click);
+ };
+
+ behavior.off = function(selection) {
+ selection.on('click.select', null);
+ };
+
+ return behavior;
+};
diff --git a/js/id/controller.js b/js/id/controller.js
index 7e74c56d4..6c4e0fd1e 100644
--- a/js/id/controller.js
+++ b/js/id/controller.js
@@ -19,9 +19,5 @@ iD.Controller = function(map, history) {
event.enter(mode);
};
- controller.exit = function() {
- controller.enter(iD.modes.Browse());
- };
-
return d3.rebind(controller, event, 'on');
};
diff --git a/js/id/modes/add_point.js b/js/id/modes/add_point.js
index feff66f43..6dd524bb5 100644
--- a/js/id/modes/add_point.js
+++ b/js/id/modes/add_point.js
@@ -32,7 +32,7 @@ iD.modes.AddPoint = function() {
}
function cancel() {
- controller.exit();
+ controller.enter(iD.modes.Browse());
}
behavior = iD.behavior.Draw(map)
diff --git a/js/id/modes/browse.js b/js/id/modes/browse.js
index b1fb1c8ae..7652576ea 100644
--- a/js/id/modes/browse.js
+++ b/js/id/modes/browse.js
@@ -14,19 +14,13 @@ iD.modes.Browse = function() {
behaviors = [
iD.behavior.Hover(),
+ iD.behavior.Select(mode),
iD.behavior.DragNode(mode),
iD.behavior.DragMidpoint(mode)];
behaviors.forEach(function(behavior) {
behavior(surface);
});
-
- 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.id]));
- }
- });
};
mode.exit = function() {
@@ -35,8 +29,6 @@ iD.modes.Browse = function() {
behaviors.forEach(function(behavior) {
behavior.off(surface);
});
-
- surface.on('click.browse', null);
};
return mode;
diff --git a/js/id/modes/move_way.js b/js/id/modes/move_way.js
index 50c228d8e..5c262e259 100644
--- a/js/id/modes/move_way.js
+++ b/js/id/modes/move_way.js
@@ -16,14 +16,18 @@ iD.modes.MoveWay = function(wayId) {
origin = d3.mouse(selection.node()),
annotation = t('operations.move.annotation.' + way.geometry(graph));
+ // If intiated via keyboard
+ if (!origin[0] && !origin[1]) origin = null;
+
history.perform(
iD.actions.Noop(),
annotation);
function move() {
var p = d3.mouse(selection.node()),
- delta = [p[0] - origin[0],
- p[1] - origin[1]];
+ delta = origin ?
+ [p[0] - origin[0], p[1] - origin[1]] :
+ [0, 0];
origin = p;
diff --git a/js/id/modes/select.js b/js/id/modes/select.js
index d32167391..f5987f0e3 100644
--- a/js/id/modes/select.js
+++ b/js/id/modes/select.js
@@ -40,6 +40,7 @@ iD.modes.Select = function(selection, initial) {
behaviors = [
iD.behavior.Hover(),
+ iD.behavior.Select(mode),
iD.behavior.DragNode(mode),
iD.behavior.DragMidpoint(mode)];
@@ -89,7 +90,7 @@ iD.modes.Select = function(selection, initial) {
inspector
.on('changeTags', changeTags)
- .on('close', function() { mode.controller.exit(); });
+ .on('close', function() { mode.controller.enter(iD.modes.Browse()); });
history.on('change.select', function() {
// Exit mode if selected entity gets undone
@@ -110,15 +111,6 @@ iD.modes.Select = function(selection, initial) {
surface.call(radialMenu.close);
});
- function click() {
- var datum = d3.select(d3.event.target).datum();
- if (datum instanceof iD.Entity) {
- mode.controller.enter(iD.modes.Select([datum.id]));
- } else {
- mode.controller.enter(iD.modes.Browse());
- }
- }
-
function dblclick() {
var target = d3.select(d3.event.target),
datum = target.datum();
@@ -138,13 +130,11 @@ iD.modes.Select = function(selection, initial) {
}
}
- surface.on('click.select', click)
- .on('dblclick.select', dblclick);
-
d3.select(document)
.call(keybinding);
- surface.selectAll("*")
+ surface.on('dblclick.select', dblclick)
+ .selectAll("*")
.filter(function (d) { return d && selection.indexOf(d.id) >= 0; })
.classed('selected', true);
@@ -186,12 +176,10 @@ iD.modes.Select = function(selection, initial) {
keybinding.off();
- surface.on('click.select', null)
- .on('dblclick.select', null);
-
history.on('change.select', null);
- surface.selectAll(".selected")
+ surface.on('dblclick.select', null)
+ .selectAll(".selected")
.classed('selected', false);
surface.call(radialMenu.close);
diff --git a/js/id/svg/labels.js b/js/id/svg/labels.js
index 774fc264e..eb4297bca 100644
--- a/js/id/svg/labels.js
+++ b/js/id/svg/labels.js
@@ -200,12 +200,31 @@ iD.svg.Labels = function(projection) {
}
+ function hideOnMouseover() {
+ var mouse = d3.mouse(this),
+ pad = 50,
+ rect = new RTree.Rectangle(mouse[0] - pad, mouse[1] - pad, 2*pad, 2*pad),
+ labels = _.pluck(rtree.search(rect, this), 'leaf'),
+ selection = d3.select(this);
+
+ selection.selectAll('.layer-label text, .layer-halo path, .layer-halo rect')
+ .style('opacity', '');
+
+ if (!labels.length) return;
+ selection.selectAll('.layer-label text, .layer-halo path, .layer-halo rect')
+ .filter(function(d) {
+ return _.contains(labels, d.id);
+ })
+ .style('opacity', 0);
+ }
var rtree = new RTree(),
rectangles = {};
return function drawLabels(surface, graph, entities, filter, dimensions, fullRedraw) {
+ d3.select(surface.node().parentNode)
+ .on('mousemove.hidelabels', hideOnMouseover);
var hidePoints = !d3.select('.node.point').node();
diff --git a/js/id/svg/lines.js b/js/id/svg/lines.js
index 65cfccd27..83c533255 100644
--- a/js/id/svg/lines.js
+++ b/js/id/svg/lines.js
@@ -35,7 +35,7 @@ iD.svg.Lines = function(projection) {
return function drawLines(surface, graph, entities, filter) {
function drawPaths(group, lines, filter, classes, lineString) {
- var paths = group.selectAll('path')
+ var paths = group.selectAll('path.line')
.filter(filter)
.data(lines, iD.Entity.key);
diff --git a/test/index.html b/test/index.html
index 96d1e47ad..e723d5af1 100644
--- a/test/index.html
+++ b/test/index.html
@@ -94,6 +94,7 @@
+