diff --git a/css/80_app.css b/css/80_app.css index d4fc664cf2..47d65cf628 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -407,6 +407,16 @@ button[disabled].action { height: 20px; } +.icon.operation use { + fill: #222; + color: #79f; +} +button.disabled .icon.operation use, +.icon.operation.disabled use { + fill: rgba(32,32,32,.2); + color: rgba(40,40,40,.2); +} + .icon.monochrome use { fill: currentColor; } @@ -3754,19 +3764,6 @@ li.issue-fix-item:not(.actionable) .fix-icon { margin-bottom: 20px; } -.help-pane .left-content .body p code { - padding: 3px 4px; - font-size: 12px; - color: #555; - vertical-align: baseline; - background-color: #f6f6f6; - border: solid 1px #ccc; - margin: 0 2px; - border-bottom-color: #bbb; - border-radius: 3px; - box-shadow: inset 0 -1px 0 #bbb; -} - .help-pane .left-content .icon.pre-text { vertical-align: text-top; margin-right: 0; @@ -3775,7 +3772,8 @@ li.issue-fix-item:not(.actionable) .fix-icon { } .help-pane .toc { - width: 40%; + width: 100%; + max-width: 200px; float: right; margin-left: 20px; margin-bottom: 20px; @@ -4408,11 +4406,6 @@ img.tile-debug { .flash-icon use { color: #222; } - -.flash-icon.operation use { - fill: #222; - color: #79f; -} .flash-icon.disabled use, .flash-icon.operation.disabled use { fill: rgba(32,32,32,0.7); @@ -4939,15 +4932,6 @@ img.tile-debug { color: #555; } -svg.mouseclick use.left { - fill: rgba(112, 146, 255, 1); - color: rgba(112, 146, 255, 0); -} -svg.mouseclick use.right { - fill: rgba(112, 146, 255, 0); - color: rgba(112, 146, 255, 1); -} - .modal-shortcuts .shortcut-keys .gesture { color: #333; padding: 3px; @@ -5414,15 +5398,8 @@ li.hide + li.version .badge .tooltip .popover-arrow { } .edit-menu-item use { - fill: #222; - color: #79f; pointer-events: none; } -.edit-menu-item.disabled use { - fill: rgba(32,32,32,.2); - color: rgba(40,40,40,.2); -} - /* Lasso ------------------------------------------------------- */ diff --git a/data/core.yaml b/data/core.yaml index 68d1642ea7..80d36ba07e 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -475,9 +475,11 @@ en: select_from_name: "Click to select {from} {fromName}" toggle: "Click for \"{turn}\"" undo: + title: Undo tooltip: "Undo: {action}" nothing: Nothing to undo. redo: + title: Redo tooltip: "Redo: {action}" nothing: Nothing to redo. tooltip_keyhint: "Shortcut:" @@ -608,10 +610,11 @@ en: view_on_keepRight: View on keepright.at feature_type: Feature Type fields: Fields - tags_count: "Tags ({count})" - members_count: "Members ({count})" - relations_count: "Relations ({count})" - features_count: "Features ({count})" + tags: Tags + members: Members + relations: Relations + features: Features + title_count: "{title} ({count})" add_to_relation: Add to a relation new_relation: New relation... choose_relation: Choose a parent relation @@ -1295,167 +1298,172 @@ en: open_data_h: "Open Data" open_data: "Edits that you make on this map will be visible to everyone who uses OpenStreetMap. Your edits can be based on personal knowledge, on-the-ground surveying, or imagery collected from aerial or street level photos. Copying from commercial sources, like Google Maps, [is strictly forbidden](https://www.openstreetmap.org/copyright)." before_start_h: "Before you start" - before_start: "You should be familiar with OpenStreetMap and this editor before you start editing. iD contains a walkthrough to teach you the basics of editing OpenStreetMap. Click \"Start the Walkthrough\" on this screen to take the tutorial - it takes only about 15 minutes." + before_start: "You should be familiar with OpenStreetMap and this editor before you start editing. iD contains a walkthrough to teach you the basics of editing OpenStreetMap. Press the \"{start_the_walkthrough}\" button on this screen to start the tutorial—it takes only about 15 minutes." open_source_h: "Open Source" open_source: "The iD editor is a collaborative open source project, and you are using version {version} now. The source code is available [on GitHub](https://github.com/openstreetmap/iD)." open_source_help: "You can help iD by [translating](https://github.com/openstreetmap/iD/blob/develop/CONTRIBUTING.md#translating) or [reporting bugs](https://github.com/openstreetmap/iD/issues)." overview: title: Overview navigation_h: "Navigation" - navigation_drag: "You can drag the map by pressing and holding down the {leftclick} left mouse button and moving the mouse around. You can also use the `↓`, `↑`, `←`, `→` arrow keys on your keyboard." - navigation_zoom: "You can zoom in or out by scrolling with the mouse wheel or trackpad, or by clicking the {plus} / {minus} buttons along the side of the map. You can also use the `+`, `-` keys on your keyboard." + navigation_drag: "You can drag the map by holding down the {leftclick} left mouse button and moving the mouse around, or by {touchdrag_icon} dragging on a touchscreen. You can also use the `↓`, `↑`, `←`, `→` arrow keys on a keyboard." + navigation_zoom: "You can zoom in or out by scrolling with a {mousewheel_icon} mouse wheel or trackpad, or by {pinch_icon} pinching with two fingers on a touchscreen. You can also press the {plus} / {minus} buttons along the side of the map or the `+`, `-` keys on a keyboard." features_h: "Map Features" features: "We use the word *features* to describe things that appear on the map, such as roads, buildings, or points of interest. Anything in the real world can be mapped as a feature on OpenStreetMap. Map features are represented on the map using *points*, *lines*, or *areas*." nodes_ways: "In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*." editing: title: "Editing & Saving" select_h: "Select" - select_left_click: "{leftclick} Left-click on a feature to select it. This will highlight it with a pulsing glow, and the sidebar will display details about that feature, such as its name or address." - select_right_click: "{rightclick} Right-click on a feature to display the editing menu, which shows the commands that are available, such as rotating, moving, and deleting." + select_left_click: "{leftclick} Left-click or {tap_icon} tap a feature to select it. This will highlight it with a pulsing glow and display further details about it in the sidebar." + select_right_click: "{rightclick} Right-click or {longpress_icon} long-press a feature to display the edit menu, which provides commands such as copy, rotate, and delete." + select_space: "The `{space}` key can also be used instead of left-click when selecting and drawing." multiselect_h: "Multiselect" - multiselect_shift_click: "`{shift}`+{leftclick} left-click to select several features together. This makes it easier to move or delete multiple items." + multiselect: "Selecting multiple features together lets you quickly edit them all at once." + multiselect_shift_click: "With a mouse and keyboard, hold `{shift}` and {leftclick} left-click features to add them to the selection. On a touchscreen, {longpress_icon} tap-and-hold one feature while {tap_icon} tapping additional features with another finger." multiselect_lasso: "Another way to select multiple features is to hold down the `{shift}` key, then press and hold down the {leftclick} left mouse button and drag the mouse to draw a selection lasso. All of the points inside the lasso area will be selected." undo_redo_h: "Undo & Redo" - undo_redo: "Your edits are stored locally in your browser until you choose to save them to the OpenStreetMap server. You can undo edits by clicking the {undo} **Undo** button, and redo them by clicking the {redo} **Redo** button." + undo_redo: "Your edits are stored locally in your browser until you choose to save them to the OpenStreetMap server. You can undo edits by pressing the {undo_icon} **{undo}** button, and redo them by pressing the {redo_icon} **{redo}** button." save_h: "Save" - save: "Click {save} **Save** to finish your edits and send them to OpenStreetMap. You should remember to save your work frequently!" + save: "Press the {save_icon} **{save}** button to finish your edits and send them to OpenStreetMap. You should remember to save your work frequently!" save_validation: "On the save screen, you'll have a chance to review what you've done. iD will also perform some basic checks for missing data and may offer helpful suggestions and warnings if something doesn't seem right." upload_h: "Upload" - upload: "Before uploading your changes you must enter a [changeset comment](https://wiki.openstreetmap.org/wiki/Good_changeset_comments). Then click **Upload** to send your changes to OpenStreetMap, where they will be merged into the map and publicly visible to everyone." + upload: "Before uploading your changes you must enter a [changeset comment](https://wiki.openstreetmap.org/wiki/Good_changeset_comments). Then press **{upload}** to send your changes to OpenStreetMap, where they will be merged into the map and publicly visible to everyone." backups_h: "Automatic Backups" - backups: "If you can't finish your edits in one sitting, for example if your computer crashes or you close the browser tab, your edits are still saved in your browser's storage. You can come back later (on the same browser and computer), and iD will offer to restore your work." + backups: "If you happen to close the browser before saving, your edits are still stored locally. iD will offer to restore your work when you come back later on the same browser and device." keyboard_h: "Keyboard Shortcuts" - keyboard: "You can view a list of keyboard shortcuts by pressing the `?` key." + keyboard: "You can view a list of keyboard shortcuts by pressing the `{shortcuts_key}` key." feature_editor: title: Feature Editor intro: "The *feature editor* appears alongside the map, and allows you to see and edit all of the information for the selected feature." definitions: "The top section displays the feature's type. The middle section contains *fields* showing the feature's attributes, such as its name or address." type_h: "Feature Type" - type: "You can click on the feature type to change the feature to a different type. Everything that exists in the real world can be added to OpenStreetMap, so there are thousands of feature types to choose from." - type_picker: "The type picker displays the most common feature types, such as parks, hospitals, restaurants, roads, and buildings. You can search for anything by typing what you're looking for in the search box. You can also click the {inspect} **Info** icon next to the feature type to learn more about it." + type: "You can press the feature type to change the feature to a different type. Everything that exists in the real world can be added to OpenStreetMap, so there are thousands of feature types to choose from." + type_picker: "The type picker displays the most common feature types, such as parks, hospitals, restaurants, roads, and buildings. You can search for anything by typing what you're looking for in the search box. You can also press the {inspect} **Info** icon next to the feature type to learn more about it." fields_h: "Fields" - fields_all_fields: "The \"Fields\" section contains all of the feature's details that you may edit. In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure." + fields_all_fields: "The \"{fields}\" section contains all of the feature's details that you may edit. In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure." fields_example: "Each feature type will display different fields. For example, a road may display fields for its surface and speed limit, but a restaurant may display fields for the type of food it serves and the hours it is open." - fields_add_field: "You can also click the \"Add field\" dropdown to add more fields, such as a description, Wikipedia link, wheelchair access, and more." + fields_add_field: "You can also use the \"Add field\" dropdown to add more fields, such as a description, Wikipedia link, wheelchair access, and more." tags_h: "Tags" - tags_all_tags: "Below the fields section, you can expand the \"Tags\" section to edit any of the OpenStreetMap *tags* for the selected feature. Each tag consists of a *key* and *value*, data elements that define all of the features stored in OpenStreetMap." + tags_all_tags: "Below the fields section, you can expand the \"{tags}\" section to edit any of the OpenStreetMap *tags* for the selected feature. Each tag consists of a *key* and *value*, data elements that define all of the features stored in OpenStreetMap." tags_resources: "Editing a feature's tags requires intermediate knowledge about OpenStreetMap. You should consult resources like the [OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Main_Page) or [Taginfo](https://taginfo.openstreetmap.org/) to learn more about accepted OpenStreetMap tagging practices." points: title: Points intro: "*Points* can be used to represent features such as shops, restaurants, and monuments. They mark a specific location, and describe what's there." add_point_h: "Adding Points" - add_point: "To add a point, click the {point} **Point** button on the toolbar above the map, or press the shortcut key `1`. This will change the mouse cursor to a cross symbol." - add_point_finish: "To place the new point on the map, position the mouse cursor where the point should go, then {leftclick} left-click or press `Space`." + add_point: "To add a point, press the {point_icon} **{point}** button on the toolbar above the map, or press the shortcut key `1`." + add_point_finish: "Next, place the new point on the map. With a mouse, position the cursor where the point should go and {leftclick} left-click. On a touchscreen, {tap_icon} tap the location." move_point_h: "Moving Points" - move_point: "To move a point, place the mouse cursor over the point, then press and hold the {leftclick} left mouse button while dragging the point to its new location." + move_point: "To move a point, {leftclick} left-click and drag it with a mouse or {touchdrag_icon} tap-and-drag it on a touchscreen." delete_point_h: "Deleting Points" delete_point: "It's OK to delete features that don't exist in the real world. Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it." - delete_point_command: "To delete a point, {rightclick} right-click on the point to select it and show the edit menu, then use the {delete} **Delete** command." + delete_point_command: "To delete a point, {rightclick} right-click or {longpress_icon} long-press the point to show the edit menu, then use the {delete_icon} **{delete}** command." lines: title: Lines intro: "*Lines* are used to represent features such as roads, railroads, and rivers. Lines should be drawn down the center of the feature that they represent." add_line_h: "Adding Lines" - add_line: "To add a line, click the {line} **Line** button on the toolbar above the map, or press the shortcut key `2`. This will change the mouse cursor to a cross symbol." - add_line_draw: "Next, position the mouse cursor where the line should begin and {leftclick} left-click or press `Space` to begin placing nodes along the line. Continue placing more nodes by clicking or pressing `Space`. While drawing, you can zoom in or drag the map in order to add more detail." - add_line_finish: "To finish a line, press `{return}` or click again on the last node." + add_line: "To add a line, press the {line_icon} **{line}** button on the toolbar above the map, or press the shortcut key `2`." + add_line_draw: "Next, mark the line's starting location. With a mouse, position the cursor where the line should begin and {leftclick} left-click to place a node. On a touchscreen, {tap_icon} tap the location." + add_line_continue: "Continue placing nodes by {leftclick} clicking or {tap_icon} tapping along the shape of the line. While drawing, you can zoom in or drag the map in order to add more detail." + add_line_finish: "To finish a line, click or tap on the last node again or press `{return}`." modify_line_h: "Modifying Lines" - modify_line_dragnode: "Often you'll see lines that aren't shaped correctly, for example a road that does not match up with the background imagery. To adjust the shape of a line, first {leftclick} left-click to select it. All nodes of the line will be drawn as small circles. You can then drag the nodes to better locations." - modify_line_addnode: "You can also create new nodes along a line either by {leftclick}**x2** double-clicking on the line or by dragging the small triangles at the midpoints between nodes." + modify_line_dragnode: "Often you'll see lines that aren't shaped correctly, for example a road that does not match up with the background imagery. To adjust the shape of a line, first select it. All nodes of the line will be drawn as small circles. You can then drag the nodes to better locations." + modify_line_addnode: "You can also create new nodes along a line by {leftclick}**x2** double-clicking or {doubletap_icon} double-tapping the line, or by dragging the small triangles at the midpoints between nodes." connect_line_h: "Connecting Lines" connect_line: "Having roads connected properly is important for the map and essential for providing driving directions." connect_line_display: "The connections between roads are drawn with gray circles. The endpoints of a line are drawn with larger white circles if they don't connect to anything." connect_line_drag: "To connect a line to another feature, drag one of the line's nodes onto the other feature until both features snap together. Tip: You can hold down the `{alt}` key to prevent nodes from connecting to other features." connect_line_tag: "If you know that the connection has traffic lights or crosswalks, you can add them by selecting the connecting node and using the feature editor to select the correct feature's type." disconnect_line_h: "Disconnecting Lines" - disconnect_line_command: "To disconnect a road from another feature, {rightclick} right-click the connecting node and select the {disconnect} **Disconnect** command from the editing menu." + disconnect_line_command: "To disconnect a road from another feature, {rightclick} right-click or {longpress_icon} long-press the connecting node and select the {disconnect_icon} **{disconnect}** command from the edit menu." move_line_h: "Moving Lines" - move_line_command: "To move an entire line, {rightclick} right-click the line and select the {move} **Move** command from the editing menu. Then move the mouse, and {leftclick} left-click to place the line in a new location." + move_line_command: "To move an entire line, {rightclick} right-click the line and select the {move_icon} **{move}** command from the edit menu. Then move the mouse, and {leftclick} left-click to place the line in a new location." move_line_connected: "Lines that are connected to other features will stay connected as you move the line to a new location. iD may prevent you from moving a line across another connected line." delete_line_h: "Deleting Lines" delete_line: "If a line is entirely incorrect, for example a road that doesn't exist in the real world, it's OK to delete it. Be careful when deleting features: the background imagery you are using might be outdated, and a road that looks wrong could simply be newly built." - delete_line_command: "To delete a line, {rightclick} right-click on the line to select it and show the edit menu, then use the {delete} **Delete** command." + delete_line_command: "To delete a line, {rightclick} right-click or {longpress_icon} long-press the line to show the edit menu, then use the {delete_icon} **{delete}** command." areas: title: Areas intro: "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas. Areas should be traced around the edge of the feature that they represent, for example, around the base of a building." point_or_area_h: "Points or Areas?" point_or_area: "Many features can be represented as points or areas. You should map buildings and property outlines as areas whenever possible. Place points inside a building area to represent businesses, amenities, and other features located inside the building." add_area_h: "Adding Areas" - add_area_command: "To add an area, click the {area} **Area** button on the toolbar above the map, or press the shortcut key `3`. This will change the mouse cursor to a cross symbol." - add_area_draw: "Next, position the mouse cursor at one of the corners of the feature and {leftclick} left-click or press `Space` to begin placing nodes around the outer edge of the area. Continue placing more nodes by clicking or pressing `Space`. While drawing, you can zoom in or drag the map in order to add more detail." - add_area_finish: "To finish an area, press `{return}` or click again on either the first or last node." + add_area_command: "To add an area, press the {area_icon} **{area}** button on the toolbar above the map, or press the shortcut key `3`." + add_area_draw: "Next, place the first corner of the area. With a mouse, position the cursor over any corner and {leftclick} left-click to place a node. On a touchscreen, {tap_icon} tap the location." + add_area_continue: "Continue placing nodes by {leftclick} clicking or {tap_icon} tapping along the edge of the area. While drawing, you can zoom in or drag the map in order to add more detail." + add_area_finish: "To finish an area, click or tap on the first or last node again or press `{return}`." square_area_h: "Square Corners" - square_area_command: "Many area features like buildings have square corners. To square the corners of an area, {rightclick} right-click the edge of the area and select the {orthogonalize} **Square** command from the editing menu." + square_area_command: "Many area features like buildings have square corners. To square the corners of an area, {rightclick} right-click or {longpress_icon} long-press the edge of the area and select the {orthogonalize_icon} **{orthogonalize}** command from the edit menu." modify_area_h: "Modifying Areas" - modify_area_dragnode: "Often you'll see areas that aren't shaped correctly, for example a building that does not match up with the background imagery. To adjust the shape of an area, first {leftclick} left-click to select it. All nodes of the area will be drawn as small circles. You can then drag the nodes to better locations." - modify_area_addnode: "You can also create new nodes along an area either by {leftclick}**x2** double-clicking on the edge of the area or by dragging the small triangles at the midpoints between nodes." + modify_area_dragnode: "Often you'll see areas that aren't shaped correctly, for example a building that does not match up with the background imagery. To adjust the shape of an area, first select it. All nodes of the area will be drawn as small circles. You can then drag the nodes to better locations." + modify_area_addnode: "You can also create new nodes along an area by {leftclick}**x2** double-clicking or {doubletap_icon} double-tapping an edge, or by dragging the small triangles at the midpoints between nodes." delete_area_h: "Deleting Areas" delete_area: "If an area is entirely incorrect, for example a building that doesn't exist in the real world, it's OK to delete it. Be cautious when deleting features - the background imagery you are using might be outdated, and a building that looks wrong could simply be newly built." - delete_area_command: "To delete an area, {rightclick} right-click on the area to select it and show the edit menu, then use the {delete} **Delete** command." + delete_area_command: "To delete an area, {rightclick} right-click or {longpress_icon} long-press the area to show the edit menu, then use the {delete_icon} **{delete}** command." relations: title: Relations intro: "A *relation* is a special type of feature in OpenStreetMap that groups together other features. The features that belong to a relation are called *members*, and each member can have a *role* in the relation." edit_relation_h: "Editing Relations" - edit_relation: "At the bottom of the feature editor, you can expand the \"Relations\" section to see if the selected feature is a member of any relations. You can then click on the relation to select and edit it." - edit_relation_add: "To add a feature to a relation, select the feature, then click the {plus} add button in the \"Relations\" section of the feature editor. You can choose from a list of nearby relations, or choose the \"New relation...\" option." - edit_relation_delete: "You can also click the {delete} **Delete** button to remove the selected feature from the relation. If you remove all of the members from a relation, the relation will be deleted automatically." + edit_relation: "At the bottom of the feature editor, you can expand the \"{relations}\" section to see if the selected feature is a member of any relations. You can then select a relation to edit it." + edit_relation_add: "To add a feature to a relation, select the feature, then press the {plus} add button in the \"{relations}\" section of the feature editor. You can choose from a list of nearby relations, or choose the \"{new_relation}\" option." + edit_relation_delete: "You can also press the {delete_icon} **{delete}** button to remove the selected feature from the relation. If you remove all of the members from a relation, the relation will be deleted automatically." maintain_relation_h: "Maintaining Relations" maintain_relation: "For the most part, iD will maintain relations automatically as you edit. You should take care when replacing features that might be members of relations. For example if you delete a section of road and draw a new section of road to replace it, you should add the new section to the same relations (routes, turn restrictions, etc.) as the original." relation_types_h: "Relation Types" multipolygon_h: "Multipolygons" multipolygon: "A *multipolygon* relation is a group of one or more *outer* features and one or more inner features. The outer features define the outer edges of the multipolygon, and the inner features define sub-areas or holes cut out from the inside of the multipolygon." - multipolygon_create: "To create a multipolygon, for example a building with a hole in it, draw the outer edge as an area and the inner edge as a line or different kind of area. Then `{shift}`+{leftclick} left-click to select both features, {rightclick} right-click to show the edit menu, and select the {merge} **Merge** command." + multipolygon_create: "To create a multipolygon, for example a building with a hole in it, draw the outer edge as an area and the inner edge as a line or different kind of area. Then `{shift}`+{leftclick} left-click to select both features, {rightclick} right-click to show the edit menu, and select the {merge_icon} **{merge}** command." multipolygon_merge: "Merging several lines or areas will create a new multipolygon relation with all selected areas as members. iD will choose the inner and outer roles automatically, based on which features are contained inside other features." turn_restriction_h: "Turn restrictions" turn_restriction: "A *turn restriction* relation is a group of several road segments in an intersection. Turn restrictions consist of a *from* road, *via* node or roads, and a *to* road." - turn_restriction_field: "To edit turn restrictions, select a junction node where two or more roads meet. The feature editor will display a special \"Turn Restrictions\" field containing a model of the intersection." - turn_restriction_editing: "In the \"Turn Restrictions\" field, click to select a \"from\" road, and see whether turns are allowed or restricted to any of the \"to\" roads. You can click on the turn icons to toggle them between allowed and restricted. iD will create relations automatically and set the from, via, and to roles based on your choices." + turn_restriction_field: "To edit turn restrictions, select a junction node where two or more roads meet. The feature editor will display a special \"{turn_restrictions}\" field containing a model of the intersection." + turn_restriction_editing: "In the \"{turn_restrictions}\" field, select a \"from\" road, and see whether turns are allowed or restricted to any of the \"to\" roads. You can press the turn icons to toggle them between allowed and restricted. iD will create relations automatically and set the from, via, and to roles based on your choices." route_h: "Routes" route: "A *route* relation is a group of one or more line features that together form a route network, like a bus route, train route, or highway route." - route_add: "To add a feature to a route relation, select the feature and scroll down to the \"Relations\" section of the feature editor, then click the {plus} add button to add this feature to a nearby existing relation or a new relation." + route_add: "To add a feature to a route relation, select the feature and scroll down to the \"{relations}\" section of the feature editor, then press the {plus} add button to add this feature to a nearby existing relation or a new relation." boundary_h: "Boundaries" boundary: "A *boundary* relation is a group of one or more line features that together form an administrative boundary." - boundary_add: "To add a feature to a boundary relation, select the feature and scroll down to the \"Relations\" section of the feature editor, then click the {plus} add button to add this feature to a nearby existing relation or a new relation." + boundary_add: "To add a feature to a boundary relation, select the feature and scroll down to the \"{relations}\" section of the feature editor, then press the {plus} add button to add this feature to a nearby existing relation or a new relation." notes: title: Notes - intro: "*Notes* are used to alert other users that a feature requires fixing or attention. Notes mark a specific location on the map. To view existing notes or add new ones, click the {data} **Map data** panel to enable the OpenStreetMap notes layer." + intro: "*Notes* are used to alert other users that a feature requires fixing or attention. Notes mark a specific location on the map. To view existing notes or add new ones, open the {data_icon} **{map_data}** panel and enable the {osm_notes} layer." add_note_h: "Adding Notes" - add_note: "To add a new note, click the {note} **Note** button on the toolbar above the map, or press the shortcut key `4`. This will change the mouse cursor to a cross symbol. To place the new note on the map, position the mouse cursor where the note should go, then {leftclick} left-click or press `Space`." - move_note: "Only new notes can be moved. To move a note, place the mouse cursor over the new note, then press and hold the {leftclick} left mouse button while dragging the note to its new location." + add_note: "To add a new note, press the {note_icon} **{note}** button on the toolbar above the map, or press the shortcut key `{add_note_key}`." + place_note: "Next, place the new note on the map. With a mouse, position the cursor where the note should go and {leftclick} left-click. On a touchscreen, {tap_icon} tap the location." + move_note: "To move a note, {leftclick} left-click and drag it with a mouse or {touchdrag_icon} tap-and-drag it on a touchscreen. Only new notes can be moved." update_note_h: "Closing, Reopening, and Commenting" update_note: "An existing note can be updated by closing it, reopening it, or adding a comment to it. Closing a note indicates that the problem has been resolved. Reopening a note indicates that the original issue is not resolved." save_note_h: "Saving Notes" - save_note: "You must save any note edits individually by clicking the buttons below the note comments. Note edits are **not** included in changesets that you upload to OpenStreetMap." + save_note: "You must save any note edits individually by pressing the buttons below the note comments. Note edits are **not** included in changesets that you upload to OpenStreetMap." imagery: title: Background Imagery intro: "The background imagery that appears beneath the map data is an important resource for mapping. This imagery can be aerial photos collected from satellites, airplanes, and drones, or it can be scanned historical maps or other freely available source data." sources_h: "Imagery Sources" - choosing: "To see which imagery sources are available for editing, click the {layers} **Background Settings** button on the side of the map." + choosing: "To see which imagery sources are available for editing, open the {layers_icon} **{background_settings}** panel on the side of the map." sources: "By default, a [Bing Maps](https://www.bing.com/maps/) satellite layer is chosen as the background image. Depending on where you are editing, other imagery sources will be available. Some may be newer or have higher resolution, so it is always useful to check and see which layer is the best one to use as a mapping reference." offsets_h: "Adjusting Imagery Offset" - offset: "Imagery is sometimes offset slightly from accurate map data. If you see a lot of roads or buildings shifted from the background imagery, it may be the imagery that's incorrect, so don't move them all to match the background. Instead, you can adjust the background so that it matches the existing data by expanding the \"Imagery Offset\" section at the bottom of the Background Settings pane." - offset_change: "Click on the small triangles to adjust the imagery offset in small steps, or hold the {leftclick} left mouse button and drag within the gray square to slide the imagery into alignment." + offset: "Imagery is sometimes offset slightly from accurate map data. If you see a lot of roads or buildings shifted from the background imagery, it may be the imagery that's incorrect, so don't move them all to match the background. Instead, you can adjust the background so that it matches the existing data by expanding the \"{imagery_offset}\" section at the bottom of the Background Settings pane." + offset_change: "Press the small triangle buttons to adjust the imagery offset in small steps, or hold the {leftclick} left mouse button and drag within the gray square to slide the imagery into alignment." streetlevel: title: Street Level Photos intro: "Street level photos are useful for mapping traffic signs, businesses, and other details that you can't see from satellite and aerial images. The iD editor supports street level photos from [Bing Streetside](https://www.microsoft.com/en-us/maps/streetside), [Mapillary](https://www.mapillary.com), and [OpenStreetCam](https://www.openstreetcam.org)." using_h: "Using Street Level Photos" - using: "To use street level photos for mapping, click the {data} **Map data** panel on the side of the map to enable or disable the available photo layers." + using: "To use street level photos for mapping, open the {data_icon} **{map_data}** panel on the side of the map to enable or disable the available photo layers." photos: "When enabled, the photo layer displays a line along the sequence of photos. At higher zoom levels, a circle marks at each photo location, and at even higher zoom levels, a cone indicates the direction the camera was facing when the photo was taken." - viewer: "When you click on one of the photo locations, a photo viewer appears in the bottom corner of the map. The photo viewer contains controls to step forward and backward in the image sequence. It also shows the username of the person who captured the image, the date it was captured, and a link to view the image on the original site." + viewer: "When you select one of the photo locations, a photo viewer appears in the bottom corner of the map. The photo viewer contains controls to step forward and backward in the image sequence. It also shows the username of the person who captured the image, the date it was captured, and a link to view the image on the original site." gps: title: GPS Traces - intro: "Collected GPS traces are a valuable source of data for OpenStreetMap. This editor supports *.gpx*, *.geojson*, and *.kml* files on your local computer. You can collect GPS traces with a smartphone, sports watch, or other GPS device." + intro: "Collected GPS traces are a valuable source of data for OpenStreetMap. This editor supports *.gpx*, *.geojson*, and *.kml* files on your local device. You can collect GPS traces with a smartphone, sports watch, or other GPS device." survey: "For information on how to perform a GPS survey, read [Mapping with a smartphone, GPS, or paper](http://learnosm.org/en/mobile-mapping/)." using_h: "Using GPS Traces" - 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." + 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. Open the {data_icon} **{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." qa: title: Quality Assurance - intro: "*Quality Assurance* (Q/A) tools can find improper tags, disconnected roads, and other issues with OpenStreetMap, which mappers can then fix. To view existing Q/A issues, click the {data} **Map data** panel to enable a specific Q/A layer." + intro: "*Quality Assurance* (Q/A) tools can find improper tags, disconnected roads, and other issues with OpenStreetMap, which mappers can then fix. To view existing Q/A issues, open the {data_icon} **{map_data}** panel and enable a specific Q/A layer." tools_h: "Tools" tools: "The following tools are currently supported: [KeepRight](https://www.keepright.at/), [ImproveOSM](https://improveosm.org/en/) and [Osmose](https://osmose.openstreetmap.fr/)." issues_h: "Handling Issues" - issues: "Handling Q/A issues is similar to handling notes. Click on a marker to view the issue details in the sidebar. Each tool has its own capabilities, but generally you can comment and/or close an issue." + issues: "Handling Q/A issues is similar to handling notes. Select a marker to view the issue details in the sidebar. Each tool has its own capabilities, but generally you can comment and/or close an issue." field: restrictions: title: Turn Restrictions Help @@ -1928,110 +1936,148 @@ en: chapters: "You can use the buttons below to skip chapters at any time or to restart a chapter if you get stuck. Let's begin! **Press '{next}' to continue.**" navigation: title: "Navigation" - drag: "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag or tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" - zoom: "You can zoom in or out by scrolling with a mouse wheel, pinching on a touchscreen, or pressing the {plus} / {minus} buttons. **Zoom the map!**" + map_info: "The main map area shows OpenStreetMap data on top of a background." + drag: "You can click-and-drag the map with the {leftclick} left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" + drag_touch: "You can {touchdrag_icon} tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**" + zoom: "You can zoom the map by scrolling with a {mousewheel_icon} mouse wheel or trackpad, or by pressing the {plus} / {minus} buttons. **Zoom the map!**" + zoom_touch: "You can zoom the map by {pinch_icon} pinching it with two fingers, {doubletap_icon} double-tapping a location, or pressing the {plus} / {minus} buttons. **Zoom the map!**" features: "We use the word *features* to describe the things that appear on the map. Anything in the real world can be mapped as a feature on OpenStreetMap." points_lines_areas: "Map features are represented using *points, lines, or areas.*" nodes_ways: "In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*." - click_townhall: "All features on the map can be selected by clicking or tapping on them. **Select the point.**" + click_townhall: "All features on the map can be selected by {leftclick} clicking on them. **Click the point to select it.**" + tap_townhall: "All features on the map can be selected by {tap_icon} tapping on them. **Tap the point to select it.**" selected_townhall: "Great! The point is now selected. Selected features are drawn with a pulsing glow." editor_townhall: "When a feature is selected, the *feature editor* is displayed alongside the map." preset_townhall: "The top part of the feature editor shows the feature's type. This point is a {preset}." fields_townhall: "The middle part of the feature editor contains *fields* showing the feature's attributes, such as its name and address." - close_townhall: "**Close the feature editor by hitting escape or pressing the {button} button in the upper corner.**" + close_townhall: "**Close the feature editor by pressing the {button} button in the upper corner or `{esc}`.**" search_street: "You can also search for features in the current view, or worldwide. **Search for '{name}'.**" choose_street: "**Choose {name} from the list to select it.**" selected_street: "Great! {name} is now selected." - editor_street: "The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by hitting escape or pressing the {button} button.**" + street_different_fields: "The fields shown for a street are different than the fields that were shown for the town hall." + editor_street: "For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by pressing the {button} button or `{esc}`.**" play: "Try exploring the map and selecting some other features to see what kinds of things can be added to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" points: title: "Points" - add_point: "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**" - place_point: "To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**" + points_info: "*Points* can be used to represent features such as shops, restaurants, and monuments." + add_point: "They mark a specific location, and describe what's there. **Press the {point_icon} {point} button to add a new point.**" + place_point: "To place the new point on the map, position your mouse cursor where the point should go, then {leftclick} left-click or press `{space}`. **Move the mouse pointer over this building, then left-click or press `{space}`.**" + place_point_touch: "To place the new point on the map, {tap_icon} tap the location where it should go. **Tap the center of this building.**" search_cafe: "There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**" choose_cafe: "**Choose {preset} from the list.**" feature_editor: "The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe." - add_name: "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**" - add_close: "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or click the {button} button to close the feature editor.**" - reselect: "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Click to select the cafe you just created.**" + fields_info: "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure." + add_name: "Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**" + add_close: "The feature editor will remember all of your changes automatically. **When you are finished adding the name, press the {button} button or `{esc}` to close the feature editor.**" + reselect: "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Select the cafe you just created.**" update: "Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**" - update_close: "**When you are finished updating the cafe, hit escape, enter, or click the {button} button to close the feature editor.**" - rightclick: "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Right-click to select the point you created and show the edit menu.**" - delete: "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Click on the {button} button to delete the point.**" - undo: "You can always undo any changes up until you save your edits to OpenStreetMap. **Click on the {button} button to undo the delete and get the point back.**" - play: "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, click '{next}'.**" + update_close: "**When you are finished updating the cafe, press the {button} button or `{esc}` to close the feature editor.**" + rightclick: "You can {rightclick} right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click or two-finger click. **Right-click to select the point you created and show the edit menu.**" + edit_menu_touch: "You can {longpress_icon} long-press on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Press-and-hold the point you created to show the edit menu.**" + delete: "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {delete_icon} {delete} button to remove the point.**" + undo: "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {undo_icon} {undo} button to get the point back.**" + play: "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, press '{next}'.**" areas: title: "Areas" - add_playground: "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Click the {button} Area button to add a new area.**" - start_playground: "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**" - continue_playground: "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**" - finish_playground: "Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**" + add_playground: "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {area_icon} {area} button to add a new area.**" + start_playground: "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature." + starting_node_click: "**Click or press `{space}` to place a starting node on one of the corners of the playground.**" + starting_node_tap: "**{tap_icon} Tap to place a starting node on one of the corners of the playground.**" + continue_playground: "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the `{alt}` key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**" + finish_area_click: "Finish the area by pressing `{return}`, or clicking again on either the first or last node." + finish_area_tap: "Finish the area by {tap_icon} tapping again on either the first or last node, or by pressing `{return}` on a keyboard." + finish_playground: "**Finish drawing an area for the playground.**" search_playground: "**Search for '{preset}'.**" choose_playground: "**Choose {preset} from the list.**" - add_field: "This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**" + add_field: "This playground doesn't have an official name, so we won't add anything in the {name} field.{br}Instead let's add some additional details about the playground to the {description} field. **Open the Add Field list.**" choose_field: "**Choose {field} from the list.**" retry_add_field: "You didn't select the {field} field. Let's try again." - describe_playground: "**Add a description, then click the {button} button to close the feature editor.**" - play: "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**" + describe_playground: "**Add a description, then press the {button} button to close the feature editor.**" + play: "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" lines: title: "Lines" - add_line: "*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**" - start_line: "Here is a road that is missing. Let's add it!{br}In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary. **Start a new line by clicking at the top end of this missing road.**" - intersect: "Click or press spacebar to add more nodes to the line.{br}Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**" + add_line: "*Lines* are used to represent features such as roads, railroads, and rivers. **Press the {line_icon} {line} button to add a new line.**" + missing_road: "Here is a road that is missing. Let's add it!" + line_draw_info: "In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary." + start_line: "**Start a new line by clicking at the top end of this missing road.**" + start_line_tap: "**Start a new line by {tap_icon} tapping at the top end of this missing road.**" + intersect: "Continue drawing the line by placing more nodes along the road.{br}Roads, along with paths and ferry routes, must be properly connected to each other for navigation apps to work. **Place an intersection node on {name} to connect the two lines.**" retry_intersect: "The road needs to intersect {name}. Let's try again!" - continue_line: "Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed.{br}When you are finished drawing, click on the last node again. **Finish drawing the road.**" + continue_line: "Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed." + finish_line_click: "When you're finished, click the last node again or press `{return}`." + finish_line_tap: "When you're finished, {tap_icon} tap the last node again or press `{return}` on a keyboard." + finish_road: "**Finish drawing the road.**" choose_category_road: "**Select {category} from the list.**" choose_preset_residential: "There are many different types of roads, but this one is a residential road. **Choose the {preset} type.**" - retry_preset_residential: "You didn't select the {preset} type. **Click here to choose again.**" - name_road: "**Give this road a name, then hit escape, enter, or click the {button} button to close the feature editor.**" + retry_preset_residential: "You didn't select the {preset} type. **Press this button to choose again.**" + name_road: "**Give this road a name, then press the {button} button or `{esc}` to close the feature editor.**" did_name_road: "Looks good! Next we will learn how to update the shape of a line." update_line: "Sometimes you will need to change the shape of an existing line. Here is a road that doesn't look quite right." add_node: "We can add some nodes to this line to improve its shape. One way to add a node is to double-click the line where you want to add a node. **Double-click on the line to create a new node.**" - start_drag_endpoint: "When a line is selected, you can drag any of its nodes by clicking and holding down the left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**" - finish_drag_endpoint: "This spot looks good. **Release the left mouse button to finish dragging.**" + add_node_touch: "We can add some nodes to this line to improve its shape. One way to add a node is to {doubletap_icon} double-tap the line where you want to add a node. **Double-tap on the line to create a new node.**" + start_drag_endpoint: "When a line is selected, you can adjust any of its nodes by clicking and holding down the {leftclick} left mouse button while you drag." + start_drag_endpoint_touch: "When a line is selected, you can {touchdrag_icon} tap-and-drag any of its nodes to adjust them." + drag_to_intersection: "**Drag the endpoint to the place where these roads should intersect.**" + spot_looks_good: "This spot looks good." + finish_drag_endpoint: "**Release the mouse button to finish dragging.**" + finish_drag_endpoint_touch: "**Let go of the node to finish dragging.**" start_drag_midpoint: "Small triangles are drawn at the *midpoints* between nodes. Another way to create a new node is to drag a midpoint to a new location. **Drag the midpoint triangle to create a new node along the curve of the road.**" - continue_drag_midpoint: "This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click OK.**" + continue_drag_midpoint: "This line is looking much better! Continue to adjust this line until the curve matches the road shape. **When you're happy with how the line looks, press {ok}.**" delete_lines: "It's OK to delete lines for roads that don't exist in the real world.{br}Here's an example where the city planned a {street} but never built it. We can improve this part of the map by deleting the extra lines." - rightclick_intersection: "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **Right click on the intersection node.**" - split_intersection: "**Click on the {button} button to split {street}.**" - retry_split: "You didn't click the Split button. Try again." - did_split_multi: "Good job! {street1} is now split into two pieces. The top part can be removed. **Click the top part of {street2} to select it.**" - did_split_single: "**Click the top part of {street2} to select it.**" - multi_select: "{selected} is now selected. Let's also select {other1}. You can shift-click to select multiple things. **Shift-click on {other2}.**" - multi_rightclick: "Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**" - multi_delete: "**Click on the {button} button to delete the extra lines.**" - retry_delete: "You didn't click the Delete button. Try again." - play: "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, click '{next}'.**" + split_street: "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it." + rightclick_intersection: "**{rightclick} Right-click on the intersection node.**" + edit_menu_intersection_touch: "**{longpress_icon} Long-press on the intersection node.**" + split_intersection: "**Press the {split_icon} {split} button to divide {street}.**" + retry_split: "You didn't press the {split_icon} {split} button. Try again." + did_split_multi: "Good job! {street1} is now split into two pieces. The top part can be removed. **Select the top part of {street2}.**" + did_split_single: "**Select the top part of {street2}.**" + multi_select: "{selected} is now selected. Let's also select {other1}." + add_to_selection_click: "You can hold `{shift}` while clicking to select multiple things. **Shift-click on {other2}.**" + add_to_selection_touch: "**{longpress_icon} Tap-and-hold {selected} and then {tap_icon} tap {other2} with another finger to select both.**" + multi_select_success: "Good! Both lines to delete are now selected." + multi_rightclick: "**{rightclick} Right-click on one of the lines to show the edit menu.**" + multi_edit_menu_touch: "**{longpress_icon} Long-press on one of the lines to show the edit menu.**" + multi_delete: "**Press the {delete_icon} {delete} button to remove the extra lines.**" + retry_delete: "You didn't press the {delete_icon} {delete} button. Try again." + play: "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, press '{next}'.**" buildings: title: "Buildings" - add_building: "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**" - start_building: "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**" - continue_building: "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**" + add_building: "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {area_icon} {area} button to add a new area.**" + start_building: "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible." + building_corner_click: "**Click or press `{space}` to place a starting node on one of the corners of the building.**" + building_corner_tap: "**{tap_icon} Tap one of the corners of the building to place a starting node.**" + continue_building: "Continue placing nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details." + finish_building: "**Finish tracing the building.**" retry_building: "It looks like you had some trouble placing the nodes at the building corners. Try again!" choose_category_building: "**Choose {category} from the list.**" choose_preset_house: "There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**" - close: "**Hit escape or click the {button} button to close the feature editor.**" - rightclick_building: "**Right-click to select the building you created and show the edit menu.**" - square_building: "The house that you just added will look even better with perfectly square corners. **Click on the {button} button to square the building shape.**" - retry_square: "You didn't click the Square button. Try again." + close: "**Press the {button} button or `{esc}` to close the feature editor.**" + rightclick_building: "**{rightclick} Right-click to select the building you created and show the edit menu.**" + edit_menu_building_touch: "**{longpress_icon} Long-press the building you created to show the edit menu.**" + square_building: "The house that you just added will look even better with perfectly square corners. **Press the {orthogonalize_icon} {orthogonalize} button to tidy up the building's shape.**" + retry_square: "You didn't press the {orthogonalize_icon} {orthogonalize} button. Try again." done_square: "See how the corners of the building moved into place? Let's learn another useful trick." - add_tank: "Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**" - start_tank: "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**" - continue_tank: "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**" + add_tank: "Next we'll trace this circular storage tank. **Press the {area_icon} {area} button to add a new area.**" + start_tank: "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge." + tank_edge_click: "**Click or press `{space}` to place a starting node on the edge of the tank.**" + tank_edge_tap: "**{tap_icon} Tap the edge of the tank to place a starting node.**" + continue_tank: "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw." + finish_tank: "**Finish tracing the tank.**" search_tank: "**Search for '{preset}'.**" choose_tank: "**Choose {preset} from the list.**" - rightclick_tank: "**Right-click to select the storage tank you created and show the edit menu.**" - circle_tank: "**Click on the {button} button to make the tank a circle.**" - retry_circle: "You didn't click the Circularize button. Try again." - play: "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, click '{next}'.**" + rightclick_tank: "**{rightclick} Right-click to select the storage tank you created and show the edit menu.**" + edit_menu_tank_touch: "**{longpress_icon} Long-press the storage tank you created to show the edit menu.**" + circle_tank: "**Press the {circularize_icon} {circularize} button to make the tank a circle.**" + retry_circle: "You didn't press the {circularize_icon} {circularize} button. Try again." + play: "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, press '{next}'.**" startediting: title: "Start Editing" - help: "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by clicking the {button} Help button or pressing the '{key}' key." - shortcuts: "You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key." + help: "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {help_icon} {help} button or the `{help_key}` key." + shortcuts: "You can view a list of commands along with their keyboard shortcuts by pressing the `{shortcuts_key}` key." save: "Don't forget to regularly save your changes!" start: "Start mapping!" shortcuts: - title: "Keyboard shortcuts" + title: "Keyboard Shortcuts" tooltip: "Show the keyboard shortcuts screen." toggle: key: '?' diff --git a/data/shortcuts.json b/data/shortcuts.json index 7620679d9f..c235a1e182 100644 --- a/data/shortcuts.json +++ b/data/shortcuts.json @@ -107,7 +107,7 @@ "text": "shortcuts.browsing.selecting.title" }, { - "shortcuts": ["Left-click", "shortcuts.key.space"], + "shortcuts": ["Left-click", "Tap", "shortcuts.key.space"], "text": "shortcuts.browsing.selecting.select_one" }, { @@ -131,7 +131,7 @@ "text": "shortcuts.browsing.with_selected.title" }, { - "shortcuts": ["Right-click", "☰"], + "shortcuts": ["Right-click", "Long-press", "☰"], "text": "shortcuts.browsing.with_selected.edit_menu" }, { @@ -193,7 +193,7 @@ "text": "shortcuts.editing.drawing.add_note" }, { - "shortcuts": ["Left-click", "shortcuts.key.space"], + "shortcuts": ["Left-click", "Tap", "shortcuts.key.space"], "text": "shortcuts.editing.drawing.place_point" }, { diff --git a/dist/locales/en.json b/dist/locales/en.json index 40a84851f4..2adb27e112 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -619,10 +619,12 @@ } }, "undo": { + "title": "Undo", "tooltip": "Undo: {action}", "nothing": "Nothing to undo." }, "redo": { + "title": "Redo", "tooltip": "Redo: {action}", "nothing": "Nothing to redo." }, @@ -770,10 +772,11 @@ "view_on_keepRight": "View on keepright.at", "feature_type": "Feature Type", "fields": "Fields", - "tags_count": "Tags ({count})", - "members_count": "Members ({count})", - "relations_count": "Relations ({count})", - "features_count": "Features ({count})", + "tags": "Tags", + "members": "Members", + "relations": "Relations", + "features": "Features", + "title_count": "{title} ({count})", "add_to_relation": "Add to a relation", "new_relation": "New relation...", "choose_relation": "Choose a parent relation", @@ -1629,7 +1632,7 @@ "open_data_h": "Open Data", "open_data": "Edits that you make on this map will be visible to everyone who uses OpenStreetMap. Your edits can be based on personal knowledge, on-the-ground surveying, or imagery collected from aerial or street level photos. Copying from commercial sources, like Google Maps, [is strictly forbidden](https://www.openstreetmap.org/copyright).", "before_start_h": "Before you start", - "before_start": "You should be familiar with OpenStreetMap and this editor before you start editing. iD contains a walkthrough to teach you the basics of editing OpenStreetMap. Click \"Start the Walkthrough\" on this screen to take the tutorial - it takes only about 15 minutes.", + "before_start": "You should be familiar with OpenStreetMap and this editor before you start editing. iD contains a walkthrough to teach you the basics of editing OpenStreetMap. Press the \"{start_the_walkthrough}\" button on this screen to start the tutorial—it takes only about 15 minutes.", "open_source_h": "Open Source", "open_source": "The iD editor is a collaborative open source project, and you are using version {version} now. The source code is available [on GitHub](https://github.com/openstreetmap/iD).", "open_source_help": "You can help iD by [translating](https://github.com/openstreetmap/iD/blob/develop/CONTRIBUTING.md#translating) or [reporting bugs](https://github.com/openstreetmap/iD/issues)." @@ -1637,8 +1640,8 @@ "overview": { "title": "Overview", "navigation_h": "Navigation", - "navigation_drag": "You can drag the map by pressing and holding down the {leftclick} left mouse button and moving the mouse around. You can also use the `↓`, `↑`, `←`, `→` arrow keys on your keyboard.", - "navigation_zoom": "You can zoom in or out by scrolling with the mouse wheel or trackpad, or by clicking the {plus} / {minus} buttons along the side of the map. You can also use the `+`, `-` keys on your keyboard.", + "navigation_drag": "You can drag the map by holding down the {leftclick} left mouse button and moving the mouse around, or by {touchdrag_icon} dragging on a touchscreen. You can also use the `↓`, `↑`, `←`, `→` arrow keys on a keyboard.", + "navigation_zoom": "You can zoom in or out by scrolling with a {mousewheel_icon} mouse wheel or trackpad, or by {pinch_icon} pinching with two fingers on a touchscreen. You can also press the {plus} / {minus} buttons along the side of the map or the `+`, `-` keys on a keyboard.", "features_h": "Map Features", "features": "We use the word *features* to describe things that appear on the map, such as roads, buildings, or points of interest. Anything in the real world can be mapped as a feature on OpenStreetMap. Map features are represented on the map using *points*, *lines*, or *areas*.", "nodes_ways": "In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*." @@ -1646,73 +1649,76 @@ "editing": { "title": "Editing & Saving", "select_h": "Select", - "select_left_click": "{leftclick} Left-click on a feature to select it. This will highlight it with a pulsing glow, and the sidebar will display details about that feature, such as its name or address.", - "select_right_click": "{rightclick} Right-click on a feature to display the editing menu, which shows the commands that are available, such as rotating, moving, and deleting.", + "select_left_click": "{leftclick} Left-click or {tap_icon} tap a feature to select it. This will highlight it with a pulsing glow and display further details about it in the sidebar.", + "select_right_click": "{rightclick} Right-click or {longpress_icon} long-press a feature to display the edit menu, which provides commands such as copy, rotate, and delete.", + "select_space": "The `{space}` key can also be used instead of left-click when selecting and drawing.", "multiselect_h": "Multiselect", - "multiselect_shift_click": "`{shift}`+{leftclick} left-click to select several features together. This makes it easier to move or delete multiple items.", + "multiselect": "Selecting multiple features together lets you quickly edit them all at once.", + "multiselect_shift_click": "With a mouse and keyboard, hold `{shift}` and {leftclick} left-click features to add them to the selection. On a touchscreen, {longpress_icon} tap-and-hold one feature while {tap_icon} tapping additional features with another finger.", "multiselect_lasso": "Another way to select multiple features is to hold down the `{shift}` key, then press and hold down the {leftclick} left mouse button and drag the mouse to draw a selection lasso. All of the points inside the lasso area will be selected.", "undo_redo_h": "Undo & Redo", - "undo_redo": "Your edits are stored locally in your browser until you choose to save them to the OpenStreetMap server. You can undo edits by clicking the {undo} **Undo** button, and redo them by clicking the {redo} **Redo** button.", + "undo_redo": "Your edits are stored locally in your browser until you choose to save them to the OpenStreetMap server. You can undo edits by pressing the {undo_icon} **{undo}** button, and redo them by pressing the {redo_icon} **{redo}** button.", "save_h": "Save", - "save": "Click {save} **Save** to finish your edits and send them to OpenStreetMap. You should remember to save your work frequently!", + "save": "Press the {save_icon} **{save}** button to finish your edits and send them to OpenStreetMap. You should remember to save your work frequently!", "save_validation": "On the save screen, you'll have a chance to review what you've done. iD will also perform some basic checks for missing data and may offer helpful suggestions and warnings if something doesn't seem right.", "upload_h": "Upload", - "upload": "Before uploading your changes you must enter a [changeset comment](https://wiki.openstreetmap.org/wiki/Good_changeset_comments). Then click **Upload** to send your changes to OpenStreetMap, where they will be merged into the map and publicly visible to everyone.", + "upload": "Before uploading your changes you must enter a [changeset comment](https://wiki.openstreetmap.org/wiki/Good_changeset_comments). Then press **{upload}** to send your changes to OpenStreetMap, where they will be merged into the map and publicly visible to everyone.", "backups_h": "Automatic Backups", - "backups": "If you can't finish your edits in one sitting, for example if your computer crashes or you close the browser tab, your edits are still saved in your browser's storage. You can come back later (on the same browser and computer), and iD will offer to restore your work.", + "backups": "If you happen to close the browser before saving, your edits are still stored locally. iD will offer to restore your work when you come back later on the same browser and device.", "keyboard_h": "Keyboard Shortcuts", - "keyboard": "You can view a list of keyboard shortcuts by pressing the `?` key." + "keyboard": "You can view a list of keyboard shortcuts by pressing the `{shortcuts_key}` key." }, "feature_editor": { "title": "Feature Editor", "intro": "The *feature editor* appears alongside the map, and allows you to see and edit all of the information for the selected feature.", "definitions": "The top section displays the feature's type. The middle section contains *fields* showing the feature's attributes, such as its name or address.", "type_h": "Feature Type", - "type": "You can click on the feature type to change the feature to a different type. Everything that exists in the real world can be added to OpenStreetMap, so there are thousands of feature types to choose from.", - "type_picker": "The type picker displays the most common feature types, such as parks, hospitals, restaurants, roads, and buildings. You can search for anything by typing what you're looking for in the search box. You can also click the {inspect} **Info** icon next to the feature type to learn more about it.", + "type": "You can press the feature type to change the feature to a different type. Everything that exists in the real world can be added to OpenStreetMap, so there are thousands of feature types to choose from.", + "type_picker": "The type picker displays the most common feature types, such as parks, hospitals, restaurants, roads, and buildings. You can search for anything by typing what you're looking for in the search box. You can also press the {inspect} **Info** icon next to the feature type to learn more about it.", "fields_h": "Fields", - "fields_all_fields": "The \"Fields\" section contains all of the feature's details that you may edit. In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.", + "fields_all_fields": "The \"{fields}\" section contains all of the feature's details that you may edit. In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.", "fields_example": "Each feature type will display different fields. For example, a road may display fields for its surface and speed limit, but a restaurant may display fields for the type of food it serves and the hours it is open.", - "fields_add_field": "You can also click the \"Add field\" dropdown to add more fields, such as a description, Wikipedia link, wheelchair access, and more.", + "fields_add_field": "You can also use the \"Add field\" dropdown to add more fields, such as a description, Wikipedia link, wheelchair access, and more.", "tags_h": "Tags", - "tags_all_tags": "Below the fields section, you can expand the \"Tags\" section to edit any of the OpenStreetMap *tags* for the selected feature. Each tag consists of a *key* and *value*, data elements that define all of the features stored in OpenStreetMap.", + "tags_all_tags": "Below the fields section, you can expand the \"{tags}\" section to edit any of the OpenStreetMap *tags* for the selected feature. Each tag consists of a *key* and *value*, data elements that define all of the features stored in OpenStreetMap.", "tags_resources": "Editing a feature's tags requires intermediate knowledge about OpenStreetMap. You should consult resources like the [OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Main_Page) or [Taginfo](https://taginfo.openstreetmap.org/) to learn more about accepted OpenStreetMap tagging practices." }, "points": { "title": "Points", "intro": "*Points* can be used to represent features such as shops, restaurants, and monuments. They mark a specific location, and describe what's there.", "add_point_h": "Adding Points", - "add_point": "To add a point, click the {point} **Point** button on the toolbar above the map, or press the shortcut key `1`. This will change the mouse cursor to a cross symbol.", - "add_point_finish": "To place the new point on the map, position the mouse cursor where the point should go, then {leftclick} left-click or press `Space`.", + "add_point": "To add a point, press the {point_icon} **{point}** button on the toolbar above the map, or press the shortcut key `1`.", + "add_point_finish": "Next, place the new point on the map. With a mouse, position the cursor where the point should go and {leftclick} left-click. On a touchscreen, {tap_icon} tap the location.", "move_point_h": "Moving Points", - "move_point": "To move a point, place the mouse cursor over the point, then press and hold the {leftclick} left mouse button while dragging the point to its new location.", + "move_point": "To move a point, {leftclick} left-click and drag it with a mouse or {touchdrag_icon} tap-and-drag it on a touchscreen.", "delete_point_h": "Deleting Points", "delete_point": "It's OK to delete features that don't exist in the real world. Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it.", - "delete_point_command": "To delete a point, {rightclick} right-click on the point to select it and show the edit menu, then use the {delete} **Delete** command." + "delete_point_command": "To delete a point, {rightclick} right-click or {longpress_icon} long-press the point to show the edit menu, then use the {delete_icon} **{delete}** command." }, "lines": { "title": "Lines", "intro": "*Lines* are used to represent features such as roads, railroads, and rivers. Lines should be drawn down the center of the feature that they represent.", "add_line_h": "Adding Lines", - "add_line": "To add a line, click the {line} **Line** button on the toolbar above the map, or press the shortcut key `2`. This will change the mouse cursor to a cross symbol.", - "add_line_draw": "Next, position the mouse cursor where the line should begin and {leftclick} left-click or press `Space` to begin placing nodes along the line. Continue placing more nodes by clicking or pressing `Space`. While drawing, you can zoom in or drag the map in order to add more detail.", - "add_line_finish": "To finish a line, press `{return}` or click again on the last node.", + "add_line": "To add a line, press the {line_icon} **{line}** button on the toolbar above the map, or press the shortcut key `2`.", + "add_line_draw": "Next, mark the line's starting location. With a mouse, position the cursor where the line should begin and {leftclick} left-click to place a node. On a touchscreen, {tap_icon} tap the location.", + "add_line_continue": "Continue placing nodes by {leftclick} clicking or {tap_icon} tapping along the shape of the line. While drawing, you can zoom in or drag the map in order to add more detail.", + "add_line_finish": "To finish a line, click or tap on the last node again or press `{return}`.", "modify_line_h": "Modifying Lines", - "modify_line_dragnode": "Often you'll see lines that aren't shaped correctly, for example a road that does not match up with the background imagery. To adjust the shape of a line, first {leftclick} left-click to select it. All nodes of the line will be drawn as small circles. You can then drag the nodes to better locations.", - "modify_line_addnode": "You can also create new nodes along a line either by {leftclick}**x2** double-clicking on the line or by dragging the small triangles at the midpoints between nodes.", + "modify_line_dragnode": "Often you'll see lines that aren't shaped correctly, for example a road that does not match up with the background imagery. To adjust the shape of a line, first select it. All nodes of the line will be drawn as small circles. You can then drag the nodes to better locations.", + "modify_line_addnode": "You can also create new nodes along a line by {leftclick}**x2** double-clicking or {doubletap_icon} double-tapping the line, or by dragging the small triangles at the midpoints between nodes.", "connect_line_h": "Connecting Lines", "connect_line": "Having roads connected properly is important for the map and essential for providing driving directions.", "connect_line_display": "The connections between roads are drawn with gray circles. The endpoints of a line are drawn with larger white circles if they don't connect to anything.", "connect_line_drag": "To connect a line to another feature, drag one of the line's nodes onto the other feature until both features snap together. Tip: You can hold down the `{alt}` key to prevent nodes from connecting to other features.", "connect_line_tag": "If you know that the connection has traffic lights or crosswalks, you can add them by selecting the connecting node and using the feature editor to select the correct feature's type.", "disconnect_line_h": "Disconnecting Lines", - "disconnect_line_command": "To disconnect a road from another feature, {rightclick} right-click the connecting node and select the {disconnect} **Disconnect** command from the editing menu.", + "disconnect_line_command": "To disconnect a road from another feature, {rightclick} right-click or {longpress_icon} long-press the connecting node and select the {disconnect_icon} **{disconnect}** command from the edit menu.", "move_line_h": "Moving Lines", - "move_line_command": "To move an entire line, {rightclick} right-click the line and select the {move} **Move** command from the editing menu. Then move the mouse, and {leftclick} left-click to place the line in a new location.", + "move_line_command": "To move an entire line, {rightclick} right-click the line and select the {move_icon} **{move}** command from the edit menu. Then move the mouse, and {leftclick} left-click to place the line in a new location.", "move_line_connected": "Lines that are connected to other features will stay connected as you move the line to a new location. iD may prevent you from moving a line across another connected line.", "delete_line_h": "Deleting Lines", "delete_line": "If a line is entirely incorrect, for example a road that doesn't exist in the real world, it's OK to delete it. Be careful when deleting features: the background imagery you are using might be outdated, and a road that looks wrong could simply be newly built.", - "delete_line_command": "To delete a line, {rightclick} right-click on the line to select it and show the edit menu, then use the {delete} **Delete** command." + "delete_line_command": "To delete a line, {rightclick} right-click or {longpress_icon} long-press the line to show the edit menu, then use the {delete_icon} **{delete}** command." }, "areas": { "title": "Areas", @@ -1720,88 +1726,90 @@ "point_or_area_h": "Points or Areas?", "point_or_area": "Many features can be represented as points or areas. You should map buildings and property outlines as areas whenever possible. Place points inside a building area to represent businesses, amenities, and other features located inside the building.", "add_area_h": "Adding Areas", - "add_area_command": "To add an area, click the {area} **Area** button on the toolbar above the map, or press the shortcut key `3`. This will change the mouse cursor to a cross symbol.", - "add_area_draw": "Next, position the mouse cursor at one of the corners of the feature and {leftclick} left-click or press `Space` to begin placing nodes around the outer edge of the area. Continue placing more nodes by clicking or pressing `Space`. While drawing, you can zoom in or drag the map in order to add more detail.", - "add_area_finish": "To finish an area, press `{return}` or click again on either the first or last node.", + "add_area_command": "To add an area, press the {area_icon} **{area}** button on the toolbar above the map, or press the shortcut key `3`.", + "add_area_draw": "Next, place the first corner of the area. With a mouse, position the cursor over any corner and {leftclick} left-click to place a node. On a touchscreen, {tap_icon} tap the location.", + "add_area_continue": "Continue placing nodes by {leftclick} clicking or {tap_icon} tapping along the edge of the area. While drawing, you can zoom in or drag the map in order to add more detail.", + "add_area_finish": "To finish an area, click or tap on the first or last node again or press `{return}`.", "square_area_h": "Square Corners", - "square_area_command": "Many area features like buildings have square corners. To square the corners of an area, {rightclick} right-click the edge of the area and select the {orthogonalize} **Square** command from the editing menu.", + "square_area_command": "Many area features like buildings have square corners. To square the corners of an area, {rightclick} right-click or {longpress_icon} long-press the edge of the area and select the {orthogonalize_icon} **{orthogonalize}** command from the edit menu.", "modify_area_h": "Modifying Areas", - "modify_area_dragnode": "Often you'll see areas that aren't shaped correctly, for example a building that does not match up with the background imagery. To adjust the shape of an area, first {leftclick} left-click to select it. All nodes of the area will be drawn as small circles. You can then drag the nodes to better locations.", - "modify_area_addnode": "You can also create new nodes along an area either by {leftclick}**x2** double-clicking on the edge of the area or by dragging the small triangles at the midpoints between nodes.", + "modify_area_dragnode": "Often you'll see areas that aren't shaped correctly, for example a building that does not match up with the background imagery. To adjust the shape of an area, first select it. All nodes of the area will be drawn as small circles. You can then drag the nodes to better locations.", + "modify_area_addnode": "You can also create new nodes along an area by {leftclick}**x2** double-clicking or {doubletap_icon} double-tapping an edge, or by dragging the small triangles at the midpoints between nodes.", "delete_area_h": "Deleting Areas", "delete_area": "If an area is entirely incorrect, for example a building that doesn't exist in the real world, it's OK to delete it. Be cautious when deleting features - the background imagery you are using might be outdated, and a building that looks wrong could simply be newly built.", - "delete_area_command": "To delete an area, {rightclick} right-click on the area to select it and show the edit menu, then use the {delete} **Delete** command." + "delete_area_command": "To delete an area, {rightclick} right-click or {longpress_icon} long-press the area to show the edit menu, then use the {delete_icon} **{delete}** command." }, "relations": { "title": "Relations", "intro": "A *relation* is a special type of feature in OpenStreetMap that groups together other features. The features that belong to a relation are called *members*, and each member can have a *role* in the relation.", "edit_relation_h": "Editing Relations", - "edit_relation": "At the bottom of the feature editor, you can expand the \"Relations\" section to see if the selected feature is a member of any relations. You can then click on the relation to select and edit it.", - "edit_relation_add": "To add a feature to a relation, select the feature, then click the {plus} add button in the \"Relations\" section of the feature editor. You can choose from a list of nearby relations, or choose the \"New relation...\" option.", - "edit_relation_delete": "You can also click the {delete} **Delete** button to remove the selected feature from the relation. If you remove all of the members from a relation, the relation will be deleted automatically.", + "edit_relation": "At the bottom of the feature editor, you can expand the \"{relations}\" section to see if the selected feature is a member of any relations. You can then select a relation to edit it.", + "edit_relation_add": "To add a feature to a relation, select the feature, then press the {plus} add button in the \"{relations}\" section of the feature editor. You can choose from a list of nearby relations, or choose the \"{new_relation}\" option.", + "edit_relation_delete": "You can also press the {delete_icon} **{delete}** button to remove the selected feature from the relation. If you remove all of the members from a relation, the relation will be deleted automatically.", "maintain_relation_h": "Maintaining Relations", "maintain_relation": "For the most part, iD will maintain relations automatically as you edit. You should take care when replacing features that might be members of relations. For example if you delete a section of road and draw a new section of road to replace it, you should add the new section to the same relations (routes, turn restrictions, etc.) as the original.", "relation_types_h": "Relation Types", "multipolygon_h": "Multipolygons", "multipolygon": "A *multipolygon* relation is a group of one or more *outer* features and one or more inner features. The outer features define the outer edges of the multipolygon, and the inner features define sub-areas or holes cut out from the inside of the multipolygon.", - "multipolygon_create": "To create a multipolygon, for example a building with a hole in it, draw the outer edge as an area and the inner edge as a line or different kind of area. Then `{shift}`+{leftclick} left-click to select both features, {rightclick} right-click to show the edit menu, and select the {merge} **Merge** command.", + "multipolygon_create": "To create a multipolygon, for example a building with a hole in it, draw the outer edge as an area and the inner edge as a line or different kind of area. Then `{shift}`+{leftclick} left-click to select both features, {rightclick} right-click to show the edit menu, and select the {merge_icon} **{merge}** command.", "multipolygon_merge": "Merging several lines or areas will create a new multipolygon relation with all selected areas as members. iD will choose the inner and outer roles automatically, based on which features are contained inside other features.", "turn_restriction_h": "Turn restrictions", "turn_restriction": "A *turn restriction* relation is a group of several road segments in an intersection. Turn restrictions consist of a *from* road, *via* node or roads, and a *to* road.", - "turn_restriction_field": "To edit turn restrictions, select a junction node where two or more roads meet. The feature editor will display a special \"Turn Restrictions\" field containing a model of the intersection.", - "turn_restriction_editing": "In the \"Turn Restrictions\" field, click to select a \"from\" road, and see whether turns are allowed or restricted to any of the \"to\" roads. You can click on the turn icons to toggle them between allowed and restricted. iD will create relations automatically and set the from, via, and to roles based on your choices.", + "turn_restriction_field": "To edit turn restrictions, select a junction node where two or more roads meet. The feature editor will display a special \"{turn_restrictions}\" field containing a model of the intersection.", + "turn_restriction_editing": "In the \"{turn_restrictions}\" field, select a \"from\" road, and see whether turns are allowed or restricted to any of the \"to\" roads. You can press the turn icons to toggle them between allowed and restricted. iD will create relations automatically and set the from, via, and to roles based on your choices.", "route_h": "Routes", "route": "A *route* relation is a group of one or more line features that together form a route network, like a bus route, train route, or highway route.", - "route_add": "To add a feature to a route relation, select the feature and scroll down to the \"Relations\" section of the feature editor, then click the {plus} add button to add this feature to a nearby existing relation or a new relation.", + "route_add": "To add a feature to a route relation, select the feature and scroll down to the \"{relations}\" section of the feature editor, then press the {plus} add button to add this feature to a nearby existing relation or a new relation.", "boundary_h": "Boundaries", "boundary": "A *boundary* relation is a group of one or more line features that together form an administrative boundary.", - "boundary_add": "To add a feature to a boundary relation, select the feature and scroll down to the \"Relations\" section of the feature editor, then click the {plus} add button to add this feature to a nearby existing relation or a new relation." + "boundary_add": "To add a feature to a boundary relation, select the feature and scroll down to the \"{relations}\" section of the feature editor, then press the {plus} add button to add this feature to a nearby existing relation or a new relation." }, "notes": { "title": "Notes", - "intro": "*Notes* are used to alert other users that a feature requires fixing or attention. Notes mark a specific location on the map. To view existing notes or add new ones, click the {data} **Map data** panel to enable the OpenStreetMap notes layer.", + "intro": "*Notes* are used to alert other users that a feature requires fixing or attention. Notes mark a specific location on the map. To view existing notes or add new ones, open the {data_icon} **{map_data}** panel and enable the {osm_notes} layer.", "add_note_h": "Adding Notes", - "add_note": "To add a new note, click the {note} **Note** button on the toolbar above the map, or press the shortcut key `4`. This will change the mouse cursor to a cross symbol. To place the new note on the map, position the mouse cursor where the note should go, then {leftclick} left-click or press `Space`.", - "move_note": "Only new notes can be moved. To move a note, place the mouse cursor over the new note, then press and hold the {leftclick} left mouse button while dragging the note to its new location.", + "add_note": "To add a new note, press the {note_icon} **{note}** button on the toolbar above the map, or press the shortcut key `{add_note_key}`.", + "place_note": "Next, place the new note on the map. With a mouse, position the cursor where the note should go and {leftclick} left-click. On a touchscreen, {tap_icon} tap the location.", + "move_note": "To move a note, {leftclick} left-click and drag it with a mouse or {touchdrag_icon} tap-and-drag it on a touchscreen. Only new notes can be moved.", "update_note_h": "Closing, Reopening, and Commenting", "update_note": "An existing note can be updated by closing it, reopening it, or adding a comment to it. Closing a note indicates that the problem has been resolved. Reopening a note indicates that the original issue is not resolved.", "save_note_h": "Saving Notes", - "save_note": "You must save any note edits individually by clicking the buttons below the note comments. Note edits are **not** included in changesets that you upload to OpenStreetMap." + "save_note": "You must save any note edits individually by pressing the buttons below the note comments. Note edits are **not** included in changesets that you upload to OpenStreetMap." }, "imagery": { "title": "Background Imagery", "intro": "The background imagery that appears beneath the map data is an important resource for mapping. This imagery can be aerial photos collected from satellites, airplanes, and drones, or it can be scanned historical maps or other freely available source data.", "sources_h": "Imagery Sources", - "choosing": "To see which imagery sources are available for editing, click the {layers} **Background Settings** button on the side of the map.", + "choosing": "To see which imagery sources are available for editing, open the {layers_icon} **{background_settings}** panel on the side of the map.", "sources": "By default, a [Bing Maps](https://www.bing.com/maps/) satellite layer is chosen as the background image. Depending on where you are editing, other imagery sources will be available. Some may be newer or have higher resolution, so it is always useful to check and see which layer is the best one to use as a mapping reference.", "offsets_h": "Adjusting Imagery Offset", - "offset": "Imagery is sometimes offset slightly from accurate map data. If you see a lot of roads or buildings shifted from the background imagery, it may be the imagery that's incorrect, so don't move them all to match the background. Instead, you can adjust the background so that it matches the existing data by expanding the \"Imagery Offset\" section at the bottom of the Background Settings pane.", - "offset_change": "Click on the small triangles to adjust the imagery offset in small steps, or hold the {leftclick} left mouse button and drag within the gray square to slide the imagery into alignment." + "offset": "Imagery is sometimes offset slightly from accurate map data. If you see a lot of roads or buildings shifted from the background imagery, it may be the imagery that's incorrect, so don't move them all to match the background. Instead, you can adjust the background so that it matches the existing data by expanding the \"{imagery_offset}\" section at the bottom of the Background Settings pane.", + "offset_change": "Press the small triangle buttons to adjust the imagery offset in small steps, or hold the {leftclick} left mouse button and drag within the gray square to slide the imagery into alignment." }, "streetlevel": { "title": "Street Level Photos", "intro": "Street level photos are useful for mapping traffic signs, businesses, and other details that you can't see from satellite and aerial images. The iD editor supports street level photos from [Bing Streetside](https://www.microsoft.com/en-us/maps/streetside), [Mapillary](https://www.mapillary.com), and [OpenStreetCam](https://www.openstreetcam.org).", "using_h": "Using Street Level Photos", - "using": "To use street level photos for mapping, click the {data} **Map data** panel on the side of the map to enable or disable the available photo layers.", + "using": "To use street level photos for mapping, open the {data_icon} **{map_data}** panel on the side of the map to enable or disable the available photo layers.", "photos": "When enabled, the photo layer displays a line along the sequence of photos. At higher zoom levels, a circle marks at each photo location, and at even higher zoom levels, a cone indicates the direction the camera was facing when the photo was taken.", - "viewer": "When you click on one of the photo locations, a photo viewer appears in the bottom corner of the map. The photo viewer contains controls to step forward and backward in the image sequence. It also shows the username of the person who captured the image, the date it was captured, and a link to view the image on the original site." + "viewer": "When you select one of the photo locations, a photo viewer appears in the bottom corner of the map. The photo viewer contains controls to step forward and backward in the image sequence. It also shows the username of the person who captured the image, the date it was captured, and a link to view the image on the original site." }, "gps": { "title": "GPS Traces", - "intro": "Collected GPS traces are a valuable source of data for OpenStreetMap. This editor supports *.gpx*, *.geojson*, and *.kml* files on your local computer. You can collect GPS traces with a smartphone, sports watch, or other GPS device.", + "intro": "Collected GPS traces are a valuable source of data for OpenStreetMap. This editor supports *.gpx*, *.geojson*, and *.kml* files on your local device. You can collect GPS traces with a smartphone, sports watch, or other GPS device.", "survey": "For information on how to perform a GPS survey, read [Mapping with a smartphone, GPS, or paper](http://learnosm.org/en/mobile-mapping/).", "using_h": "Using GPS Traces", - "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.", + "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. Open the {data_icon} **{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." }, "qa": { "title": "Quality Assurance", - "intro": "*Quality Assurance* (Q/A) tools can find improper tags, disconnected roads, and other issues with OpenStreetMap, which mappers can then fix. To view existing Q/A issues, click the {data} **Map data** panel to enable a specific Q/A layer.", + "intro": "*Quality Assurance* (Q/A) tools can find improper tags, disconnected roads, and other issues with OpenStreetMap, which mappers can then fix. To view existing Q/A issues, open the {data_icon} **{map_data}** panel and enable a specific Q/A layer.", "tools_h": "Tools", "tools": "The following tools are currently supported: [KeepRight](https://www.keepright.at/), [ImproveOSM](https://improveosm.org/en/) and [Osmose](https://osmose.openstreetmap.fr/).", "issues_h": "Handling Issues", - "issues": "Handling Q/A issues is similar to handling notes. Click on a marker to view the issue details in the sidebar. Each tool has its own capabilities, but generally you can comment and/or close an issue." + "issues": "Handling Q/A issues is similar to handling notes. Select a marker to view the issue details in the sidebar. Each tool has its own capabilities, but generally you can comment and/or close an issue." }, "field": { "restrictions": { @@ -2403,117 +2411,155 @@ }, "navigation": { "title": "Navigation", - "drag": "The main map area shows OpenStreetMap data on top of a background.{br}You can click-and-drag or tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", - "zoom": "You can zoom in or out by scrolling with a mouse wheel, pinching on a touchscreen, or pressing the {plus} / {minus} buttons. **Zoom the map!**", + "map_info": "The main map area shows OpenStreetMap data on top of a background.", + "drag": "You can click-and-drag the map with the {leftclick} left mouse button to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", + "drag_touch": "You can {touchdrag_icon} tap-and-drag the map to move it around. You can also use the arrow keys on a keyboard. **Drag the map!**", + "zoom": "You can zoom the map by scrolling with a {mousewheel_icon} mouse wheel or trackpad, or by pressing the {plus} / {minus} buttons. **Zoom the map!**", + "zoom_touch": "You can zoom the map by {pinch_icon} pinching it with two fingers, {doubletap_icon} double-tapping a location, or pressing the {plus} / {minus} buttons. **Zoom the map!**", "features": "We use the word *features* to describe the things that appear on the map. Anything in the real world can be mapped as a feature on OpenStreetMap.", "points_lines_areas": "Map features are represented using *points, lines, or areas.*", "nodes_ways": "In OpenStreetMap, points are sometimes called *nodes*, and lines and areas are sometimes called *ways*.", - "click_townhall": "All features on the map can be selected by clicking or tapping on them. **Select the point.**", + "click_townhall": "All features on the map can be selected by {leftclick} clicking on them. **Click the point to select it.**", + "tap_townhall": "All features on the map can be selected by {tap_icon} tapping on them. **Tap the point to select it.**", "selected_townhall": "Great! The point is now selected. Selected features are drawn with a pulsing glow.", "editor_townhall": "When a feature is selected, the *feature editor* is displayed alongside the map.", "preset_townhall": "The top part of the feature editor shows the feature's type. This point is a {preset}.", "fields_townhall": "The middle part of the feature editor contains *fields* showing the feature's attributes, such as its name and address.", - "close_townhall": "**Close the feature editor by hitting escape or pressing the {button} button in the upper corner.**", + "close_townhall": "**Close the feature editor by pressing the {button} button in the upper corner or `{esc}`.**", "search_street": "You can also search for features in the current view, or worldwide. **Search for '{name}'.**", "choose_street": "**Choose {name} from the list to select it.**", "selected_street": "Great! {name} is now selected.", - "editor_street": "The fields shown for a street are different than the fields that were shown for the town hall.{br}For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by hitting escape or pressing the {button} button.**", + "street_different_fields": "The fields shown for a street are different than the fields that were shown for the town hall.", + "editor_street": "For this selected street, the feature editor shows fields like '{field1}' and '{field2}'. **Close the feature editor by pressing the {button} button or `{esc}`.**", "play": "Try exploring the map and selecting some other features to see what kinds of things can be added to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" }, "points": { "title": "Points", - "add_point": "*Points* can be used to represent features such as shops, restaurants, and monuments.{br}They mark a specific location, and describe what's there. **Click the {button} Point button to add a new point.**", - "place_point": "To place the new point on the map, position your mouse cursor where the point should go, then left-click or press the spacebar. **Move the mouse pointer over this building, then left-click or press the spacebar.**", + "points_info": "*Points* can be used to represent features such as shops, restaurants, and monuments.", + "add_point": "They mark a specific location, and describe what's there. **Press the {point_icon} {point} button to add a new point.**", + "place_point": "To place the new point on the map, position your mouse cursor where the point should go, then {leftclick} left-click or press `{space}`. **Move the mouse pointer over this building, then left-click or press `{space}`.**", + "place_point_touch": "To place the new point on the map, {tap_icon} tap the location where it should go. **Tap the center of this building.**", "search_cafe": "There are many different features that can be represented by points. The point you just added is a cafe. **Search for '{preset}'.**", "choose_cafe": "**Choose {preset} from the list.**", "feature_editor": "The point is now marked as a cafe. Using the feature editor, we can add more information about the cafe.", - "add_name": "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.{br}Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**", - "add_close": "The feature editor will remember all of your changes automatically. **When you are finished adding the name, hit escape, enter, or click the {button} button to close the feature editor.**", - "reselect": "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Click to select the cafe you just created.**", + "fields_info": "In OpenStreetMap, all of the fields are optional, and it's OK to leave a field blank if you are unsure.", + "add_name": "Let's pretend that you have local knowledge of this cafe, and you know its name. **Add a name for the cafe.**", + "add_close": "The feature editor will remember all of your changes automatically. **When you are finished adding the name, press the {button} button or `{esc}` to close the feature editor.**", + "reselect": "Often points will already exist, but have mistakes or be incomplete. We can edit existing points. **Select the cafe you just created.**", "update": "Let's fill in some more details for this cafe. You can change its name, add a cuisine, or add an address. **Change the cafe details.**", - "update_close": "**When you are finished updating the cafe, hit escape, enter, or click the {button} button to close the feature editor.**", - "rightclick": "You can right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Right-click to select the point you created and show the edit menu.**", - "delete": "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Click on the {button} button to delete the point.**", - "undo": "You can always undo any changes up until you save your edits to OpenStreetMap. **Click on the {button} button to undo the delete and get the point back.**", - "play": "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, click '{next}'.**" + "update_close": "**When you are finished updating the cafe, press the {button} button or `{esc}` to close the feature editor.**", + "rightclick": "You can {rightclick} right-click on any feature to see the *edit menu*, which shows a list of editing operations that can be performed.{br}A right-click might be the same as a control-click or two-finger click. **Right-click to select the point you created and show the edit menu.**", + "edit_menu_touch": "You can {longpress_icon} long-press on any feature to see the *edit menu*, which shows a list of editing operations that can be performed. **Press-and-hold the point you created to show the edit menu.**", + "delete": "It's OK to delete features that don't exist in the real world.{br}Deleting a feature from OpenStreetMap removes it from the map that everyone uses, so you should make sure a feature is really gone before you delete it. **Press the {delete_icon} {delete} button to remove the point.**", + "undo": "You can always undo any changes up until you save your edits to OpenStreetMap. **Press the {undo_icon} {undo} button to get the point back.**", + "play": "Now that you know how to create and edit points, try creating a few more points for practice! **When you are ready to continue to the next chapter, press '{next}'.**" }, "areas": { "title": "Areas", - "add_playground": "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Click the {button} Area button to add a new area.**", - "start_playground": "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature. **Click or press spacebar to place a starting node on one of the corners of the playground.**", - "continue_playground": "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the '{alt}' key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**", - "finish_playground": "Finish the area by pressing enter, or clicking again on either the first or last node. **Finish drawing an area for the playground.**", + "add_playground": "*Areas* are used to show the boundaries of features like lakes, buildings, and residential areas.{br}They can also be used for more detailed mapping of many features you might normally map as points. **Press the {area_icon} {area} button to add a new area.**", + "start_playground": "Let's add this playground to the map by drawing an area. Areas are drawn by placing *nodes* along the outer edge of the feature.", + "starting_node_click": "**Click or press `{space}` to place a starting node on one of the corners of the playground.**", + "starting_node_tap": "**{tap_icon} Tap to place a starting node on one of the corners of the playground.**", + "continue_playground": "Continue drawing the area by placing more nodes along the playground's edge. It is OK to connect the area to the existing walking paths.{br}Tip: You can hold down the `{alt}` key to prevent nodes from connecting to other features. **Continue drawing an area for the playground.**", + "finish_area_click": "Finish the area by pressing `{return}`, or clicking again on either the first or last node.", + "finish_area_tap": "Finish the area by {tap_icon} tapping again on either the first or last node, or by pressing `{return}` on a keyboard.", + "finish_playground": "**Finish drawing an area for the playground.**", "search_playground": "**Search for '{preset}'.**", "choose_playground": "**Choose {preset} from the list.**", - "add_field": "This playground doesn't have an official name, so we won't add anything in the Name field.{br}Instead let's add some additional details about the playground to the Description field. **Open the Add Field list.**", + "add_field": "This playground doesn't have an official name, so we won't add anything in the {name} field.{br}Instead let's add some additional details about the playground to the {description} field. **Open the Add Field list.**", "choose_field": "**Choose {field} from the list.**", "retry_add_field": "You didn't select the {field} field. Let's try again.", - "describe_playground": "**Add a description, then click the {button} button to close the feature editor.**", - "play": "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, click '{next}'.**" + "describe_playground": "**Add a description, then press the {button} button to close the feature editor.**", + "play": "Good job! Try drawing a few more areas, and see what other kinds of area features you can add to OpenStreetMap. **When you are ready to continue to the next chapter, press '{next}'.**" }, "lines": { "title": "Lines", - "add_line": "*Lines* are used to represent features such as roads, railroads, and rivers. **Click the {button} Line button to add a new line.**", - "start_line": "Here is a road that is missing. Let's add it!{br}In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary. **Start a new line by clicking at the top end of this missing road.**", - "intersect": "Click or press spacebar to add more nodes to the line.{br}Roads, and many other types of lines, are part of a larger network. It is important for these lines to be connected properly in order for routing applications to work. **Click on {name} to create an intersection connecting the two lines.**", + "add_line": "*Lines* are used to represent features such as roads, railroads, and rivers. **Press the {line_icon} {line} button to add a new line.**", + "missing_road": "Here is a road that is missing. Let's add it!", + "line_draw_info": "In OpenStreetMap, lines should be drawn down the center of the road. You can drag and zoom the map while drawing if necessary.", + "start_line": "**Start a new line by clicking at the top end of this missing road.**", + "start_line_tap": "**Start a new line by {tap_icon} tapping at the top end of this missing road.**", + "intersect": "Continue drawing the line by placing more nodes along the road.{br}Roads, along with paths and ferry routes, must be properly connected to each other for navigation apps to work. **Place an intersection node on {name} to connect the two lines.**", "retry_intersect": "The road needs to intersect {name}. Let's try again!", - "continue_line": "Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed.{br}When you are finished drawing, click on the last node again. **Finish drawing the road.**", + "continue_line": "Continue drawing the line for the new road. Remember that you can drag and zoom the map if needed.", + "finish_line_click": "When you're finished, click the last node again or press `{return}`.", + "finish_line_tap": "When you're finished, {tap_icon} tap the last node again or press `{return}` on a keyboard.", + "finish_road": "**Finish drawing the road.**", "choose_category_road": "**Select {category} from the list.**", "choose_preset_residential": "There are many different types of roads, but this one is a residential road. **Choose the {preset} type.**", - "retry_preset_residential": "You didn't select the {preset} type. **Click here to choose again.**", - "name_road": "**Give this road a name, then hit escape, enter, or click the {button} button to close the feature editor.**", + "retry_preset_residential": "You didn't select the {preset} type. **Press this button to choose again.**", + "name_road": "**Give this road a name, then press the {button} button or `{esc}` to close the feature editor.**", "did_name_road": "Looks good! Next we will learn how to update the shape of a line.", "update_line": "Sometimes you will need to change the shape of an existing line. Here is a road that doesn't look quite right.", "add_node": "We can add some nodes to this line to improve its shape. One way to add a node is to double-click the line where you want to add a node. **Double-click on the line to create a new node.**", - "start_drag_endpoint": "When a line is selected, you can drag any of its nodes by clicking and holding down the left mouse button while you drag. **Drag the endpoint to the place where these roads should intersect.**", - "finish_drag_endpoint": "This spot looks good. **Release the left mouse button to finish dragging.**", + "add_node_touch": "We can add some nodes to this line to improve its shape. One way to add a node is to {doubletap_icon} double-tap the line where you want to add a node. **Double-tap on the line to create a new node.**", + "start_drag_endpoint": "When a line is selected, you can adjust any of its nodes by clicking and holding down the {leftclick} left mouse button while you drag.", + "start_drag_endpoint_touch": "When a line is selected, you can {touchdrag_icon} tap-and-drag any of its nodes to adjust them.", + "drag_to_intersection": "**Drag the endpoint to the place where these roads should intersect.**", + "spot_looks_good": "This spot looks good.", + "finish_drag_endpoint": "**Release the mouse button to finish dragging.**", + "finish_drag_endpoint_touch": "**Let go of the node to finish dragging.**", "start_drag_midpoint": "Small triangles are drawn at the *midpoints* between nodes. Another way to create a new node is to drag a midpoint to a new location. **Drag the midpoint triangle to create a new node along the curve of the road.**", - "continue_drag_midpoint": "This line is looking much better! Continue to adjust this line by double-clicking or dragging midpoints until the curve matches the road shape. **When you're happy with how the line looks, click OK.**", + "continue_drag_midpoint": "This line is looking much better! Continue to adjust this line until the curve matches the road shape. **When you're happy with how the line looks, press {ok}.**", "delete_lines": "It's OK to delete lines for roads that don't exist in the real world.{br}Here's an example where the city planned a {street} but never built it. We can improve this part of the map by deleting the extra lines.", - "rightclick_intersection": "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it. **Right click on the intersection node.**", - "split_intersection": "**Click on the {button} button to split {street}.**", - "retry_split": "You didn't click the Split button. Try again.", - "did_split_multi": "Good job! {street1} is now split into two pieces. The top part can be removed. **Click the top part of {street2} to select it.**", - "did_split_single": "**Click the top part of {street2} to select it.**", - "multi_select": "{selected} is now selected. Let's also select {other1}. You can shift-click to select multiple things. **Shift-click on {other2}.**", - "multi_rightclick": "Good! Both lines to delete are now selected. **Right-click on one of the lines to show the edit menu.**", - "multi_delete": "**Click on the {button} button to delete the extra lines.**", - "retry_delete": "You didn't click the Delete button. Try again.", - "play": "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, click '{next}'.**" + "split_street": "The last real street is {street1}, so we will *split* {street2} at this intersection and remove everything above it.", + "rightclick_intersection": "**{rightclick} Right-click on the intersection node.**", + "edit_menu_intersection_touch": "**{longpress_icon} Long-press on the intersection node.**", + "split_intersection": "**Press the {split_icon} {split} button to divide {street}.**", + "retry_split": "You didn't press the {split_icon} {split} button. Try again.", + "did_split_multi": "Good job! {street1} is now split into two pieces. The top part can be removed. **Select the top part of {street2}.**", + "did_split_single": "**Select the top part of {street2}.**", + "multi_select": "{selected} is now selected. Let's also select {other1}.", + "add_to_selection_click": "You can hold `{shift}` while clicking to select multiple things. **Shift-click on {other2}.**", + "add_to_selection_touch": "**{longpress_icon} Tap-and-hold {selected} and then {tap_icon} tap {other2} with another finger to select both.**", + "multi_select_success": "Good! Both lines to delete are now selected.", + "multi_rightclick": "**{rightclick} Right-click on one of the lines to show the edit menu.**", + "multi_edit_menu_touch": "**{longpress_icon} Long-press on one of the lines to show the edit menu.**", + "multi_delete": "**Press the {delete_icon} {delete} button to remove the extra lines.**", + "retry_delete": "You didn't press the {delete_icon} {delete} button. Try again.", + "play": "Great! Use the skills that you've learned in this chapter to practice editing some more lines. **When you are ready to continue to the next chapter, press '{next}'.**" }, "buildings": { "title": "Buildings", - "add_building": "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Click the {button} Area button to add a new area.**", - "start_building": "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible. **Click or press spacebar to place a starting node on one of the corners of the building.**", - "continue_building": "Continue adding more nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.{br}Finish the building by pressing enter, or clicking again on either the first or last node. **Finish tracing the building.**", + "add_building": "OpenStreetMap is the world's largest database of buildings.{br}You can help improve this database by tracing buildings that aren't already mapped. **Press the {area_icon} {area} button to add a new area.**", + "start_building": "Let's add this house to the map by tracing its outline.{br}Buildings should be traced around their footprint as accurately as possible.", + "building_corner_click": "**Click or press `{space}` to place a starting node on one of the corners of the building.**", + "building_corner_tap": "**{tap_icon} Tap one of the corners of the building to place a starting node.**", + "continue_building": "Continue placing nodes to trace the outline of the building. Remember that you can zoom in if you want to add more details.", + "finish_building": "**Finish tracing the building.**", "retry_building": "It looks like you had some trouble placing the nodes at the building corners. Try again!", "choose_category_building": "**Choose {category} from the list.**", "choose_preset_house": "There are many different types of buildings, but this one is clearly a house.{br}If you're not sure of the type, it's OK to just choose the generic Building type. **Choose the {preset} type.**", - "close": "**Hit escape or click the {button} button to close the feature editor.**", - "rightclick_building": "**Right-click to select the building you created and show the edit menu.**", - "square_building": "The house that you just added will look even better with perfectly square corners. **Click on the {button} button to square the building shape.**", - "retry_square": "You didn't click the Square button. Try again.", + "close": "**Press the {button} button or `{esc}` to close the feature editor.**", + "rightclick_building": "**{rightclick} Right-click to select the building you created and show the edit menu.**", + "edit_menu_building_touch": "**{longpress_icon} Long-press the building you created to show the edit menu.**", + "square_building": "The house that you just added will look even better with perfectly square corners. **Press the {orthogonalize_icon} {orthogonalize} button to tidy up the building's shape.**", + "retry_square": "You didn't press the {orthogonalize_icon} {orthogonalize} button. Try again.", "done_square": "See how the corners of the building moved into place? Let's learn another useful trick.", - "add_tank": "Next we'll trace this circular storage tank. **Click the {button} Area button to add a new area.**", - "start_tank": "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge. **Click or press spacebar to place a starting node on the edge of the tank.**", - "continue_tank": "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.{br}Finish the area by pressing enter, or clicking again on either the first or last node. **Finish tracing the tank.**", + "add_tank": "Next we'll trace this circular storage tank. **Press the {area_icon} {area} button to add a new area.**", + "start_tank": "Don't worry, you won't need to draw a perfect circle. Just draw an area inside the tank that touches its edge.", + "tank_edge_click": "**Click or press `{space}` to place a starting node on the edge of the tank.**", + "tank_edge_tap": "**{tap_icon} Tap the edge of the tank to place a starting node.**", + "continue_tank": "Add a few more nodes around the edge. The circle will be created outside the nodes that you draw.", + "finish_tank": "**Finish tracing the tank.**", "search_tank": "**Search for '{preset}'.**", "choose_tank": "**Choose {preset} from the list.**", - "rightclick_tank": "**Right-click to select the storage tank you created and show the edit menu.**", - "circle_tank": "**Click on the {button} button to make the tank a circle.**", - "retry_circle": "You didn't click the Circularize button. Try again.", - "play": "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, click '{next}'.**" + "rightclick_tank": "**{rightclick} Right-click to select the storage tank you created and show the edit menu.**", + "edit_menu_tank_touch": "**{longpress_icon} Long-press the storage tank you created to show the edit menu.**", + "circle_tank": "**Press the {circularize_icon} {circularize} button to make the tank a circle.**", + "retry_circle": "You didn't press the {circularize_icon} {circularize} button. Try again.", + "play": "Great Job! Practice tracing a few more buildings, and try some of the other commands on the edit menu. **When you are ready to continue to the next chapter, press '{next}'.**" }, "startediting": { "title": "Start Editing", - "help": "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by clicking the {button} Help button or pressing the '{key}' key.", - "shortcuts": "You can view a list of commands along with their keyboard shortcuts by pressing the '{key}' key.", + "help": "You're now ready to edit OpenStreetMap!{br}You can replay this walkthrough anytime or view more documentation by pressing the {help_icon} {help} button or the `{help_key}` key.", + "shortcuts": "You can view a list of commands along with their keyboard shortcuts by pressing the `{shortcuts_key}` key.", "save": "Don't forget to regularly save your changes!", "start": "Start mapping!" } }, "shortcuts": { - "title": "Keyboard shortcuts", + "title": "Keyboard Shortcuts", "tooltip": "Show the keyboard shortcuts screen.", "toggle": { "key": "?" diff --git a/modules/core/context.js b/modules/core/context.js index 0119603585..77e61ca336 100644 --- a/modules/core/context.js +++ b/modules/core/context.js @@ -80,6 +80,7 @@ export function coreContext() { /* User interface and keybinding */ let _ui; context.ui = () => _ui; + context.lastPointerType = () => _ui.lastPointerType(); let _keybinding = utilKeybinding('context'); context.keybinding = () => _keybinding; diff --git a/modules/ui/cmd.js b/modules/ui/cmd.js index c2203adb15..66784056af 100644 --- a/modules/ui/cmd.js +++ b/modules/ui/cmd.js @@ -53,7 +53,7 @@ uiCmd.display = function(code) { '↘': mac ? '↘ ' + t('shortcuts.key.pgdn') : t('shortcuts.key.pgdn'), '⇞': mac ? '⇞ ' + t('shortcuts.key.home') : t('shortcuts.key.home'), '⇟': mac ? '⇟ ' + t('shortcuts.key.end') : t('shortcuts.key.end'), - '↵': mac ? '↵ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'), + '↵': mac ? '⏎ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'), '⎋': mac ? '⎋ ' + t('shortcuts.key.esc') : t('shortcuts.key.esc'), '☰': mac ? '☰ ' + t('shortcuts.key.menu') : t('shortcuts.key.menu'), }; diff --git a/modules/ui/curtain.js b/modules/ui/curtain.js index 380aa47024..4e9fd3abef 100644 --- a/modules/ui/curtain.js +++ b/modules/ui/curtain.js @@ -64,9 +64,12 @@ export function uiCurtain(containerNode) { * @param {integer} [options.duration] transition time in milliseconds * @param {string} [options.buttonText] if set, create a button with this text label * @param {function} [options.buttonCallback] if set, the callback for the button + * @param {function} [options.padding] extra margin in px to put around bbox * @param {String|ClientRect} [options.tooltipBox] box for tooltip position, if different from box for the curtain */ curtain.reveal = function(box, text, options) { + options = options || {}; + if (typeof box === 'string') { box = d3_select(box).node(); } @@ -76,8 +79,14 @@ export function uiCurtain(containerNode) { box.top -= containerRect.top; box.left -= containerRect.left; } - - options = options || {}; + if (box && options.padding) { + box.top -= options.padding; + box.left -= options.padding; + box.bottom += options.padding; + box.right += options.padding; + box.height += options.padding * 2; + box.width += options.padding * 2; + } var tooltipBox; if (options.tooltipBox) { diff --git a/modules/ui/edit_menu.js b/modules/ui/edit_menu.js index 94741bfe67..b149ba7c56 100644 --- a/modules/ui/edit_menu.js +++ b/modules/ui/edit_menu.js @@ -1,12 +1,16 @@ import { event as d3_event, select as d3_select } from 'd3-selection'; +import { dispatch as d3_dispatch } from 'd3-dispatch'; import { geoVecAdd } from '../geo'; import { localizer } from '../core/localizer'; import { uiTooltip } from './tooltip'; +import { utilRebind } from '../util/rebind'; import { svgIcon } from '../svg/icon'; export function uiEditMenu(context) { + var dispatch = d3_dispatch('toggled'); + var _menu = d3_select(null); var _operations = []; // the position the menu should be displayed relative to @@ -99,7 +103,7 @@ export function uiEditMenu(context) { .call(tooltip) .append('div') .attr('class', 'icon-wrap') - .call(svgIcon('#iD-operation-' + d.id, 'operation-icon')); + .call(svgIcon('#iD-operation-' + d.id, 'operation')); }); if (showLabels) { @@ -161,6 +165,8 @@ export function uiEditMenu(context) { } lastPointerUpType = null; } + + dispatch.call('toggled', this, true); }; function updatePosition() { @@ -269,6 +275,8 @@ export function uiEditMenu(context) { _menu.remove(); _tooltips = []; + + dispatch.call('toggled', this, false); }; editMenu.anchorLoc = function(val) { @@ -290,5 +298,5 @@ export function uiEditMenu(context) { return editMenu; }; - return editMenu; + return utilRebind(editMenu, dispatch, 'on'); } diff --git a/modules/ui/flash.js b/modules/ui/flash.js index 0ed943ca90..d7ad2507db 100644 --- a/modules/ui/flash.js +++ b/modules/ui/flash.js @@ -7,7 +7,7 @@ export function uiFlash(context) { var _iconName = '#iD-icon-no'; var _iconClass = 'disabled'; var _text = ''; - var _textClass; + var _textClass; function flash() { if (_flashTimer) { @@ -31,7 +31,7 @@ export function uiFlash(context) { var iconEnter = contentEnter .append('svg') - .attr('class', 'flash-icon') + .attr('class', 'flash-icon icon') .append('g') .attr('transform', 'translate(10,10)'); @@ -56,7 +56,7 @@ export function uiFlash(context) { content .selectAll('.flash-icon') - .attr('class', 'flash-icon ' + (_iconClass || '')); + .attr('class', 'icon flash-icon ' + (_iconClass || '')); content .selectAll('.flash-icon use') diff --git a/modules/ui/init.js b/modules/ui/init.js index 35d5d23dd9..f2a8980c68 100644 --- a/modules/ui/init.js +++ b/modules/ui/init.js @@ -52,6 +52,8 @@ export function uiInit(context) { var _initCounter = 0; var _needWidth = {}; + var _lastPointerType; + function render(container) { @@ -95,13 +97,15 @@ export function uiInit(context) { if ('PointerEvent' in window) { d3_select(window) .on('pointerdown.ui pointerup.ui', function() { - var pointerType = d3_event.pointerType || 'mouse'; - if (container.attr('pointer') !== pointerType) { + var pointerType = d3_event.pointerType || 'mouse'; + if (_lastPointerType !== pointerType) { + _lastPointerType = pointerType; container .attr('pointer', pointerType); } }, true); } else { + _lastPointerType = 'mouse'; container .attr('pointer', 'mouse'); } @@ -481,6 +485,10 @@ export function uiInit(context) { ui.ensureLoaded(); }; + ui.lastPointerType = function() { + return _lastPointerType; + }; + ui.flash = uiFlash(context); ui.sidebar = uiSidebar(context); @@ -587,7 +595,11 @@ export function uiInit(context) { }; - var _editMenu; // uiEditMenu + var _editMenu = uiEditMenu(context); + + ui.editMenu = function() { + return _editMenu; + }; ui.showEditMenu = function(anchorPoint, triggerType, operations) { @@ -606,9 +618,6 @@ export function uiInit(context) { surfaceNode.focus(); } - // don't load the menu until it's needed - if (!_editMenu) _editMenu = uiEditMenu(context); - operations.forEach(function(operation) { if (operation.point) operation.point(anchorPoint); }); diff --git a/modules/ui/intro/area.js b/modules/ui/intro/area.js index 53b4db2c5f..2eabd6b67b 100644 --- a/modules/ui/intro/area.js +++ b/modules/ui/intro/area.js @@ -13,14 +13,14 @@ import { t } from '../../core/localizer'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { uiCmd } from '../cmd'; -import { icon, pad, transitionTime } from './helper'; +import { helpString, icon, pad, transitionTime } from './helper'; export function uiIntroArea(context, reveal) { var dispatch = d3_dispatch('done'); var playground = [-85.63552, 41.94159]; var playgroundPreset = presetManager.item('leisure/playground'); + var nameField = presetManager.field('name'); var descriptionField = presetManager.field('description'); var timeouts = []; var _areaID; @@ -60,7 +60,7 @@ export function uiIntroArea(context, reveal) { timeout(function() { var tooltip = reveal('button.add-area', - t('intro.areas.add_playground', { button: icon('#iD-icon-area', 'pre-text') })); + helpString('intro.areas.add_playground')); tooltip.selectAll('.popover-inner') .insert('svg', 'span') @@ -90,14 +90,16 @@ export function uiIntroArea(context, reveal) { context.map().zoomEase(19.5, 500); timeout(function() { + var textId = context.lastPointerType() === 'mouse' ? 'starting_node_click' : 'starting_node_tap'; + var startDrawString = helpString('intro.areas.start_playground') + helpString('intro.areas.' + textId); revealPlayground(playground, - t('intro.areas.start_playground'), { duration: 250 } + startDrawString, { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.start_playground'), { duration: 0 } + startDrawString, { duration: 0 } ); }); context.on('enter.intro', function(mode) { @@ -123,14 +125,14 @@ export function uiIntroArea(context, reveal) { _areaID = null; revealPlayground(playground, - t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }), + helpString('intro.areas.continue_playground'), { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }), + helpString('intro.areas.continue_playground'), { duration: 0 } ); }); @@ -166,14 +168,17 @@ export function uiIntroArea(context, reveal) { } _areaID = null; + + var finishString = helpString('intro.areas.finish_area_' + (context.lastPointerType() === 'mouse' ? 'click' : 'tap')) + + helpString('intro.areas.finish_playground'); revealPlayground(playground, - t('intro.areas.finish_playground'), { duration: 250 } + finishString, { duration: 250 } ); timeout(function() { context.map().on('move.intro drawn.intro', function() { revealPlayground(playground, - t('intro.areas.finish_playground'), { duration: 0 } + finishString, { duration: 0 } ); }); }, 250); // after reveal @@ -218,7 +223,7 @@ export function uiIntroArea(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.areas.search_playground', { preset: playgroundPreset.name() }) + helpString('intro.areas.search_playground', { preset: playgroundPreset.name() }) ); }, 400); // after preset list pane visible.. @@ -242,7 +247,7 @@ export function uiIntroArea(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.areas.search_playground', { preset: playgroundPreset.name() }) + helpString('intro.areas.search_playground', { preset: playgroundPreset.name() }) ); context.history().on('change.intro', null); @@ -254,7 +259,7 @@ export function uiIntroArea(context, reveal) { if (first.classed('preset-leisure-playground')) { reveal(first.select('.preset-list-button').node(), - t('intro.areas.choose_playground', { preset: playgroundPreset.name() }), + helpString('intro.areas.choose_playground', { preset: playgroundPreset.name() }), { duration: 300 } ); @@ -326,7 +331,10 @@ export function uiIntroArea(context, reveal) { timeout(function() { reveal('.more-fields .combobox-input', - t('intro.areas.add_field'), + helpString('intro.areas.add_field', { + name: nameField.label(), + description: descriptionField.label() + }), { duration: 300 } ); @@ -391,7 +399,7 @@ export function uiIntroArea(context, reveal) { }, 300); reveal('div.combobox', - t('intro.areas.choose_field', { field: descriptionField.label() }), + helpString('intro.areas.choose_field', { field: descriptionField.label() }), { duration: 300 } ); @@ -428,7 +436,7 @@ export function uiIntroArea(context, reveal) { }); reveal('.entity-editor-pane', - t('intro.areas.describe_playground', { button: icon('#iD-icon-apply', 'pre-text') }), + helpString('intro.areas.describe_playground', { button: icon('#iD-icon-close', 'pre-text') }), { duration: 300 } ); @@ -452,7 +460,7 @@ export function uiIntroArea(context, reveal) { context.container().select('.inspector-wrap .panewrap').style('right', '0%'); reveal('.entity-editor-pane', - t('intro.areas.retry_add_field', { field: descriptionField.label() }), { + helpString('intro.areas.retry_add_field', { field: descriptionField.label() }), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(clickAddField); } }); @@ -471,7 +479,7 @@ export function uiIntroArea(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.areas.play', { next: t('intro.lines.title') }), { + helpString('intro.areas.play', { next: t('intro.lines.title') }), { tooltipBox: '.intro-nav-wrap .chapter-line', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/building.js b/modules/ui/intro/building.js index 00f6a3ea86..226127b33a 100644 --- a/modules/ui/intro/building.js +++ b/modules/ui/intro/building.js @@ -5,11 +5,11 @@ import { } from 'd3-selection'; import { presetManager } from '../../presets'; -import { t, localizer } from '../../core/localizer'; +import { t } from '../../core/localizer'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilArrayUniq, utilRebind } from '../../util'; -import { icon, pad, isMostlySquare, selectMenuItem, transitionTime } from './helper'; +import { helpString, icon, pad, isMostlySquare, selectMenuItem, transitionTime } from './helper'; export function uiIntroBuilding(context, reveal) { @@ -54,24 +54,6 @@ export function uiIntroBuilding(context, reveal) { } - function revealEditMenu(loc, text, options) { - var rect = context.surfaceRect(); - var point = context.curtainProjection(loc); - var pad = 40; - var width = 250 + (2 * pad); - var height = 350; - var startX = rect.left + point[0]; - var left = (localizer.textDirection() === 'rtl') ? (startX - width + pad) : (startX - pad); - var box = { - left: left, - top: point[1] + rect.top - 60, - width: width, - height: height - }; - reveal(box, text, options); - } - - function addHouse() { context.enter(modeBrowse(context)); context.history().reset('initial'); @@ -83,7 +65,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { var tooltip = reveal('button.add-area', - t('intro.buildings.add_building', { button: icon('#iD-icon-area', 'pre-text') })); + helpString('intro.buildings.add_building')); tooltip.selectAll('.popover-inner') .insert('svg', 'span') @@ -113,10 +95,12 @@ export function uiIntroBuilding(context, reveal) { context.map().zoomEase(20, 500); timeout(function() { - revealHouse(house, t('intro.buildings.start_building')); + var startString = helpString('intro.buildings.start_building') + + helpString('intro.buildings.building_corner_' + (context.lastPointerType() === 'mouse' ? 'click' : 'tap')); + revealHouse(house, startString); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.start_building'), { duration: 0 }); + revealHouse(house, startString, { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -141,10 +125,14 @@ export function uiIntroBuilding(context, reveal) { _houseID = null; - revealHouse(house, t('intro.buildings.continue_building')); + var continueString = helpString('intro.buildings.continue_building') + '{br}' + + helpString('intro.areas.finish_area_' + (context.lastPointerType() === 'mouse' ? 'click' : 'tap')) + + helpString('intro.buildings.finish_building'); + + revealHouse(house, continueString); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.continue_building'), { duration: 0 }); + revealHouse(house, continueString, { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -180,12 +168,12 @@ export function uiIntroBuilding(context, reveal) { function retryHouse() { var onClick = function() { continueTo(addHouse); }; - revealHouse(house, t('intro.buildings.retry_building'), + revealHouse(house, helpString('intro.buildings.retry_building'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.retry_building'), + revealHouse(house, helpString('intro.buildings.retry_building'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -216,7 +204,7 @@ export function uiIntroBuilding(context, reveal) { var button = context.container().select('.preset-category-building .preset-list-button'); reveal(button.node(), - t('intro.buildings.choose_category_building', { category: buildingCatetory.name() }) + helpString('intro.buildings.choose_category_building', { category: buildingCatetory.name() }) ); button.on('click.intro', function() { @@ -265,7 +253,7 @@ export function uiIntroBuilding(context, reveal) { var button = context.container().select('.preset-building-house .preset-list-button'); reveal(button.node(), - t('intro.buildings.choose_preset_house', { preset: housePreset.name() }), + helpString('intro.buildings.choose_preset_house', { preset: housePreset.name() }), { duration: 300 } ); @@ -312,7 +300,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.buildings.close', { button: icon('#iD-icon-apply', 'pre-text') }) + helpString('intro.buildings.close', { button: icon('#iD-icon-close', 'pre-text') }) ); }, 500); @@ -347,7 +335,8 @@ export function uiIntroBuilding(context, reveal) { }); context.map().on('move.intro drawn.intro', function() { - revealHouse(house, t('intro.buildings.rightclick_building'), { duration: 0 }); + var rightclickString = helpString('intro.buildings.' + (context.lastPointerType() === 'mouse' ? 'rightclick_building' : 'edit_menu_building_touch')); + revealHouse(house, rightclickString, { duration: 0 }); }); context.history().on('change.intro', function() { @@ -372,10 +361,10 @@ export function uiIntroBuilding(context, reveal) { if (!node) { return continueTo(rightClickHouse); } var wasChanged = false; - var menuCoords = context.map().mouseCoordinates(); - revealEditMenu(menuCoords, - t('intro.buildings.square_building', { button: icon('#iD-operation-orthogonalize', 'pre-text') }) + reveal('.edit-menu', + helpString('intro.buildings.square_building'), + { padding: 50 } ); context.on('enter.intro', function(mode) { @@ -390,9 +379,9 @@ export function uiIntroBuilding(context, reveal) { var node = selectMenuItem(context, 'orthogonalize').node(); if (!wasChanged && !node) { return continueTo(rightClickHouse); } - revealEditMenu(menuCoords, - t('intro.buildings.square_building', { button: icon('#iD-operation-orthogonalize', 'pre-text') }), - { duration: 0 } + reveal('.edit-menu', + helpString('intro.buildings.square_building'), + { duration: 0, padding: 50 } ); }); @@ -422,7 +411,7 @@ export function uiIntroBuilding(context, reveal) { function retryClickSquare() { context.enter(modeBrowse(context)); - revealHouse(house, t('intro.buildings.retry_square'), { + revealHouse(house, helpString('intro.buildings.retry_square'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(rightClickHouse); } }); @@ -436,7 +425,7 @@ export function uiIntroBuilding(context, reveal) { function doneSquare() { context.history().checkpoint('doneSquare'); - revealHouse(house, t('intro.buildings.done_square'), { + revealHouse(house, helpString('intro.buildings.done_square'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(addTank); } }); @@ -458,7 +447,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { reveal('button.add-area', - t('intro.buildings.add_tank', { button: icon('#iD-icon-area', 'pre-text') }) + helpString('intro.buildings.add_tank') ); context.on('enter.intro', function(mode) { @@ -482,10 +471,12 @@ export function uiIntroBuilding(context, reveal) { _tankID = null; timeout(function() { - revealTank(tank, t('intro.buildings.start_tank')); + var startString = helpString('intro.buildings.start_tank') + + helpString('intro.buildings.tank_edge_' + (context.lastPointerType() === 'mouse' ? 'click' : 'tap')); + revealTank(tank, startString); context.map().on('move.intro drawn.intro', function() { - revealTank(tank, t('intro.buildings.start_tank'), { duration: 0 }); + revealTank(tank, startString, { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -510,10 +501,14 @@ export function uiIntroBuilding(context, reveal) { _tankID = null; - revealTank(tank, t('intro.buildings.continue_tank')); + var continueString = helpString('intro.buildings.continue_tank') + '{br}' + + helpString('intro.areas.finish_area_' + (context.lastPointerType() === 'mouse' ? 'click' : 'tap')) + + helpString('intro.buildings.finish_tank'); + + revealTank(tank, continueString); context.map().on('move.intro drawn.intro', function() { - revealTank(tank, t('intro.buildings.continue_tank'), { duration: 0 }); + revealTank(tank, continueString, { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -556,7 +551,7 @@ export function uiIntroBuilding(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.buildings.search_tank', { preset: tankPreset.name() }) + helpString('intro.buildings.search_tank', { preset: tankPreset.name() }) ); }, 400); // after preset list pane visible.. @@ -580,7 +575,7 @@ export function uiIntroBuilding(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.buildings.search_tank', { preset: tankPreset.name() }) + helpString('intro.buildings.search_tank', { preset: tankPreset.name() }) ); context.history().on('change.intro', null); @@ -592,7 +587,7 @@ export function uiIntroBuilding(context, reveal) { if (first.classed('preset-man_made-storage_tank')) { reveal(first.select('.preset-list-button').node(), - t('intro.buildings.choose_tank', { preset: tankPreset.name() }), + helpString('intro.buildings.choose_tank', { preset: tankPreset.name() }), { duration: 300 } ); @@ -633,7 +628,7 @@ export function uiIntroBuilding(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.buildings.close', { button: icon('#iD-icon-apply', 'pre-text') }) + helpString('intro.buildings.close', { button: icon('#iD-icon-close', 'pre-text') }) ); }, 500); @@ -664,10 +659,12 @@ export function uiIntroBuilding(context, reveal) { }, 50); // after menu visible }); - revealTank(tank, t('intro.buildings.rightclick_tank')); + var rightclickString = helpString('intro.buildings.' + (context.lastPointerType() === 'mouse' ? 'rightclick_tank' : 'edit_menu_tank_touch')); + + revealTank(tank, rightclickString); context.map().on('move.intro drawn.intro', function() { - revealTank(tank, t('intro.buildings.rightclick_tank'), { duration: 0 }); + revealTank(tank, rightclickString, { duration: 0 }); }); context.history().on('change.intro', function() { @@ -694,10 +691,10 @@ export function uiIntroBuilding(context, reveal) { if (!node) { return continueTo(rightClickTank); } var wasChanged = false; - var menuCoords = context.map().mouseCoordinates(); - revealEditMenu(menuCoords, - t('intro.buildings.circle_tank', { button: icon('#iD-operation-circularize', 'pre-text') }) + reveal('.edit-menu', + helpString('intro.buildings.circle_tank'), + { padding: 50 } ); context.on('enter.intro', function(mode) { @@ -712,9 +709,9 @@ export function uiIntroBuilding(context, reveal) { var node = selectMenuItem(context, 'circularize').node(); if (!wasChanged && !node) { return continueTo(rightClickTank); } - revealEditMenu(menuCoords, - t('intro.buildings.circle_tank', { button: icon('#iD-operation-circularize', 'pre-text') }), - { duration: 0 } + reveal('.edit-menu', + helpString('intro.buildings.circle_tank'), + { duration: 0, padding: 50 } ); }); @@ -744,7 +741,7 @@ export function uiIntroBuilding(context, reveal) { function retryClickCircle() { context.enter(modeBrowse(context)); - revealTank(tank, t('intro.buildings.retry_circle'), { + revealTank(tank, helpString('intro.buildings.retry_circle'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(rightClickTank); } }); @@ -758,7 +755,7 @@ export function uiIntroBuilding(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.buildings.play', { next: t('intro.startediting.title') }), { + helpString('intro.buildings.play', { next: t('intro.startediting.title') }), { tooltipBox: '.intro-nav-wrap .chapter-startEditing', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/helper.js b/modules/ui/intro/helper.js index 7249d2e817..36a4554f28 100644 --- a/modules/ui/intro/helper.js +++ b/modules/ui/intro/helper.js @@ -1,6 +1,6 @@ -import { t } from '../../core/localizer'; +import { t, localizer } from '../../core/localizer'; import { geoSphericalDistance, geoVecNormalizedDot } from '../../geo'; - +import { uiCmd } from '../cmd'; export function pointBox(loc, context) { var rect = context.surfaceRect(); @@ -42,6 +42,96 @@ export function icon(name, svgklass, useklass) { (useklass ? ' class="' + useklass + '"' : '') + '>'; } +var helpStringReplacements; + +// Returns the localized string for `id` with a standardized set of icon, key, and +// label replacements suitable for tutorials and documentation. Optionally supplemented +// with custom `replacements` +export function helpString(id, replacements) { + // only load these the first time + if (!helpStringReplacements) helpStringReplacements = { + // insert icons corresponding to various UI elements + point_icon: icon('#iD-icon-point', 'pre-text'), + line_icon: icon('#iD-icon-line', 'pre-text'), + area_icon: icon('#iD-icon-area', 'pre-text'), + note_icon: icon('#iD-icon-note', 'pre-text add-note'), + plus: icon('#iD-icon-plus', 'pre-text'), + minus: icon('#iD-icon-minus', 'pre-text'), + move_icon: icon('#iD-operation-move', 'pre-text operation'), + merge_icon: icon('#iD-operation-merge', 'pre-text operation'), + delete_icon: icon('#iD-operation-delete', 'pre-text operation'), + circularize_icon: icon('#iD-operation-circularize', 'pre-text operation'), + split_icon: icon('#iD-operation-split', 'pre-text operation'), + orthogonalize_icon: icon('#iD-operation-orthogonalize', 'pre-text operation'), + disconnect_icon: icon('#iD-operation-disconnect', 'pre-text operation'), + layers_icon: icon('#iD-icon-layers', 'pre-text'), + data_icon: icon('#iD-icon-data', 'pre-text'), + inspect: icon('#iD-icon-inspect', 'pre-text'), + help_icon: icon('#iD-icon-help', 'pre-text'), + undo_icon: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-redo' : '#iD-icon-undo', 'pre-text'), + redo_icon: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-undo' : '#iD-icon-redo', 'pre-text'), + save_icon: icon('#iD-icon-save', 'pre-text'), + leftclick: icon('#iD-walkthrough-mouse-left', 'pre-text operation'), + rightclick: icon('#iD-walkthrough-mouse-right', 'pre-text operation'), + mousewheel_icon: icon('#iD-walkthrough-mousewheel', 'pre-text operation'), + tap_icon: icon('#iD-walkthrough-tap', 'pre-text operation'), + doubletap_icon: icon('#iD-walkthrough-doubletap', 'pre-text operation'), + longpress_icon: icon('#iD-walkthrough-longpress', 'pre-text operation'), + touchdrag_icon: icon('#iD-walkthrough-touchdrag', 'pre-text operation'), + pinch_icon: icon('#iD-walkthrough-pinch-apart', 'pre-text operation'), + + // insert keys; may be localized and platform-dependent + shift: uiCmd.display('⇧'), + alt: uiCmd.display('⌥'), + return: uiCmd.display('↵'), + esc: t('shortcuts.key.esc'), + space: t('shortcuts.key.space'), + add_note_key: t('modes.add_note.key'), + help_key: t('help.key'), + shortcuts_key: t('shortcuts.toggle.key'), + + // reference localized UI labels directly so that they'll always match + save: t('save.title'), + undo: t('undo.title'), + redo: t('redo.title'), + upload: t('commit.save'), + point: t('modes.add_point.title'), + line: t('modes.add_line.title'), + area: t('modes.add_area.title'), + note: t('modes.add_note.title'), + delete: t('operations.delete.title'), + move: t('operations.move.title'), + orthogonalize: t('operations.orthogonalize.title'), + circularize: t('operations.circularize.title'), + merge: t('operations.merge.title'), + disconnect: t('operations.disconnect.title'), + split: t('operations.split.title'), + map_data: t('map_data.title'), + osm_notes: t('map_data.layers.notes.title'), + fields: t('inspector.fields'), + tags: t('inspector.tags'), + relations: t('inspector.relations'), + new_relation: t('inspector.new_relation'), + turn_restrictions: t('presets.fields.restrictions.label'), + background_settings: t('background.description'), + imagery_offset: t('background.fix_misalignment'), + start_the_walkthrough: t('splash.walkthrough'), + help: t('help.title'), + ok: t('intro.ok') + }; + + var reps; + if (replacements) { + reps = Object.assign(replacements, helpStringReplacements); + } else { + reps = helpStringReplacements; + } + + return t(id, reps) + // use keyboard key styling for shortcuts + .replace(/\`(.*?)\`/g, '$1'); +} + function slugify(text) { return text.toString().toLowerCase() diff --git a/modules/ui/intro/line.js b/modules/ui/intro/line.js index 6e4440dccf..72fcb0ac2b 100644 --- a/modules/ui/intro/line.js +++ b/modules/ui/intro/line.js @@ -6,12 +6,12 @@ import { } from 'd3-selection'; import { presetManager } from '../../presets'; -import { t, localizer } from '../../core/localizer'; +import { t } from '../../core/localizer'; import { geoSphericalDistance } from '../../geo'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { icon, pad, selectMenuItem, transitionTime } from './helper'; +import { helpString, icon, pad, selectMenuItem, transitionTime } from './helper'; export function uiIntroLine(context, reveal) { @@ -56,24 +56,6 @@ export function uiIntroLine(context, reveal) { } - function revealEditMenu(loc, text, options) { - var rect = context.surfaceRect(); - var point = context.curtainProjection(loc); - var pad = 40; - var width = 250 + (2 * pad); - var height = 350; - var startX = rect.left + point[0]; - var left = (localizer.textDirection() === 'rtl') ? (startX - width + pad) : (startX - pad); - var box = { - left: left, - top: point[1] + rect.top - 60, - width: width, - height: height - }; - reveal(box, text, options); - } - - function addLine() { context.enter(modeBrowse(context)); context.history().reset('initial'); @@ -84,7 +66,7 @@ export function uiIntroLine(context, reveal) { timeout(function() { var tooltip = reveal('button.add-line', - t('intro.lines.add_line', { button: icon('#iD-icon-line', 'pre-text') })); + helpString('intro.lines.add_line')); tooltip.selectAll('.popover-inner') .insert('svg', 'span') @@ -113,13 +95,18 @@ export function uiIntroLine(context, reveal) { var padding = 70 * Math.pow(2, context.map().zoom() - 18); var box = pad(tulipRoadStart, padding, context); box.height = box.height + 100; - reveal(box, t('intro.lines.start_line')); + + var textId = context.lastPointerType() === 'mouse' ? 'start_line' : 'start_line_tap'; + var startLineString = helpString('intro.lines.missing_road') + '{br}' + + helpString('intro.lines.line_draw_info') + + helpString('intro.lines.' + textId); + reveal(box, startLineString); context.map().on('move.intro drawn.intro', function() { padding = 70 * Math.pow(2, context.map().zoom() - 18); box = pad(tulipRoadStart, padding, context); box.height = box.height + 100; - reveal(box, t('intro.lines.start_line'), { duration: 0 }); + reveal(box, startLineString, { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -146,7 +133,7 @@ export function uiIntroLine(context, reveal) { var box = pad(tulipRoadMidpoint, padding, context); box.height = box.height * 2; reveal(box, - t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }) + helpString('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }) ); context.map().on('move.intro drawn.intro', function() { @@ -154,7 +141,7 @@ export function uiIntroLine(context, reveal) { box = pad(tulipRoadMidpoint, padding, context); box.height = box.height * 2; reveal(box, - t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }), + helpString('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }), { duration: 0 } ); }); @@ -204,7 +191,7 @@ export function uiIntroLine(context, reveal) { var box = pad(tulipRoadIntersection, 80, context); reveal(box, - t('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') }) + helpString('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') }) ); timeout(chapter.restart, 3000); @@ -218,7 +205,11 @@ export function uiIntroLine(context, reveal) { context.map().centerEase(tulipRoadIntersection, 500); - reveal('.surface', t('intro.lines.continue_line')); + var continueLineText = helpString('intro.lines.continue_line') + '{br}' + + helpString('intro.lines.finish_line_' + (context.lastPointerType() === 'mouse' ? 'click' : 'tap')) + + helpString('intro.lines.finish_road'); + + reveal('.surface', continueLineText); context.on('enter.intro', function(mode) { if (mode.id === 'draw-line') @@ -254,7 +245,7 @@ export function uiIntroLine(context, reveal) { context.container().select('.inspector-wrap .panewrap').style('right', '-100%'); reveal(button.node(), - t('intro.lines.choose_category_road', { category: roadCategory.name() }) + helpString('intro.lines.choose_category_road', { category: roadCategory.name() }) ); button.on('click.intro', function() { @@ -294,7 +285,7 @@ export function uiIntroLine(context, reveal) { timeout(function() { reveal(subgrid.node(), - t('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }), + helpString('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }), { tooltipBox: '.preset-highway-residential .preset-list-button', duration: 300 } ); }, 300); @@ -322,7 +313,7 @@ export function uiIntroLine(context, reveal) { var button = context.container().select('.entity-editor-pane .preset-list-button'); reveal(button.node(), - t('intro.lines.retry_preset_residential', { preset: residentialPreset.name() }) + helpString('intro.lines.retry_preset_residential', { preset: residentialPreset.name() }) ); button.on('click.intro', function() { @@ -347,7 +338,7 @@ export function uiIntroLine(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.lines.name_road', { button: icon('#iD-icon-apply', 'pre-text') }), + helpString('intro.lines.name_road', { button: icon('#iD-icon-close', 'pre-text') }), { tooltipClass: 'intro-lines-name_road' } ); }, 500); @@ -363,7 +354,7 @@ export function uiIntroLine(context, reveal) { context.history().checkpoint('doneAddLine'); timeout(function() { - reveal('.surface', t('intro.lines.did_name_road'), { + reveal('.surface', helpString('intro.lines.did_name_road'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(updateLine); } }); @@ -390,14 +381,14 @@ export function uiIntroLine(context, reveal) { var box = pad(woodRoadDragMidpoint, padding, context); var advance = function() { continueTo(addNode); }; - reveal(box, t('intro.lines.update_line'), + reveal(box, helpString('intro.lines.update_line'), { buttonText: t('intro.ok'), buttonCallback: advance } ); context.map().on('move.intro drawn.intro', function() { var padding = 250 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragMidpoint, padding, context); - reveal(box, t('intro.lines.update_line'), + reveal(box, helpString('intro.lines.update_line'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -418,12 +409,13 @@ export function uiIntroLine(context, reveal) { var padding = 40 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadAddNode, padding, context); - reveal(box, t('intro.lines.add_node')); + var addNodeString = helpString('intro.lines.add_node' + (context.lastPointerType() === 'mouse' ? '' : '_touch')); + reveal(box, addNodeString); context.map().on('move.intro drawn.intro', function() { var padding = 40 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadAddNode, padding, context); - reveal(box, t('intro.lines.add_node'), { duration: 0 }); + reveal(box, addNodeString, { duration: 0 }); }); context.history().on('change.intro', function(changed) { @@ -456,7 +448,9 @@ export function uiIntroLine(context, reveal) { } var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.start_drag_endpoint')); + var startDragString = helpString('intro.lines.start_drag_endpoint' + (context.lastPointerType() === 'mouse' ? '' : '_touch')) + + helpString('intro.lines.drag_to_intersection'); + reveal(box, startDragString); context.map().on('move.intro drawn.intro', function() { if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) { @@ -464,7 +458,7 @@ export function uiIntroLine(context, reveal) { } var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.start_drag_endpoint'), { duration: 0 }); + reveal(box, startDragString, { duration: 0 }); var entity = context.entity(woodRoadEndID); if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 4) { @@ -486,7 +480,9 @@ export function uiIntroLine(context, reveal) { var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.finish_drag_endpoint')); + var finishDragString = helpString('intro.lines.spot_looks_good') + + helpString('intro.lines.finish_drag_endpoint' + (context.lastPointerType() === 'mouse' ? '' : '_touch')); + reveal(box, finishDragString); context.map().on('move.intro drawn.intro', function() { if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) { @@ -494,7 +490,7 @@ export function uiIntroLine(context, reveal) { } var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); - reveal(box, t('intro.lines.finish_drag_endpoint'), { duration: 0 }); + reveal(box, finishDragString, { duration: 0 }); var entity = context.entity(woodRoadEndID); if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 4) { @@ -524,7 +520,7 @@ export function uiIntroLine(context, reveal) { var padding = 80 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragMidpoint, padding, context); - reveal(box, t('intro.lines.start_drag_midpoint')); + reveal(box, helpString('intro.lines.start_drag_midpoint')); context.map().on('move.intro drawn.intro', function() { if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) { @@ -532,7 +528,7 @@ export function uiIntroLine(context, reveal) { } var padding = 80 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragMidpoint, padding, context); - reveal(box, t('intro.lines.start_drag_midpoint'), { duration: 0 }); + reveal(box, helpString('intro.lines.start_drag_midpoint'), { duration: 0 }); }); context.history().on('change.intro', function(changed) { @@ -571,7 +567,7 @@ export function uiIntroLine(context, reveal) { continueTo(deleteLines); }; - reveal(box, t('intro.lines.continue_drag_midpoint'), + reveal(box, helpString('intro.lines.continue_drag_midpoint'), { buttonText: t('intro.ok'), buttonCallback: advance } ); @@ -582,7 +578,7 @@ export function uiIntroLine(context, reveal) { var padding = 100 * Math.pow(2, context.map().zoom() - 19); var box = pad(woodRoadDragEndpoint, padding, context); box.height += 400; - reveal(box, t('intro.lines.continue_drag_midpoint'), + reveal(box, helpString('intro.lines.continue_drag_midpoint'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -615,7 +611,7 @@ export function uiIntroLine(context, reveal) { box.height += 400; var advance = function() { continueTo(rightClickIntersection); }; - reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), + reveal(box, helpString('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), { buttonText: t('intro.ok'), buttonCallback: advance } ); @@ -624,7 +620,7 @@ export function uiIntroLine(context, reveal) { var box = pad(deleteLinesLoc, padding, context); box.top -= 200; box.height += 400; - reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), + reveal(box, helpString('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -651,18 +647,21 @@ export function uiIntroLine(context, reveal) { context.map().centerZoomEase(eleventhAvenueEnd, 18, 500); + var rightClickString = helpString('intro.lines.split_street', { + street1: t('intro.graph.name.11th-avenue'), + street2: t('intro.graph.name.washington-street') + }) + + helpString('intro.lines.' + (context.lastPointerType() === 'mouse' ? 'rightclick_intersection' : 'edit_menu_intersection_touch')); + timeout(function() { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.rightclick_intersection', - { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }) - ); + reveal(box, rightClickString); context.map().on('move.intro drawn.intro', function() { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.rightclick_intersection', - { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }), + reveal(box, rightClickString, { duration: 0 } ); }); @@ -707,20 +706,20 @@ export function uiIntroLine(context, reveal) { if (!node) { return continueTo(rightClickIntersection); } var wasChanged = false; - var menuCoords = context.map().mouseCoordinates(); _washingtonSegmentID = null; - revealEditMenu(menuCoords, t('intro.lines.split_intersection', - { button: icon('#iD-operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }) + reveal('.edit-menu', helpString('intro.lines.split_intersection', + { street: t('intro.graph.name.washington-street') }), + { padding: 50 } ); context.map().on('move.intro drawn.intro', function() { var node = selectMenuItem(context, 'split').node(); if (!wasChanged && !node) { return continueTo(rightClickIntersection); } - revealEditMenu(menuCoords, t('intro.lines.split_intersection', - { button: icon('#iD-operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }), - { duration: 0 } + reveal('.edit-menu', helpString('intro.lines.split_intersection', + { street: t('intro.graph.name.washington-street') }), + { duration: 0, padding: 50 } ); }); @@ -752,14 +751,14 @@ export function uiIntroLine(context, reveal) { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.retry_split'), + reveal(box, helpString('intro.lines.retry_split'), { buttonText: t('intro.ok'), buttonCallback: advance } ); context.map().on('move.intro drawn.intro', function() { var padding = 60 * Math.pow(2, context.map().zoom() - 18); var box = pad(eleventhAvenueEnd, padding, context); - reveal(box, t('intro.lines.retry_split'), + reveal(box, helpString('intro.lines.retry_split'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance } ); }); @@ -787,7 +786,7 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); box.width = box.width / 2; - reveal(box, t(string, { street1: street, street2: street }), + reveal(box, helpString(string, { street1: street, street2: street }), { duration: 500 } ); @@ -798,7 +797,7 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); box.width = box.width / 2; - reveal(box, t(string, { street1: street, street2: street }), + reveal(box, helpString(string, { street1: street, street2: street }), { duration: 0 } ); }); @@ -868,7 +867,10 @@ export function uiIntroLine(context, reveal) { } reveal(box, - t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }) + helpString('intro.lines.multi_select', + { selected: selected, other1: other }) + ' ' + + helpString('intro.lines.add_to_selection_' + (context.lastPointerType() === 'mouse' ? 'click' : 'touch'), + { selected: selected, other2: other }) ); context.map().on('move.intro drawn.intro', function() { @@ -887,7 +889,10 @@ export function uiIntroLine(context, reveal) { } reveal(box, - t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }), + helpString('intro.lines.multi_select', + { selected: selected, other1: other }) + ' ' + + helpString('intro.lines.add_to_selection_' + (context.lastPointerType() === 'mouse' ? 'click' : 'touch'), + { selected: selected, other2: other }), { duration: 0 } ); }); @@ -927,15 +932,20 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); - reveal(box, t('intro.lines.multi_rightclick')); + + var rightClickString = helpString('intro.lines.multi_select_success') + + helpString('intro.lines.multi_' + (context.lastPointerType() === 'mouse' ? 'rightclick' : 'edit_menu_touch')); + reveal(box, rightClickString); context.map().on('move.intro drawn.intro', function() { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); - reveal(box, t('intro.lines.multi_rightclick'), { duration: 0 }); + reveal(box, rightClickString, { duration: 0 }); }); - d3_select(window).on('click.intro contextmenu.intro', function() { + context.ui().editMenu().on('toggled.intro', function(open) { + if (!open) return; + timeout(function() { var ids = context.selectedIDs(); if (ids.length === 2 && @@ -951,7 +961,7 @@ export function uiIntroLine(context, reveal) { return continueTo(didSplit); } }, 300); // after edit menu visible - }, true); + }); context.history().on('change.intro', function() { if (!_washingtonSegmentID || @@ -965,7 +975,7 @@ export function uiIntroLine(context, reveal) { function continueTo(nextStep) { context.map().on('move.intro drawn.intro', null); - d3_select(window).on('click.intro contextmenu.intro', null, true); + context.ui().editMenu().on('toggled.intro', null); context.history().on('change.intro', null); nextStep(); } @@ -984,15 +994,15 @@ export function uiIntroLine(context, reveal) { var node = selectMenuItem(context, 'delete').node(); if (!node) return continueTo(multiRightClick); - var menuCoords = context.map().mouseCoordinates(); - revealEditMenu(menuCoords, - t('intro.lines.multi_delete', { button: icon('#iD-operation-delete', 'pre-text') }) + reveal('.edit-menu', + helpString('intro.lines.multi_delete'), + { padding: 50 } ); context.map().on('move.intro drawn.intro', function() { - revealEditMenu(menuCoords, - t('intro.lines.multi_delete', { button: icon('#iD-operation-delete', 'pre-text') }), - { duration: 0 } + reveal('.edit-menu', + helpString('intro.lines.multi_delete'), + { duration: 0, padding: 50 } ); }); @@ -1024,7 +1034,7 @@ export function uiIntroLine(context, reveal) { var padding = 200 * Math.pow(2, context.map().zoom() - 18); var box = pad(twelfthAvenue, padding, context); - reveal(box, t('intro.lines.retry_delete'), { + reveal(box, helpString('intro.lines.retry_delete'), { buttonText: t('intro.ok'), buttonCallback: function() { continueTo(multiSelect); } }); @@ -1038,7 +1048,7 @@ export function uiIntroLine(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.lines.play', { next: t('intro.buildings.title') }), { + helpString('intro.lines.play', { next: t('intro.buildings.title') }), { tooltipBox: '.intro-nav-wrap .chapter-building', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/navigation.js b/modules/ui/intro/navigation.js index 6b9e20b6bf..87ee5828e2 100644 --- a/modules/ui/intro/navigation.js +++ b/modules/ui/intro/navigation.js @@ -10,7 +10,7 @@ import { t } from '../../core/localizer'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { icon, pointBox, transitionTime } from './helper'; +import { helpString, icon, pointBox, transitionTime } from './helper'; export function uiIntroNavigation(context, reveal) { @@ -58,9 +58,11 @@ export function uiIntroNavigation(context, reveal) { timeout(function() { var centerStart = context.map().center(); - reveal('.surface', t('intro.navigation.drag')); + var textId = context.lastPointerType() === 'mouse' ? 'drag' : 'drag_touch'; + var dragString = helpString('intro.navigation.map_info') + '{br}' + helpString('intro.navigation.' + textId); + reveal('.surface', dragString); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.drag'), { duration: 0 }); + reveal('.surface', dragString, { duration: 0 }); }); context.map().on('move.intro', function() { @@ -83,20 +85,13 @@ export function uiIntroNavigation(context, reveal) { function zoomMap() { var zoomStart = context.map().zoom(); - reveal('.surface', - t('intro.navigation.zoom', { - plus: icon('#iD-icon-plus', 'pre-text'), - minus: icon('#iD-icon-minus', 'pre-text') - }) - ); + var textId = context.lastPointerType() === 'mouse' ? 'zoom' : 'zoom_touch'; + var zoomString = helpString('intro.navigation.' + textId); + + reveal('.surface', zoomString); context.map().on('drawn.intro', function() { - reveal('.surface', - t('intro.navigation.zoom', { - plus: icon('#iD-icon-plus', 'pre-text'), - minus: icon('#iD-icon-minus', 'pre-text') - }), { duration: 0 } - ); + reveal('.surface', zoomString, { duration: 0 }); }); context.map().on('move.intro', function() { @@ -116,12 +111,12 @@ export function uiIntroNavigation(context, reveal) { function features() { var onClick = function() { continueTo(pointsLinesAreas); }; - reveal('.surface', t('intro.navigation.features'), + reveal('.surface', helpString('intro.navigation.features'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.features'), + reveal('.surface', helpString('intro.navigation.features'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -135,12 +130,12 @@ export function uiIntroNavigation(context, reveal) { function pointsLinesAreas() { var onClick = function() { continueTo(nodesWays); }; - reveal('.surface', t('intro.navigation.points_lines_areas'), + reveal('.surface', helpString('intro.navigation.points_lines_areas'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.points_lines_areas'), + reveal('.surface', helpString('intro.navigation.points_lines_areas'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -154,12 +149,12 @@ export function uiIntroNavigation(context, reveal) { function nodesWays() { var onClick = function() { continueTo(clickTownHall); }; - reveal('.surface', t('intro.navigation.nodes_ways'), + reveal('.surface', helpString('intro.navigation.nodes_ways'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); context.map().on('drawn.intro', function() { - reveal('.surface', t('intro.navigation.nodes_ways'), + reveal('.surface', helpString('intro.navigation.nodes_ways'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -183,13 +178,14 @@ export function uiIntroNavigation(context, reveal) { var entity = context.hasEntity(hallId); if (!entity) return; var box = pointBox(entity.loc, context); - reveal(box, t('intro.navigation.click_townhall')); + var textId = context.lastPointerType() === 'mouse' ? 'click_townhall' : 'tap_townhall'; + reveal(box, helpString('intro.navigation.' + textId)); context.map().on('move.intro drawn.intro', function() { var entity = context.hasEntity(hallId); if (!entity) return; var box = pointBox(entity.loc, context); - reveal(box, t('intro.navigation.click_townhall'), { duration: 0 }); + reveal(box, helpString('intro.navigation.' + textId), { duration: 0 }); }); context.on('enter.intro', function() { @@ -222,7 +218,7 @@ export function uiIntroNavigation(context, reveal) { var box = pointBox(entity.loc, context); var onClick = function() { continueTo(editorTownHall); }; - reveal(box, t('intro.navigation.selected_townhall'), + reveal(box, helpString('intro.navigation.selected_townhall'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -230,7 +226,7 @@ export function uiIntroNavigation(context, reveal) { var entity = context.hasEntity(hallId); if (!entity) return; var box = pointBox(entity.loc, context); - reveal(box, t('intro.navigation.selected_townhall'), + reveal(box, helpString('intro.navigation.selected_townhall'), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -258,7 +254,7 @@ export function uiIntroNavigation(context, reveal) { var onClick = function() { continueTo(presetTownHall); }; reveal('.entity-editor-pane', - t('intro.navigation.editor_townhall'), + helpString('intro.navigation.editor_townhall'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -296,7 +292,7 @@ export function uiIntroNavigation(context, reveal) { var onClick = function() { continueTo(fieldsTownHall); }; reveal('.entity-editor-pane .section-feature-type', - t('intro.navigation.preset_townhall', { preset: preset.name() }), + helpString('intro.navigation.preset_townhall', { preset: preset.name() }), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -330,7 +326,7 @@ export function uiIntroNavigation(context, reveal) { var onClick = function() { continueTo(closeTownHall); }; reveal('.entity-editor-pane .section-preset-fields', - t('intro.navigation.fields_townhall'), + helpString('intro.navigation.fields_townhall'), { buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -360,7 +356,7 @@ export function uiIntroNavigation(context, reveal) { var href = d3_select(selector).attr('href') || '#iD-icon-close'; reveal('.entity-editor-pane', - t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }) + helpString('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }) ); context.on('exit.intro', function() { @@ -373,7 +369,7 @@ export function uiIntroNavigation(context, reveal) { var href = d3_select(selector).attr('href') || '#iD-icon-close'; reveal('.entity-editor-pane', - t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }), + helpString('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }), { duration: 0 } ); }); @@ -396,7 +392,7 @@ export function uiIntroNavigation(context, reveal) { timeout(function() { reveal('.search-header input', - t('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') }) + helpString('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') }) ); context.container().select('.search-header input') @@ -412,7 +408,7 @@ export function uiIntroNavigation(context, reveal) { if (!firstName.empty() && firstName.text() === name) { reveal(first.node(), - t('intro.navigation.choose_street', { name: name }), + helpString('intro.navigation.choose_street', { name: name }), { duration: 300 } ); @@ -446,7 +442,7 @@ export function uiIntroNavigation(context, reveal) { box.height = 500; reveal(box, - t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), + helpString('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), { duration: 600, buttonText: t('intro.ok'), buttonCallback: onClick } ); @@ -457,7 +453,7 @@ export function uiIntroNavigation(context, reveal) { var box = pointBox(entity.loc, context); box.height = 500; reveal(box, - t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), + helpString('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }), { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick } ); }); @@ -495,13 +491,12 @@ export function uiIntroNavigation(context, reveal) { var selector = '.entity-editor-pane button.close svg use'; var href = d3_select(selector).attr('href') || '#iD-icon-close'; - reveal('.entity-editor-pane', - t('intro.navigation.editor_street', { + reveal('.entity-editor-pane', helpString('intro.navigation.street_different_fields') + '{br}' + + helpString('intro.navigation.editor_street', { button: icon(href, 'pre-text'), field1: onewayField.label(), field2: maxspeedField.label() - }) - ); + })); context.on('exit.intro', function() { continueTo(play); @@ -512,11 +507,11 @@ export function uiIntroNavigation(context, reveal) { var selector = '.entity-editor-pane button.close svg use'; var href = d3_select(selector).attr('href') || '#iD-icon-close'; - reveal('.entity-editor-pane', - t('intro.navigation.editor_street', { + reveal('.entity-editor-pane', helpString('intro.navigation.street_different_fields') + '{br}' + + helpString('intro.navigation.editor_street', { button: icon(href, 'pre-text'), - field1: onewayField.label().toLowerCase(), - field2: maxspeedField.label().toLowerCase() + field1: onewayField.label(), + field2: maxspeedField.label() }), { duration: 0 } ); }); @@ -532,7 +527,7 @@ export function uiIntroNavigation(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.navigation.play', { next: t('intro.points.title') }), { + helpString('intro.navigation.play', { next: t('intro.points.title') }), { tooltipBox: '.intro-nav-wrap .chapter-point', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/point.js b/modules/ui/intro/point.js index a10c96072f..8aa6fe53af 100644 --- a/modules/ui/intro/point.js +++ b/modules/ui/intro/point.js @@ -5,12 +5,12 @@ import { } from 'd3-selection'; import { presetManager } from '../../presets'; -import { t, localizer } from '../../core/localizer'; +import { t } from '../../core/localizer'; import { actionChangePreset } from '../../actions/change_preset'; import { modeBrowse } from '../../modes/browse'; import { modeSelect } from '../../modes/select'; import { utilRebind } from '../../util/rebind'; -import { icon, pointBox, pad, selectMenuItem, transitionTime } from './helper'; +import { helpString, icon, pointBox, pad, selectMenuItem, transitionTime } from './helper'; export function uiIntroPoint(context, reveal) { @@ -32,24 +32,6 @@ export function uiIntroPoint(context, reveal) { } - function revealEditMenu(loc, text, options) { - var rect = context.surfaceRect(); - var point = context.curtainProjection(loc); - var pad = 40; - var width = 250 + (2 * pad); - var height = 250; - var startX = rect.left + point[0]; - var left = (localizer.textDirection() === 'rtl') ? (startX - width + pad) : (startX - pad); - var box = { - left: left, - top: point[1] + rect.top - 60, - width: width, - height: height - }; - reveal(box, text, options); - } - - function eventCancel() { d3_event.stopPropagation(); d3_event.preventDefault(); @@ -66,7 +48,7 @@ export function uiIntroPoint(context, reveal) { timeout(function() { var tooltip = reveal('button.add-point', - t('intro.points.add_point', { button: icon('#iD-icon-point', 'pre-text') })); + helpString('intro.points.points_info') + '{br}' + helpString('intro.points.add_point')); _pointID = null; @@ -95,11 +77,12 @@ export function uiIntroPoint(context, reveal) { } var pointBox = pad(building, 150, context); - reveal(pointBox, t('intro.points.place_point')); + var textId = context.lastPointerType() === 'mouse' ? 'place_point' : 'place_point_touch'; + reveal(pointBox, helpString('intro.points.' + textId)); context.map().on('move.intro drawn.intro', function() { pointBox = pad(building, 150, context); - reveal(pointBox, t('intro.points.place_point'), { duration: 0 }); + reveal(pointBox, helpString('intro.points.' + textId), { duration: 0 }); }); context.on('enter.intro', function(mode) { @@ -129,7 +112,7 @@ export function uiIntroPoint(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.points.search_cafe', { preset: cafePreset.name() }) + helpString('intro.points.search_cafe', { preset: cafePreset.name() }) ); context.on('enter.intro', function(mode) { @@ -150,7 +133,7 @@ export function uiIntroPoint(context, reveal) { .on('keyup.intro', checkPresetSearch); reveal('.preset-search-input', - t('intro.points.search_cafe', { preset: cafePreset.name() }) + helpString('intro.points.search_cafe', { preset: cafePreset.name() }) ); context.history().on('change.intro', null); @@ -167,7 +150,7 @@ export function uiIntroPoint(context, reveal) { .on('keyup.intro', null); reveal(first.select('.preset-list-button').node(), - t('intro.points.choose_cafe', { preset: cafePreset.name() }), + helpString('intro.points.choose_cafe', { preset: cafePreset.name() }), { duration: 300 } ); @@ -193,7 +176,7 @@ export function uiIntroPoint(context, reveal) { } timeout(function() { - reveal('.entity-editor-pane', t('intro.points.feature_editor'), { + reveal('.entity-editor-pane', helpString('intro.points.feature_editor'), { tooltipClass: 'intro-points-describe', buttonText: t('intro.ok'), buttonCallback: function() { continueTo(addName); } @@ -220,13 +203,15 @@ export function uiIntroPoint(context, reveal) { // reset pane, in case user happened to change it.. context.container().select('.inspector-wrap .panewrap').style('right', '0%'); + var addNameString = helpString('intro.points.fields_info') + '{br}' + helpString('intro.points.add_name'); + timeout(function() { // It's possible for the user to add a name in a previous step.. // If so, don't tell them to add the name in this step. // Give them an OK button instead. var entity = context.entity(_pointID); if (entity.tags.name) { - var tooltip = reveal('.entity-editor-pane', t('intro.points.add_name'), { + var tooltip = reveal('.entity-editor-pane', addNameString, { tooltipClass: 'intro-points-describe', buttonText: t('intro.ok'), buttonCallback: function() { continueTo(addCloseEditor); } @@ -234,7 +219,7 @@ export function uiIntroPoint(context, reveal) { tooltip.select('.instruction').style('display', 'none'); } else { - reveal('.entity-editor-pane', t('intro.points.add_name'), + reveal('.entity-editor-pane', addNameString, { tooltipClass: 'intro-points-describe' } ); } @@ -269,7 +254,7 @@ export function uiIntroPoint(context, reveal) { }); reveal('.entity-editor-pane', - t('intro.points.add_close', { button: icon(href, 'pre-text') }) + helpString('intro.points.add_close', { button: icon(href, 'pre-text') }) ); function continueTo(nextStep) { @@ -296,14 +281,14 @@ export function uiIntroPoint(context, reveal) { timeout(function() { var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.reselect'), { duration: 600 }); + reveal(box, helpString('intro.points.reselect'), { duration: 600 }); timeout(function() { context.map().on('move.intro drawn.intro', function() { var entity = context.hasEntity(_pointID); if (!entity) return chapter.restart(); var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.reselect'), { duration: 0 }); + reveal(box, helpString('intro.points.reselect'), { duration: 0 }); }); }, 600); // after reveal.. @@ -339,7 +324,7 @@ export function uiIntroPoint(context, reveal) { }); timeout(function() { - reveal('.entity-editor-pane', t('intro.points.update'), + reveal('.entity-editor-pane', helpString('intro.points.update'), { tooltipClass: 'intro-points-describe' } ); }, 400); @@ -366,7 +351,7 @@ export function uiIntroPoint(context, reveal) { timeout(function() { reveal('.entity-editor-pane', - t('intro.points.update_close', { button: icon('#iD-icon-apply', 'pre-text') }) + helpString('intro.points.update_close', { button: icon('#iD-icon-close', 'pre-text') }) ); }, 500); @@ -385,14 +370,15 @@ export function uiIntroPoint(context, reveal) { context.enter(modeBrowse(context)); var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.rightclick'), { duration: 600 }); + var textId = context.lastPointerType() === 'mouse' ? 'rightclick' : 'edit_menu_touch'; + reveal(box, helpString('intro.points.' + textId), { duration: 600 }); timeout(function() { context.map().on('move.intro', function() { var entity = context.hasEntity(_pointID); if (!entity) return chapter.restart(); var box = pointBox(entity.loc, context); - reveal(box, t('intro.points.rightclick'), { duration: 0 }); + reveal(box, helpString('intro.points.' + textId), { duration: 0 }); }); }, 600); // after reveal @@ -424,15 +410,16 @@ export function uiIntroPoint(context, reveal) { var node = selectMenuItem(context, 'delete').node(); if (!node) { return continueTo(rightClickPoint); } - revealEditMenu(entity.loc, - t('intro.points.delete', { button: icon('#iD-operation-delete', 'pre-text') }) + reveal('.edit-menu', + helpString('intro.points.delete'), + { padding: 50 } ); timeout(function() { context.map().on('move.intro', function() { - revealEditMenu(entity.loc, - t('intro.points.delete', { button: icon('#iD-operation-delete', 'pre-text') }), - { duration: 0} + reveal('.edit-menu', + helpString('intro.points.delete'), + { duration: 0, padding: 50 } ); }); }, 300); // after menu visible @@ -463,9 +450,8 @@ export function uiIntroPoint(context, reveal) { continueTo(play); }); - var iconName = '#iD-icon-' + (localizer.textDirection() === 'rtl' ? 'redo' : 'undo'); reveal('.top-toolbar button.undo-button', - t('intro.points.undo', { button: icon(iconName, 'pre-text') }) + helpString('intro.points.undo') ); function continueTo(nextStep) { @@ -478,7 +464,7 @@ export function uiIntroPoint(context, reveal) { function play() { dispatch.call('done'); reveal('.ideditor', - t('intro.points.play', { next: t('intro.areas.title') }), { + helpString('intro.points.play', { next: t('intro.areas.title') }), { tooltipBox: '.intro-nav-wrap .chapter-area', buttonText: t('intro.ok'), buttonCallback: function() { reveal('.ideditor'); } diff --git a/modules/ui/intro/start_editing.js b/modules/ui/intro/start_editing.js index 75cd23db1a..47ba615fe3 100644 --- a/modules/ui/intro/start_editing.js +++ b/modules/ui/intro/start_editing.js @@ -4,7 +4,7 @@ import { } from 'd3-selection'; import { t } from '../../core/localizer'; -import { icon } from './helper'; +import { helpString } from './helper'; import { uiModal } from '../modal'; import { utilRebind } from '../../util/rebind'; @@ -20,7 +20,7 @@ export function uiIntroStartEditing(context, reveal) { function showHelp() { reveal('.map-control.help-control', - t('intro.startediting.help', { button: icon('#iD-icon-help', 'pre-text'), key: t('help.key') }), { + helpString('intro.startediting.help'), { buttonText: t('intro.ok'), buttonCallback: function() { shortcuts(); } } @@ -29,7 +29,7 @@ export function uiIntroStartEditing(context, reveal) { function shortcuts() { reveal('.map-control.help-control', - t('intro.startediting.shortcuts', { key: t('shortcuts.toggle.key') }), { + helpString('intro.startediting.shortcuts'), { buttonText: t('intro.ok'), buttonCallback: function() { showSave(); } } @@ -39,7 +39,7 @@ export function uiIntroStartEditing(context, reveal) { function showSave() { context.container().selectAll('.shaded').remove(); // in case user opened keyboard shortcuts reveal('.top-toolbar button.save', - t('intro.startediting.save'), { + helpString('intro.startediting.save'), { buttonText: t('intro.ok'), buttonCallback: function() { showStart(); } } diff --git a/modules/ui/intro/welcome.js b/modules/ui/intro/welcome.js index 841606d574..d4300748d9 100644 --- a/modules/ui/intro/welcome.js +++ b/modules/ui/intro/welcome.js @@ -1,5 +1,6 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { helpString } from './helper'; import { t } from '../../core/localizer'; import { utilRebind } from '../../util/rebind'; @@ -15,21 +16,21 @@ export function uiIntroWelcome(context, reveal) { function welcome() { context.map().centerZoom([-85.63591, 41.94285], 19); reveal('.intro-nav-wrap .chapter-welcome', - t('intro.welcome.welcome'), + helpString('intro.welcome.welcome'), { buttonText: t('intro.ok'), buttonCallback: practice } ); } function practice() { reveal('.intro-nav-wrap .chapter-welcome', - t('intro.welcome.practice'), + helpString('intro.welcome.practice'), { buttonText: t('intro.ok'), buttonCallback: words } ); } function words() { reveal('.intro-nav-wrap .chapter-welcome', - t('intro.welcome.words'), + helpString('intro.welcome.words'), { buttonText: t('intro.ok'), buttonCallback: chapters } ); } @@ -38,7 +39,7 @@ export function uiIntroWelcome(context, reveal) { function chapters() { dispatch.call('done'); reveal('.intro-nav-wrap .chapter-navigation', - t('intro.welcome.chapters', { next: t('intro.navigation.title') }) + helpString('intro.welcome.chapters', { next: t('intro.navigation.title') }) ); } diff --git a/modules/ui/panes/help.js b/modules/ui/panes/help.js index a8ec04471e..a77ef0c811 100644 --- a/modules/ui/panes/help.js +++ b/modules/ui/panes/help.js @@ -1,14 +1,13 @@ import marked from 'marked'; import { svgIcon } from '../../svg/icon'; -import { uiCmd } from '../cmd'; import { uiIntro } from '../intro/intro'; import { uiShortcuts } from '../shortcuts'; import { uiPane } from '../pane'; import { t, localizer } from '../../core/localizer'; import { uiTooltip } from '../tooltip'; -import { icon } from '../intro/helper'; +import { helpString } from '../intro/helper'; export function uiPaneHelp(context) { @@ -35,7 +34,9 @@ export function uiPaneHelp(context) { 'select_h', 'select_left_click', 'select_right_click', + 'select_space', 'multiselect_h', + 'multiselect', 'multiselect_shift_click', 'multiselect_lasso', 'undo_redo_h', @@ -80,6 +81,7 @@ export function uiPaneHelp(context) { 'add_line_h', 'add_line', 'add_line_draw', + 'add_line_continue', 'add_line_finish', 'modify_line_h', 'modify_line_dragnode', @@ -105,6 +107,7 @@ export function uiPaneHelp(context) { 'add_area_h', 'add_area_command', 'add_area_draw', + 'add_area_continue', 'add_area_finish', 'square_area_h', 'square_area_command', @@ -143,13 +146,13 @@ export function uiPaneHelp(context) { 'intro', 'add_note_h', 'add_note', + 'place_note', 'move_note', 'update_note_h', 'update_note', 'save_note_h', 'save_note' ]], - ['imagery', [ 'intro', 'sources_h', @@ -231,46 +234,23 @@ export function uiPaneHelp(context) { 'help.qa.issues_h': 3 }; - var replacements = { - point: icon('#iD-icon-point', 'pre-text'), - line: icon('#iD-icon-line', 'pre-text'), - area: icon('#iD-icon-area', 'pre-text'), - note: icon('#iD-icon-note', 'pre-text add-note'), - plus: icon('#iD-icon-plus', 'pre-text'), - minus: icon('#iD-icon-minus', 'pre-text'), - orthogonalize: icon('#iD-operation-orthogonalize', 'pre-text'), - disconnect: icon('#iD-operation-disconnect', 'pre-text'), - layers: icon('#iD-icon-layers', 'pre-text'), - data: icon('#iD-icon-data', 'pre-text'), - inspect: icon('#iD-icon-inspect', 'pre-text'), - move: icon('#iD-operation-move', 'pre-text'), - merge: icon('#iD-operation-merge', 'pre-text'), - delete: icon('#iD-operation-delete', 'pre-text'), - close: icon('#iD-icon-close', 'pre-text'), - undo: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-redo' : '#iD-icon-undo', 'pre-text'), - redo: icon(localizer.textDirection() === 'rtl' ? '#iD-icon-undo' : '#iD-icon-redo', 'pre-text'), - save: icon('#iD-icon-save', 'pre-text'), - leftclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'left'), - rightclick: icon('#iD-walkthrough-mouse', 'pre-text mouseclick', 'right'), - shift: uiCmd.display('⇧'), - alt: uiCmd.display('⌥'), - return: uiCmd.display('↵'), - version: context.version - }; - // For each section, squash all the texts into a single markdown document var docs = docKeys.map(function(key) { var helpkey = 'help.' + key[0]; + var helpPaneReplacements = { version: context.version }; var text = key[1].reduce(function(all, part) { var subkey = helpkey + '.' + part; var depth = headings[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 all + hhh + helpString(subkey, helpPaneReplacements) + '\n\n'; }, ''); return { title: t(helpkey + '.title'), html: marked(text.trim()) + // use keyboard key styling for shortcuts + .replace(//g, '') + .replace(/<\/code>/g, '<\/kbd>') }; }); diff --git a/modules/ui/sections/raw_member_editor.js b/modules/ui/sections/raw_member_editor.js index 5e263a87d2..387dfce0b1 100644 --- a/modules/ui/sections/raw_member_editor.js +++ b/modules/ui/sections/raw_member_editor.js @@ -33,7 +33,8 @@ export function uiSectionRawMemberEditor(context) { if (!entity) return ''; var gt = entity.members.length > _maxMembers ? '>' : ''; - return t('inspector.members_count', { count: gt + entity.members.slice(0, _maxMembers).length }); + var count = gt + entity.members.slice(0, _maxMembers).length; + return t('inspector.title_count', { title: t('inspector.members'), count: count }); }) .disclosureContent(renderDisclosureContent); diff --git a/modules/ui/sections/raw_membership_editor.js b/modules/ui/sections/raw_membership_editor.js index c3f514b576..43b1ff3c5d 100644 --- a/modules/ui/sections/raw_membership_editor.js +++ b/modules/ui/sections/raw_membership_editor.js @@ -33,7 +33,8 @@ export function uiSectionRawMembershipEditor(context) { var parents = context.graph().parentRelations(entity); var gt = parents.length > _maxMemberships ? '>' : ''; - return t('inspector.relations_count', { count: gt + parents.slice(0, _maxMemberships).length }); + var count = gt + parents.slice(0, _maxMemberships).length; + return t('inspector.title_count', { title: t('inspector.relations'), count: count }); }) .disclosureContent(renderDisclosureContent); diff --git a/modules/ui/sections/raw_tag_editor.js b/modules/ui/sections/raw_tag_editor.js index 7b25ff41d3..b24a0a75b4 100644 --- a/modules/ui/sections/raw_tag_editor.js +++ b/modules/ui/sections/raw_tag_editor.js @@ -17,7 +17,7 @@ export function uiSectionRawTagEditor(id, context) { .classes('raw-tag-editor') .title(function() { var count = Object.keys(_tags).filter(function(d) { return d; }).length; - return t('inspector.tags_count', { count: count }); + return t('inspector.title_count', { title: t('inspector.tags'), count: count }); }) .expandedByDefault(false) .disclosureContent(renderDisclosureContent); diff --git a/modules/ui/sections/selection_list.js b/modules/ui/sections/selection_list.js index 4398009764..e639ac0097 100644 --- a/modules/ui/sections/selection_list.js +++ b/modules/ui/sections/selection_list.js @@ -17,7 +17,7 @@ export function uiSectionSelectionList(context) { return _selectedIDs.length > 1; }) .title(function() { - return t('inspector.features_count', { count: _selectedIDs.length }); + return t('inspector.title_count', { title: t('inspector.features'), count: _selectedIDs.length }); }) .disclosureContent(renderDisclosureContent); diff --git a/modules/ui/shortcuts.js b/modules/ui/shortcuts.js index 5ffbb7cbf2..4612682803 100644 --- a/modules/ui/shortcuts.js +++ b/modules/ui/shortcuts.js @@ -198,7 +198,13 @@ export function uiShortcuts(context) { if (click && click[1]) { // replace "left_click", "right_click" with mouse icon selection - .call(svgIcon('#iD-walkthrough-mouse', 'mouseclick', click[1])); + .call(svgIcon('#iD-walkthrough-mouse-' + click[1], 'operation')); + } else if (d.shortcut.toLowerCase() === 'long-press') { + selection + .call(svgIcon('#iD-walkthrough-longpress', 'longpress operation')); + } else if (d.shortcut.toLowerCase() === 'tap') { + selection + .call(svgIcon('#iD-walkthrough-tap', 'tap operation')); } else { selection .append('kbd') diff --git a/svg/iD-sprite/graphics/walkthrough-doubletap.svg b/svg/iD-sprite/graphics/walkthrough-doubletap.svg new file mode 100644 index 0000000000..a783dfc44b --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-doubletap.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svg/iD-sprite/graphics/walkthrough-longpress.svg b/svg/iD-sprite/graphics/walkthrough-longpress.svg new file mode 100644 index 0000000000..4e4e19620f --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-longpress.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svg/iD-sprite/graphics/walkthrough-mouse-left.svg b/svg/iD-sprite/graphics/walkthrough-mouse-left.svg new file mode 100644 index 0000000000..742c30ad78 --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-mouse-left.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svg/iD-sprite/graphics/walkthrough-mouse-right.svg b/svg/iD-sprite/graphics/walkthrough-mouse-right.svg new file mode 100644 index 0000000000..1a48bfee9f --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-mouse-right.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svg/iD-sprite/graphics/walkthrough-mouse.svg b/svg/iD-sprite/graphics/walkthrough-mouse.svg deleted file mode 100644 index 7b5ebdbece..0000000000 --- a/svg/iD-sprite/graphics/walkthrough-mouse.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/svg/iD-sprite/graphics/walkthrough-mousewheel.svg b/svg/iD-sprite/graphics/walkthrough-mousewheel.svg new file mode 100644 index 0000000000..38d510b6ab --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-mousewheel.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svg/iD-sprite/graphics/walkthrough-pinch-apart.svg b/svg/iD-sprite/graphics/walkthrough-pinch-apart.svg new file mode 100644 index 0000000000..617fe704a7 --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-pinch-apart.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svg/iD-sprite/graphics/walkthrough-tap.svg b/svg/iD-sprite/graphics/walkthrough-tap.svg new file mode 100644 index 0000000000..82acab4116 --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-tap.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/svg/iD-sprite/graphics/walkthrough-touchdrag.svg b/svg/iD-sprite/graphics/walkthrough-touchdrag.svg new file mode 100644 index 0000000000..baf0944e51 --- /dev/null +++ b/svg/iD-sprite/graphics/walkthrough-touchdrag.svg @@ -0,0 +1,5 @@ + + + + +