diff --git a/data/core.yaml b/data/core.yaml index 94f603eb8..dc0d97aa9 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -742,6 +742,32 @@ en: using: "To use a GPS trace for mapping, drag and drop the data file onto the map editor. If it's recognized, it will be drawn on the map as a bright purple line. Click the {data} **Map data** panel on the side of the map to enable, disable, or zoom to your GPS data." tracing: "The GPS track isn't sent to OpenStreetMap - the best way to use it is to draw on the map, using it as a guide for the new features that you add." upload: "You can also [upload your GPS data to OpenStreetMap](https://www.openstreetmap.org/trace/create) for other users to use." + field: + restrictions: + title: Editing Turn Restrictions + inspecting: + title: Inspecting + about: "To inspect turn restrictions, hover over a starting segment." + shadow: "All paths starting from that segment will be drawn with a line shadow." + from: "{from} Starting segment" + allow: "{allowed} Allowed" + restrict: "{restricted} Restricted" + only: "{only} Only" + modifying: + title: Modifying + about: "To modify turn restrictions, click on a starting segment." + indicators: "All of the possible TO destinations from that segment will appear as turn indicators." + indicators2: "Click on a turn indicator to toggle it between \"Allowed\", \"Restricted\", and \"Only\"." + allow: "{allowed} Allowed" + restrict: "{restricted} Restricted" + only: "{only} Only" + tips: + title: Tips + tip1: "* Prefer simple restrictions over complex ones." + tip2: For example, avoid using a via-way restriction if a simpler turn restriction will do. + tip3: "* Some restrictions are \"(indirect)\". These restrictions exist because of another nearby restriction." + tip4: "For example, a route with an \"Only Straight On\" turn restriction will indirectly create \"No Turn\" restrictions." + tip5: "* You may not edit an indirect restriction. Instead, edit the nearby direct restriction." intro: done: done ok: OK diff --git a/dist/locales/en.json b/dist/locales/en.json index 7ae8fdecb..b367ceeca 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -882,6 +882,37 @@ "using": "To use a GPS trace for mapping, drag and drop the data file onto the map editor. If it's recognized, it will be drawn on the map as a bright purple line. Click the {data} **Map data** panel on the side of the map to enable, disable, or zoom to your GPS data.", "tracing": "The GPS track isn't sent to OpenStreetMap - the best way to use it is to draw on the map, using it as a guide for the new features that you add.", "upload": "You can also [upload your GPS data to OpenStreetMap](https://www.openstreetmap.org/trace/create) for other users to use." + }, + "field": { + "restrictions": { + "title": "Editing Turn Restrictions", + "inspecting": { + "title": "Inspecting", + "about": "To inspect turn restrictions, hover over a starting segment.", + "shadow": "All paths starting from that segment will be drawn with a line shadow.", + "from": "{from} Starting segment", + "allow": "{allowed} Allowed", + "restrict": "{restricted} Restricted", + "only": "{only} Only" + }, + "modifying": { + "title": "Modifying", + "about": "To modify turn restrictions, click on a starting segment.", + "indicators": "All of the possible TO destinations from that segment will appear as turn indicators.", + "indicators2": "Click on a turn indicator to toggle it between \"Allowed\", \"Restricted\", and \"Only\".", + "allow": "{allowed} Allowed", + "restrict": "{restricted} Restricted", + "only": "{only} Only" + }, + "tips": { + "title": "Tips", + "tip1": "* Prefer simple restrictions over complex ones.", + "tip2": "For example, avoid using a via-way restriction if a simpler turn restriction will do.", + "tip3": "* Some restrictions are \"(indirect)\". These restrictions exist because of another nearby restriction.", + "tip4": "For example, a route with an \"Only Straight On\" turn restriction will indirectly create \"No Turn\" restrictions.", + "tip5": "* You may not edit an indirect restriction. Instead, edit the nearby direct restriction." + } + } } }, "intro": { diff --git a/modules/ui/field_help.js b/modules/ui/field_help.js index 71aebf076..0530f7571 100644 --- a/modules/ui/field_help.js +++ b/modules/ui/field_help.js @@ -3,16 +3,75 @@ import { select as d3_select } from 'd3-selection'; -import { t } from '../util/locale'; +import marked from 'marked'; +import { t, textDirection } from '../util/locale'; import { svgIcon } from '../svg'; +// This currently only works with the 'restrictions' field +var fieldHelpKeys = { + restrictions: [ + ['inspecting',[ + 'title', + 'about', + 'shadow', + 'from', + 'allow', + 'restrict', + 'only' + ]], + ['modifying',[ + 'title', + 'about', + 'indicators', + 'indicators2', + 'allow', + 'restrict', + 'only' + ]], + ['tips',[ + 'title', + 'tip1', + 'tip2', + 'tip3', + 'tip4', + 'tip5' + ]] + ] +}; + +var fieldHelpHeadings = { + 'help.field.restrictions.inspecting.title': 3, + 'help.field.restrictions.modifying.title': 3, + 'help.field.restrictions.tips.title': 3 +}; + +var replacements = {}; + + export function uiFieldHelp(fieldName) { var fieldHelp = {}; var _body = d3_select(null); var _showing; + // For each section, squash all the texts into a single markdown document + var docs = fieldHelpKeys[fieldName].map(function(key) { + var helpkey = 'help.field.' + fieldName + '.' + key[0]; + var text = key[1].reduce(function(all, part) { + var subkey = helpkey + '.' + part; + var depth = fieldHelpHeadings[subkey]; // is this subkey a heading? + var hhh = depth ? Array(depth + 1).join('#') + ' ' : ''; // if so, prepend with some ##'s + return all + hhh + t(subkey, replacements) + '\n\n'; + }, ''); + + return { + title: t(helpkey + '.title'), + html: marked(text.trim()) + }; + }); + + function show() { _body .classed('hide', false) @@ -37,6 +96,53 @@ export function uiFieldHelp(fieldName) { } + function clickHelp(d, i) { + var rtl = (textDirection === 'rtl'); + + _body.selectAll('.field-help-content').html(d.html); + var nav = _body.selectAll('.field-help-nav').html(''); + + if (rtl) { + nav.call(drawNext).call(drawPrevious); + } else { + nav.call(drawPrevious).call(drawNext); + } + + function drawNext(selection) { + if (i < docs.length - 1) { + var nextLink = selection + .append('a') + .attr('class', 'next') + .on('click', function() { + clickHelp(docs[i + 1], i + 1); + }); + + nextLink + .append('span') + .text(docs[i + 1].title) + .call(svgIcon((rtl ? '#icon-backward' : '#icon-forward'), 'inline')); + } + } + + + function drawPrevious(selection) { + if (i > 0) { + var prevLink = selection + .append('a') + .attr('class', 'previous') + .on('click', function() { + clickHelp(docs[i - 1], i - 1); + }); + + prevLink + .call(svgIcon((rtl ? '#icon-forward' : '#icon-backward'), 'inline')) + .append('span') + .text(docs[i - 1].title); + } + } + } + + fieldHelp.button = function(selection) { var button = selection.selectAll('.field-help-button') .data([0]); @@ -73,17 +179,23 @@ export function uiFieldHelp(fieldName) { .attr('class', 'field-help-body cf hide') .style('height', '0px'); -//debug -for (var i = 0; i < 15; i++) { enter - .append('p') - .attr('class', 'field-help-description') - .text('lorem ipsum'); -} + .append('h2') + .text(t('help.field.' + fieldName + '.title')); + + enter + .append('div') + .attr('class', 'field-help-content'); + + enter + .append('div') + .attr('class', 'field-help-nav'); _body = _body .merge(enter); + clickHelp(docs[0], 0); + if (_showing === false) { hide(); }