diff --git a/Makefile b/Makefile
index c9d13ff60..70ac208d6 100644
--- a/Makefile
+++ b/Makefile
@@ -38,6 +38,8 @@ all: \
js/id/behavior/*.js \
js/id/modes.js \
js/id/modes/*.js \
+ js/id/operations.js \
+ js/id/operations/*.js \
js/id/controller/*.js \
js/id/graph/*.js \
js/id/renderer/*.js \
diff --git a/css/map.css b/css/map.css
index 8f235bb18..7b3038d6c 100644
--- a/css/map.css
+++ b/css/map.css
@@ -16,7 +16,7 @@ g.point .shadow {
transition: transform 100ms linear;
-moz-transition: fill 100ms linear;
}
-g.point.hover .shadow {
+.behavior-hover g.point.hover .shadow {
fill: #E96666;
fill-opacity: 0.3;
}
@@ -106,7 +106,7 @@ g.vertex .shadow {
transition: transform 100ms linear;
-moz-transition: fill 100ms linear;
}
-g.vertex.hover .shadow {
+.behavior-hover g.vertex.hover .shadow {
fill: #E96666;
fill-opacity: 0.3;
}
@@ -120,7 +120,7 @@ g.vertex.selected .shadow {
g.midpoint .fill {
fill:#aaa;
}
-g.midpoint .fill.hover {
+.behavior-hover g.midpoint .fill.hover {
fill:#fff;
stroke:#000;
}
@@ -133,7 +133,7 @@ g.midpoint .shadow {
transition: transform 100ms linear;
-moz-transition: fill 100ms linear;
}
-g.midpoint .shadow.hover {
+.behavior-hover g.midpoint .shadow.hover {
fill:#E96666;
fill-opacity: 0.3;
}
@@ -161,7 +161,7 @@ path.shadow {
-webkit-transition: stroke 100ms linear;
}
-path.shadow.hover {
+.behavior-hover path.shadow.hover {
stroke: #E96666;
stroke-opacity: 0.3;
}
@@ -691,17 +691,17 @@ text.point.tag-amenity {
cursor:url(../img/cursor-draw.png) 9 9, auto;
}
-.mode-draw-line .way,
-.mode-draw-area .way,
-.mode-add-line .way,
-.mode-add-area .way {
+.mode-draw-line .behavior-hover .way,
+.mode-draw-area .behavior-hover .way,
+.mode-add-line .behavior-hover .way,
+.mode-add-area .behavior-hover .way {
cursor:url(../img/cursor-draw-connect-line.png) 9 9, auto;
}
-.mode-draw-line .vertex,
-.mode-draw-area .vertex,
-.mode-add-line .vertex,
-.mode-add-area .vertex {
+.mode-draw-line .behavior-hover .vertex,
+.mode-draw-area .behavior-hover .vertex,
+.mode-add-line .behavior-hover .vertex,
+.mode-add-area .behavior-hover .vertex {
cursor:url(../img/cursor-draw-connect-vertex.png) 9 9, auto;
}
diff --git a/index.html b/index.html
index af436a86e..deadb5add 100644
--- a/index.html
+++ b/index.html
@@ -92,7 +92,6 @@
-
@@ -104,8 +103,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/js/id/actions/circular.js b/js/id/actions/circular.js
index d6af08560..da7965c79 100644
--- a/js/id/actions/circular.js
+++ b/js/id/actions/circular.js
@@ -51,7 +51,7 @@ iD.actions.Circular = function(wayId, map) {
};
action.enabled = function(graph) {
- return true;
+ return graph.entity(wayId).isClosed();
};
return action;
diff --git a/js/id/actions/delete_node.js b/js/id/actions/delete_node.js
index 48e704ac3..a93129ce3 100644
--- a/js/id/actions/delete_node.js
+++ b/js/id/actions/delete_node.js
@@ -1,6 +1,6 @@
// https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
iD.actions.DeleteNode = function(nodeId) {
- var action = function(graph) {
+ return function(graph) {
var node = graph.entity(nodeId);
graph.parentWays(node)
@@ -20,10 +20,4 @@ iD.actions.DeleteNode = function(nodeId) {
return graph.remove(node);
};
-
- action.enabled = function(graph) {
- return true;
- };
-
- return action;
};
diff --git a/js/id/actions/delete_way.js b/js/id/actions/delete_way.js
index eb58223cb..211447228 100644
--- a/js/id/actions/delete_way.js
+++ b/js/id/actions/delete_way.js
@@ -1,6 +1,6 @@
// https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
iD.actions.DeleteWay = function(wayId) {
- var action = function(graph) {
+ return function(graph) {
var way = graph.entity(wayId);
graph.parentRelations(way)
@@ -27,10 +27,4 @@ iD.actions.DeleteWay = function(wayId) {
return graph.remove(way);
};
-
- action.enabled = function(graph) {
- return true;
- };
-
- return action;
};
diff --git a/js/id/actions/reverse_way.js b/js/id/actions/reverse_way.js
index 4a7d392b7..160017637 100644
--- a/js/id/actions/reverse_way.js
+++ b/js/id/actions/reverse_way.js
@@ -53,7 +53,7 @@ iD.actions.ReverseWay = function(wayId) {
}
}
- var action = function(graph) {
+ return function(graph) {
var way = graph.entity(wayId),
nodes = way.nodes.slice().reverse(),
tags = {}, key, role;
@@ -73,10 +73,4 @@ iD.actions.ReverseWay = function(wayId) {
return graph.replace(way.update({nodes: nodes, tags: tags}));
};
-
- action.enabled = function(graph) {
- return true;
- };
-
- return action;
};
diff --git a/js/id/behavior/add_way.js b/js/id/behavior/add_way.js
index 7c02355fb..021377890 100644
--- a/js/id/behavior/add_way.js
+++ b/js/id/behavior/add_way.js
@@ -3,11 +3,9 @@ iD.behavior.AddWay = function(mode) {
history = mode.history,
controller = mode.controller,
event = d3.dispatch('startFromNode', 'startFromWay', 'start'),
- hover, draw;
-
- function add() {
- var datum = d3.select(d3.event.target).datum() || {};
+ draw;
+ function add(datum) {
if (datum.type === 'node') {
event.startFromNode(datum);
} else if (datum.type === 'way') {
@@ -26,8 +24,7 @@ iD.behavior.AddWay = function(mode) {
.minzoom(16)
.dblclickEnable(false);
- surface.call(hover)
- .call(draw);
+ surface.call(draw);
};
addWay.off = function(surface) {
@@ -39,16 +36,13 @@ iD.behavior.AddWay = function(mode) {
map.dblclickEnable(true);
}, 1000);
- surface.call(hover.off)
- .call(draw.off);
+ surface.call(draw.off);
};
addWay.cancel = function() {
controller.exit();
};
- hover = iD.behavior.Hover();
-
draw = iD.behavior.Draw()
.on('add', add)
.on('cancel', addWay.cancel)
diff --git a/js/id/behavior/drag_way.js b/js/id/behavior/drag_way.js
deleted file mode 100644
index 6de8ca252..000000000
--- a/js/id/behavior/drag_way.js
+++ /dev/null
@@ -1,28 +0,0 @@
-iD.behavior.DragWay = function(mode) {
- var history = mode.history,
- projection = mode.map.projection;
-
- return iD.behavior.drag()
- .delegate('.casing, .stroke, .area')
- .filter(function(d) {
- return d && d.id === mode.entity.id;
- })
- .origin(function(entity) {
- return projection(history.graph().entity(entity.nodes[0]).loc);
- })
- .on('start', function() {
- history.perform(
- iD.actions.Noop());
- })
- .on('move', function(entity) {
- d3.event.sourceEvent.stopPropagation();
- history.replace(
- iD.actions.MoveWay(entity.id, d3.event.delta, projection),
- 'moved a way');
- })
- .on('end', function() {
- history.replace(
- iD.actions.Noop(),
- 'moved a way');
- });
-};
diff --git a/js/id/behavior/draw.js b/js/id/behavior/draw.js
index 2725b8111..4d0153505 100644
--- a/js/id/behavior/draw.js
+++ b/js/id/behavior/draw.js
@@ -1,45 +1,64 @@
iD.behavior.Draw = function () {
var event = d3.dispatch('move', 'add', 'undo', 'cancel', 'finish'),
keybinding = d3.keybinding('draw'),
- down;
+ down, surface, hover;
+
+ function datum() {
+ if (d3.event.altKey) {
+ return {};
+ } else {
+ return d3.event.target.__data__ || {};
+ }
+ }
+
+ function mousedown() {
+ down = true;
+ }
+
+ function mouseup() {
+ down = false;
+ }
+
+ function mousemove() {
+ if (!down) {
+ event.move(datum());
+ }
+ }
+
+ function click() {
+ event.add(datum());
+ }
+
+ function keydown() {
+ if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
+ surface.call(hover.off);
+ }
+ }
+
+ function keyup() {
+ if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
+ surface.call(hover);
+ }
+ }
+
+ function backspace() {
+ d3.event.preventDefault();
+ event.undo();
+ }
+
+ function del() {
+ d3.event.preventDefault();
+ event.cancel();
+ }
+
+ function ret() {
+ d3.event.preventDefault();
+ event.finish();
+ }
function draw(selection) {
- function mousemove() {
- if (!down) event.move();
- }
-
- function click() {
- event.add();
- }
-
- function mousedown() {
- down = true;
- }
-
- function mouseup() {
- down = false;
- }
-
- function backspace() {
- d3.event.preventDefault();
- event.undo();
- }
-
- function del() {
- d3.event.preventDefault();
- event.cancel();
- }
-
- function ret() {
- d3.event.preventDefault();
- event.finish();
- }
-
- selection
- .on('mousedown.draw', mousedown)
- .on('mouseup.draw', mouseup)
- .on('mousemove.draw', mousemove)
- .on('click.draw', click);
+ surface = selection;
+ hover = iD.behavior.Hover();
keybinding
.on('⌫', backspace)
@@ -47,18 +66,33 @@ iD.behavior.Draw = function () {
.on('⎋', ret)
.on('↩', ret);
+ selection
+ .on('mousedown.draw', mousedown)
+ .on('mouseup.draw', mouseup)
+ .on('mousemove.draw', mousemove)
+ .on('click.draw', click)
+ .call(hover);
+
d3.select(document)
- .call(keybinding);
+ .call(keybinding)
+ .on('keydown.draw', keydown)
+ .on('keyup.draw', keyup);
return draw;
}
draw.off = function(selection) {
selection
+ .on('mousedown.draw', null)
+ .on('mouseup.draw', null)
.on('mousemove.draw', null)
- .on('click.draw', null);
+ .on('click.draw', null)
+ .call(hover.off);
- keybinding.off();
+ d3.select(document)
+ .call(keybinding.off)
+ .on('keydown.draw', null)
+ .on('keyup.draw', null);
};
return d3.rebind(draw, event, 'on');
diff --git a/js/id/behavior/draw_way.js b/js/id/behavior/draw_way.js
index 0e5bcf4fd..63526df7a 100644
--- a/js/id/behavior/draw_way.js
+++ b/js/id/behavior/draw_way.js
@@ -5,7 +5,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) {
event = d3.dispatch('add', 'addHead', 'addTail', 'addNode', 'addWay'),
way = mode.history.graph().entity(wayId),
finished = false,
- hover, draw;
+ draw;
var node = iD.Node({loc: map.mouseCoordinates()}),
nodeId = node.id;
@@ -14,13 +14,19 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) {
iD.actions.AddNode(node),
iD.actions.AddWayNode(wayId, node.id, index));
- function move() {
- history.replace(iD.actions.MoveNode(nodeId, map.mouseCoordinates()));
+ function move(datum) {
+ var loc = map.mouseCoordinates();
+
+ if (datum.type === 'node' || datum.midpoint) {
+ loc = datum.loc;
+ } else if (datum.type === 'way') {
+ loc = iD.geo.chooseIndex(datum, d3.mouse(map.surface.node()), map).loc;
+ }
+
+ history.replace(iD.actions.MoveNode(nodeId, loc));
}
- function add() {
- var datum = d3.select(d3.event.target).datum() || {};
-
+ function add(datum) {
if (datum.id === headId) {
event.addHead(datum);
} else if (datum.id === tailId) {
@@ -47,8 +53,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) {
.minzoom(16)
.dblclickEnable(false);
- surface.call(hover)
- .call(draw)
+ surface.call(draw)
.selectAll('.way, .node')
.filter(function (d) { return d.id === wayId || d.id === nodeId; })
.classed('active', true);
@@ -68,8 +73,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) {
map.dblclickEnable(true);
}, 1000);
- surface.call(hover.off)
- .call(draw.off)
+ surface.call(draw.off)
.selectAll('.way, .node')
.classed('active', false);
@@ -145,8 +149,6 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode, baseGraph) {
controller.enter(iD.modes.Browse());
};
- hover = iD.behavior.Hover();
-
draw = iD.behavior.Draw()
.on('move', move)
.on('add', add)
diff --git a/js/id/behavior/hover.js b/js/id/behavior/hover.js
index 9d50cbbd0..e4d33dd98 100644
--- a/js/id/behavior/hover.js
+++ b/js/id/behavior/hover.js
@@ -9,6 +9,8 @@
*/
iD.behavior.Hover = function () {
var hover = function(selection) {
+ selection.classed('behavior-hover', true);
+
selection.on('mouseover.hover', function () {
var datum = d3.event.target.__data__;
if (datum) {
@@ -25,7 +27,8 @@ iD.behavior.Hover = function () {
};
hover.off = function(selection) {
- selection.on('mouseover.hover', null)
+ selection.classed('behavior-hover', false)
+ .on('mouseover.hover', null)
.on('mouseout.hover', null);
};
diff --git a/js/id/modes/move_way.js b/js/id/modes/move_way.js
new file mode 100644
index 000000000..7fe07d1ce
--- /dev/null
+++ b/js/id/modes/move_way.js
@@ -0,0 +1,69 @@
+iD.modes.MoveWay = function(wayId) {
+ var mode = {
+ id: 'move-way'
+ };
+
+ var keybinding = d3.keybinding('move-way');
+
+ mode.enter = function() {
+ var map = mode.map,
+ history = mode.history,
+ graph = history.graph(),
+ selection = map.surface,
+ controller = mode.controller,
+ projection = map.projection;
+
+ var way = graph.entity(wayId),
+ origin = d3.mouse(selection.node());
+
+ history.perform(
+ iD.actions.Noop(),
+ 'moved a way');
+
+ function move() {
+ var p = d3.mouse(selection.node()),
+ delta = [p[0] - origin[0],
+ p[1] - origin[1]];
+
+ origin = p;
+
+ history.replace(
+ iD.actions.MoveWay(wayId, delta, projection),
+ 'moved a way');
+ }
+
+ function finish() {
+ d3.event.stopPropagation();
+ controller.enter(iD.modes.Select(way, true));
+ }
+
+ function cancel() {
+ history.pop();
+ controller.enter(iD.modes.Select(way, true));
+ }
+
+ selection
+ .on('mousemove.move-way', move)
+ .on('click.move-way', finish);
+
+ keybinding
+ .on('⎋', cancel)
+ .on('↩', finish);
+
+ d3.select(document)
+ .call(keybinding);
+ };
+
+ mode.exit = function() {
+ var map = mode.map,
+ selection = map.surface;
+
+ selection
+ .on('mousemove.move-way', null)
+ .on('click.move-way', null);
+
+ keybinding.off();
+ };
+
+ return mode;
+};
diff --git a/js/id/modes/select.js b/js/id/modes/select.js
index fb4e5dc06..06c05b7ea 100644
--- a/js/id/modes/select.js
+++ b/js/id/modes/select.js
@@ -43,7 +43,6 @@ iD.modes.Select = function(entity, initial) {
behaviors = [
iD.behavior.Hover(),
iD.behavior.DragNode(mode),
- iD.behavior.DragWay(mode),
iD.behavior.DragMidpoint(mode)];
behaviors.forEach(function(behavior) {
@@ -138,7 +137,7 @@ iD.modes.Select = function(entity, initial) {
})
.classed('selected', true);
- radialMenu = iD.ui.RadialMenu(entity, history, mode.map);
+ radialMenu = iD.ui.RadialMenu(entity, mode);
if (d3.event && !initial) {
var loc = map.mouseCoordinates();
diff --git a/js/id/operations.js b/js/id/operations.js
new file mode 100644
index 000000000..2786d046f
--- /dev/null
+++ b/js/id/operations.js
@@ -0,0 +1 @@
+iD.operations = {}
diff --git a/js/id/operations/circular.js b/js/id/operations/circular.js
new file mode 100644
index 000000000..0af64aa20
--- /dev/null
+++ b/js/id/operations/circular.js
@@ -0,0 +1,34 @@
+iD.operations.Circular = function(entityId, mode) {
+ var action = iD.actions.Circular(entityId, mode.map);
+
+ var operation = function(history) {
+ var graph = history.graph(),
+ entity = graph.entity(entityId),
+ geometry = entity.geometry(graph);
+
+ if (geometry === 'line') {
+ history.perform(
+ action,
+ 'made a line circular');
+
+ } else if (geometry === 'area') {
+ history.perform(
+ action,
+ 'made an area circular');
+ }
+ };
+
+ operation.available = function(graph) {
+ var entity = graph.entity(entityId);
+ return entity.geometry(graph) === 'area' || entity.geometry(graph) === 'line';
+ };
+
+ operation.enabled = function(graph) {
+ return action.enabled(graph);
+ };
+
+ operation.id = "circular";
+ operation.title = "Circular";
+
+ return operation;
+};
diff --git a/js/id/operations/delete.js b/js/id/operations/delete.js
new file mode 100644
index 000000000..53038dbc4
--- /dev/null
+++ b/js/id/operations/delete.js
@@ -0,0 +1,42 @@
+iD.operations.Delete = function(entityId) {
+ var operation = function(history) {
+ var graph = history.graph(),
+ entity = graph.entity(entityId),
+ geometry = entity.geometry(graph);
+
+ if (geometry === 'vertex') {
+ history.perform(
+ iD.actions.DeleteNode(entityId),
+ 'deleted a vertex');
+
+ } else if (geometry === 'point') {
+ history.perform(
+ iD.actions.DeleteNode(entityId),
+ 'deleted a point');
+
+ } else if (geometry === 'line') {
+ history.perform(
+ iD.actions.DeleteWay(entityId),
+ 'deleted a line');
+
+ } else if (geometry === 'area') {
+ history.perform(
+ iD.actions.DeleteWay(entityId),
+ 'deleted an area');
+ }
+ };
+
+ operation.available = function(graph) {
+ var entity = graph.entity(entityId);
+ return _.contains(['vertex', 'point', 'line', 'area'], entity.geometry(graph));
+ };
+
+ operation.enabled = function() {
+ return true;
+ };
+
+ operation.id = "delete";
+ operation.title = "Delete";
+
+ return operation;
+};
diff --git a/js/id/operations/move.js b/js/id/operations/move.js
new file mode 100644
index 000000000..9806ede67
--- /dev/null
+++ b/js/id/operations/move.js
@@ -0,0 +1,18 @@
+iD.operations.Move = function(entityId, mode) {
+ var operation = function() {
+ mode.controller.enter(iD.modes.MoveWay(entityId));
+ };
+
+ operation.available = function(graph) {
+ return graph.entity(entityId).type === 'way';
+ };
+
+ operation.enabled = function() {
+ return true;
+ };
+
+ operation.id = "move";
+ operation.title = "Move";
+
+ return operation;
+};
diff --git a/js/id/operations/reverse.js b/js/id/operations/reverse.js
new file mode 100644
index 000000000..941d8a4da
--- /dev/null
+++ b/js/id/operations/reverse.js
@@ -0,0 +1,21 @@
+iD.operations.Reverse = function(entityId) {
+ var operation = function(history) {
+ history.perform(
+ iD.actions.ReverseWay(entityId),
+ 'reversed a line');
+ };
+
+ operation.available = function(graph) {
+ var entity = graph.entity(entityId);
+ return entity.geometry(graph) === 'line';
+ };
+
+ operation.enabled = function() {
+ return true;
+ };
+
+ operation.id = "reverse";
+ operation.title = "Reverse";
+
+ return operation;
+};
diff --git a/js/id/operations/split.js b/js/id/operations/split.js
new file mode 100644
index 000000000..838dac88e
--- /dev/null
+++ b/js/id/operations/split.js
@@ -0,0 +1,21 @@
+iD.operations.Split = function(entityId) {
+ var action = iD.actions.SplitWay(entityId);
+
+ var operation = function(history) {
+ history.perform(action, 'split a way');
+ };
+
+ operation.available = function(graph) {
+ var entity = graph.entity(entityId);
+ return entity.geometry(graph) === 'vertex';
+ };
+
+ operation.enabled = function(graph) {
+ return action.enabled(graph);
+ };
+
+ operation.id = "split";
+ operation.title = "Split";
+
+ return operation;
+};
diff --git a/js/id/operations/unjoin.js b/js/id/operations/unjoin.js
new file mode 100644
index 000000000..985a41697
--- /dev/null
+++ b/js/id/operations/unjoin.js
@@ -0,0 +1,21 @@
+iD.operations.Unjoin = function(entityId) {
+ var action = iD.actions.UnjoinNode(entityId);
+
+ var operation = function(history) {
+ history.perform(action, 'unjoined lines');
+ };
+
+ operation.available = function(graph) {
+ var entity = graph.entity(entityId);
+ return entity.geometry(graph) === 'vertex';
+ };
+
+ operation.enabled = function(graph) {
+ return action.enabled(graph);
+ };
+
+ operation.id = "unjoin";
+ operation.title = "Unjoin";
+
+ return operation;
+};
diff --git a/js/id/ui/radial_menu.js b/js/id/ui/radial_menu.js
index ff895ea81..d38ef3679 100644
--- a/js/id/ui/radial_menu.js
+++ b/js/id/ui/radial_menu.js
@@ -1,82 +1,16 @@
-iD.ui.RadialMenu = function(entity, history, map) {
+iD.ui.RadialMenu = function(entity, mode) {
var arcs;
var radialMenu = function(selection, center) {
- var operations,
+ var history = mode.map.history(),
graph = history.graph(),
- geometry = entity.geometry(graph);
+ operations = d3.values(iD.operations)
+ .map(function (o) { return o(entity.id, mode); })
+ .filter(function (o) { return o.available(graph); });
- if (geometry === 'vertex') {
- operations = [
- {
- id: 'delete',
- text: 'Delete',
- description: 'deleted a node',
- action: iD.actions.DeleteNode(entity.id)
- },
- {
- id: 'split',
- text: 'Split Way',
- description: 'split a way',
- action: iD.actions.SplitWay(entity.id)
- },
- {
- id: 'unjoin',
- text: 'Unjoin',
- description: 'unjoined lines',
- action: iD.actions.UnjoinNode(entity.id)
- }
- ];
- } else if (geometry === 'point') {
- operations = [
- {
- id: 'delete',
- text: 'Delete',
- description: 'deleted a point',
- action: iD.actions.DeleteNode(entity.id)
- }
- ];
- } else if (geometry === 'line') {
- operations = [
- {
- id: 'delete',
- text: 'Delete',
- description: 'deleted a line',
- action: iD.actions.DeleteWay(entity.id)
- },
- {
- id: 'reverse',
- text: 'Reverse',
- description: 'reversed a way',
- action: iD.actions.ReverseWay(entity.id)
- }
- ];
- if (entity.isClosed()) {
- operations.push({
- id: 'circlar',
- text: 'Circular',
- description: 'made way circular',
- action: iD.actions.Circular(entity.id, map)
- });
- }
- } else if (geometry === 'area') {
- operations = [
- {
- id: 'delete',
- text: 'Delete',
- description: 'deleted an area',
- action: iD.actions.DeleteWay(entity.id)
- },
- {
- id: 'circlar',
- text: 'Circular',
- description: 'made area circular',
- action: iD.actions.Circular(entity.id, map)
- }
- ];
- } else {
- // Relation, not implemented yet.
- return;
+ function click(operation) {
+ d3.event.stopPropagation();
+ operation(history);
}
var arc = d3.svg.arc()
@@ -98,14 +32,14 @@ iD.ui.RadialMenu = function(entity, history, map) {
arcs.append('path')
.attr('class', function (d) { return 'radial-menu-item radial-menu-item-' + d.id; })
.attr('d', arc)
- .classed('disabled', function (d) { return !d.action.enabled(history.graph()); })
- .on('click', function (d) { history.perform(d.action, d.description); });
+ .classed('disabled', function (d) { return !d.enabled(graph); })
+ .on('click', click);
arcs.append('text')
.attr("transform", function(d, i) { return "translate(" + arc.centroid(d, i) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
- .text(function(d) { return d.text; });
+ .text(function(d) { return d.title; });
};
radialMenu.close = function(selection) {
diff --git a/test/index.html b/test/index.html
index 859d5b95d..12cf31886 100644
--- a/test/index.html
+++ b/test/index.html
@@ -86,7 +86,6 @@
-
@@ -98,8 +97,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/test/spec/behavior/hover.js b/test/spec/behavior/hover.js
index 817654d59..62d301d19 100644
--- a/test/spec/behavior/hover.js
+++ b/test/spec/behavior/hover.js
@@ -9,8 +9,23 @@ describe("iD.behavior.Hover", function() {
container.remove();
});
+ describe("#on", function () {
+ it("adds the .behavior-hover class to the selection", function () {
+ container.call(iD.behavior.Hover());
+ expect(container).to.be.classed('behavior-hover')
+ });
+ });
+
+ describe("#off", function () {
+ it("removes the .behavior-hover class from the selection", function () {
+ container.classed('behavior-hover', true);
+ container.call(iD.behavior.Hover().off);
+ expect(container).not.to.be.classed('behavior-hover')
+ });
+ });
+
describe("mouseover", function () {
- it("adds the 'hover' class to all elements to which the same datum is bound", function () {
+ it("adds the .hover class to all elements to which the same datum is bound", function () {
container.selectAll('span')
.data(['a', 'b', 'a', 'b'])
.enter().append('span').attr('class', Object);
@@ -24,7 +39,7 @@ describe("iD.behavior.Hover", function() {
});
describe("mouseout", function () {
- it("removes the 'hover' class from all elements", function () {
+ it("removes the .hover class from all elements", function () {
container.append('span').attr('class', 'hover');
container.call(iD.behavior.Hover());