I18n for modes and operations

This commit is contained in:
John Firebaugh
2013-01-31 11:20:34 -05:00
parent f0414f7ca1
commit 7e8126ded9
20 changed files with 198 additions and 114 deletions

View File

@@ -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;

View File

@@ -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));
});
};

View File

@@ -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());

View File

@@ -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
});
}

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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();

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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"
}
};

View File

@@ -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 {