diff --git a/js/id/behavior/drag_midpoint.js b/js/id/behavior/drag_midpoint.js index bd1a40bd9..6041946cd 100644 --- a/js/id/behavior/drag_midpoint.js +++ b/js/id/behavior/drag_midpoint.js @@ -25,7 +25,7 @@ iD.behavior.DragMidpoint = function(mode) { .on('end', function() { history.replace( iD.actions.Noop(), - 'Added a node to a way.'); + t('operations.add.annotation.vertex')); }); return behavior; diff --git a/js/id/behavior/drag_node.js b/js/id/behavior/drag_node.js index 1bfddfed6..b9846617d 100644 --- a/js/id/behavior/drag_node.js +++ b/js/id/behavior/drag_node.js @@ -25,6 +25,10 @@ iD.behavior.DragNode = function(mode) { nudgeInterval = null; } + function annotation(entity) { + return t('operations.move.annotation.' + entity.geometry(mode.history.graph())); + } + return iD.behavior.drag() .delegate(".node") .origin(function(entity) { @@ -43,12 +47,12 @@ iD.behavior.DragNode = function(mode) { history.replace( iD.actions.MoveNode(entity.id, projection.invert(d3.event.point)), - 'moved a node'); + annotation(entity)); }) - .on('end', function() { + .on('end', function(entity) { stopNudge(); history.replace( iD.actions.Noop(), - 'moved a node'); + annotation(entity)); }); }; diff --git a/js/id/behavior/draw_way.js b/js/id/behavior/draw_way.js index 21c13d2fa..c8341337c 100644 --- a/js/id/behavior/draw_way.js +++ b/js/id/behavior/draw_way.js @@ -2,9 +2,11 @@ iD.behavior.DrawWay = function(wayId, index, mode, baseGraph) { var map = mode.map, history = mode.history, controller = mode.controller, - way = mode.history.graph().entity(wayId), + way = history.graph().entity(wayId), finished = false, - annotation = 'Added to a way.', + annotation = t((way.isDegenerate() ? + 'operations.start.annotation.' : + 'operations.continue.annotation.') + way.geometry(history.graph())), draw = iD.behavior.Draw(map); var node = iD.Node({loc: map.mouseCoordinates()}), @@ -71,12 +73,6 @@ iD.behavior.DrawWay = function(wayId, index, mode, baseGraph) { history.on('undone.draw', null); }; - drawWay.annotation = function(_) { - if (!arguments.length) return annotation; - annotation = _; - return drawWay; - }; - function ReplaceTemporaryNode(newNode) { return function(graph) { return graph @@ -153,7 +149,7 @@ iD.behavior.DrawWay = function(wayId, index, mode, baseGraph) { drawWay.cancel = function() { history.perform( d3.functor(baseGraph), - 'Cancelled drawing.'); + t('operations.cancel_draw.annotation')); finished = true; controller.enter(iD.modes.Browse()); diff --git a/js/id/graph/validate.js b/js/id/graph/validate.js index 805b775c3..aa7d8771b 100644 --- a/js/id/graph/validate.js +++ b/js/id/graph/validate.js @@ -21,22 +21,22 @@ iD.validate = function(changes, graph) { if (change.geometry(graph) === 'point' && _.isEmpty(change.tags)) { warnings.push({ - message: 'Untagged point which is not part of a line or area', + message: t('validations.untagged_point'), entity: change }); } if (change.geometry(graph) === 'line' && _.isEmpty(change.tags)) { - warnings.push({ message: 'Untagged line', entity: change }); + warnings.push({ message: t('validations.untagged_line'), entity: change }); } if (change.geometry(graph) === 'area' && _.isEmpty(change.tags)) { - warnings.push({ message: 'Untagged area', entity: change }); + warnings.push({ message: t('validations.untagged_area'), entity: change }); } if (change.geometry(graph) === 'line' && tagSuggestsArea(change)) { warnings.push({ - message: 'The tag ' + tagSuggestsArea(change) + ' suggests line should be area, but it is not and area', + message: t('validations.tag_suggests_area', {tag: tagSuggestsArea(change)}), entity: change }); } diff --git a/js/id/modes/add_area.js b/js/id/modes/add_area.js index 614c66677..03b7582cc 100644 --- a/js/id/modes/add_area.js +++ b/js/id/modes/add_area.js @@ -2,9 +2,9 @@ iD.modes.AddArea = function() { var mode = { id: 'add-area', button: 'area', - title: 'Area', - description: 'Add parks, buildings, lakes, or other areas to the map.', - key: 'a' + title: t('modes.add_area.title'), + description: t('modes.add_area.description'), + key: t('modes.add_area.key') }; var behavior, @@ -77,7 +77,7 @@ iD.modes.AddArea = function() { .on('startFromMidpoint', startFromMidpoint); mode.map.surface.call(behavior); - mode.map.tail('Click on the map to start drawing an area, like a park, lake, or building.', true); + mode.map.tail(t('modes.add_area.tail'), true); }; mode.exit = function() { diff --git a/js/id/modes/add_line.js b/js/id/modes/add_line.js index 90adac738..c40a78fce 100644 --- a/js/id/modes/add_line.js +++ b/js/id/modes/add_line.js @@ -2,9 +2,9 @@ iD.modes.AddLine = function() { var mode = { id: 'add-line', button: 'line', - title: 'Line', - description: 'Lines can be highways, streets, pedestrian paths, or even canals.', - key: 'l' + title: t('modes.add_line.title'), + description: t('modes.add_line.description'), + key: t('modes.add_line.key') }; var behavior, @@ -84,7 +84,7 @@ iD.modes.AddLine = function() { .on('startFromMidpoint', startFromMidpoint); mode.map.surface.call(behavior); - mode.map.tail('Click on the map to start drawing an road, path, or route.', true); + mode.map.tail(t('modes.add_line.tail'), true); }; mode.exit = function() { diff --git a/js/id/modes/add_point.js b/js/id/modes/add_point.js index 1b9781a9d..5db73dc0f 100644 --- a/js/id/modes/add_point.js +++ b/js/id/modes/add_point.js @@ -1,27 +1,24 @@ iD.modes.AddPoint = function() { var mode = { id: 'add-point', - title: 'Point', - description: 'Restaurants, monuments, and postal boxes are points.', - key: 'p' + title: t('modes.add_point.title'), + description: t('modes.add_point.description'), + key: t('modes.add_point.key') }; var behavior; mode.enter = function() { var map = mode.map, - surface = map.surface, history = mode.history, controller = mode.controller; - map.tail('Click on the map to add a point.', true); - function add(loc) { var node = iD.Node({loc: loc}); history.perform( iD.actions.AddNode(node), - 'Added a point.'); + t('operations.add.annotation.point')); controller.enter(iD.modes.Select(node, true)); } @@ -44,8 +41,10 @@ iD.modes.AddPoint = function() { .on('clickNode', addNode) .on('clickMidpoint', addNode) .on('cancel', cancel) - .on('finish', cancel) - (surface); + .on('finish', cancel); + + mode.map.surface.call(behavior); + mode.map.tail(t('modes.add_point.tail'), true); }; mode.exit = function() { diff --git a/js/id/modes/browse.js b/js/id/modes/browse.js index ab6bc80cb..c7358bdea 100644 --- a/js/id/modes/browse.js +++ b/js/id/modes/browse.js @@ -2,9 +2,9 @@ iD.modes.Browse = function() { var mode = { button: 'browse', id: 'browse', - title: 'Browse', - description: 'Pan and zoom the map.', - key: 'b' + title: t('modes.browse.title'), + description: t('modes.browse.description'), + key: t('modes.browse.key') }; var behaviors; diff --git a/js/id/modes/draw_area.js b/js/id/modes/draw_area.js index 8423ff436..fd26d5eda 100644 --- a/js/id/modes/draw_area.js +++ b/js/id/modes/draw_area.js @@ -11,8 +11,7 @@ iD.modes.DrawArea = function(wayId, baseGraph) { headId = way.nodes[way.nodes.length - 2], tailId = way.first(); - behavior = iD.behavior.DrawWay(wayId, -1, mode, baseGraph) - .annotation(way.isDegenerate() ? 'started an area' : 'continued an area'); + behavior = iD.behavior.DrawWay(wayId, -1, mode, baseGraph); var addNode = behavior.addNode; @@ -25,7 +24,7 @@ iD.modes.DrawArea = function(wayId, baseGraph) { }; mode.map.surface.call(behavior); - mode.map.tail('Click to add points to your area. Click the first point to finish the area.', true); + mode.map.tail(t('modes.draw_area.tail'), true); }; mode.exit = function() { diff --git a/js/id/modes/draw_line.js b/js/id/modes/draw_line.js index ae54ab2e1..0596c9065 100644 --- a/js/id/modes/draw_line.js +++ b/js/id/modes/draw_line.js @@ -11,8 +11,7 @@ iD.modes.DrawLine = function(wayId, direction, baseGraph) { index = (direction === 'forward') ? undefined : 0, headId = (direction === 'forward') ? way.last() : way.first(); - behavior = iD.behavior.DrawWay(wayId, index, mode, baseGraph) - .annotation(way.isDegenerate() ? 'Started a line.' : 'Continued a line.'); + behavior = iD.behavior.DrawWay(wayId, index, mode, baseGraph); var addNode = behavior.addNode; @@ -25,9 +24,7 @@ iD.modes.DrawLine = function(wayId, direction, baseGraph) { }; mode.map.surface.call(behavior); - mode.map.tail('Click to add more points to the line. ' + - 'Click on other lines to connect to them, and double-click to ' + - 'end the line.', true); + mode.map.tail(t('modes.draw_line.tail'), true); }; mode.exit = function() { diff --git a/js/id/modes/move_way.js b/js/id/modes/move_way.js index 18c6ee619..d977f6719 100644 --- a/js/id/modes/move_way.js +++ b/js/id/modes/move_way.js @@ -11,14 +11,14 @@ iD.modes.MoveWay = function(wayId) { graph = history.graph(), selection = map.surface, controller = mode.controller, - projection = map.projection; - - var way = graph.entity(wayId), - origin = d3.mouse(selection.node()); + projection = map.projection, + way = graph.entity(wayId), + origin = d3.mouse(selection.node()), + annotation = t('operations.move.annotation.' + way.geometry(graph)); history.perform( iD.actions.Noop(), - 'Moved a way.'); + annotation); function move() { var p = d3.mouse(selection.node()), @@ -29,7 +29,7 @@ iD.modes.MoveWay = function(wayId) { history.replace( iD.actions.MoveWay(wayId, delta, projection), - 'Moved a way.'); + annotation); } function finish() { diff --git a/js/id/modes/select.js b/js/id/modes/select.js index 1ddd4ffc4..455f94913 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -14,7 +14,7 @@ iD.modes.Select = function(entity, initial) { if (!_.isEqual(entity.tags, tags)) { mode.history.perform( iD.actions.ChangeEntityTags(d.id, tags), - 'Changed tags.'); + t('operations.change_tags.annotation')); } } @@ -114,7 +114,7 @@ iD.modes.Select = function(entity, initial) { history.perform( iD.actions.AddNode(node), iD.actions.AddWayNode(datum.id, node.id, choice.index), - 'Added a point to a road.'); + t('operations.add.annotation.vertex')); d3.event.preventDefault(); d3.event.stopPropagation(); diff --git a/js/id/operations/circularize.js b/js/id/operations/circularize.js index ce161aef4..91921dc2a 100644 --- a/js/id/operations/circularize.js +++ b/js/id/operations/circularize.js @@ -5,24 +5,15 @@ iD.operations.Circularize = function(entityId, mode) { var operation = function() { var graph = history.graph(), entity = graph.entity(entityId), - geometry = entity.geometry(graph); + annotation = t('operations.circularize.annotation.' + entity.geometry(graph)); - if (geometry === 'line') { - history.perform( - action, - 'Made a line circular.'); - - } else if (geometry === 'area') { - history.perform( - action, - 'Made an area circular.'); - } + history.perform(action, annotation); }; operation.available = function() { var graph = history.graph(), entity = graph.entity(entityId); - return entity.geometry(graph) === 'area' || entity.geometry(graph) === 'line'; + return entity.type === 'way'; }; operation.enabled = function() { @@ -31,9 +22,9 @@ iD.operations.Circularize = function(entityId, mode) { }; operation.id = "circularize"; - operation.key = "O"; - operation.title = "Circularize"; - operation.description = "Make this round"; + operation.key = t('operations.circularize.key'); + operation.title = t('operations.circularize.title'); + operation.description = t('operations.circularize.description'); return operation; }; diff --git a/js/id/operations/delete.js b/js/id/operations/delete.js index cc3750360..993d3eef4 100644 --- a/js/id/operations/delete.js +++ b/js/id/operations/delete.js @@ -4,34 +4,18 @@ iD.operations.Delete = function(entityId, mode) { var operation = function() { var graph = history.graph(), entity = graph.entity(entityId), - geometry = entity.geometry(graph); + action = {way: iD.actions.DeleteWay, node: iD.actions.DeleteNode}[entity.type], + annotation = t('operations.delete.annotation.' + 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.'); - } + history.perform( + action(entityId), + annotation); }; operation.available = function() { var graph = history.graph(), entity = graph.entity(entityId); - return _.contains(['vertex', 'point', 'line', 'area'], entity.geometry(graph)); + return entity.type === 'way' || entity.type === 'node'; }; operation.enabled = function() { @@ -39,9 +23,9 @@ iD.operations.Delete = function(entityId, mode) { }; operation.id = "delete"; - operation.key = "⌫"; - operation.title = "Delete"; - operation.description = "Remove this from the map."; + operation.key = t('operations.delete.key'); + operation.title = t('operations.delete.title'); + operation.description = t('operations.delete.description'); return operation; }; diff --git a/js/id/operations/move.js b/js/id/operations/move.js index 383ca4206..5034c2f75 100644 --- a/js/id/operations/move.js +++ b/js/id/operations/move.js @@ -15,9 +15,9 @@ iD.operations.Move = function(entityId, mode) { }; operation.id = "move"; - operation.key = "M"; - operation.title = "Move"; - operation.description = "Move this to a different location"; + operation.key = t('operations.move.key'); + operation.title = t('operations.move.title'); + operation.description = t('operations.move.description'); return operation; }; diff --git a/js/id/operations/reverse.js b/js/id/operations/reverse.js index 62fd8810b..ca9dd6440 100644 --- a/js/id/operations/reverse.js +++ b/js/id/operations/reverse.js @@ -4,7 +4,7 @@ iD.operations.Reverse = function(entityId, mode) { var operation = function() { history.perform( iD.actions.ReverseWay(entityId), - 'Reversed a line.'); + t('operations.reverse.annotation')); }; operation.available = function() { @@ -18,9 +18,9 @@ iD.operations.Reverse = function(entityId, mode) { }; operation.id = "reverse"; - operation.key = "V"; - operation.title = "Reverse"; - operation.description = "Make this way go in the opposite direction."; + operation.key = t('operations.reverse.key'); + operation.title = t('operations.reverse.title'); + operation.description = t('operations.reverse.description'); return operation; }; diff --git a/js/id/operations/split.js b/js/id/operations/split.js index 40aa55fd0..ff3f8af20 100644 --- a/js/id/operations/split.js +++ b/js/id/operations/split.js @@ -3,7 +3,7 @@ iD.operations.Split = function(entityId, mode) { action = iD.actions.SplitWay(entityId); var operation = function() { - history.perform(action, 'Split a way.'); + history.perform(action, t('operations.split.annotation')); }; operation.available = function() { @@ -18,9 +18,9 @@ iD.operations.Split = function(entityId, mode) { }; operation.id = "split"; - operation.key = "X"; - operation.title = "Split"; - operation.description = "Split this into two ways at this point."; + operation.key = t('operations.split.key'); + operation.title = t('operations.split.title'); + operation.description = t('operations.split.description'); return operation; }; diff --git a/js/id/operations/unjoin.js b/js/id/operations/unjoin.js index f38333bb4..175c13973 100644 --- a/js/id/operations/unjoin.js +++ b/js/id/operations/unjoin.js @@ -18,9 +18,9 @@ iD.operations.Unjoin = function(entityId, mode) { }; operation.id = "unjoin"; - operation.key = "⇧-J"; - operation.title = "Unjoin"; - operation.description = "Disconnect these ways from each other."; + operation.key = t('operations.unjoin.key'); + operation.title = t('operations.unjoin.title'); + operation.description = t('operations.unjoin.description'); return operation; }; diff --git a/locale/en.js b/locale/en.js index 2a011a734..d7fc3628f 100644 --- a/locale/en.js +++ b/locale/en.js @@ -1,8 +1,118 @@ locale.en = { - "browse": "Browse", - "point": "Point", - "line": "Line", - "area": "Area", + modes: { + add_area: { + title: "Area", + description: "Add parks, buildings, lakes, or other areas to the map.", + tail: "Click on the map to start drawing an area, like a park, lake, or building.", + key: "A" + }, + add_line: { + title: "Line", + description: "Lines can be highways, streets, pedestrian paths, or even canals.", + tail: "Click on the map to start drawing an road, path, or route.", + key: "L" + }, + add_point: { + title: "Point", + description: "Restaurants, monuments, and postal boxes are points.", + tail: "Click on the map to add a point.", + key: "P" + }, + browse: { + title: "Browse", + description: "Pan and zoom the map.", + key: "B" + }, + draw_area: { + tail: "Click to add points to your area. Click the first point to finish the area." + }, + draw_line: { + tail: "Click to add more points to the line. Click on other lines to connect to them, and double-click to end the line." + } + }, + + operations: { + add: { + annotation: { + point: "Added a point.", + vertex: "Added a node to a way." + } + }, + start: { + annotation: { + line: "Started a line.", + area: "Started an area." + } + }, + continue: { + annotation: { + line: "Continued a line.", + area: "Continued an area." + } + }, + cancel_draw: { + annotation: "Cancelled drawing." + }, + change_tags: { + annotation: "Changed tags." + }, + circularize: { + title: "Circularize", + description: "Make this round.", + key: "O", + annotation: { + line: "Made a line circular.", + area: "Made an area circular." + } + }, + delete: { + title: "Delete", + description: "Remove this from the map.", + key: "⌫", + annotation: { + point: "Deleted a point.", + vertex: "Deleted a node from a way.", + line: "Deleted a line.", + area: "Deleted an area." + } + }, + move: { + title: "Move", + description: "Move this to a different location.", + key: "M", + annotation: { + point: "Moved a point.", + vertex: "Moved a node in a way.", + line: "Moved a line.", + area: "Moved an area." + } + }, + reverse: { + title: "Reverse", + description: "Make this line go in the opposite direction.", + key: "V", + annotation: "Reversed a line." + }, + split: { + title: "Split", + description: "Split this into two ways at this point.", + key: "X", + annotation: "Split a way." + }, + unjoin: { + title: "Unjoin", + description: "Disconnect these ways from each other.", + key: "⇧-J", + annotation: "Unjoined ways." + } + }, + + validations: { + untagged_point: "Untagged point which is not part of a line or area", + untagged_line: "Untagged line", + untagged_area: "Untagged area", + tag_suggests_area: "The tag {tag} suggests line should be area, but it is not an area" + }, "save": "Save", "save_help": "Save changes to OpenStreetMap, making them visible to other users", @@ -37,4 +147,4 @@ locale.en = { "layers": "Layers", "percent_opacity": "{opacity}% opacity" -} +}; diff --git a/locale/locale.js b/locale/locale.js index 9e4786059..291b255a0 100644 --- a/locale/locale.js +++ b/locale/locale.js @@ -1,8 +1,12 @@ var locale = { current: 'en' }; function t(s, o) { - if (locale[locale.current][s] !== undefined) { - var rep = locale[locale.current][s]; + var path = s.split(".").reverse(), + rep = locale[locale.current]; + + while (rep !== undefined && path.length) rep = rep[path.pop()]; + + if (rep !== undefined) { if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]); return rep; } else {