From 81d910b4727dfe5ab77e36214dd11f5695018878 Mon Sep 17 00:00:00 2001 From: TheAdventurer64 <50059322+TheAdventurer64@users.noreply.github.com> Date: Wed, 9 Sep 2020 18:33:48 -1000 Subject: [PATCH 01/37] Fixed typo and added new search terms. --- data/presets/presets/shop/music.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/presets/presets/shop/music.json b/data/presets/presets/shop/music.json index 0a8b57eb9..dfc92cc29 100644 --- a/data/presets/presets/shop/music.json +++ b/data/presets/presets/shop/music.json @@ -8,7 +8,10 @@ "tape casettes", "CDs", "compact discs", - "vinyl records" + "vinyl records", + "CD store", + "casette", + "casette store" ], "tags": { "shop": "music" From 99f762e3b838e7dea2eb5f40e87c53444907c298 Mon Sep 17 00:00:00 2001 From: mikenath223 Date: Thu, 17 Sep 2020 00:23:24 +0100 Subject: [PATCH 02/37] Deprecate bench:seats for bench:capacity --- data/deprecated.json | 4 ++++ data/taginfo.json | 1 + 2 files changed, 5 insertions(+) diff --git a/data/deprecated.json b/data/deprecated.json index bce2e0f6d..293509cef 100644 --- a/data/deprecated.json +++ b/data/deprecated.json @@ -227,6 +227,10 @@ "old": {"barrier": "wood_fence"}, "replace": {"barrier": "fence", "fence_type": "wood"} }, + { + "old": {"bench": "capacity"}, + "replace": {"bench": "seats"} + }, { "old": {"bicycle:oneway": "*"}, "replace": {"oneway:bicycle": "$1"} diff --git a/data/taginfo.json b/data/taginfo.json index 4812c5eb8..27073243d 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -2080,6 +2080,7 @@ {"key": "barrier", "value": "railing", "description": "🄳 ➜ barrier=fence + fence_type=railing"}, {"key": "barrier", "value": "wire_fence", "description": "🄳 ➜ barrier=fence + fence_type=wire"}, {"key": "barrier", "value": "wood_fence", "description": "🄳 ➜ barrier=fence + fence_type=wood"}, + {"key": "bench", "value": "capacity", "description": "🄳 ➜ bench=seats"}, {"key": "bicycle:oneway", "description": "🄳 ➜ oneway:bicycle=*"}, {"key": "bridge", "value": "1", "description": "🄳 ➜ bridge=yes"}, {"key": "bridge", "value": "true", "description": "🄳 ➜ bridge=yes"}, From 057b80f6dc4e81d81d19934749e7919b507a65c7 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 10:04:09 -0400 Subject: [PATCH 03/37] Add fields to Cairn --- data/presets/presets.json | 2 +- data/presets/presets/man_made/cairn.json | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/data/presets/presets.json b/data/presets/presets.json index df70e888a..e56bc1769 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -752,7 +752,7 @@ "man_made/breakwater": {"fields": ["material", "seamark/type"], "geometry": ["line", "area"], "tags": {"man_made": "breakwater"}, "name": "Breakwater"}, "man_made/bridge": {"icon": "maki-bridge", "fields": ["name", "bridge_combo", "layer", "maxweight"], "moreFields": ["gnis/feature_id", "manufacturer", "material", "seamark/type"], "geometry": ["area"], "tags": {"man_made": "bridge"}, "addTags": {"man_made": "bridge", "layer": "1"}, "removeTags": {"man_made": "bridge", "layer": "*"}, "reference": {"key": "man_made", "value": "bridge"}, "name": "Bridge Area", "matchScore": 0.85}, "man_made/bunker_silo": {"icon": "temaki-bunker_silo", "fields": ["content"], "moreFields": ["gnis/feature_id"], "geometry": ["point", "area"], "terms": ["Silage", "Storage"], "tags": {"man_made": "bunker_silo"}, "name": "Bunker Silo"}, - "man_made/cairn": {"icon": "temaki-cairn", "geometry": ["point", "area"], "terms": ["rock pile", "stone stack", "stone pile", "càrn"], "tags": {"man_made": "cairn"}, "name": "Cairn"}, + "man_made/cairn": {"icon": "temaki-cairn", "fields": ["height", "ele", "ele_node", "check_date"], "moreFields": ["colour", "material", "name", "operator", "ref"], "geometry": ["point", "area"], "terms": ["rock pile", "stone stack", "stone pile", "càrn"], "tags": {"man_made": "cairn"}, "name": "Cairn"}, "man_made/chimney": {"icon": "temaki-chimney", "fields": ["operator", "material", "height"], "geometry": ["point", "area"], "tags": {"man_made": "chimney"}, "name": "Chimney"}, "man_made/clearcut": {"icon": "maki-logging", "geometry": ["area"], "tags": {"man_made": "clearcut"}, "terms": ["cut", "forest", "lumber", "tree", "wood"], "name": "Clearcut Forest"}, "man_made/courtyard": {"icon": "maki-square-stroked", "fields": ["name"], "moreFields": [], "geometry": ["area"], "tags": {"man_made": "courtyard"}, "terms": ["court", "enclosed open air", "quadrangle", "yard"], "name": "Courtyard"}, diff --git a/data/presets/presets/man_made/cairn.json b/data/presets/presets/man_made/cairn.json index e4fa7a670..d09c9326f 100644 --- a/data/presets/presets/man_made/cairn.json +++ b/data/presets/presets/man_made/cairn.json @@ -1,5 +1,18 @@ { "icon": "temaki-cairn", + "fields": [ + "height", + "ele", + "ele_node", + "check_date" + ], + "moreFields": [ + "colour", + "material", + "name", + "operator", + "ref" + ], "geometry": [ "point", "area" From 673ea19b4615bd9b925d8514dc0c19db1e814193 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 10:13:45 -0400 Subject: [PATCH 04/37] Fix issue where Safari 14 wouldn't always autofocus the preset list (close #8003) --- modules/ui/preset_list.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/ui/preset_list.js b/modules/ui/preset_list.js index 3616f09c0..a657e25c5 100644 --- a/modules/ui/preset_list.js +++ b/modules/ui/preset_list.js @@ -132,6 +132,12 @@ export function uiPresetList(context) { if (_autofocus) { search.node().focus(); + + // Safari 14 doesn't always like to focus immediately, + // so try again on the next pass + setTimeout(function() { + search.node().focus(); + }, 0); } var listWrap = selection From 6e4697877fa4dc2dc7282212a167896504c6d533 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 11:19:17 -0400 Subject: [PATCH 05/37] Update ACCESSIBILITY.md --- ACCESSIBILITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ACCESSIBILITY.md b/ACCESSIBILITY.md index 8182f52b2..d2d9eb6f2 100644 --- a/ACCESSIBILITY.md +++ b/ACCESSIBILITY.md @@ -110,7 +110,7 @@ such as opening the edit menu via long-pressing instead of right-clicking. | | Icon | Input Setup | Notes | Issues | |---|---|---|---|---| | ✅ | 🖱⌨️ | [Mouse](https://en.wikipedia.org/wiki/Computer_mouse) + [keyboard](https://en.wikipedia.org/wiki/Computer_keyboard) | iD's original input paradigm. Any mouse-like device such as a [trackpad](https://en.wikipedia.org/wiki/Touchpad), [trackball](https://en.wikipedia.org/wiki/Trackball), or [pointing stick](https://en.wikipedia.org/wiki/Pointing_stick) is grouped into "mouse" for this table | -| 🟠 | ⌨️ | Keyboard only | iD hasn't been optimized for keyboard-only navigation, but some is possible. Geometry editing isn't possible | [#7770](https://github.com/openstreetmap/iD/issues/7770) | +| 🟠 | ⌨️ | Keyboard only | iD hasn't been optimized for keyboard-only navigation, but some is possible. Geometry editing isn't possible | [#8004](https://github.com/openstreetmap/iD/issues/8004) | | 🟠 | 🖱 | Mouse only | The primary [mouse button](https://en.wikipedia.org/wiki/Mouse_button) (e.g. left click) alone is sufficient. Multiselection and disabling of node-snapping aren't possible | | 🟠 | 🖐 | [Multi-touch](https://en.wikipedia.org/wiki/Multi-touch) on a [touchscreen](https://en.wikipedia.org/wiki/Touchscreen) | Moving and rotating selections isn't possible | [#7599](https://github.com/openstreetmap/iD/issues/7599) | | 🟠 | ✍️ | [Stylus](https://en.wikipedia.org/wiki/Stylus_(computing)) on a touchscreen | Moving and rotating selections isn't possible, nor is selecting multiple features | From d88d599f2c62a4d8d5a516f1d4dc9d8d1585d904 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 11:33:46 -0400 Subject: [PATCH 06/37] Don't add undefined class to button --- modules/ui/tag_reference.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index fafaeb70f..5d3f760a1 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -152,7 +152,7 @@ export function uiTagReference(what) { _button = _button.enter() .append('button') - .attr('class', 'tag-reference-button ' + klass) + .attr('class', 'tag-reference-button ' + (klass || '')) .attr('title', t('icons.information')) .attr('tabindex', -1) .call(svgIcon('#iD-icon-' + (iconName || 'inspect'))) From 58014ace62e3835bc0a3b0ebfae52568cd4549fc Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 12:07:20 -0400 Subject: [PATCH 07/37] Don't prevent default tabbing to elements (re: #8004) --- modules/ui/changeset_editor.js | 1 - modules/ui/feature_info.js | 1 - modules/ui/field.js | 2 -- modules/ui/field_help.js | 1 - modules/ui/fields/input.js | 2 -- modules/ui/fields/localized.js | 1 - modules/ui/fields/wikidata.js | 2 -- modules/ui/fields/wikipedia.js | 1 - modules/ui/full_screen.js | 1 - modules/ui/improveOSM_comments.js | 1 - modules/ui/init.js | 4 ---- modules/ui/issues_info.js | 1 - modules/ui/note_comments.js | 1 - modules/ui/note_editor.js | 1 - modules/ui/panels/history.js | 8 -------- modules/ui/popover.js | 1 + modules/ui/sections/data_layers.js | 1 - modules/ui/sections/entity_issues.js | 1 - modules/ui/sections/raw_member_editor.js | 2 -- modules/ui/sections/raw_membership_editor.js | 2 -- modules/ui/sections/raw_tag_editor.js | 1 - modules/ui/success.js | 2 -- modules/ui/tag_reference.js | 4 ---- modules/ui/tools/notes.js | 1 - 24 files changed, 1 insertion(+), 42 deletions(-) diff --git a/modules/ui/changeset_editor.js b/modules/ui/changeset_editor.js index 6adf1313e..bf70af160 100644 --- a/modules/ui/changeset_editor.js +++ b/modules/ui/changeset_editor.js @@ -104,7 +104,6 @@ export function uiChangesetEditor(context) { commentEnter .append('a') .attr('target', '_blank') - .attr('tabindex', -1) .call(svgIcon('#iD-icon-alert', 'inline')) .attr('href', t('commit.google_warning_link')) .append('span') diff --git a/modules/ui/feature_info.js b/modules/ui/feature_info.js index 845412f39..f4fecc933 100644 --- a/modules/ui/feature_info.js +++ b/modules/ui/feature_info.js @@ -28,7 +28,6 @@ export function uiFeatureInfo(context) { selection.append('a') .attr('class', 'chip') .attr('href', '#') - .attr('tabindex', -1) .html(t('feature_info.hidden_warning', { count: count })) .call(tooltipBehavior) .on('click', function() { diff --git a/modules/ui/field.js b/modules/ui/field.js index 271800754..9dae64fb3 100644 --- a/modules/ui/field.js +++ b/modules/ui/field.js @@ -143,7 +143,6 @@ export function uiField(context, presetField, entityIDs, options) { .append('button') .attr('class', 'remove-icon') .attr('title', t('icons.remove')) - .attr('tabindex', -1) .call(svgIcon('#iD-operation-delete')); } @@ -152,7 +151,6 @@ export function uiField(context, presetField, entityIDs, options) { .append('button') .attr('class', 'modified-icon') .attr('title', t('icons.undo')) - .attr('tabindex', -1) .call(svgIcon((localizer.textDirection() === 'rtl') ? '#iD-icon-redo' : '#iD-icon-undo')); } } diff --git a/modules/ui/field_help.js b/modules/ui/field_help.js index ba8b0e9b7..f61f30d58 100644 --- a/modules/ui/field_help.js +++ b/modules/ui/field_help.js @@ -149,7 +149,6 @@ export function uiFieldHelp(context, fieldName) { button.enter() .append('button') .attr('class', 'field-help-button') - .attr('tabindex', -1) .call(svgIcon('#iD-icon-help')) .merge(button) .on('click', function () { diff --git a/modules/ui/fields/input.js b/modules/ui/fields/input.js index 3f231cb17..4482f081c 100644 --- a/modules/ui/fields/input.js +++ b/modules/ui/fields/input.js @@ -80,7 +80,6 @@ export function uiFieldText(field, context) { buttons.enter() .append('button') - .attr('tabindex', -1) .attr('class', function(d) { var which = (d === 1 ? 'increment' : 'decrement'); return 'form-field-button ' + which; @@ -106,7 +105,6 @@ export function uiFieldText(field, context) { outlinkButton.enter() .append('button') - .attr('tabindex', -1) .call(svgIcon('#iD-icon-out-link')) .attr('class', 'form-field-button foreign-id-permalink') .attr('title', function() { diff --git a/modules/ui/fields/localized.js b/modules/ui/fields/localized.js index 3906b494f..9cd5529ba 100644 --- a/modules/ui/fields/localized.js +++ b/modules/ui/fields/localized.js @@ -219,7 +219,6 @@ export function uiFieldLocalized(field, context) { translateButton = translateButton.enter() .append('button') .attr('class', 'localized-add form-field-button') - .attr('tabindex', -1) .call(svgIcon('#iD-icon-plus')) .merge(translateButton); diff --git a/modules/ui/fields/wikidata.js b/modules/ui/fields/wikidata.js index 51586b55b..23a80985a 100644 --- a/modules/ui/fields/wikidata.js +++ b/modules/ui/fields/wikidata.js @@ -94,7 +94,6 @@ export function uiFieldWikidata(field, context) { .append('button') .attr('class', 'form-field-button wiki-link') .attr('title', t('icons.view_on', { domain: 'wikidata.org' })) - .attr('tabindex', -1) .call(svgIcon('#iD-icon-out-link')) .on('click', function() { d3_event.preventDefault(); @@ -131,7 +130,6 @@ export function uiFieldWikidata(field, context) { .append('button') .attr('class', 'form-field-button') .attr('title', t('icons.copy')) - .attr('tabindex', -1) .call(svgIcon('#iD-operation-copy')) .on('click', function() { d3_event.preventDefault(); diff --git a/modules/ui/fields/wikipedia.js b/modules/ui/fields/wikipedia.js index 0db48abc7..97ec971a1 100644 --- a/modules/ui/fields/wikipedia.js +++ b/modules/ui/fields/wikipedia.js @@ -128,7 +128,6 @@ export function uiFieldWikipedia(field, context) { link = link.enter() .append('button') .attr('class', 'form-field-button wiki-link') - .attr('tabindex', -1) .attr('title', t('icons.view_on', { domain: 'wikipedia.org' })) .call(svgIcon('#iD-icon-out-link')) .merge(link); diff --git a/modules/ui/full_screen.js b/modules/ui/full_screen.js index 9422afbf1..296d35e02 100644 --- a/modules/ui/full_screen.js +++ b/modules/ui/full_screen.js @@ -65,7 +65,6 @@ export function uiFullScreen(context) { // button = selection.append('button') // .attr('title', t('full_screen')) - // .attr('tabindex', -1) // .on('click', fullScreen) // .call(tooltip); diff --git a/modules/ui/improveOSM_comments.js b/modules/ui/improveOSM_comments.js index e4ba9e779..034b24454 100644 --- a/modules/ui/improveOSM_comments.js +++ b/modules/ui/improveOSM_comments.js @@ -52,7 +52,6 @@ export function uiImproveOsmComments() { .append('a') .attr('class', 'comment-author-link') .attr('href', osm.userURL(d.username)) - .attr('tabindex', -1) .attr('target', '_blank'); } selection diff --git a/modules/ui/init.js b/modules/ui/init.js index 6f51d89d3..3422e8d99 100644 --- a/modules/ui/init.js +++ b/modules/ui/init.js @@ -298,13 +298,11 @@ export function uiInit(context) { aboutList .append('li') .attr('class', 'feature-warning') - .attr('tabindex', -1) .call(uiFeatureInfo(context)); aboutList .append('li') .attr('class', 'issues-info') - .attr('tabindex', -1) .call(uiIssuesInfo(context)); var apiConnections = context.apiConnections(); @@ -312,7 +310,6 @@ export function uiInit(context) { aboutList .append('li') .attr('class', 'source-switch') - .attr('tabindex', -1) .call(uiSourceSwitch(context) .keys(apiConnections) ); @@ -321,7 +318,6 @@ export function uiInit(context) { aboutList .append('li') .attr('class', 'user-list') - .attr('tabindex', -1) .call(uiContributors(context)); diff --git a/modules/ui/issues_info.js b/modules/ui/issues_info.js index 147aba79d..bf96cf3e5 100644 --- a/modules/ui/issues_info.js +++ b/modules/ui/issues_info.js @@ -56,7 +56,6 @@ export function uiIssuesInfo(context) { return 'chip ' + d.id + '-count'; }) .attr('href', '#') - .attr('tabindex', -1) .each(function(d) { var chipSelection = d3_select(this); diff --git a/modules/ui/note_comments.js b/modules/ui/note_comments.js index b8ea4ba5c..09dddaa67 100644 --- a/modules/ui/note_comments.js +++ b/modules/ui/note_comments.js @@ -51,7 +51,6 @@ export function uiNoteComments() { .append('a') .attr('class', 'comment-author-link') .attr('href', osm.userURL(d.user)) - .attr('tabindex', -1) .attr('target', '_blank'); } selection diff --git a/modules/ui/note_editor.js b/modules/ui/note_editor.js index c49dcdfaa..dfa07db02 100644 --- a/modules/ui/note_editor.js +++ b/modules/ui/note_editor.js @@ -304,7 +304,6 @@ export function uiNoteEditor(context) { .attr('class', 'user-info') .text(user.display_name) .attr('href', osm.userURL(user.display_name)) - .attr('tabindex', -1) .attr('target', '_blank'); prose diff --git a/modules/ui/panels/history.js b/modules/ui/panels/history.js index 6ba0eea1f..2f5631f40 100644 --- a/modules/ui/panels/history.js +++ b/modules/ui/panels/history.js @@ -40,7 +40,6 @@ export function uiPanelHistory(context) { .attr('class', 'user-osm-link') .attr('href', osm.userURL(userName)) .attr('target', '_blank') - .attr('tabindex', -1) .text('OSM'); } @@ -49,7 +48,6 @@ export function uiPanelHistory(context) { .attr('class', 'user-hdyc-link') .attr('href', 'https://hdyc.neis-one.org/?' + userName) .attr('target', '_blank') - .attr('tabindex', -1) .text('HDYC'); } @@ -77,7 +75,6 @@ export function uiPanelHistory(context) { .attr('class', 'changeset-osm-link') .attr('href', osm.changesetURL(changeset)) .attr('target', '_blank') - .attr('tabindex', -1) .text('OSM'); } @@ -86,7 +83,6 @@ export function uiPanelHistory(context) { .attr('class', 'changeset-osmcha-link') .attr('href', 'https://osmcha.org/changesets/' + changeset) .attr('target', '_blank') - .attr('tabindex', -1) .text('OSMCha'); links @@ -94,7 +90,6 @@ export function uiPanelHistory(context) { .attr('class', 'changeset-achavi-link') .attr('href', 'https://overpass-api.de/achavi/?changeset=' + changeset) .attr('target', '_blank') - .attr('tabindex', -1) .text('Achavi'); } @@ -169,7 +164,6 @@ export function uiPanelHistory(context) { .append('a') .attr('class', 'view-history-on-osm') .attr('target', '_blank') - .attr('tabindex', -1) .attr('href', osm.noteURL(note)) .call(svgIcon('#iD-icon-out-link', 'inline')) .append('span') @@ -196,7 +190,6 @@ export function uiPanelHistory(context) { .attr('class', 'view-history-on-osm') .attr('href', osm.historyURL(entity)) .attr('target', '_blank') - .attr('tabindex', -1) .attr('title', t('info_panels.history.link_text')) .text('OSM'); } @@ -205,7 +198,6 @@ export function uiPanelHistory(context) { .attr('class', 'pewu-history-viewer-link') .attr('href', 'https://pewu.github.io/osm-history/#/' + entity.type + '/' + entity.osmId()) .attr('target', '_blank') - .attr('tabindex', -1) .text('PeWu'); var list = selection diff --git a/modules/ui/popover.js b/modules/ui/popover.js index bf5915570..42ee586ee 100644 --- a/modules/ui/popover.js +++ b/modules/ui/popover.js @@ -189,6 +189,7 @@ export function uiPopover(klass) { .on('click.popover', toggle); popoverSelection + // This attribute lets the popover take focus .attr('tabindex', 0) .on('blur.popover', function() { anchor.each(function() { diff --git a/modules/ui/sections/data_layers.js b/modules/ui/sections/data_layers.js index e8a0d43b8..f74cb9b4d 100644 --- a/modules/ui/sections/data_layers.js +++ b/modules/ui/sections/data_layers.js @@ -229,7 +229,6 @@ export function uiSectionDataLayers(context) { .attr('class', 'vectortile-footer') .append('a') .attr('target', '_blank') - .attr('tabindex', -1) .call(svgIcon('#iD-icon-out-link', 'inline')) .attr('href', 'https://github.com/osmus/detroit-mapping-challenge') .append('span') diff --git a/modules/ui/sections/entity_issues.js b/modules/ui/sections/entity_issues.js index 1f2a45228..0a403f1b9 100644 --- a/modules/ui/sections/entity_issues.js +++ b/modules/ui/sections/entity_issues.js @@ -113,7 +113,6 @@ export function uiSectionEntityIssues(context) { .append('button') .attr('class', 'issue-info-button') .attr('title', t('icons.information')) - .attr('tabindex', -1) .call(svgIcon('#iD-icon-inspect')); infoButton diff --git a/modules/ui/sections/raw_member_editor.js b/modules/ui/sections/raw_member_editor.js index 1d08585c3..44aebb11f 100644 --- a/modules/ui/sections/raw_member_editor.js +++ b/modules/ui/sections/raw_member_editor.js @@ -199,7 +199,6 @@ export function uiSectionRawMemberEditor(context) { label .append('button') - .attr('tabindex', -1) .attr('title', t('icons.remove')) .attr('class', 'remove member-delete') .call(svgIcon('#iD-operation-delete')); @@ -230,7 +229,6 @@ export function uiSectionRawMemberEditor(context) { .append('button') .attr('class', 'member-download') .attr('title', t('icons.download')) - .attr('tabindex', -1) .call(svgIcon('#iD-icon-load')) .on('click', downloadMember); } diff --git a/modules/ui/sections/raw_membership_editor.js b/modules/ui/sections/raw_membership_editor.js index 077d1e9d3..cbe830d01 100644 --- a/modules/ui/sections/raw_membership_editor.js +++ b/modules/ui/sections/raw_membership_editor.js @@ -274,7 +274,6 @@ export function uiSectionRawMembershipEditor(context) { labelEnter .append('button') - .attr('tabindex', -1) .attr('class', 'remove member-delete') .call(svgIcon('#iD-operation-delete')) .on('click', deleteMembership); @@ -333,7 +332,6 @@ export function uiSectionRawMembershipEditor(context) { newLabelEnter .append('button') - .attr('tabindex', -1) .attr('class', 'remove member-delete') .call(svgIcon('#iD-operation-delete')) .on('click', function() { diff --git a/modules/ui/sections/raw_tag_editor.js b/modules/ui/sections/raw_tag_editor.js index bdb012542..8c7eec6d4 100644 --- a/modules/ui/sections/raw_tag_editor.js +++ b/modules/ui/sections/raw_tag_editor.js @@ -204,7 +204,6 @@ export function uiSectionRawTagEditor(id, context) { innerWrap .append('button') - .attr('tabindex', -1) .attr('class', 'form-field-button remove') .attr('title', t('icons.remove')) .call(svgIcon('#iD-operation-delete')); diff --git a/modules/ui/success.js b/modules/ui/success.js index 46454d7e2..4a12d4b3a 100644 --- a/modules/ui/success.js +++ b/modules/ui/success.js @@ -100,7 +100,6 @@ export function uiSuccess(context) { .append('a') .attr('class', 'link-out') .attr('target', '_blank') - .attr('tabindex', -1) .attr('href', t('success.help_link_url')) .call(svgIcon('#iD-icon-out-link', 'inline')) .append('span') @@ -221,7 +220,6 @@ export function uiSuccess(context) { .append('a') .attr('class', 'link-out') .attr('target', '_blank') - .attr('tabindex', -1) .call(svgIcon('#iD-icon-out-link', 'inline')) .attr('href', 'https://github.com/osmlab/osm-community-index/issues') .append('span') diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index 5d3f760a1..bccf58625 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -68,7 +68,6 @@ export function uiTagReference(what) { .append('a') .attr('class', 'tag-reference-edit') .attr('target', '_blank') - .attr('tabindex', -1) .attr('title', t('inspector.edit_reference')) .attr('href', docs.editURL) .call(svgIcon('#iD-icon-edit', 'inline')); @@ -78,7 +77,6 @@ export function uiTagReference(what) { .append('a') .attr('class', 'tag-reference-link') .attr('target', '_blank') - .attr('tabindex', -1) .attr('href', docs.wiki.url) .call(svgIcon('#iD-icon-out-link', 'inline')) .append('span') @@ -91,7 +89,6 @@ export function uiTagReference(what) { .append('a') .attr('class', 'tag-reference-comment-link') .attr('target', '_blank') - .attr('tabindex', -1) .call(svgIcon('#iD-icon-out-link', 'inline')) .attr('href', t('commit.about_changeset_comments_link')) .append('span') @@ -154,7 +151,6 @@ export function uiTagReference(what) { .append('button') .attr('class', 'tag-reference-button ' + (klass || '')) .attr('title', t('icons.information')) - .attr('tabindex', -1) .call(svgIcon('#iD-icon-' + (iconName || 'inspect'))) .merge(_button); diff --git a/modules/ui/tools/notes.js b/modules/ui/tools/notes.js index 49c750ab3..02c48a5b0 100644 --- a/modules/ui/tools/notes.js +++ b/modules/ui/tools/notes.js @@ -73,7 +73,6 @@ export function uiToolNotes(context) { // enter var buttonsEnter = buttons.enter() .append('button') - .attr('tabindex', -1) .attr('class', function(d) { return d.id + ' add-button bar-button'; }) .on('click.notes', function(d) { if (!enabled(d)) return; From 2c96f5644031dba66b0e12904d1d7bc48c9bb45e Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 12:45:48 -0400 Subject: [PATCH 08/37] Make the document order of the footer items the same as the appearance order (re: #8004) --- css/80_app.css | 37 ++++++++++------------------------ modules/ui/account.js | 7 ++++--- modules/ui/init.js | 46 +++++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 53 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index d4e99ea4d..6ec3b8572 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -4464,52 +4464,35 @@ img.tile-debug { /* Footer - About, Source Switcher ------------------------------------------------------- */ .map-footer-bar .info-block { - flex: 1 1 auto; + flex: 1 1 100%; + overflow: hidden; } .map-footer-list { - text-align: right; - margin-right: 10px; display: flex; - flex-direction: row-reverse; - flex-wrap: wrap; + flex-flow: row nowrap; position: relative; height: 100%; -} -.ideditor[dir='rtl'] .map-footer-list { - text-align: left; - margin-left: 10px; - margin-right: 0; + justify-content: flex-end; } .map-footer-list li { - border-left: 1px solid rgba(255,255,255,.5); - padding: 5px 0 5px 5px; - margin-left: 5px; height: 100%; display: flex; align-items: center; + white-space: nowrap; + padding: 5px; } -.ideditor[dir='rtl'] .map-footer-list li { - border-left: none; +.ideditor[dir='ltr'] .map-footer-list li:not(:last-child) { border-right: 1px solid rgba(255,255,255,.5); - margin-left: 0; - margin-right: 5px; - padding: 5px 5px 5px 0; +} +.ideditor[dir='rtl'] .map-footer-list li:not(:last-child) { + border-left: 1px solid rgba(255,255,255,.5); } .map-footer-list li:empty { display: none; } -.map-footer-list li:last-child { - border-left: 0; - margin-left: 0; - padding-left: 0; -} -.ideditor[dir='rtl'] .map-footer-list li:last-child { - border-right: none; -} - .map-footer-list a.chip { padding: 1px 4px 1px 4px; border-radius: 2px; diff --git a/modules/ui/account.js b/modules/ui/account.js index 91ab09fcd..2bc627e02 100644 --- a/modules/ui/account.js +++ b/modules/ui/account.js @@ -62,14 +62,15 @@ export function uiAccount(context) { return function(selection) { - selection.append('li') - .attr('class', 'logoutLink') - .classed('hide', true); selection.append('li') .attr('class', 'userLink') .classed('hide', true); + selection.append('li') + .attr('class', 'logoutLink') + .classed('hide', true); + if (osm) { osm.on('change.account', function() { update(selection); }); update(selection); diff --git a/modules/ui/init.js b/modules/ui/init.js index 3422e8d99..05bf29768 100644 --- a/modules/ui/init.js +++ b/modules/ui/init.js @@ -268,15 +268,30 @@ export function uiInit(context) { .append('ul') .attr('class', 'map-footer-list'); - if (!context.embed()) { + aboutList + .append('li') + .attr('class', 'user-list') + .call(uiContributors(context)); + + var apiConnections = context.apiConnections(); + if (apiConnections && apiConnections.length > 1) { aboutList - .call(uiAccount(context)); + .append('li') + .attr('class', 'source-switch') + .call(uiSourceSwitch(context) + .keys(apiConnections) + ); } aboutList .append('li') - .attr('class', 'version') - .call(uiVersion(context)); + .attr('class', 'issues-info') + .call(uiIssuesInfo(context)); + + aboutList + .append('li') + .attr('class', 'feature-warning') + .call(uiFeatureInfo(context)); var issueLinks = aboutList .append('li'); @@ -297,29 +312,14 @@ export function uiInit(context) { aboutList .append('li') - .attr('class', 'feature-warning') - .call(uiFeatureInfo(context)); + .attr('class', 'version') + .call(uiVersion(context)); - aboutList - .append('li') - .attr('class', 'issues-info') - .call(uiIssuesInfo(context)); - - var apiConnections = context.apiConnections(); - if (apiConnections && apiConnections.length > 1) { + if (!context.embed()) { aboutList - .append('li') - .attr('class', 'source-switch') - .call(uiSourceSwitch(context) - .keys(apiConnections) - ); + .call(uiAccount(context)); } - aboutList - .append('li') - .attr('class', 'user-list') - .call(uiContributors(context)); - // Setup map dimensions and move map to initial center/zoom. // This should happen after .main-content and toolbars exist. From dea0a0afd61c19bfe9cfa2207efab1ea4d6fd356 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 12:46:14 -0400 Subject: [PATCH 09/37] Make links use the hover color when focused (re: #8004) --- css/80_app.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/css/80_app.css b/css/80_app.css index 6ec3b8572..f14bafe40 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -127,6 +127,9 @@ a:visited, a:active { color: #7092ff; } +a:focus { + color: #597be7; +} @media (hover: hover) { a:hover { color: #597be7; From af1cb3e7ba66352fb210ba4d6fd9b0563020556f Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 12:50:30 -0400 Subject: [PATCH 10/37] Fix issue where logged in account link on standalone iD wasn't active --- modules/ui/account.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ui/account.js b/modules/ui/account.js index 2bc627e02..817f91da4 100644 --- a/modules/ui/account.js +++ b/modules/ui/account.js @@ -30,22 +30,22 @@ export function uiAccount(context) { .classed('hide', false); // Link - userLink.append('a') + var userLinkA = userLink.append('a') .attr('href', osm.userURL(details.display_name)) .attr('target', '_blank'); // Add thumbnail or dont if (details.image_url) { - userLink.append('img') + userLinkA.append('img') .attr('class', 'icon pre-text user-icon') .attr('src', details.image_url); } else { - userLink + userLinkA .call(svgIcon('#iD-icon-avatar', 'pre-text light')); } // Add user name - userLink.append('span') + userLinkA.append('span') .attr('class', 'label') .text(details.display_name); From 792a5cd323563ce9ac0ec34888143fbfe89f7af9 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 13:39:59 -0400 Subject: [PATCH 11/37] Apply hovering to style to more elements when focused --- css/80_app.css | 66 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index f14bafe40..21b5d76b9 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -956,7 +956,8 @@ a.hide-toggle { .ideditor[dir='rtl'] .geocode-item { left: -25%; } -.geocode-item:active { +.geocode-item:active, +.geocode-item:focus { background-color: #aaa; } @media (hover: hover) { @@ -970,7 +971,8 @@ a.hide-toggle { font-weight: bold; display: flex; } -.feature-list-item:active { +.feature-list-item:active, +.feature-list-item:focus { background-color: #ececec; } @media (hover: hover) { @@ -1009,7 +1011,8 @@ a.hide-toggle { .feature-list-item .entity-type { color: #7092ff; } -.feature-list-item:active .entity-type { +.feature-list-item:active .entity-type, +.feature-list-item:focus .entity-type { color: #597be7; } @media (hover: hover) { @@ -1272,7 +1275,8 @@ a.hide-toggle { .ideditor[dir='rtl'] .preset-list-button-wrap:not(.category) button:last-child { border-radius: 4px 0 0 4px; } -.preset-list-button-wrap button.tag-reference-button:active { +.preset-list-button-wrap button.tag-reference-button:active, +.preset-list-button-wrap button.tag-reference-button:hover { background: #f1f1f1; } @media (hover: hover) { @@ -1436,7 +1440,8 @@ a.hide-toggle { border-left: none; border-right: 1px solid #ccc; } -.field-label button:active { +.field-label button:active, +.field-label button:focus { background: #f1f1f1; } @media (hover: hover) { @@ -1505,7 +1510,8 @@ a.hide-toggle { border-left-width: 1px; border-right-width: 0; } -.form-field-button:active { +.form-field-button:active, +.form-field-button:focus { background-color: #f1f1f1; } @media (hover: hover) { @@ -1793,7 +1799,8 @@ a.hide-toggle { .form-field-input-check > .reverser.hide { display: none; } -.form-field-input-check:active { +.form-field-input-check:active, +.form-field-input-check:focus { background: #f1f1f1; } @media (hover: hover) { @@ -1833,7 +1840,8 @@ a.hide-toggle { .form-field-input-radio > label:last-child { border-radius: 0 0 4px 4px; } -.form-field-input-radio > label:active { +.form-field-input-radio > label:active, +.form-field-input-radio > label:focus { background-color: #ececec; } @media (hover: hover) { @@ -2185,7 +2193,8 @@ div.combobox { } .combobox a.selected, -.combobox a:active { +.combobox a:active, +.combobox a:focus { background: #ececec; } @media (hover: hover) { @@ -2270,7 +2279,8 @@ div.combobox { color: #7092ff; border-bottom: 2px solid; } -.field-help-nav-item:active { +.field-help-nav-item:active, +.field-help-nav-item:focus { color: #597be7; background-color: #efefef; } @@ -2491,7 +2501,8 @@ button.raw-tag-option svg.icon { border-right-width: 0; } -.tag-row button:active { +.tag-row button:active, +.tag-row button:focus { background: #f1f1f1; } @media (hover: hover) { @@ -2992,7 +3003,8 @@ div.full-screen > button, div.full-screen > button.active { height: 40px; background: transparent; } -div.full-screen > button:active { +div.full-screen > button:active, +div.full-screen > button:focus { background-color: rgba(0, 0, 0, .8); } @media (hover: hover) { @@ -3084,7 +3096,8 @@ div.full-screen > button:active { .layer-list li:not(:last-child) { border-bottom: 1px solid #ccc; } -.layer-list li:active { +.layer-list li:active, +.layer-list li:focus { background-color: #ececec; } @media (hover: hover) { @@ -3289,11 +3302,15 @@ button.autofix.action.active { fill: #b15500; } .warnings-list .issue.severity-warning .issue-label:active, -.issue.severity-warning .issue-fix-item.actionable:active { +.warnings-list .issue.severity-warning .issue-label:focus, +.issue.severity-warning .issue-fix-item.actionable:active, +.issue.severity-warning .issue-fix-item.actionable:focus { background: #ff8; } .issue.severity-warning .issue-fix-item.actionable:active, -.issue-container.active .issue.severity-warning .issue-info-button:active { +.issue.severity-warning .issue-fix-item.actionable:focus, +.issue-container.active .issue.severity-warning .issue-info-button:active, +.issue-container.active .issue.severity-warning .issue-info-button:focus { color: #7f3d00; fill: #7f3d00; } @@ -3337,11 +3354,15 @@ button.autofix.action.active { color: #dd1400; } .errors-list .issue.severity-error .issue-label:active, -.issue.severity-error .issue-fix-item.actionable:active { +.errors-list .issue.severity-error .issue-label:focus, +.issue.severity-error .issue-fix-item.actionable:active, +.issue.severity-error .issue-fix-item.actionable:focus { background: #ffb6b6; } .issue.severity-error .issue-fix-item.actionable:active, -.issue-container.active .issue.severity-error .issue-info-button:active { +.issue.severity-error .issue-fix-item.actionable:focus, +.issue-container.active .issue.severity-error .issue-info-button:active, +.issue-container.active .issue.severity-error .issue-info-button:focus { color: #840c00; fill: #840c00; } @@ -3429,7 +3450,9 @@ input.square-degrees-input { background: #f6f6f6; } .section-entity-issues .issue-container:not(.active) .issue-text:active, -.section-entity-issues .issue-container:not(.active) .issue-info-button:active { +.section-entity-issues .issue-container:not(.active) .issue-text:focus, +.section-entity-issues .issue-container:not(.active) .issue-info-button:active, +.section-entity-issues .issue-container:not(.active) .issue-info-button:focus { background: #f1f1f1; } @media (hover: hover) { @@ -3800,6 +3823,8 @@ li.issue-fix-item:not(.actionable) .fix-icon { .help-pane .toc li a { border-bottom: 0; } +.help-pane .toc li a:focus, +.help-pane .nav a:focus, .help-pane .toc li a:active, .help-pane .nav a:active { background: #ececec; @@ -4240,6 +4265,7 @@ img.tile-debug { .ideditor[dir='rtl'] .panel-title button.close { float: left; } +.panel-title button.close:focus, .panel-title button.close:active { color: #fff; } @@ -4371,6 +4397,7 @@ img.tile-debug { .attribution-wrap .attribution a:visited { color: #ccf; } +.attribution-wrap .attribution a:focus, .attribution-wrap .attribution a:hover { color: #aaf; } @@ -4565,6 +4592,7 @@ img.tile-debug { color: #ccc; pointer-events: all; } +.api-status a:focus, .api-status a:active { color: inherit; } @@ -4884,6 +4912,7 @@ img.tile-debug { color: #7092ff; border-bottom: 2px solid; } +.modal-shortcuts .tab:focus, .modal-shortcuts .tab:active { color: #597be7; background-color: #efefef; @@ -5023,6 +5052,7 @@ img.tile-debug { padding: 5px 10px; cursor: pointer; } +.ideditor.mode-save .changeset-list li:focus, .ideditor.mode-save .changeset-list li:active { background-color: #ececec; } From b16d39452efad60509b4ef32103cba9a62b1bfa8 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 14:16:20 -0400 Subject: [PATCH 12/37] Fix navigation of the background layer list via the keyboard (re: #8004) --- modules/ui/sections/background_list.js | 30 ++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/modules/ui/sections/background_list.js b/modules/ui/sections/background_list.js index 63f9cfaff..770483e48 100644 --- a/modules/ui/sections/background_list.js +++ b/modules/ui/sections/background_list.js @@ -164,10 +164,18 @@ export function uiSectionBackgroundList(context) { function drawListItems(layerList, type, change, filter) { var sources = context.background() .sources(context.map().extent(), context.map().zoom(), true) - .filter(filter); + .filter(filter) + .sort(function(a, b) { + return a.best() && !b.best() ? -1 + : b.best() && !a.best() ? 1 + : d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0; + }); var layerLinks = layerList.selectAll('li') - .data(sources, function(d) { return d.name(); }); + // We have to be a bit inefficient about reordering the list since + // arrow key navigation of radio values likes to work in the order + // they were added, not the display document order. + .data(sources, function(d, i) { return d.id + '---' + i; }); layerLinks.exit() .remove(); @@ -183,7 +191,10 @@ export function uiSectionBackgroundList(context) { label .append('input') .attr('type', type) - .attr('name', 'layers') + .attr('name', 'background-layer') + .attr('value', function(d) { + return d.id; + }) .on('change', change); label @@ -210,19 +221,8 @@ export function uiSectionBackgroundList(context) { .append('span') .html('★'); - - layerList.selectAll('li') - .sort(sortSources); - layerList .call(updateLayerSelections); - - - function sortSources(a, b) { - return a.best() && !b.best() ? -1 - : b.best() && !a.best() ? 1 - : d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0; - } } function updateLayerSelections(selection) { @@ -244,12 +244,10 @@ export function uiSectionBackgroundList(context) { return editCustom(); } - d3_event.preventDefault(); var previousBackground = context.background().baseLayerSource(); prefs('background-last-used-toggle', previousBackground.id); prefs('background-last-used', d.id); context.background().baseLayerSource(d); - document.activeElement.blur(); } From 6f2a7464406a680647b927fa2f6f8d67f44a54e6 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Thu, 17 Sep 2020 15:20:33 -0400 Subject: [PATCH 13/37] Standardize return key comments --- modules/ui/feature_list.js | 4 +++- modules/ui/note_editor.js | 3 ++- modules/ui/preset_list.js | 3 ++- modules/ui/sections/preset_fields.js | 4 +++- modules/ui/sections/validation_rules.js | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/ui/feature_list.js b/modules/ui/feature_list.js index 69b9709b7..0efee6019 100644 --- a/modules/ui/feature_list.js +++ b/modules/ui/feature_list.js @@ -89,7 +89,9 @@ export function uiFeatureList(context) { function keypress() { var q = search.property('value'), items = list.selectAll('.feature-list-item'); - if (d3_event.keyCode === 13 && q.length && items.size()) { // return + if (d3_event.keyCode === 13 && // ↩ Return + q.length && + items.size()) { click(items.datum()); } } diff --git a/modules/ui/note_editor.js b/modules/ui/note_editor.js index dfa07db02..77494cc02 100644 --- a/modules/ui/note_editor.js +++ b/modules/ui/note_editor.js @@ -177,7 +177,8 @@ export function uiNoteEditor(context) { // fast submit if user presses cmd+enter function keydown() { - if (!(d3_event.keyCode === 13 && d3_event.metaKey)) return; + if (!(d3_event.keyCode === 13 && // ↩ Return + d3_event.metaKey)) return; var osm = services.osm; if (!osm) return; diff --git a/modules/ui/preset_list.js b/modules/ui/preset_list.js index a657e25c5..8f9f62552 100644 --- a/modules/ui/preset_list.js +++ b/modules/ui/preset_list.js @@ -85,7 +85,8 @@ export function uiPresetList(context) { function keypress() { // enter var value = search.property('value'); - if (d3_event.keyCode === 13 && value.length) { + if (d3_event.keyCode === 13 && // ↩ Return + value.length) { list.selectAll('.preset-list-item:first-child') .each(function(d) { d.choose.call(this); }); } diff --git a/modules/ui/sections/preset_fields.js b/modules/ui/sections/preset_fields.js index a8061e22f..06dc9245e 100644 --- a/modules/ui/sections/preset_fields.js +++ b/modules/ui/sections/preset_fields.js @@ -127,7 +127,9 @@ export function uiSectionPresetFields(context) { selection.selectAll('.wrap-form-field input') .on('keydown', function() { // if user presses enter, and combobox is not active, accept edits.. - if (d3_event.keyCode === 13 && context.container().select('.combobox').empty()) { + if (d3_event.keyCode === 13 && // ↩ Return + context.container().select('.combobox').empty()) { + context.enter(modeBrowse(context)); } }); diff --git a/modules/ui/sections/validation_rules.js b/modules/ui/sections/validation_rules.js index 2be50e261..feefcbc0e 100644 --- a/modules/ui/sections/validation_rules.js +++ b/modules/ui/sections/validation_rules.js @@ -144,7 +144,7 @@ export function uiSectionValidationRules(context) { this.select(); }) .on('keyup', function () { - if (d3_event.keyCode === 13) { // enter + if (d3_event.keyCode === 13) { // ↩ Return this.blur(); this.select(); } From 72c5afb27d5238310db5a6273c1a86abbc23c676 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 11:20:53 -0400 Subject: [PATCH 14/37] Make the issues inspector section navigable with the keyboard (re: #8004) --- css/80_app.css | 54 ++++++++++++++++------------ modules/ui/sections/entity_issues.js | 33 +++++++++-------- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 21b5d76b9..8405d7c2a 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -3198,6 +3198,9 @@ div.full-screen > button:focus { display: flex; flex-flow: row nowrap; cursor: pointer; + text-align: initial; + background: none; + font-weight: initial; } .issue-text .issue-icon { @@ -3296,19 +3299,19 @@ button.autofix.action.active { color: #f90; } -.issue.severity-warning .issue-fix-item.actionable, +.issue.severity-warning .issue-fix-item button.actionable, .issue-container.active .issue.severity-warning .issue-info-button { color: #b15500; fill: #b15500; } .warnings-list .issue.severity-warning .issue-label:active, .warnings-list .issue.severity-warning .issue-label:focus, -.issue.severity-warning .issue-fix-item.actionable:active, -.issue.severity-warning .issue-fix-item.actionable:focus { +.issue.severity-warning .issue-fix-item button.actionable:active, +.issue.severity-warning .issue-fix-item button.actionable:focus { background: #ff8; } -.issue.severity-warning .issue-fix-item.actionable:active, -.issue.severity-warning .issue-fix-item.actionable:focus, +.issue.severity-warning .issue-fix-item button.actionable:active, +.issue.severity-warning .issue-fix-item button.actionable:focus, .issue-container.active .issue.severity-warning .issue-info-button:active, .issue-container.active .issue.severity-warning .issue-info-button:focus { color: #7f3d00; @@ -3316,10 +3319,10 @@ button.autofix.action.active { } @media (hover: hover) { .warnings-list .issue.severity-warning .issue-label:hover, - .issue.severity-warning .issue-fix-item.actionable:hover { + .issue.severity-warning .issue-fix-item button.actionable:hover { background: #ff8; } - .issue.severity-warning .issue-fix-item.actionable:hover, + .issue.severity-warning .issue-fix-item button.actionable:hover, .issue-container.active .issue.severity-warning .issue-info-button:hover { color: #7f3d00; fill: #7f3d00; @@ -3345,7 +3348,7 @@ button.autofix.action.active { background: #ffc6c6; } -.issue.severity-error .issue-fix-item.actionable, +.issue.severity-error .issue-fix-item button.actionable, .issue-container.active .issue.severity-error .issue-info-button { color: #b91201; fill: #b91201; @@ -3355,12 +3358,12 @@ button.autofix.action.active { } .errors-list .issue.severity-error .issue-label:active, .errors-list .issue.severity-error .issue-label:focus, -.issue.severity-error .issue-fix-item.actionable:active, -.issue.severity-error .issue-fix-item.actionable:focus { +.issue.severity-error .issue-fix-item button.actionable:active, +.issue.severity-error .issue-fix-item button.actionable:focus { background: #ffb6b6; } -.issue.severity-error .issue-fix-item.actionable:active, -.issue.severity-error .issue-fix-item.actionable:focus, +.issue.severity-error .issue-fix-item button.actionable:active, +.issue.severity-error .issue-fix-item button.actionable:focus, .issue-container.active .issue.severity-error .issue-info-button:active, .issue-container.active .issue.severity-error .issue-info-button:focus { color: #840c00; @@ -3368,10 +3371,10 @@ button.autofix.action.active { } @media (hover: hover) { .errors-list .issue.severity-error .issue-label:hover, - .issue.severity-error .issue-fix-item.actionable:hover { + .issue.severity-error .issue-fix-item button.actionable:hover { background: #ffb6b6; } - .issue.severity-error .issue-fix-item.actionable:hover, + .issue.severity-error .issue-fix-item button.actionable:hover, .issue-container.active .issue.severity-error .issue-info-button:hover { color: #840c00; fill: #840c00; @@ -3469,7 +3472,7 @@ input.square-degrees-input { padding-left: 10px; } -.section-entity-issues .issue-container.active .issue-label .issue-text { +.section-entity-issues .issue-container.active .issue-label button.issue-text { font-weight: bold; } .section-entity-issues .issue-container:not(:last-of-type) { @@ -3491,27 +3494,32 @@ input.square-degrees-input { display: none; } -li.issue-fix-item { +li.issue-fix-item button { padding: 2px 10px 2px 20px; + background: transparent; + width: 100%; + text-align: initial; + font-weight: initial; } -.ideditor[dir='rtl'] li.issue-fix-item { +.ideditor[dir='rtl'] li.issue-fix-item button { padding: 2px 20px 2px 10px; } -li.issue-fix-item:first-of-type { +li.issue-fix-item:first-of-type button { padding-top: 5px; } -li.issue-fix-item:last-of-type { +li.issue-fix-item:last-of-type button { padding-bottom: 5px; } -li.issue-fix-item .fix-message { +li.issue-fix-item button .fix-message { padding: 0 10px; + vertical-align: middle; } -li.issue-fix-item.actionable { +li.issue-fix-item button.actionable { cursor: pointer; } -li.issue-fix-item:not(.actionable) .fix-icon { +li.issue-fix-item button:not(.actionable) .fix-icon { color: #555; fill: #555; } @@ -3963,7 +3971,7 @@ li.issue-fix-item:not(.actionable) .fix-icon { .inspector-hover .section-entity-issues .issue-container.active .issue-label { border-bottom: 0; } -.inspector-hover .section-entity-issues .issue-container.active .issue-label .issue-text { +.inspector-hover .section-entity-issues .issue-container .issue-label button.issue-text { font-weight: normal; } diff --git a/modules/ui/sections/entity_issues.js b/modules/ui/sections/entity_issues.js index 0a403f1b9..d70ea82f6 100644 --- a/modules/ui/sections/entity_issues.js +++ b/modules/ui/sections/entity_issues.js @@ -79,7 +79,11 @@ export function uiSectionEntityIssues(context) { var labelsEnter = itemsEnter .append('div') - .attr('class', 'issue-label') + .attr('class', 'issue-label'); + + var textEnter = labelsEnter + .append('button') + .attr('class', 'issue-text') .on('click', function(d) { makeActiveIssue(d.id); // expand only the clicked item @@ -91,17 +95,11 @@ export function uiSectionEntityIssues(context) { } }); - var textEnter = labelsEnter - .append('span') - .attr('class', 'issue-text'); - textEnter - .append('span') - .attr('class', 'issue-icon') .each(function(d) { var iconName = '#iD-icon-' + (d.severity === 'warning' ? 'alert' : 'error'); d3_select(this) - .call(svgIcon(iconName)); + .call(svgIcon(iconName, 'issue-icon')); }); textEnter @@ -188,10 +186,13 @@ export function uiSectionEntityIssues(context) { var fixesEnter = fixes.enter() .append('li') - .attr('class', 'issue-fix-item') + .attr('class', 'issue-fix-item'); + + var buttons = fixesEnter + .append('button') .on('click', function(d) { // not all fixes are actionable - if (!d3_select(this).classed('actionable') || !d.onClick) return; + if (d3_select(this).attr('disabled') || !d.onClick) return; // Don't run another fix for this issue within a second of running one // (Necessary for "Select a feature type" fix. Most fixes should only ever run once) @@ -220,26 +221,28 @@ export function uiSectionEntityIssues(context) { utilHighlightEntities(d.entityIds, false, context); }); - fixesEnter - .append('span') - .attr('class', 'fix-icon') + buttons .each(function(d) { var iconName = d.icon || 'iD-icon-wrench'; if (iconName.startsWith('maki')) { iconName += '-15'; } - d3_select(this).call(svgIcon('#' + iconName)); + d3_select(this).call(svgIcon('#' + iconName, 'fix-icon')); }); - fixesEnter + buttons .append('span') .attr('class', 'fix-message') .text(function(d) { return d.title; }); fixesEnter.merge(fixes) + .selectAll('button') .classed('actionable', function(d) { return d.onClick; }) + .attr('disabled', function(d) { + return d.onClick ? null : 'true'; + }) .attr('title', function(d) { if (d.disabledReason) { return d.disabledReason; From c0d420eb4b282c180a3879352eb155938dae1b21 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 11:43:24 -0400 Subject: [PATCH 15/37] Fix keyboard navigation of the changeset upload raw tag list editor (re: #8004) --- modules/ui/commit.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/ui/commit.js b/modules/ui/commit.js index 01271385a..b4da581c4 100644 --- a/modules/ui/commit.js +++ b/modules/ui/commit.js @@ -388,6 +388,12 @@ export function uiCommit(context) { .on('click.save', function() { if (!d3_select(this).classed('disabled')) { this.blur(); // avoid keeping focus on the button - #4641 + + for (var key in context.changeset.tags) { + // remove any empty keys before upload + if (!key) delete context.changeset.tags[key]; + } + context.uploader().save(context.changeset); } }); @@ -547,14 +553,12 @@ export function uiCommit(context) { k = context.cleanTagKey(k); if (readOnlyTags.indexOf(k) !== -1) return; - if (k !== '' && v !== undefined) { - if (onInput) { - tags[k] = v; - } else { - tags[k] = context.cleanTagValue(v); - } - } else { + if (v === undefined) { delete tags[k]; + } else if (onInput) { + tags[k] = v; + } else { + tags[k] = context.cleanTagValue(v); } }); From 006c10cf4290039e772fe1216a78403112d2bdd9 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 12:48:07 -0400 Subject: [PATCH 16/37] Add Inscription field to Bust preset (close #8007) --- data/presets/presets.json | 2 +- data/presets/presets/tourism/artwork/bust.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/data/presets/presets.json b/data/presets/presets.json index e56bc1769..de3b3af49 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -1235,7 +1235,7 @@ "tourism/apartment": {"icon": "maki-lodging", "fields": ["name", "operator", "address", "building_area", "rooms", "internet_access", "internet_access/fee"], "moreFields": ["building/levels_building", "email", "fax", "height_building", "internet_access/ssid", "level", "payment_multi", "phone", "reservation", "smoking", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"tourism": "apartment"}, "terms": ["bnb", "holiday rental", "lodging", "overnight accommodations", "vacation rental"], "name": "Guest Apartment / Condo"}, "tourism/aquarium": {"icon": "maki-aquarium", "fields": ["name", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19"], "moreFields": ["charge_fee", "email", "fax", "fee", "gnis/feature_id", "internet_access", "internet_access/fee", "internet_access/ssid", "payment_multi_fee", "phone", "ref/vatin", "smoking", "website", "wheelchair"], "geometry": ["point", "area"], "terms": ["fish", "sea", "water"], "tags": {"tourism": "aquarium"}, "name": "Aquarium"}, "tourism/artwork": {"icon": "maki-art-gallery", "fields": ["name", "artwork_type", "artist"], "moreFields": ["level", "material", "website"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork"}, "terms": ["mural", "sculpture", "statue"], "name": "Artwork"}, - "tourism/artwork/bust": {"icon": "fas-user-alt", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex"], "tags": {"tourism": "artwork", "artwork_type": "bust"}, "reference": {"key": "artwork_type", "value": "bust"}, "terms": ["figure"], "name": "Bust"}, + "tourism/artwork/bust": {"icon": "fas-user-alt", "fields": ["name", "artist", "material", "inscription"], "geometry": ["point", "vertex"], "tags": {"tourism": "artwork", "artwork_type": "bust"}, "reference": {"key": "artwork_type", "value": "bust"}, "terms": ["figure"], "name": "Bust"}, "tourism/artwork/graffiti": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "graffiti"}, "reference": {"key": "artwork_type", "value": "graffiti"}, "terms": ["Street Artwork", "Guerilla Artwork", "Graffiti Artwork"], "name": "Graffiti"}, "tourism/artwork/installation": {"icon": "temaki-sculpture", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "installation"}, "reference": {"key": "artwork_type", "value": "installation"}, "terms": ["interactive art", "intervention art", "modern art"], "name": "Art Installation"}, "tourism/artwork/mural": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "mural"}, "reference": {"key": "artwork_type", "value": "mural"}, "terms": ["fresco", "wall painting"], "name": "Mural"}, diff --git a/data/presets/presets/tourism/artwork/bust.json b/data/presets/presets/tourism/artwork/bust.json index e45c5db9c..253dcd313 100644 --- a/data/presets/presets/tourism/artwork/bust.json +++ b/data/presets/presets/tourism/artwork/bust.json @@ -3,7 +3,8 @@ "fields": [ "name", "artist", - "material" + "material", + "inscription" ], "geometry": [ "point", From 1d19cd1b9ad05504e900c0f70ccfac242c6912e2 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 12:56:24 -0400 Subject: [PATCH 17/37] Allow default browser focus styling for links, radio buttons, and checkboxes (re: #8004) --- css/80_app.css | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 8405d7c2a..fd14d35b3 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -98,7 +98,14 @@ h4, h5 { padding-bottom: 10px; } -:focus { +button:focus, +textarea:focus, +input[type=text]:focus, +input[type=search]:focus, +input[type=number]:focus, +input[type=url]:focus, +input[type=tel]:focus, +input[type=email]:focus { outline-color: transparent; outline-style: none; } @@ -763,11 +770,6 @@ button.add-note svg.icon { width: 16px; height: 16px; margin-top: -3px; - margin-left: -3px; -} -.ideditor[dir='rtl'] .hide-toggle .icon.pre-text { - margin-left: 0; - margin-right: -3px; } a:visited.hide-toggle, @@ -775,7 +777,7 @@ a.hide-toggle { display: inline-block; font-size: 14px; font-weight: bold; - padding-bottom: 5px; + margin-bottom: 5px; } From 7157feba209f022d2490d48fe10c68f211f0df65 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 13:14:01 -0400 Subject: [PATCH 18/37] Don't make button text bold by default Make the oneway field reverser a button instead of a link --- css/80_app.css | 16 +++++++--------- modules/ui/fields/check.js | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index fd14d35b3..8ca4c244c 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -315,7 +315,6 @@ button { text-align: center; border: 0; background: #fff; - font-weight: bold; color: #333; font-size: 12px; display: inline-block; @@ -371,6 +370,7 @@ button.disabled { button.action { background: #7092ff; color: #fff; + font-weight: bold; } button.action:focus, button.action:active { @@ -378,6 +378,7 @@ button.action:active { } button.secondary-action { background: #ececec; + font-weight: bold; } button.secondary-action:focus, button.secondary-action:active { @@ -563,6 +564,7 @@ button.bar-button { min-width: 30px; white-space: nowrap; display: flex; + font-weight: bold; } button.bar-button .icon { flex: 0 0 20px; @@ -1244,8 +1246,8 @@ a.hide-toggle { .preset-list-button .label-inner .namepart { text-overflow: ellipsis; } -.preset-list-button .label-inner .namepart:nth-child(2) { - font-weight: normal; +.preset-list-button .label-inner .namepart:nth-child(1) { + font-weight: bold; } .preset-list-button:focus .label, @@ -1791,6 +1793,7 @@ a.hide-toggle { border: 1px solid #ccd5e3; border-radius: 2px; padding: 0px 8px; + color: inherit; } .ideditor[dir='ltr'] .form-field-input-check > .reverser { padding-right: 2px; @@ -3202,7 +3205,6 @@ div.full-screen > button:focus { cursor: pointer; text-align: initial; background: none; - font-weight: initial; } .issue-text .issue-icon { @@ -3501,7 +3503,6 @@ li.issue-fix-item button { background: transparent; width: 100%; text-align: initial; - font-weight: initial; } .ideditor[dir='rtl'] li.issue-fix-item button { padding: 2px 20px 2px 10px; @@ -3973,9 +3974,6 @@ li.issue-fix-item button:not(.actionable) .fix-icon { .inspector-hover .section-entity-issues .issue-container.active .issue-label { border-bottom: 0; } -.inspector-hover .section-entity-issues .issue-container .issue-label button.issue-text { - font-weight: normal; -} /* Styles for raw tag inspector on hover */ @@ -4751,7 +4749,6 @@ img.tile-debug { display: flex; } .modal-actions button { - font-weight: normal; color: #7092ff; border-bottom: 1px solid #ccc; border-radius: 0; @@ -5154,6 +5151,7 @@ img.tile-debug { padding: 20px 5px; font-size: 150%; border-radius: 8px; + font-weight: bold; } .notice .zoom-to:focus, diff --git a/modules/ui/fields/check.js b/modules/ui/fields/check.js index 8e0342fea..b25d28f38 100644 --- a/modules/ui/fields/check.js +++ b/modules/ui/fields/check.js @@ -113,7 +113,7 @@ export function uiFieldCheck(field, context) { if (field.type === 'onewayCheck') { enter - .append('a') + .append('button') .attr('class', 'reverser' + (reverserHidden() ? ' hide' : '')) .attr('href', '#') .append('span') From 28dd2c45077c1c881dedf9b3eaa7afabb4312e7f Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 13:58:41 -0400 Subject: [PATCH 19/37] Make the errors, warnings, and changes lists in the commit sidebar keyboard-navigable (re: #8004) --- css/80_app.css | 69 ++++++++++++---------------------- modules/ui/commit_warnings.js | 45 +++++++++++----------- modules/ui/sections/changes.js | 24 +++++------- 3 files changed, 58 insertions(+), 80 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 8ca4c244c..7e9446a40 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -3101,8 +3101,7 @@ div.full-screen > button:focus { .layer-list li:not(:last-child) { border-bottom: 1px solid #ccc; } -.layer-list li:active, -.layer-list li:focus { +.layer-list li:active { background-color: #ececec; } @media (hover: hover) { @@ -3291,7 +3290,7 @@ button.autofix.action.active { .warnings-list .issue.severity-warning .issue-label, .issue.severity-warning .issue-fix-list, -.ideditor.mode-save .warning-section { +.warning-section { background: #ffc; } @@ -3344,7 +3343,7 @@ button.autofix.action.active { .errors-list .issue.severity-error .issue-label, .issue.severity-error .issue-fix-list, -.ideditor.mode-save .error-section { +.error-section { background: #ffd6d6; } @@ -5006,20 +5005,20 @@ img.tile-debug { /* Save Mode ------------------------------------------------------- */ -.ideditor.mode-save a.user-info { +a.user-info { display: inline-block; } -.ideditor.mode-save .commit-form { +.commit-form { margin-bottom: 0; } -.ideditor.mode-save .user-info img { +.user-info img { float: left; } .note-save .field-warning, -.ideditor.mode-save .field-warning { +.field-warning { background: #ffb; border: 1px solid #ccc; border-radius: 4px; @@ -5027,63 +5026,45 @@ img.tile-debug { } .note-save .field-warning:empty, -.ideditor.mode-save .field-warning:empty { +.field-warning:empty { display: none; } -.ideditor.mode-save .field-warning, -.ideditor.mode-save .changeset-info, -.ideditor.mode-save .request-review, -.ideditor.mode-save .commit-info { +.field-warning, +.changeset-info, +.request-review, +.commit-info { margin-bottom: 10px; } -.ideditor.mode-save .request-review label { +.request-review label { cursor: pointer; } -.ideditor.mode-save .changeset-list { +.changeset-list { border: 1px solid #ccc; border-radius: 4px; background: #fff; margin-bottom: 10px; + overflow: hidden; } -.ideditor.mode-save .warning-section .changeset-list button { - border-left: 1px solid #ccc; -} - -.ideditor.mode-save .changeset-list li { - position: relative; - border-top: 1px solid #ccc; +.changeset-list li button { padding: 5px 10px; - cursor: pointer; + width: 100%; + border-radius: 0; + text-align: initial; } -.ideditor.mode-save .changeset-list li:focus, -.ideditor.mode-save .changeset-list li:active { - background-color: #ececec; +.changeset-list li { + border-top: 1px solid #ccc; } -@media (hover: hover) { - .ideditor.mode-save .changeset-list li:hover { - background-color: #ececec; - } +.changeset-list li:first-child { + border-top: 0; } - -.ideditor.mode-save .changeset-list .alert { +.changeset-list .alert { opacity: 0.5; } -.changeset-list li span.count { - font-size: 10px; - color: #555; -} - -.changeset-list li span.count:before { content: '('; } - -.changeset-list li span.count:after { content: ')'; } - -.changeset-list li:first-child { border-top: 0;} - /* Conflict resolution ------------------------------------------------------- */ @@ -5097,7 +5078,7 @@ img.tile-debug { padding: 20px; } -.ideditor.mode-save button.conflicts-button { +button.conflicts-button { float: left; } diff --git a/modules/ui/commit_warnings.js b/modules/ui/commit_warnings.js index 2ed0e8912..d9eb362a4 100644 --- a/modules/ui/commit_warnings.js +++ b/modules/ui/commit_warnings.js @@ -47,28 +47,8 @@ export function uiCommitWarnings(context) { .append('li') .attr('class', issueItem); - itemsEnter - .call(svgIcon('#iD-icon-alert', 'pre-text')); - - itemsEnter - .append('strong') - .attr('class', 'issue-message'); - - itemsEnter.filter(function(d) { return d.tooltip; }) - .call(uiTooltip() - .title(function(d) { return d.tooltip; }) - .placement('top') - ); - - items = itemsEnter - .merge(items); - - items.selectAll('.issue-message') - .text(function(d) { - return d.message(context); - }); - - items + var buttons = itemsEnter + .append('button') .on('mouseover', function(d) { if (d.entityIds) { context.surface().selectAll( @@ -86,6 +66,27 @@ export function uiCommitWarnings(context) { .on('click', function(d) { context.validator().focusIssue(d); }); + + buttons + .call(svgIcon('#iD-icon-alert', 'pre-text')); + + buttons + .append('strong') + .attr('class', 'issue-message'); + + buttons.filter(function(d) { return d.tooltip; }) + .call(uiTooltip() + .title(function(d) { return d.tooltip; }) + .placement('top') + ); + + items = itemsEnter + .merge(items); + + items.selectAll('.issue-message') + .text(function(d) { + return d.message(context); + }); } } diff --git a/modules/ui/sections/changes.js b/modules/ui/sections/changes.js index c30bfce35..5d03cb1de 100644 --- a/modules/ui/sections/changes.js +++ b/modules/ui/sections/changes.js @@ -59,18 +59,24 @@ export function uiSectionChanges(context) { .append('li') .attr('class', 'change-item'); - itemsEnter + var buttons = itemsEnter + .append('button') + .on('mouseover', mouseover) + .on('mouseout', mouseout) + .on('click', click); + + buttons .each(function(d) { d3_select(this) .call(svgIcon('#iD-icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType)); }); - itemsEnter + buttons .append('span') .attr('class', 'change-type') .text(function(d) { return t('commit.' + d.changeType) + ' '; }); - itemsEnter + buttons .append('strong') .attr('class', 'entity-type') .text(function(d) { @@ -78,7 +84,7 @@ export function uiSectionChanges(context) { return (matched && matched.name()) || utilDisplayType(d.entity.id); }); - itemsEnter + buttons .append('span') .attr('class', 'entity-name') .text(function(d) { @@ -90,19 +96,9 @@ export function uiSectionChanges(context) { return string += ' ' + name; }); - itemsEnter - .style('opacity', 0) - .transition() - .style('opacity', 1); - items = itemsEnter .merge(items); - items - .on('mouseover', mouseover) - .on('mouseout', mouseout) - .on('click', click); - // Download changeset link var changeset = new osmChangeset().update({ id: undefined }); From c084c569a7bb099ecdd74c386c49386539066999 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 14:03:03 -0400 Subject: [PATCH 20/37] Make the DOM/focus order of the raw tag editor view buttons match their display order (re: #8004) --- css/80_app.css | 2 +- modules/ui/sections/raw_tag_editor.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 7e9446a40..323f413dc 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -2383,7 +2383,7 @@ div.combobox { .raw-tag-options { display: flex; flex-flow: row nowrap; - flex-direction: row-reverse; + justify-content: flex-end; margin-top: -28px; } button.raw-tag-option { diff --git a/modules/ui/sections/raw_tag_editor.js b/modules/ui/sections/raw_tag_editor.js index 8c7eec6d4..add6f01f1 100644 --- a/modules/ui/sections/raw_tag_editor.js +++ b/modules/ui/sections/raw_tag_editor.js @@ -25,8 +25,8 @@ export function uiSectionRawTagEditor(id, context) { var taginfo = services.taginfo; var dispatch = d3_dispatch('change'); var availableViews = [ - { id: 'text', icon: '#fas-i-cursor' }, - { id: 'list', icon: '#fas-th-list' } + { id: 'list', icon: '#fas-th-list' }, + { id: 'text', icon: '#fas-i-cursor' } ]; var _tagView = (prefs('raw-tag-editor-view') || 'list'); // 'list, 'text' From 45fbd5e604ac1405ee699ed755a6f22f4a569a6c Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Fri, 18 Sep 2020 14:33:21 -0400 Subject: [PATCH 21/37] Fix some issue with logical focus order (re: #8004) --- css/80_app.css | 7 ++++--- modules/ui/sections/map_features.js | 8 ++++---- modules/ui/sections/validation_rules.js | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 323f413dc..6cde02f2c 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -3264,7 +3264,7 @@ button.autofix.action.active { .autofix-all { display: flex; flex-flow: row nowrap; - flex-direction: row-reverse; + justify-content: flex-end; margin-top: -25px; padding-bottom: 5px; } @@ -3421,7 +3421,7 @@ button.autofix.action.active { .section-footer { display: flex; flex-flow: row nowrap; - flex-direction: row-reverse; + justify-content: flex-end; height: 30px; } .section-footer a { @@ -4220,7 +4220,8 @@ img.tile-debug { ------------------------------------------------------- */ .info-panels { display: flex; - flex-flow: row-reverse wrap-reverse; + flex-flow: row wrap-reverse; + justify-content: flex-end; width: 100%; z-index: 1; -ms-user-select: element; diff --git a/modules/ui/sections/map_features.js b/modules/ui/sections/map_features.js index 2bed5cd18..993ad3102 100644 --- a/modules/ui/sections/map_features.js +++ b/modules/ui/sections/map_features.js @@ -32,18 +32,18 @@ export function uiSectionMapFeatures(context) { .append('a') .attr('class', 'feature-list-link') .attr('href', '#') - .text(t('issues.enable_all')) + .text(t('issues.disable_all')) .on('click', function() { - context.features().enableAll(); + context.features().disableAll(); }); footer .append('a') .attr('class', 'feature-list-link') .attr('href', '#') - .text(t('issues.disable_all')) + .text(t('issues.enable_all')) .on('click', function() { - context.features().disableAll(); + context.features().enableAll(); }); // Update diff --git a/modules/ui/sections/validation_rules.js b/modules/ui/sections/validation_rules.js index feefcbc0e..487de3b33 100644 --- a/modules/ui/sections/validation_rules.js +++ b/modules/ui/sections/validation_rules.js @@ -46,18 +46,18 @@ export function uiSectionValidationRules(context) { .append('a') .attr('class', 'issue-rules-link') .attr('href', '#') - .text(t('issues.enable_all')) + .text(t('issues.disable_all')) .on('click', function() { - context.validator().disableRules([]); + context.validator().disableRules(_ruleKeys); }); ruleLinks .append('a') .attr('class', 'issue-rules-link') .attr('href', '#') - .text(t('issues.disable_all')) + .text(t('issues.enable_all')) .on('click', function() { - context.validator().disableRules(_ruleKeys); + context.validator().disableRules([]); }); From c35d33da380e3c3c4a2e03b4fa7ebb28d34ac4e3 Mon Sep 17 00:00:00 2001 From: mikenath223 Date: Fri, 18 Sep 2020 20:08:03 +0100 Subject: [PATCH 22/37] Adjust amenity-bench name as requested --- data/deprecated.json | 4 ++-- data/taginfo.json | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/data/deprecated.json b/data/deprecated.json index 293509cef..ff2d07d51 100644 --- a/data/deprecated.json +++ b/data/deprecated.json @@ -228,8 +228,8 @@ "replace": {"barrier": "fence", "fence_type": "wood"} }, { - "old": {"bench": "capacity"}, - "replace": {"bench": "seats"} + "old": {"amenity": "bench", "capacity": "*"}, + "replace": {"amenity": "bench", "seats": "$1"} }, { "old": {"bicycle:oneway": "*"}, diff --git a/data/taginfo.json b/data/taginfo.json index 27073243d..4812c5eb8 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -2080,7 +2080,6 @@ {"key": "barrier", "value": "railing", "description": "🄳 ➜ barrier=fence + fence_type=railing"}, {"key": "barrier", "value": "wire_fence", "description": "🄳 ➜ barrier=fence + fence_type=wire"}, {"key": "barrier", "value": "wood_fence", "description": "🄳 ➜ barrier=fence + fence_type=wood"}, - {"key": "bench", "value": "capacity", "description": "🄳 ➜ bench=seats"}, {"key": "bicycle:oneway", "description": "🄳 ➜ oneway:bicycle=*"}, {"key": "bridge", "value": "1", "description": "🄳 ➜ bridge=yes"}, {"key": "bridge", "value": "true", "description": "🄳 ➜ bridge=yes"}, From bcb613c29b6c8ddd122b98c7f39c17ba6acf8d7c Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 10:01:16 -0400 Subject: [PATCH 23/37] Properly disable the zoom to custom data button when there's no data --- modules/ui/sections/data_layers.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/ui/sections/data_layers.js b/modules/ui/sections/data_layers.js index f74cb9b4d..5a418fe3d 100644 --- a/modules/ui/sections/data_layers.js +++ b/modules/ui/sections/data_layers.js @@ -329,6 +329,7 @@ export function uiSectionDataLayers(context) { liEnter .append('button') + .attr('class', 'open-data-options') .call(uiTooltip() .title(t('settings.custom_data.tooltip')) .placement((localizer.textDirection() === 'rtl') ? 'right' : 'left') @@ -338,16 +339,19 @@ export function uiSectionDataLayers(context) { liEnter .append('button') + .attr('class', 'zoom-to-data') .call(uiTooltip() .title(t('map_data.layers.custom.zoom')) .placement((localizer.textDirection() === 'rtl') ? 'right' : 'left') ) .on('click', function() { + if (d3_select(this).classed('disabled')) return; + d3_event.preventDefault(); d3_event.stopPropagation(); dataLayer.fitZoom(); }) - .call(svgIcon('#iD-icon-framed-dot')); + .call(svgIcon('#iD-icon-framed-dot', 'monochrome')); // Update ul = ul @@ -360,6 +364,9 @@ export function uiSectionDataLayers(context) { .selectAll('input') .property('disabled', !hasData) .property('checked', showsData); + + ul.selectAll('button.zoom-to-data') + .classed('disabled', !hasData); } function editCustom() { From 4fe62d0efba4c3d121b42452872b73272cab401e Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 10:59:45 -0400 Subject: [PATCH 24/37] Move plus/minus key list to utilKeybinding property --- modules/ui/zoom.js | 5 +++-- modules/util/keybinding.js | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/ui/zoom.js b/modules/ui/zoom.js index 1a1cc4c55..30d58bc4e 100644 --- a/modules/ui/zoom.js +++ b/modules/ui/zoom.js @@ -7,6 +7,7 @@ import { t, localizer } from '../core/localizer'; import { svgIcon } from '../svg/icon'; import { uiCmd } from './cmd'; import { uiTooltip } from './tooltip'; +import { utilKeybinding } from '../util/keybinding'; export function uiZoom(context) { @@ -95,12 +96,12 @@ export function uiZoom(context) { .call(svgIcon('#' + d.icon, 'light')); }); - ['plus', 'ffplus', '=', 'ffequals'].forEach(function(key) { + utilKeybinding.plusKeys.forEach(function(key) { context.keybinding().on([key], zoomIn); context.keybinding().on([uiCmd('⌥' + key)], zoomInFurther); }); - ['_', '-', 'ffminus', 'dash'].forEach(function(key) { + utilKeybinding.minusKeys.forEach(function(key) { context.keybinding().on([key], zoomOut); context.keybinding().on([uiCmd('⌥' + key)], zoomOutFurther); }); diff --git a/modules/util/keybinding.js b/modules/util/keybinding.js index 02a55e89a..591050a78 100644 --- a/modules/util/keybinding.js +++ b/modules/util/keybinding.js @@ -214,6 +214,9 @@ utilKeybinding.modifierProperties = { 91: 'metaKey' }; +utilKeybinding.plusKeys = ['plus', 'ffplus', '=', 'ffequals']; +utilKeybinding.minusKeys = ['_', '-', 'ffminus', 'dash']; + utilKeybinding.keys = { // Backspace key, on Mac: ⌫ (Backspace) '⌫': 'Backspace', backspace: 'Backspace', From 28ea0828929cb23d46c69516d80a685e33c582b1 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 11:00:00 -0400 Subject: [PATCH 25/37] Add additional Enter key characters --- modules/util/keybinding.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/util/keybinding.js b/modules/util/keybinding.js index 591050a78..fc5482fa2 100644 --- a/modules/util/keybinding.js +++ b/modules/util/keybinding.js @@ -223,7 +223,7 @@ utilKeybinding.keys = { // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥ '⇥': 'Tab', '⇆': 'Tab', tab: 'Tab', // Return key, ↩ - '↩': 'Enter', 'return': 'Enter', enter: 'Enter', '⌅': 'Enter', + '↩': 'Enter', '↵': 'Enter', '⏎': 'Enter', 'return': 'Enter', enter: 'Enter', '⌅': 'Enter', // Pause/Break key 'pause': 'Pause', 'pause-break': 'Pause', // Caps Lock key, ⇪ @@ -324,7 +324,7 @@ utilKeybinding.keyCodes = { // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥ '⇥': 9, '⇆': 9, tab: 9, // Return key, ↩ - '↩': 13, 'return': 13, enter: 13, '⌅': 13, + '↩': 13, '↵': 13, '⏎': 13, 'return': 13, enter: 13, '⌅': 13, // Pause/Break key 'pause': 19, 'pause-break': 19, // Caps Lock key, ⇪ From 45decdb54c7e19cbb01e5bd0da4bbe1ee7f09c08 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 14:02:41 -0400 Subject: [PATCH 26/37] Enable scaling the selection via hotkeys --- data/core.yaml | 24 +++++++++++ data/shortcuts.json | 12 ++++++ dist/locales/en.json | 34 +++++++++++++++ modules/actions/index.js | 1 + modules/actions/scale.js | 24 +++++++++++ modules/modes/select.js | 85 +++++++++++++++++++++++++++++++++++++- modules/ui/zoom.js | 4 ++ modules/util/keybinding.js | 11 +++-- 8 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 modules/actions/scale.js diff --git a/data/core.yaml b/data/core.yaml index 3a7b49899..7c8cd8724 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -400,6 +400,28 @@ en: line: Reversed a line. lines: Reversed multiple lines. features: Reversed multiple features. + scale: + annotation: + down: + feature: + one: Scaled down a feature. + other: "Scaled down {n} features." + up: + feature: + one: Scaled up a feature. + other: "Scaled up {n} features." + too_small: + single: This feature can't be scaled down because it would become too small. + multiple: These features can't be scaled down because they would become too small. + too_large: + single: This feature can't be scaled because not enough of it is currently visible. + multiple: These features can't be scaled because not enough of them are currently visible. + connected_to_hidden: + single: This feature can't be scaled because it is connected to a hidden feature. + multiple: These features can't be scaled because some are connected to hidden features. + not_downloaded: + single: This feature can't be scaled because parts of it have not yet been downloaded. + multiple: These features can't be scaled because parts of them have not yet been downloaded. split: title: Split description: @@ -2172,6 +2194,8 @@ en: move: "Move selected features" nudge: "Nudge selected features" nudge_more: "Nudge selected features by a lot" + scale: "Scale selected features" + scale_more: "Scale selected features by a lot" rotate: "Rotate selected features" orthogonalize: "Square corners of a line or area" straighten: "Straighten a line or points" diff --git a/data/shortcuts.json b/data/shortcuts.json index 6b910899b..2997ed427 100644 --- a/data/shortcuts.json +++ b/data/shortcuts.json @@ -281,6 +281,18 @@ "text": "shortcuts.editing.operations.nudge_more", "separator": "," }, + { + "modifiers": ["⇧"], + "shortcuts": ["+", "-"], + "text": "shortcuts.editing.operations.scale", + "separator": "," + }, + { + "modifiers": ["⌥", "⇧"], + "shortcuts": ["+", "-"], + "text": "shortcuts.editing.operations.scale_more", + "separator": "," + }, { "shortcuts": ["operations.rotate.key"], "text": "shortcuts.editing.operations.rotate" diff --git a/dist/locales/en.json b/dist/locales/en.json index 4f2c141ca..6ffc48503 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -527,6 +527,38 @@ "features": "Reversed multiple features." } }, + "scale": { + "annotation": { + "down": { + "feature": { + "one": "Scaled down a feature.", + "other": "Scaled down {n} features." + } + }, + "up": { + "feature": { + "one": "Scaled up a feature.", + "other": "Scaled up {n} features." + } + } + }, + "too_small": { + "single": "This feature can't be scaled down because it would become too small.", + "multiple": "These features can't be scaled down because they would become too small." + }, + "too_large": { + "single": "This feature can't be scaled because not enough of it is currently visible.", + "multiple": "These features can't be scaled because not enough of them are currently visible." + }, + "connected_to_hidden": { + "single": "This feature can't be scaled because it is connected to a hidden feature.", + "multiple": "These features can't be scaled because some are connected to hidden features." + }, + "not_downloaded": { + "single": "This feature can't be scaled because parts of it have not yet been downloaded.", + "multiple": "These features can't be scaled because parts of them have not yet been downloaded." + } + }, "split": { "title": "Split", "description": { @@ -2674,6 +2706,8 @@ "move": "Move selected features", "nudge": "Nudge selected features", "nudge_more": "Nudge selected features by a lot", + "scale": "Scale selected features", + "scale_more": "Scale selected features by a lot", "rotate": "Rotate selected features", "orthogonalize": "Square corners of a line or area", "straighten": "Straighten a line or points", diff --git a/modules/actions/index.js b/modules/actions/index.js index dfdd1c7e6..ca8fe5f3d 100644 --- a/modules/actions/index.js +++ b/modules/actions/index.js @@ -30,6 +30,7 @@ export { actionRestrictTurn } from './restrict_turn'; export { actionReverse } from './reverse'; export { actionRevert } from './revert'; export { actionRotate } from './rotate'; +export { actionScale } from './scale'; export { actionSplit } from './split'; export { actionStraightenNodes } from './straighten_nodes'; export { actionStraightenWay } from './straighten_way'; diff --git a/modules/actions/scale.js b/modules/actions/scale.js new file mode 100644 index 000000000..c95f0224f --- /dev/null +++ b/modules/actions/scale.js @@ -0,0 +1,24 @@ +import { utilGetAllNodes } from '../util'; + +export function actionScale(ids, pivotLoc, scaleFactor, projection) { + return function(graph) { + return graph.update(function(graph) { + let point, radial; + + utilGetAllNodes(ids, graph).forEach(function(node) { + + point = projection(node.loc); + radial = [ + point[0] - pivotLoc[0], + point[1] - pivotLoc[1] + ]; + point = [ + pivotLoc[0] + (scaleFactor * radial[0]), + pivotLoc[1] + (scaleFactor * radial[1]) + ]; + + graph = graph.replace(node.move(projection.invert(point))); + }); + }); + }; +} diff --git a/modules/modes/select.js b/modules/modes/select.js index ac9e35f29..4bbebe361 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -5,6 +5,7 @@ import { t } from '../core/localizer'; import { actionAddMidpoint } from '../actions/add_midpoint'; import { actionDeleteRelation } from '../actions/delete_relation'; import { actionMove } from '../actions/move'; +import { actionScale } from '../actions/scale'; import { behaviorBreathe } from '../behavior/breathe'; import { behaviorHover } from '../behavior/hover'; @@ -14,7 +15,7 @@ import { behaviorSelect } from '../behavior/select'; import { operationMove } from '../operations/move'; -import { geoExtent, geoChooseEdge } from '../geo'; +import { geoExtent, geoChooseEdge, geoMetersToLat, geoMetersToLon } from '../geo'; import { modeBrowse } from './browse'; import { modeDragNode } from './drag_node'; import { modeDragNote } from './drag_note'; @@ -23,7 +24,7 @@ import * as Operations from '../operations/index'; import { uiCmd } from '../ui/cmd'; import { utilArrayIntersection, utilDeepMemberSelector, utilEntityOrDeepMemberSelector, - utilEntitySelector, utilKeybinding + utilEntitySelector, utilKeybinding, utilTotalExtent, utilGetAllNodes } from '../util'; @@ -243,6 +244,10 @@ export function modeSelect(context, selectedIDs) { .on(uiCmd('⇧⌥↑'), nudgeSelection([0, -100])) .on(uiCmd('⇧⌥→'), nudgeSelection([100, 0])) .on(uiCmd('⇧⌥↓'), nudgeSelection([0, 100])) + .on(utilKeybinding.plusKeys.map((key) => uiCmd('⇧' + key)), scaleSelection(1.05)) + .on(utilKeybinding.plusKeys.map((key) => uiCmd('⇧⌥' + key)), scaleSelection(Math.pow(1.05, 5))) + .on(utilKeybinding.minusKeys.map((key) => uiCmd('⇧' + key)), scaleSelection(1/1.05)) + .on(utilKeybinding.minusKeys.map((key) => uiCmd('⇧⌥' + key)), scaleSelection(1/Math.pow(1.05, 5))) .on(['\\', 'pause'], nextParent) .on('⎋', esc, true); @@ -303,6 +308,82 @@ export function modeSelect(context, selectedIDs) { .text(moveOp.tooltip)(); } else { context.perform(actionMove(selectedIDs, delta, context.projection), moveOp.annotation()); + context.validator().validate(); + } + }; + } + + function scaleSelection(factor) { + return function() { + // prevent scaling during low zoom selection + if (!context.map().withinEditableZoom()) return; + + let nodes = utilGetAllNodes(selectedIDs, context.graph()); + + let isUp = factor > 1; + + // can only scale if multiple nodes are selected + if (nodes.length <= 1) return; + + let extent = utilTotalExtent(selectedIDs, context.graph()); + + // These disabled checks would normally be handled by an operation + // object, but we don't want an actual scale operation at this point. + function scalingDisabled() { + + if (tooSmall()) { + return 'too_small'; + } else if (extent.percentContainedIn(context.map().extent()) < 0.8) { + return 'too_large'; + } else if (someMissing() || selectedIDs.some(incompleteRelation)) { + return 'not_downloaded'; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return 'connected_to_hidden'; + } + + return false; + + function tooSmall() { + if (isUp) return false; + let dLon = Math.abs(extent[1][0] - extent[0][0]); + let dLat = Math.abs(extent[1][1] - extent[0][1]); + return dLon < geoMetersToLon(1, extent[1][1]) && + dLat < geoMetersToLat(1); + } + + function someMissing() { + if (context.inIntro()) return false; + let osm = context.connection(); + if (osm) { + let missing = nodes.filter(function(n) { return !osm.isDataLoaded(n.loc); }); + if (missing.length) { + missing.forEach(function(loc) { context.loadTileAtLoc(loc); }); + return true; + } + } + return false; + } + + function incompleteRelation(id) { + let entity = context.entity(id); + return entity.type === 'relation' && !entity.isComplete(context.graph()); + } + } + + const disabled = scalingDisabled(); + + if (disabled) { + let multi = (selectedIDs.length === 1 ? 'single' : 'multiple'); + context.ui().flash + .duration(4000) + .iconName('#iD-icon-no') + .iconClass('operation disabled') + .text(t('operations.scale.' + disabled + '.' + multi))(); + } else { + const pivot = context.projection(extent.center()); + const annotation = t('operations.scale.annotation.' + (isUp ? 'up' : 'down') + '.feature', { n: selectedIDs.length }); + context.perform(actionScale(selectedIDs, pivot, factor, context.projection), annotation); + context.validator().validate(); } }; } diff --git a/modules/ui/zoom.js b/modules/ui/zoom.js index 30d58bc4e..e60568d52 100644 --- a/modules/ui/zoom.js +++ b/modules/ui/zoom.js @@ -35,21 +35,25 @@ export function uiZoom(context) { }]; function zoomIn() { + if (d3_event.shiftKey) return; d3_event.preventDefault(); context.map().zoomIn(); } function zoomOut() { + if (d3_event.shiftKey) return; d3_event.preventDefault(); context.map().zoomOut(); } function zoomInFurther() { + if (d3_event.shiftKey) return; d3_event.preventDefault(); context.map().zoomInFurther(); } function zoomOutFurther() { + if (d3_event.shiftKey) return; d3_event.preventDefault(); context.map().zoomOutFurther(); } diff --git a/modules/util/keybinding.js b/modules/util/keybinding.js index fc5482fa2..34a112a33 100644 --- a/modules/util/keybinding.js +++ b/modules/util/keybinding.js @@ -28,17 +28,22 @@ export function utilKeybinding(namespace) { if (matches(binding, true)) { binding.callback(); didMatch = true; + + // match a max of one binding per event + break; } } - // then unshifted keybindings if (didMatch) return; + + // then unshifted keybindings for (i = 0; i < bindings.length; i++) { binding = bindings[i]; if (binding.event.modifiers.shiftKey) continue; // shift if (!!binding.capture !== isCapturing) continue; if (matches(binding, false)) { binding.callback(); + break; } } @@ -214,8 +219,8 @@ utilKeybinding.modifierProperties = { 91: 'metaKey' }; -utilKeybinding.plusKeys = ['plus', 'ffplus', '=', 'ffequals']; -utilKeybinding.minusKeys = ['_', '-', 'ffminus', 'dash']; +utilKeybinding.plusKeys = ['plus', 'ffplus', '=', 'ffequals', '≠', '±']; +utilKeybinding.minusKeys = ['_', '-', 'ffminus', 'dash', '–', '—']; utilKeybinding.keys = { // Backspace key, on Mac: ⌫ (Backspace) From da58542161f440cf5ac67406a6d4fda02fc99b94 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:10:57 -0400 Subject: [PATCH 27/37] Add derived data for #8008 --- data/presets.yaml | 2 +- data/presets/presets.json | 2 +- dist/locales/en.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/presets.yaml b/data/presets.yaml index f389f06e7..450a678c1 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -8354,7 +8354,7 @@ en: shop/music: # shop=music name: Music Store - # 'terms: tape cassettes,CDs,compact discs,vinyl records' + # 'terms: tape cassettes,CDs,compact discs,vinyl records,CD store,casette,casette store' terms: '' shop/musical_instrument: # shop=musical_instrument diff --git a/data/presets/presets.json b/data/presets/presets.json index de3b3af49..1a97dff0a 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -1169,7 +1169,7 @@ "shop/money_lender": {"icon": "temaki-money_hand", "fields": ["{shop}", "currency_multi"], "geometry": ["point", "area"], "tags": {"shop": "money_lender"}, "name": "Money Lender"}, "shop/motorcycle_repair": {"icon": "temaki-motorcycle_repair", "fields": ["{shop}", "service/vehicle"], "geometry": ["point", "area"], "terms": ["auto", "bike", "garage", "motorcycle", "repair", "service"], "tags": {"shop": "motorcycle_repair"}, "name": "Motorcycle Repair Shop"}, "shop/motorcycle": {"icon": "fas-motorcycle", "fields": ["name", "brand", "{shop}"], "geometry": ["point", "area"], "terms": ["bike"], "tags": {"shop": "motorcycle"}, "name": "Motorcycle Dealership"}, - "shop/music": {"icon": "fas-compact-disc", "geometry": ["point", "area"], "terms": ["tape cassettes", "CDs", "compact discs", "vinyl records"], "tags": {"shop": "music"}, "name": "Music Store"}, + "shop/music": {"icon": "fas-compact-disc", "geometry": ["point", "area"], "terms": ["tape cassettes", "CDs", "compact discs", "vinyl records", "CD store", "casette", "casette store"], "tags": {"shop": "music"}, "name": "Music Store"}, "shop/musical_instrument": {"icon": "fas-guitar", "geometry": ["point", "area"], "terms": ["guitar"], "tags": {"shop": "musical_instrument"}, "name": "Musical Instrument Store"}, "shop/newsagent": {"icon": "fas-newspaper", "geometry": ["point", "area"], "tags": {"shop": "newsagent"}, "name": "Newspaper/Magazine Shop"}, "shop/nutrition_supplements": {"icon": "fas-pills", "geometry": ["point", "area"], "terms": ["health", "supplement", "vitamin"], "tags": {"shop": "nutrition_supplements"}, "name": "Nutrition Supplements Store"}, diff --git a/dist/locales/en.json b/dist/locales/en.json index 6ffc48503..60c0f489c 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -9896,7 +9896,7 @@ }, "shop/music": { "name": "Music Store", - "terms": "tape cassettes,CDs,compact discs,vinyl records" + "terms": "tape cassettes,CDs,compact discs,vinyl records,CD store,casette,casette store" }, "shop/musical_instrument": { "name": "Musical Instrument Store", From 0226b6f4b36da8082c24f018d67878f60a8e605f Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:14:04 -0400 Subject: [PATCH 28/37] Add more picnic table fields (close #8009) --- data/presets/presets.json | 2 +- data/presets/presets/leisure/picnic_table.json | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/data/presets/presets.json b/data/presets/presets.json index 1a97dff0a..e721b9a23 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -700,7 +700,7 @@ "leisure/nature_reserve": {"icon": "maki-park", "geometry": ["area", "point"], "fields": ["name", "operator", "address", "opening_hours", "opening_hours/covid19"], "moreFields": ["dog", "email", "fax", "gnis/feature_id", "phone", "website"], "tags": {"leisure": "nature_reserve"}, "terms": ["protected", "wildlife"], "name": "Nature Reserve"}, "leisure/outdoor_seating": {"icon": "maki-picnic-site", "geometry": ["point", "area"], "fields": ["name", "operator"], "moreFields": ["level"], "terms": ["al fresco", "beer garden", "dining", "cafe", "restaurant", "pub", "bar", "patio"], "tags": {"leisure": "outdoor_seating"}, "name": "Outdoor Seating Area"}, "leisure/park": {"icon": "temaki-tree_and_bench", "fields": ["name", "operator", "address", "opening_hours", "opening_hours/covid19"], "moreFields": ["dog", "email", "fax", "gnis/feature_id", "phone", "smoking", "website"], "geometry": ["area", "point"], "terms": ["esplanade", "estate", "forest", "garden", "grass", "green", "grounds", "lawn", "lot", "meadow", "parkland", "place", "playground", "plaza", "pleasure garden", "recreation area", "square", "tract", "village green", "woodland"], "tags": {"leisure": "park"}, "name": "Park"}, - "leisure/picnic_table": {"icon": "maki-picnic-site", "fields": ["material", "lit", "bench"], "moreFields": ["level"], "geometry": ["point"], "tags": {"leisure": "picnic_table"}, "terms": ["bench"], "name": "Picnic Table"}, + "leisure/picnic_table": {"icon": "maki-picnic-site", "fields": ["material", "lit", "bench", "colour"], "moreFields": ["height", "level", "manufacturer", "operator"], "geometry": ["point"], "tags": {"leisure": "picnic_table"}, "terms": ["bench"], "name": "Picnic Table"}, "leisure/picnic_table/chess": {"icon": "fas-chess-pawn", "geometry": ["point"], "tags": {"leisure": "picnic_table", "sport": "chess"}, "reference": {"key": "sport", "value": "chess"}, "terms": ["bench", "chess board", "checkerboard", "checkers", "chequerboard", "game table"], "name": "Chess Table"}, "leisure/pitch": {"icon": "maki-pitch", "fields": ["name", "sport", "access_simple", "surface", "lit"], "moreFields": ["address", "charge_fee", "covered", "fee", "gnis/feature_id", "indoor", "payment_multi_fee"], "geometry": ["area", "point"], "tags": {"leisure": "pitch"}, "terms": ["field"], "name": "Sport Pitch"}, "leisure/pitch/american_football": {"icon": "maki-american-football", "geometry": ["area", "point"], "tags": {"leisure": "pitch", "sport": "american_football"}, "reference": {"key": "sport", "value": "american_football"}, "terms": ["football", "gridiron"], "name": "American Football Field"}, diff --git a/data/presets/presets/leisure/picnic_table.json b/data/presets/presets/leisure/picnic_table.json index 24ad415f4..b11416b01 100644 --- a/data/presets/presets/leisure/picnic_table.json +++ b/data/presets/presets/leisure/picnic_table.json @@ -3,10 +3,14 @@ "fields": [ "material", "lit", - "bench" + "bench", + "colour" ], "moreFields": [ - "level" + "height", + "level", + "manufacturer", + "operator" ], "geometry": [ "point" From f141d1a77db92edd6f7491780ad50e56cd66054b Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 15:25:14 -0400 Subject: [PATCH 29/37] Show Telephone and Website fields by default on more POI presets (close #7877) --- data/presets/presets.json | 16 ++++++++-------- data/presets/presets/amenity/cafe.json | 6 +++--- data/presets/presets/amenity/fast_food.json | 6 +++--- data/presets/presets/amenity/internet_cafe.json | 6 +++--- data/presets/presets/club.json | 4 +++- data/presets/presets/craft.json | 6 +++--- data/presets/presets/healthcare.json | 6 +++--- data/presets/presets/polling_station.json | 6 +++--- data/presets/presets/shop.json | 6 +++--- scripts/build_data.js | 16 ++++++---------- 10 files changed, 38 insertions(+), 40 deletions(-) diff --git a/data/presets/presets.json b/data/presets/presets.json index e721b9a23..da0a5cdf3 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -81,7 +81,7 @@ "amenity/biergarten": {"icon": "fas-beer", "fields": ["name", "address", "opening_hours", "opening_hours/covid19", "outdoor_seating", "brewery"], "moreFields": ["{amenity/bar}", "building_area", "cuisine"], "geometry": ["point", "area"], "tags": {"amenity": "biergarten"}, "terms": ["beer", "bier", "booze"], "name": "Biergarten"}, "amenity/boat_rental": {"icon": "temaki-boat_rental", "fields": ["name", "operator", "operator/type", "opening_hours", "opening_hours/covid19", "fee", "payment_multi_fee", "charge_fee"], "moreFields": ["access_simple", "address", "email", "fax", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "boat_rental"}, "name": "Boat Rental"}, "amenity/bureau_de_change": {"icon": "temaki-money_hand", "fields": ["name", "operator", "payment_multi", "currency_multi", "address", "building_area"], "moreFields": ["email", "fax", "level", "opening_hours", "opening_hours/covid19", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "terms": ["bureau de change", "money changer"], "tags": {"amenity": "bureau_de_change"}, "name": "Currency Exchange"}, - "amenity/cafe": {"icon": "maki-cafe", "fields": ["name", "cuisine", "address", "building_area", "opening_hours", "opening_hours/covid19", "outdoor_seating", "internet_access", "internet_access/fee", "internet_access/ssid"], "moreFields": ["air_conditioning", "bar", "brand", "capacity", "delivery", "diet_multi", "email", "fax", "gnis/feature_id", "level", "min_age", "not/name", "payment_multi", "phone", "ref/vatin", "reservation", "smoking", "takeaway", "website", "wheelchair"], "geometry": ["point", "area"], "terms": ["bistro", "coffee", "tea"], "tags": {"amenity": "cafe"}, "name": "Cafe"}, + "amenity/cafe": {"icon": "maki-cafe", "fields": ["name", "cuisine", "address", "building_area", "opening_hours", "opening_hours/covid19", "outdoor_seating", "internet_access", "internet_access/fee", "internet_access/ssid", "phone", "website"], "moreFields": ["air_conditioning", "bar", "brand", "capacity", "delivery", "diet_multi", "email", "fax", "gnis/feature_id", "level", "min_age", "not/name", "payment_multi", "ref/vatin", "reservation", "smoking", "takeaway", "wheelchair"], "geometry": ["point", "area"], "terms": ["bistro", "coffee", "tea"], "tags": {"amenity": "cafe"}, "name": "Cafe"}, "amenity/cafe/bubble_tea": {"icon": "temaki-bubble_tea", "geometry": ["point", "area"], "tags": {"amenity": "cafe", "cuisine": "bubble_tea"}, "reference": {"key": "cuisine", "value": "bubble_tea"}, "terms": ["boba", "bubble milk tea", "pearl milk tea", "taiwanese tea drink", "tapioca", "pearl tea", "boba drink"], "name": "Bubble Tea Cafe"}, "amenity/cafe/coffee_shop": {"icon": "temaki-hot_drink_cup", "geometry": ["point", "area"], "tags": {"amenity": "cafe", "cuisine": "coffee_shop"}, "reference": {"key": "cuisine", "value": "coffee_shop"}, "terms": ["americano", "brew", "cafe", "café", "caffe", "caffè", "cappuccino", "cocoa", "coffee shop", "drip", "espresso", "hot drinks", "latte", "macchiato", "tea"], "name": "Coffeehouse"}, "amenity/car_pooling": {"icon": "temaki-car_pool", "fields": ["name", "operator", "operator/type", "capacity", "address", "opening_hours", "opening_hours/covid19", "lit"], "moreFields": ["email", "fax", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "car_pooling"}, "terms": ["car sharing", "carpooling", "lift sharing", "ride sharing"], "name": "Car Pooling Station"}, @@ -113,7 +113,7 @@ "amenity/driving_school": {"icon": "maki-car", "fields": ["name", "operator", "operator/type", "address", "building_area", "opening_hours", "opening_hours/covid19"], "moreFields": ["email", "fax", "gnis/feature_id", "level", "payment_multi", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "driving_school"}, "name": "Driving School"}, "amenity/events_venue": {"icon": "fas-users", "fields": ["name", "operator", "building_area", "address", "website", "internet_access", "internet_access/fee", "internet_access/ssid"], "moreFields": ["air_conditioning", "email", "fax", "gnis/feature_id", "level", "min_age", "phone", "smoking", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "events_venue"}, "terms": ["banquet hall", "baptism", "Bar Mitzvah", "Bat Mitzvah", "birthdays", "celebrations", "conferences", "confirmation", "meetings", "parties", "party", "quinceañera", "reunions", "weddings"], "name": "Events Venue"}, "amenity/exhibition_centre": {"icon": "fas-user-tie", "fields": ["name", "operator", "operator/type", "building_area", "address", "website", "internet_access", "internet_access/fee", "internet_access/ssid"], "moreFields": ["air_conditioning", "email", "fax", "gnis/feature_id", "not/name", "phone", "smoking", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "exhibition_centre"}, "terms": ["exhibition center", "fair", "exhibition", "exposition", "trade fair", "trade show", "trade exhibition", "expo", "tradeshow"], "name": "Exposition Center"}, - "amenity/fast_food": {"icon": "maki-fast-food", "fields": ["name", "cuisine", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19", "drive_through"], "moreFields": ["air_conditioning", "brand", "capacity", "delivery", "diet_multi", "email", "fax", "gnis/feature_id", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "opening_hours", "opening_hours/covid19", "outdoor_seating", "payment_multi", "phone", "ref/vatin", "smoking", "takeaway", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "fast_food"}, "terms": ["restaurant", "takeaway"], "name": "Fast Food"}, + "amenity/fast_food": {"icon": "maki-fast-food", "fields": ["name", "cuisine", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19", "drive_through", "phone", "website"], "moreFields": ["air_conditioning", "brand", "capacity", "delivery", "diet_multi", "email", "fax", "gnis/feature_id", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "opening_hours", "opening_hours/covid19", "outdoor_seating", "payment_multi", "ref/vatin", "smoking", "takeaway", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "fast_food"}, "terms": ["restaurant", "takeaway"], "name": "Fast Food"}, "amenity/fast_food/ice_cream": {"icon": "fas-ice-cream", "geometry": ["point", "area"], "tags": {"amenity": "fast_food", "cuisine": "ice_cream"}, "reference": {"key": "cuisine", "value": "ice_cream"}, "name": "Ice Cream Fast Food", "searchable": false}, "amenity/fast_food/burger": {"icon": "maki-fast-food", "geometry": ["point", "area"], "terms": ["breakfast", "dine", "dining", "dinner", "drive-in", "eat", "grill", "lunch", "table"], "tags": {"amenity": "fast_food", "cuisine": "burger"}, "reference": {"key": "cuisine", "value": "burger"}, "name": "Burger Fast Food"}, "amenity/fast_food/chicken": {"icon": "fas-drumstick-bite", "geometry": ["point", "area"], "terms": ["breakfast", "canteen", "dine", "dining", "dinner", "drive-in", "eat", "grill", "lunch", "table"], "tags": {"amenity": "fast_food", "cuisine": "chicken"}, "reference": {"key": "cuisine", "value": "chicken"}, "name": "Chicken Fast Food"}, @@ -136,7 +136,7 @@ "amenity/hospital": {"icon": "maki-hospital", "fields": ["name", "operator", "operator/type", "healthcare/speciality", "address", "emergency"], "moreFields": ["email", "fax", "gnis/feature_id", "internet_access", "internet_access/fee", "internet_access/ssid", "phone", "website", "wheelchair"], "geometry": ["area", "point"], "terms": ["clinic", "doctor", "emergency room", "health", "infirmary", "institution", "sanatorium", "sanitarium", "sick", "surgery", "ward"], "tags": {"amenity": "hospital"}, "addTags": {"amenity": "hospital", "healthcare": "hospital"}, "reference": {"key": "amenity", "value": "hospital"}, "name": "Hospital Grounds"}, "amenity/hunting_stand": {"icon": "temaki-binoculars", "fields": ["access_simple", "lockable"], "geometry": ["point", "vertex", "area"], "terms": ["game", "gun", "lookout", "rifle", "shoot*", "wild", "watch"], "tags": {"amenity": "hunting_stand"}, "name": "Hunting Stand"}, "amenity/ice_cream": {"icon": "fas-ice-cream", "fields": ["name", "address", "building_area", "opening_hours", "opening_hours/covid19", "outdoor_seating"], "moreFields": ["delivery", "diet_multi", "drive_through", "email", "fax", "gnis/feature_id", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "payment_multi", "phone", "takeaway", "website", "wheelchair"], "geometry": ["point", "area"], "terms": ["gelato", "sorbet", "sherbet", "frozen", "yogurt"], "tags": {"amenity": "ice_cream"}, "name": "Ice Cream Shop"}, - "amenity/internet_cafe": {"icon": "temaki-antenna", "fields": ["name", "operator", "operator/type", "address", "building_area", "internet_access", "internet_access/fee", "internet_access/ssid"], "moreFields": ["air_conditioning", "email", "fax", "gnis/feature_id", "level", "min_age", "opening_hours", "opening_hours/covid19", "outdoor_seating", "payment_multi", "phone", "ref/vatin", "smoking", "website", "wheelchair"], "geometry": ["point", "area"], "terms": ["cybercafe", "taxiphone", "teleboutique", "coffee", "cafe", "net", "lanhouse"], "tags": {"amenity": "internet_cafe"}, "name": "Internet Cafe"}, + "amenity/internet_cafe": {"icon": "temaki-antenna", "fields": ["name", "operator", "operator/type", "address", "building_area", "internet_access", "internet_access/fee", "internet_access/ssid", "phone", "website"], "moreFields": ["air_conditioning", "email", "fax", "gnis/feature_id", "level", "min_age", "opening_hours", "opening_hours/covid19", "outdoor_seating", "payment_multi", "ref/vatin", "smoking", "wheelchair"], "geometry": ["point", "area"], "terms": ["cybercafe", "taxiphone", "teleboutique", "coffee", "cafe", "net", "lanhouse"], "tags": {"amenity": "internet_cafe"}, "name": "Internet Cafe"}, "amenity/karaoke_box": {"icon": "maki-karaoke", "fields": ["name", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19", "website"], "moreFields": ["air_conditioning", "email", "fax", "gnis/feature_id", "level", "min_age", "payment_multi", "phone", "ref/vatin", "smoking", "wheelchair"], "geometry": ["point", "area"], "terms": ["karaoke club", "karaoke room", "karaoke television", "KTV"], "tags": {"amenity": "karaoke_box"}, "name": "Karaoke Box"}, "amenity/kindergarten": {"icon": "temaki-school", "fields": ["name", "operator", "operator/type", "address", "phone", "preschool"], "moreFields": ["email", "fax", "gnis/feature_id", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "max_age", "min_age", "not/name", "opening_hours", "opening_hours/covid19", "payment_multi", "website", "wheelchair"], "geometry": ["area", "point"], "terms": ["kindergarden", "pre-school"], "tags": {"amenity": "kindergarten"}, "name": "Preschool / Kindergarten Grounds"}, "amenity/kneipp_water_cure": {"icon": "maki-hospital", "fields": ["kneipp_water_cure_multi", "opening_hours", "opening_hours/covid19", "fee"], "geometry": ["point", "area"], "terms": [], "tags": {"amenity": "kneipp_water_cure"}, "reference": {"key": "amenity", "value": "kneipp_water_cure"}, "name": "Kneipp Water Cure"}, @@ -394,9 +394,9 @@ "building/transportation": {"icon": "maki-building", "fields": ["{building}", "smoking"], "geometry": ["area"], "tags": {"building": "transportation"}, "matchScore": 0.5, "name": "Transportation Building"}, "building/university": {"icon": "fas-school", "moreFields": ["{building}", "polling_station"], "geometry": ["area"], "terms": ["college"], "tags": {"building": "university"}, "matchScore": 0.5, "name": "University Building"}, "building/warehouse": {"icon": "maki-warehouse", "geometry": ["area"], "tags": {"building": "warehouse"}, "matchScore": 0.5, "name": "Warehouse"}, - "club": {"icon": "fas-handshake", "fields": ["name", "club", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19"], "moreFields": ["access_simple", "building/levels_building", "email", "fax", "gnis/feature_id", "height_building", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "max_age", "min_age", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"club": "*"}, "terms": ["social"], "name": "Club"}, + "club": {"icon": "fas-handshake", "fields": ["name", "club", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19", "phone", "website"], "moreFields": ["access_simple", "building/levels_building", "email", "fax", "gnis/feature_id", "height_building", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "max_age", "min_age", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"club": "*"}, "terms": ["social"], "name": "Club"}, "club/sport": {"icon": "maki-pitch", "fields": ["name", "sport", "{club}"], "geometry": ["point", "area"], "tags": {"club": "sport"}, "terms": ["athletics club", "sporting club", "sports association", "sports society"], "name": "Sports Club"}, - "craft": {"icon": "temaki-tools", "fields": ["name", "craft", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19"], "moreFields": ["air_conditioning", "building/levels_building", "ele", "email", "fax", "gnis/feature_id", "height_building", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "phone", "product", "ref/vatin", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"craft": "*"}, "terms": [], "name": "Craft"}, + "craft": {"icon": "temaki-tools", "fields": ["name", "craft", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19", "phone", "website"], "moreFields": ["air_conditioning", "building/levels_building", "ele", "email", "fax", "gnis/feature_id", "height_building", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "product", "ref/vatin", "wheelchair"], "geometry": ["point", "area"], "tags": {"craft": "*"}, "terms": [], "name": "Craft"}, "craft/locksmith": {"icon": "maki-marker-stroked", "geometry": ["point", "area"], "tags": {"craft": "locksmith"}, "reference": {"key": "shop", "value": "locksmith"}, "name": "Locksmith", "searchable": false}, "craft/tailor": {"icon": "temaki-needle_and_spool", "geometry": ["point", "area"], "tags": {"craft": "tailor"}, "reference": {"key": "shop", "value": "tailor"}, "name": "Tailor", "searchable": false}, "craft/agricultural_engines": {"icon": "temaki-tools", "geometry": ["point", "area"], "tags": {"craft": "agricultural_engines"}, "terms": ["combines", "farm equipment", "harvesters", "tractors"], "name": "Agricultural Engines Mechanic"}, @@ -488,7 +488,7 @@ "golf/rough": {"icon": "maki-golf", "fields": ["name"], "geometry": ["area"], "tags": {"golf": "rough"}, "addTags": {"golf": "rough", "landuse": "grass"}, "name": "Rough"}, "golf/tee": {"icon": "maki-golf", "fields": ["name"], "geometry": ["area"], "tags": {"golf": "tee"}, "addTags": {"golf": "tee", "landuse": "grass"}, "terms": ["teeing ground"], "name": "Tee Box"}, "golf/water_hazard": {"icon": "maki-golf", "fields": ["name"], "geometry": ["area"], "tags": {"golf": "water_hazard"}, "addTags": {"golf": "water_hazard", "natural": "water"}, "name": "Water Hazard"}, - "healthcare": {"icon": "maki-hospital", "fields": ["name", "healthcare", "operator", "healthcare/speciality", "address", "building_area"], "moreFields": ["brand", "building/levels_building", "email", "fax", "gnis/feature_id", "height_building", "level", "opening_hours", "opening_hours/covid19", "payment_multi", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"healthcare": "*"}, "terms": ["clinic", "doctor", "disease", "health", "institution", "sick", "surgery", "wellness"], "name": "Healthcare Facility"}, + "healthcare": {"icon": "maki-hospital", "fields": ["name", "healthcare", "operator", "healthcare/speciality", "address", "building_area", "phone", "website"], "moreFields": ["brand", "building/levels_building", "email", "fax", "gnis/feature_id", "height_building", "level", "opening_hours", "opening_hours/covid19", "payment_multi", "wheelchair"], "geometry": ["point", "area"], "tags": {"healthcare": "*"}, "terms": ["clinic", "doctor", "disease", "health", "institution", "sick", "surgery", "wellness"], "name": "Healthcare Facility"}, "healthcare/alternative": {"icon": "maki-hospital", "geometry": ["point", "area"], "terms": ["acupuncture", "anthroposophical", "applied kinesiology", "aromatherapy", "ayurveda", "herbalism", "homeopathy", "hydrotherapy", "hypnosis", "naturopathy", "osteopathy", "reflexology", "reiki", "shiatsu", "traditional", "tuina", "unani"], "tags": {"healthcare": "alternative"}, "name": "Alternative Medicine"}, "healthcare/alternative/chiropractic": {"icon": "maki-hospital", "geometry": ["point", "area"], "terms": ["back", "pain", "spine"], "tags": {"healthcare": "alternative", "healthcare:speciality": "chiropractic"}, "name": "Chiropractor"}, "healthcare/audiologist": {"icon": "maki-hospital", "geometry": ["point", "area"], "terms": ["ear", "hearing", "sound"], "tags": {"healthcare": "audiologist"}, "name": "Audiologist"}, @@ -954,7 +954,7 @@ "playground/swing": {"icon": "maki-playground", "fields": ["capacity", "baby_seat", "wheelchair", "blind"], "geometry": ["point"], "tags": {"playground": "swing"}, "name": "Swing"}, "playground/zipwire": {"icon": "maki-playground", "geometry": ["point", "line"], "tags": {"playground": "zipwire"}, "terms": ["zipline", "zip wire", "zipwire"], "name": "Play Zip Line"}, "point": {"fields": ["name"], "geometry": ["vertex", "point"], "tags": {}, "terms": ["node", "other", "vertex", "vertices"], "name": "Point", "matchScore": 0.1}, - "polling_station": {"icon": "fas-vote-yea", "fields": ["name", "ref", "operator", "address", "opening_hours", "opening_hours/covid19", "building_area"], "moreFields": ["air_conditioning", "email", "fax", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "terms": ["ballot box", "ballot drop", "democracy", "elections", "polling place", "vote", "voting booth", "voting machine"], "tags": {"polling_station": "*"}, "matchScore": 0.75, "name": "Temporary Polling Place"}, + "polling_station": {"icon": "fas-vote-yea", "fields": ["name", "ref", "operator", "address", "opening_hours", "opening_hours/covid19", "building_area", "phone", "website"], "moreFields": ["air_conditioning", "email", "fax", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "wheelchair"], "geometry": ["point", "area"], "terms": ["ballot box", "ballot drop", "democracy", "elections", "polling place", "vote", "voting booth", "voting machine"], "tags": {"polling_station": "*"}, "matchScore": 0.75, "name": "Temporary Polling Place"}, "power/cable": {"icon": "temaki-cable", "fields": ["name", "ref", "operator", "voltage", "location", "layer"], "geometry": ["line"], "tags": {"power": "cable"}, "searchable": false, "name": "Power Cable"}, "power/cable/underground": {"icon": "temaki-cable", "geometry": ["line"], "tags": {"power": "cable", "location": "underground"}, "addTags": {"power": "cable", "location": "underground", "layer": "-1"}, "name": "Underground Power Cable"}, "power/generator": {"icon": "temaki-power", "fields": ["ref", "operator", "generator/source", "generator/method", "generator/type", "generator/output/electricity"], "moreFields": ["colour", "height", "level", "manufacturer", "material"], "geometry": ["point", "vertex", "area"], "terms": ["hydro", "solar", "turbine", "wind"], "tags": {"power": "generator"}, "name": "Power Generator"}, @@ -1057,7 +1057,7 @@ "seamark/buoy_lateral/green": {"icon": "temaki-buoy", "geometry": ["point", "vertex"], "terms": ["lateral buoy", "buoy lateral", "cevni", "channel marker", "iala", "lateral mark"], "tags": {"seamark:type": "buoy_lateral", "seamark:buoy_lateral:colour": "green"}, "name": "Green Buoy"}, "seamark/buoy_lateral/red": {"icon": "temaki-buoy", "geometry": ["point", "vertex"], "terms": ["lateral buoy", "buoy lateral", "cevni", "channel marker", "iala", "lateral mark"], "tags": {"seamark:type": "buoy_lateral", "seamark:buoy_lateral:colour": "red"}, "name": "Red Buoy"}, "seamark/mooring": {"icon": "temaki-buoy", "fields": ["ref", "operator", "seamark/mooring/category", "seamark/type"], "geometry": ["point"], "terms": ["dolphin", "pile", "bollard", "buoy", "post"], "tags": {"seamark:type": "mooring"}, "name": "Mooring"}, - "shop": {"icon": "maki-shop", "fields": ["name", "shop", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19", "payment_multi"], "moreFields": ["air_conditioning", "brand", "building/levels_building", "currency_multi", "ele", "email", "fax", "gnis/feature_id", "height_building", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "not/name", "phone", "ref/vatin", "second_hand", "stroller", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"shop": "*"}, "terms": [], "name": "Shop"}, + "shop": {"icon": "maki-shop", "fields": ["name", "shop", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19", "payment_multi", "phone", "website"], "moreFields": ["air_conditioning", "brand", "building/levels_building", "currency_multi", "ele", "email", "fax", "gnis/feature_id", "height_building", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "not/name", "ref/vatin", "second_hand", "stroller", "wheelchair"], "geometry": ["point", "area"], "tags": {"shop": "*"}, "terms": [], "name": "Shop"}, "shop/boutique": {"icon": "maki-shop", "fields": ["name", "clothes", "{shop}"], "geometry": ["point", "area"], "tags": {"shop": "boutique"}, "searchable": false, "name": "Boutique"}, "shop/fashion": {"icon": "maki-shop", "fields": ["name", "clothes", "{shop}"], "geometry": ["point", "area"], "tags": {"shop": "fashion"}, "searchable": false, "name": "Fashion Store"}, "shop/vacant": {"icon": "maki-shop", "fields": ["name", "address", "building_area"], "geometry": ["point", "area"], "tags": {"shop": "vacant"}, "name": "Vacant Shop", "searchable": false}, diff --git a/data/presets/presets/amenity/cafe.json b/data/presets/presets/amenity/cafe.json index a858cc0a7..ffe3042b3 100644 --- a/data/presets/presets/amenity/cafe.json +++ b/data/presets/presets/amenity/cafe.json @@ -10,7 +10,9 @@ "outdoor_seating", "internet_access", "internet_access/fee", - "internet_access/ssid" + "internet_access/ssid", + "phone", + "website" ], "moreFields": [ "air_conditioning", @@ -26,12 +28,10 @@ "min_age", "not/name", "payment_multi", - "phone", "ref/vatin", "reservation", "smoking", "takeaway", - "website", "wheelchair" ], "geometry": [ diff --git a/data/presets/presets/amenity/fast_food.json b/data/presets/presets/amenity/fast_food.json index 1657b9503..2ef3e64c1 100644 --- a/data/presets/presets/amenity/fast_food.json +++ b/data/presets/presets/amenity/fast_food.json @@ -8,7 +8,9 @@ "building_area", "opening_hours", "opening_hours/covid19", - "drive_through" + "drive_through", + "phone", + "website" ], "moreFields": [ "air_conditioning", @@ -27,11 +29,9 @@ "opening_hours/covid19", "outdoor_seating", "payment_multi", - "phone", "ref/vatin", "smoking", "takeaway", - "website", "wheelchair" ], "geometry": [ diff --git a/data/presets/presets/amenity/internet_cafe.json b/data/presets/presets/amenity/internet_cafe.json index f60a9bc84..db74faffa 100644 --- a/data/presets/presets/amenity/internet_cafe.json +++ b/data/presets/presets/amenity/internet_cafe.json @@ -8,7 +8,9 @@ "building_area", "internet_access", "internet_access/fee", - "internet_access/ssid" + "internet_access/ssid", + "phone", + "website" ], "moreFields": [ "air_conditioning", @@ -21,10 +23,8 @@ "opening_hours/covid19", "outdoor_seating", "payment_multi", - "phone", "ref/vatin", "smoking", - "website", "wheelchair" ], "geometry": [ diff --git a/data/presets/presets/club.json b/data/presets/presets/club.json index 44e7ffb77..f612d9c58 100644 --- a/data/presets/presets/club.json +++ b/data/presets/presets/club.json @@ -7,7 +7,9 @@ "address", "building_area", "opening_hours", - "opening_hours/covid19" + "opening_hours/covid19", + "phone", + "website" ], "moreFields": [ "access_simple", diff --git a/data/presets/presets/craft.json b/data/presets/presets/craft.json index 1144319b2..62e139d11 100644 --- a/data/presets/presets/craft.json +++ b/data/presets/presets/craft.json @@ -7,7 +7,9 @@ "address", "building_area", "opening_hours", - "opening_hours/covid19" + "opening_hours/covid19", + "phone", + "website" ], "moreFields": [ "air_conditioning", @@ -21,10 +23,8 @@ "internet_access/fee", "internet_access/ssid", "level", - "phone", "product", "ref/vatin", - "website", "wheelchair" ], "geometry": [ diff --git a/data/presets/presets/healthcare.json b/data/presets/presets/healthcare.json index 451e62680..a3db274c1 100644 --- a/data/presets/presets/healthcare.json +++ b/data/presets/presets/healthcare.json @@ -6,7 +6,9 @@ "operator", "healthcare/speciality", "address", - "building_area" + "building_area", + "phone", + "website" ], "moreFields": [ "brand", @@ -19,8 +21,6 @@ "opening_hours", "opening_hours/covid19", "payment_multi", - "phone", - "website", "wheelchair" ], "geometry": [ diff --git a/data/presets/presets/polling_station.json b/data/presets/presets/polling_station.json index 7972ad50d..8070894fd 100644 --- a/data/presets/presets/polling_station.json +++ b/data/presets/presets/polling_station.json @@ -7,7 +7,9 @@ "address", "opening_hours", "opening_hours/covid19", - "building_area" + "building_area", + "phone", + "website" ], "moreFields": [ "air_conditioning", @@ -17,8 +19,6 @@ "internet_access/fee", "internet_access/ssid", "level", - "phone", - "website", "wheelchair" ], "geometry": [ diff --git a/data/presets/presets/shop.json b/data/presets/presets/shop.json index 685cd8c39..b821da2b1 100644 --- a/data/presets/presets/shop.json +++ b/data/presets/presets/shop.json @@ -8,7 +8,9 @@ "building_area", "opening_hours", "opening_hours/covid19", - "payment_multi" + "payment_multi", + "phone", + "website" ], "moreFields": [ "air_conditioning", @@ -25,11 +27,9 @@ "internet_access/ssid", "level", "not/name", - "phone", "ref/vatin", "second_hand", "stroller", - "website", "wheelchair" ], "geometry": [ diff --git a/scripts/build_data.js b/scripts/build_data.js index e272b92c7..a5ec8ee8f 100644 --- a/scripts/build_data.js +++ b/scripts/build_data.js @@ -683,8 +683,7 @@ function validateCategoryPresets(categories, presets) { function validatePresetFields(presets, fields) { const betweenBracketsRegex = /([^{]*?)(?=\})/; - const maxFieldsBeforeError = 12; - const maxFieldsBeforeWarning = 8; + const maxFieldsBeforeError = 10; for (let presetID in presets) { let preset = presets[presetID]; @@ -734,23 +733,20 @@ function validatePresetFields(presets, fields) { // since `moreFields` is available, check that `fields` doesn't get too cluttered let fieldCount = preset.fields.length; - if (fieldCount > maxFieldsBeforeWarning) { - // Fields with `prerequisiteTag` probably won't show up initially, + if (fieldCount > maxFieldsBeforeError) { + // Fields with `prerequisiteTag` or `geometry` may not always be shown, // so don't count them against the limits. - const fieldsWithoutPrerequisites = preset.fields.filter(fieldID => { - if (fields[fieldID] && fields[fieldID].prerequisiteTag) return false; + const alwaysShownFields = preset.fields.filter(fieldID => { + if (fields[fieldID] && fields[fieldID].prerequisiteTag || fields[fieldID].geometry) return false; return true; }); - fieldCount = fieldsWithoutPrerequisites.length; + fieldCount = alwaysShownFields.length; } if (fieldCount > maxFieldsBeforeError) { console.error(fieldCount + ' values in "fields" of "' + preset.name + '" (' + presetID + '). Limit: ' + maxFieldsBeforeError + '. Please move lower-priority fields to "moreFields".'); console.log(''); process.exit(1); } - else if (fieldCount > maxFieldsBeforeWarning) { - console.log('Warning: ' + fieldCount + ' values in "fields" of "' + preset.name + '" (' + presetID + '). Recommended: ' + maxFieldsBeforeWarning + ' or fewer. Consider moving lower-priority fields to "moreFields".'); - } } } } From a51b82b54618a894079feaa526c2df2c37c0bc21 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 17:00:46 -0400 Subject: [PATCH 30/37] Add check to make sure presets share geometry with all their fields --- scripts/build_data.js | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/scripts/build_data.js b/scripts/build_data.js index a5ec8ee8f..24ef65988 100644 --- a/scripts/build_data.js +++ b/scripts/build_data.js @@ -710,22 +710,37 @@ function validatePresetFields(presets, fields) { if (!preset[fieldsKey]) continue; // no fields are referenced, okay for (let fieldIndex in preset[fieldsKey]) { - let field = preset[fieldsKey][fieldIndex]; - if (fields[field] !== undefined) continue; // field found, okay + let fieldID = preset[fieldsKey][fieldIndex]; + let field = fields[fieldID]; + if (field) { + if (field.geometry) { + let sharedGeometry = field.geometry.filter(value => preset.geometry.includes(value)); + if (!sharedGeometry.length) { + console.error('The preset "' + presetID + '" (' + preset.name + ') will never display the field "' + fieldID + '" since they don\'t share geometry types.'); + console.log(''); + process.exit(1); + } + } - let regexResult = betweenBracketsRegex.exec(field); - if (regexResult) { - let foreignPresetID = regexResult[0]; - if (presets[foreignPresetID] === undefined) { - console.error('Unknown preset "' + foreignPresetID + '" referenced in "' + fieldsKey + '" array of preset "' + presetID + '" (' + preset.name + ')'); + } else { + // no field found with this ID... + + let regexResult = betweenBracketsRegex.exec(fieldID); + if (regexResult) { + let foreignPresetID = regexResult[0]; + if (presets[foreignPresetID] === undefined) { + console.error('Unknown preset "' + foreignPresetID + '" referenced in "' + fieldsKey + '" array of preset "' + presetID + '" (' + preset.name + ')'); + console.log(''); + process.exit(1); + } + } else { + console.error('Unknown preset field "' + fieldID + '" in "' + fieldsKey + '" array of preset "' + presetID + '" (' + preset.name + ')'); console.log(''); process.exit(1); } - } else { - console.error('Unknown preset field "' + field + '" in "' + fieldsKey + '" array of preset "' + presetID + '" (' + preset.name + ')'); - console.log(''); - process.exit(1); } + + } } From e04dff10ecc62e9511212a1d02c032fed8bbb730 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Mon, 21 Sep 2020 17:02:46 -0400 Subject: [PATCH 31/37] Add amenity=binoculars preset (close #7985) --- data/presets.yaml | 5 +++ data/presets/presets.json | 1 + data/presets/presets/amenity/binoculars.json | 39 ++++++++++++++++++++ data/taginfo.json | 1 + dist/locales/en.json | 4 ++ 5 files changed, 50 insertions(+) create mode 100644 data/presets/presets/amenity/binoculars.json diff --git a/data/presets.yaml b/data/presets.yaml index 450a678c1..a31134c65 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -3203,6 +3203,11 @@ en: name: Biergarten # 'terms: beer,bier,booze' terms: '' + amenity/binoculars: + # amenity=binoculars + name: Mounted Binoculars + # 'terms: observation viewer,optical ranger,spotting scope,sight,spyglass,telescope,tower viewer,viewfinder,viewing stand' + terms: '' amenity/boat_rental: # amenity=boat_rental name: Boat Rental diff --git a/data/presets/presets.json b/data/presets/presets.json index da0a5cdf3..c8902b860 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -79,6 +79,7 @@ "amenity/bicycle_rental": {"icon": "temaki-bicycle_rental", "fields": ["capacity", "network", "operator", "operator/type", "fee", "payment_multi_fee"], "moreFields": ["address", "covered", "email", "fax", "level", "opening_hours", "opening_hours/covid19", "phone", "website", "wheelchair"], "geometry": ["point", "vertex", "area"], "terms": ["bike", "bicycle", "bikeshare", "bike share", "bicycle share", "cycle dock", "cycle hub", "cycleshare", "cycling"], "tags": {"amenity": "bicycle_rental"}, "name": "Bicycle Rental"}, "amenity/bicycle_repair_station": {"icon": "temaki-bicycle_repair", "fields": ["operator", "brand", "opening_hours", "opening_hours/covid19", "fee", "payment_multi_fee", "charge_fee", "service/bicycle"], "moreFields": ["colour", "covered", "indoor", "level", "manufacturer"], "geometry": ["point", "vertex"], "terms": ["bike chain", "bike multitool", "bike repair", "bike tools", "cycle pump", "cycle repair", "cycling"], "tags": {"amenity": "bicycle_repair_station"}, "name": "Bicycle Repair Tool Stand"}, "amenity/biergarten": {"icon": "fas-beer", "fields": ["name", "address", "opening_hours", "opening_hours/covid19", "outdoor_seating", "brewery"], "moreFields": ["{amenity/bar}", "building_area", "cuisine"], "geometry": ["point", "area"], "tags": {"amenity": "biergarten"}, "terms": ["beer", "bier", "booze"], "name": "Biergarten"}, + "amenity/binoculars": {"icon": "temaki-binoculars", "fields": ["operator", "access_simple", "fee", "payment_multi_fee", "charge_fee", "direction", "height", "ele_node"], "moreFields": ["colour", "covered", "indoor", "lit", "manufacturer", "ref"], "geometry": ["point"], "terms": ["observation viewer", "optical ranger", "spotting scope", "sight", "spyglass", "telescope", "tower viewer", "viewfinder", "viewing stand"], "tags": {"amenity": "binoculars"}, "name": "Mounted Binoculars"}, "amenity/boat_rental": {"icon": "temaki-boat_rental", "fields": ["name", "operator", "operator/type", "opening_hours", "opening_hours/covid19", "fee", "payment_multi_fee", "charge_fee"], "moreFields": ["access_simple", "address", "email", "fax", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"amenity": "boat_rental"}, "name": "Boat Rental"}, "amenity/bureau_de_change": {"icon": "temaki-money_hand", "fields": ["name", "operator", "payment_multi", "currency_multi", "address", "building_area"], "moreFields": ["email", "fax", "level", "opening_hours", "opening_hours/covid19", "phone", "website", "wheelchair"], "geometry": ["point", "area"], "terms": ["bureau de change", "money changer"], "tags": {"amenity": "bureau_de_change"}, "name": "Currency Exchange"}, "amenity/cafe": {"icon": "maki-cafe", "fields": ["name", "cuisine", "address", "building_area", "opening_hours", "opening_hours/covid19", "outdoor_seating", "internet_access", "internet_access/fee", "internet_access/ssid", "phone", "website"], "moreFields": ["air_conditioning", "bar", "brand", "capacity", "delivery", "diet_multi", "email", "fax", "gnis/feature_id", "level", "min_age", "not/name", "payment_multi", "ref/vatin", "reservation", "smoking", "takeaway", "wheelchair"], "geometry": ["point", "area"], "terms": ["bistro", "coffee", "tea"], "tags": {"amenity": "cafe"}, "name": "Cafe"}, diff --git a/data/presets/presets/amenity/binoculars.json b/data/presets/presets/amenity/binoculars.json new file mode 100644 index 000000000..1d619e382 --- /dev/null +++ b/data/presets/presets/amenity/binoculars.json @@ -0,0 +1,39 @@ +{ + "icon": "temaki-binoculars", + "fields": [ + "operator", + "access_simple", + "fee", + "payment_multi_fee", + "charge_fee", + "direction", + "height", + "ele_node" + ], + "moreFields": [ + "colour", + "covered", + "indoor", + "lit", + "manufacturer", + "ref" + ], + "geometry": [ + "point" + ], + "terms": [ + "observation viewer", + "optical ranger", + "spotting scope", + "sight", + "spyglass", + "telescope", + "tower viewer", + "viewfinder", + "viewing stand" + ], + "tags": { + "amenity": "binoculars" + }, + "name": "Mounted Binoculars" +} diff --git a/data/taginfo.json b/data/taginfo.json index d83d820b0..ed863dbef 100644 --- a/data/taginfo.json +++ b/data/taginfo.json @@ -83,6 +83,7 @@ {"key": "amenity", "value": "bicycle_rental", "description": "🄿 Bicycle Rental", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/bicycle_rental.svg"}, {"key": "amenity", "value": "bicycle_repair_station", "description": "🄿 Bicycle Repair Tool Stand", "object_types": ["node"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/bicycle_repair.svg"}, {"key": "amenity", "value": "biergarten", "description": "🄿 Biergarten", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/openstreetmap/iD@develop/svg/fontawesome/fas-beer.svg"}, + {"key": "amenity", "value": "binoculars", "description": "🄿 Mounted Binoculars", "object_types": ["node"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/binoculars.svg"}, {"key": "amenity", "value": "boat_rental", "description": "🄿 Boat Rental", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/boat_rental.svg"}, {"key": "amenity", "value": "bureau_de_change", "description": "🄿 Currency Exchange", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/money_hand.svg"}, {"key": "amenity", "value": "cafe", "description": "🄿 Cafe", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/mapbox/maki/icons/cafe-15.svg"}, diff --git a/dist/locales/en.json b/dist/locales/en.json index 60c0f489c..006ebfc49 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -5583,6 +5583,10 @@ "name": "Biergarten", "terms": "beer,bier,booze" }, + "amenity/binoculars": { + "name": "Mounted Binoculars", + "terms": "observation viewer,optical ranger,spotting scope,sight,spyglass,telescope,tower viewer,viewfinder,viewing stand" + }, "amenity/boat_rental": { "name": "Boat Rental", "terms": "" From 79688ce2d97914cd07aec6bae5c8ae3bbb90a0b5 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:10:49 -0400 Subject: [PATCH 32/37] Show count and use plural forms for more operation strings (re: #8014) --- data/core.yaml | 54 ++++++++++++------- dist/locales/en.json | 66 ++++++++++++++++-------- modules/modes/move.js | 2 +- modules/modes/rotate.js | 2 +- modules/operations/circularize.js | 2 +- modules/operations/move.js | 2 +- modules/operations/orthogonalize.js | 2 +- modules/operations/reflect.js | 2 +- modules/operations/reverse.js | 9 ++-- modules/operations/rotate.js | 2 +- modules/operations/straighten.js | 8 +-- modules/ui/fields/check.js | 2 +- modules/ui/intro/building.js | 4 +- modules/validations/impossible_oneway.js | 2 +- modules/validations/unsquare_way.js | 4 +- 15 files changed, 101 insertions(+), 62 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 7c8cd8724..3c6b030fd 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -101,8 +101,9 @@ en: multiple: Make these features circular. key: O annotation: - single: Made a feature circular. - multiple: Made features circular. + feature: + one: Made a feature circular. + other: "Made {n} features circular." multiple_blockers: multiple: These can't be made circular for multiple reasons. not_closed: @@ -132,11 +133,11 @@ en: key: Q annotation: corner: - single: Squared a corner. - multiple: Squared several corners. + one: Squared a corner. + other: "Squared {n} corners." feature: - single: Squared the corners of a feature. - multiple: Squared the corners of several features. + one: Squared the corners of a feature. + other: "Squared the corners of {n} features." multiple_blockers: multiple: These can't be squared for multiple reasons. end_vertex: @@ -165,9 +166,12 @@ en: lines: Straighten these lines. key: S annotation: - points: Straightened several points. - line: Straightened a line. - lines: Straightened several lines. + point: + one: Straightened a point. + other: "Straightened {n} points." + line: + one: Straightened a line. + other: "Straightened {n} lines." too_bendy: single: This can't be straightened because it bends too much. multiple: These can't be straightened because they bend too much. @@ -316,7 +320,9 @@ en: line: Moved a line. area: Moved an area. relation: Moved a relation. - multiple: Moved multiple features. + feature: + one: "Moved a feature." + other: "Moved {n} features." incomplete_relation: single: This feature can't be moved because it hasn't been fully downloaded. multiple: These features can't be moved because they haven't been fully downloaded. @@ -345,11 +351,13 @@ en: short: Y annotation: long: - single: Flipped a feature across its long axis. - multiple: Flipped multiple features across their long axis. + feature: + one: Flipped a feature across its long axis. + other: "Flipped {n} features across their long axis." short: - single: Flipped a feature across its short axis. - multiple: Flipped multiple features across their short axis. + feature: + one: Flipped a feature across its short axis. + other: "Flipped {n} features across their short axis." incomplete_relation: single: This feature can't be flipped because it hasn't been fully downloaded. multiple: These features can't be flipped because they haven't been fully downloaded. @@ -371,8 +379,10 @@ en: annotation: line: Rotated a line. area: Rotated an area. - multiple: Rotated multiple features. relation: Rotated a relation. + feature: + one: Rotated a feature. + other: "Rotated {n} features." incomplete_relation: single: This feature can't be rotated because it hasn't been fully downloaded. multiple: These features can't be rotated because they haven't been fully downloaded. @@ -395,11 +405,15 @@ en: features: Flip the directions of these features. key: V annotation: - point: Reversed a point. - points: Reversed multiple points. - line: Reversed a line. - lines: Reversed multiple lines. - features: Reversed multiple features. + point: + one: Reversed a point. + other: "Reversed {n} points." + line: + one: Reversed a line. + other: "Reversed {n} lines." + feature: + one: Reversed a feature. + other: "Reversed {n} features." scale: annotation: down: diff --git a/dist/locales/en.json b/dist/locales/en.json index 006ebfc49..a9ec33916 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -131,8 +131,10 @@ }, "key": "O", "annotation": { - "single": "Made a feature circular.", - "multiple": "Made features circular." + "feature": { + "one": "Made a feature circular.", + "other": "Made {n} features circular." + } }, "multiple_blockers": { "multiple": "These can't be made circular for multiple reasons." @@ -173,12 +175,12 @@ "key": "Q", "annotation": { "corner": { - "single": "Squared a corner.", - "multiple": "Squared several corners." + "one": "Squared a corner.", + "other": "Squared {n} corners." }, "feature": { - "single": "Squared the corners of a feature.", - "multiple": "Squared the corners of several features." + "one": "Squared the corners of a feature.", + "other": "Squared the corners of {n} features." } }, "multiple_blockers": { @@ -218,9 +220,14 @@ }, "key": "S", "annotation": { - "points": "Straightened several points.", - "line": "Straightened a line.", - "lines": "Straightened several lines." + "point": { + "one": "Straightened a point.", + "other": "Straightened {n} points." + }, + "line": { + "one": "Straightened a line.", + "other": "Straightened {n} lines." + } }, "too_bendy": { "single": "This can't be straightened because it bends too much.", @@ -414,7 +421,10 @@ "line": "Moved a line.", "area": "Moved an area.", "relation": "Moved a relation.", - "multiple": "Moved multiple features." + "feature": { + "one": "Moved a feature.", + "other": "Moved {n} features." + } }, "incomplete_relation": { "single": "This feature can't be moved because it hasn't been fully downloaded.", @@ -454,12 +464,16 @@ }, "annotation": { "long": { - "single": "Flipped a feature across its long axis.", - "multiple": "Flipped multiple features across their long axis." + "feature": { + "one": "Flipped a feature across its long axis.", + "other": "Flipped {n} features across their long axis." + } }, "short": { - "single": "Flipped a feature across its short axis.", - "multiple": "Flipped multiple features across their short axis." + "feature": { + "one": "Flipped a feature across its short axis.", + "other": "Flipped {n} features across their short axis." + } } }, "incomplete_relation": { @@ -489,8 +503,11 @@ "annotation": { "line": "Rotated a line.", "area": "Rotated an area.", - "multiple": "Rotated multiple features.", - "relation": "Rotated a relation." + "relation": "Rotated a relation.", + "feature": { + "one": "Rotated a feature.", + "other": "Rotated {n} features." + } }, "incomplete_relation": { "single": "This feature can't be rotated because it hasn't been fully downloaded.", @@ -520,11 +537,18 @@ }, "key": "V", "annotation": { - "point": "Reversed a point.", - "points": "Reversed multiple points.", - "line": "Reversed a line.", - "lines": "Reversed multiple lines.", - "features": "Reversed multiple features." + "point": { + "one": "Reversed a point.", + "other": "Reversed {n} points." + }, + "line": { + "one": "Reversed a line.", + "other": "Reversed {n} lines." + }, + "feature": { + "one": "Reversed a feature.", + "other": "Reversed {n} features." + } } }, "scale": { diff --git a/modules/modes/move.js b/modules/modes/move.js index 6a6a7e97a..56db93c4d 100644 --- a/modules/modes/move.js +++ b/modules/modes/move.js @@ -39,7 +39,7 @@ export function modeMove(context, entityIDs, baseGraph) { ]; var annotation = entityIDs.length === 1 ? t('operations.move.annotation.' + context.graph().geometry(entityIDs[0])) : - t('operations.move.annotation.multiple'); + t('operations.move.annotation.feature', { n: entityIDs.length }); var _prevGraph; var _cache; diff --git a/modules/modes/rotate.js b/modules/modes/rotate.js index d22bf8eee..b11e300de 100644 --- a/modules/modes/rotate.js +++ b/modules/modes/rotate.js @@ -43,7 +43,7 @@ export function modeRotate(context, entityIDs) { ]; var annotation = entityIDs.length === 1 ? t('operations.rotate.annotation.' + context.graph().geometry(entityIDs[0])) : - t('operations.rotate.annotation.multiple'); + t('operations.rotate.annotation.feature', { n: entityIDs.length }); var _prevGraph; var _prevAngle; diff --git a/modules/operations/circularize.js b/modules/operations/circularize.js index 0ecbe3d1a..b7497c045 100644 --- a/modules/operations/circularize.js +++ b/modules/operations/circularize.js @@ -102,7 +102,7 @@ export function operationCircularize(context, selectedIDs) { operation.annotation = function() { - return t('operations.circularize.annotation.' + _amount); + return t('operations.circularize.annotation.feature', { n: _actions.length }); }; diff --git a/modules/operations/move.js b/modules/operations/move.js index f8e7a3ff6..4078714c8 100644 --- a/modules/operations/move.js +++ b/modules/operations/move.js @@ -67,7 +67,7 @@ export function operationMove(context, selectedIDs) { operation.annotation = function() { return selectedIDs.length === 1 ? t('operations.move.annotation.' + context.graph().geometry(selectedIDs[0])) : - t('operations.move.annotation.multiple'); + t('operations.move.annotation.feature', { n: selectedIDs.length }); }; diff --git a/modules/operations/orthogonalize.js b/modules/operations/orthogonalize.js index cb4a1a382..c8b89445d 100644 --- a/modules/operations/orthogonalize.js +++ b/modules/operations/orthogonalize.js @@ -125,7 +125,7 @@ export function operationOrthogonalize(context, selectedIDs) { operation.annotation = function() { - return t('operations.orthogonalize.annotation.' + _type + '.' + _amount); + return t('operations.orthogonalize.annotation.' + _type, { n: _actions.length }); }; diff --git a/modules/operations/reflect.js b/modules/operations/reflect.js index 9be80cfb9..2a0e17271 100644 --- a/modules/operations/reflect.js +++ b/modules/operations/reflect.js @@ -83,7 +83,7 @@ export function operationReflect(context, selectedIDs, axis) { operation.annotation = function() { - return t('operations.reflect.annotation.' + axis + '.' + multi); + return t('operations.reflect.annotation.' + axis + '.feature', { n: selectedIDs.length }); }; diff --git a/modules/operations/reverse.js b/modules/operations/reverse.js index 16e854826..55ad14c2d 100644 --- a/modules/operations/reverse.js +++ b/modules/operations/reverse.js @@ -41,9 +41,9 @@ export function operationReverse(context, selectedIDs) { var entity = context.hasEntity(act.entityID()); return entity && entity.type === 'node'; }).length; - var typeID = nodeActionCount === 0 ? 'line' : (nodeActionCount === acts.length ? 'point' : 'features'); - if (typeID !== 'features' && acts.length > 1) typeID += 's'; - return typeID; + if (nodeActionCount === 0) return 'line'; + if (nodeActionCount === acts.length) return 'point'; + return 'feature'; } @@ -63,7 +63,8 @@ export function operationReverse(context, selectedIDs) { operation.annotation = function() { - return t('operations.reverse.annotation.' + reverseTypeID()); + var acts = actions(); + return t('operations.reverse.annotation.' + reverseTypeID(), { n: acts.length }); }; diff --git a/modules/operations/rotate.js b/modules/operations/rotate.js index 574acd99e..b8a4c5ea6 100644 --- a/modules/operations/rotate.js +++ b/modules/operations/rotate.js @@ -67,7 +67,7 @@ export function operationRotate(context, selectedIDs) { operation.annotation = function() { return selectedIDs.length === 1 ? t('operations.rotate.annotation.' + context.graph().geometry(selectedIDs[0])) : - t('operations.rotate.annotation.multiple'); + t('operations.rotate.annotation.feature', { n: selectedIDs.length }); }; diff --git a/modules/operations/straighten.js b/modules/operations/straighten.js index f1829c15d..56b5b4050 100644 --- a/modules/operations/straighten.js +++ b/modules/operations/straighten.js @@ -20,7 +20,7 @@ export function operationStraighten(context, selectedIDs) { function chooseAction() { // straighten selected nodes if (_wayIDs.length === 0 && _nodeIDs.length > 2) { - _geometry = 'points'; + _geometry = 'point'; return actionStraightenNodes(_nodeIDs, context.projection); // straighten selected ways (possibly between range of 2 selected nodes) @@ -67,7 +67,7 @@ export function operationStraighten(context, selectedIDs) { _extent = utilTotalExtent(_nodeIDs, context.graph()); } - _geometry = _wayIDs.length === 1 ? 'line' : 'lines'; + _geometry = 'line'; return actionStraightenWay(selectedIDs, context.projection); } @@ -125,12 +125,12 @@ export function operationStraighten(context, selectedIDs) { var disable = operation.disabled(); return disable ? t('operations.straighten.' + disable + '.' + _amount) : - t('operations.straighten.description.' + _geometry); + t('operations.straighten.description.' + _geometry + (_wayIDs.length === 1 ? '' : 's')); }; operation.annotation = function() { - return t('operations.straighten.annotation.' + _geometry); + return t('operations.straighten.annotation.' + _geometry, { n: _wayIDs.length ? _wayIDs.length : _nodeIDs.length }); }; diff --git a/modules/ui/fields/check.js b/modules/ui/fields/check.js index b25d28f38..37c1bb3f2 100644 --- a/modules/ui/fields/check.js +++ b/modules/ui/fields/check.js @@ -163,7 +163,7 @@ export function uiFieldCheck(field, context) { } return graph; }, - t('operations.reverse.annotation') + t('operations.reverse.annotation.line', { n: 1 }) ); // must manually revalidate since no 'change' event was called diff --git a/modules/ui/intro/building.js b/modules/ui/intro/building.js index 989c70ee1..1fc26ce23 100644 --- a/modules/ui/intro/building.js +++ b/modules/ui/intro/building.js @@ -391,7 +391,7 @@ export function uiIntroBuilding(context, reveal) { // Something changed. Wait for transition to complete and check undo annotation. timeout(function() { - if (context.history().undoAnnotation() === t('operations.orthogonalize.annotation.feature.single')) { + if (context.history().undoAnnotation() === t('operations.orthogonalize.annotation.feature', { n: 1 })) { continueTo(doneSquare); } else { continueTo(retryClickSquare); @@ -721,7 +721,7 @@ export function uiIntroBuilding(context, reveal) { // Something changed. Wait for transition to complete and check undo annotation. timeout(function() { - if (context.history().undoAnnotation() === t('operations.circularize.annotation.single')) { + if (context.history().undoAnnotation() === t('operations.circularize.annotation.feature', { n: 1 })) { continueTo(play); } else { continueTo(retryClickCircle); diff --git a/modules/validations/impossible_oneway.js b/modules/validations/impossible_oneway.js index 66443757a..a6aaa597d 100644 --- a/modules/validations/impossible_oneway.js +++ b/modules/validations/impossible_oneway.js @@ -180,7 +180,7 @@ export function validationImpossibleOneway() { entityIds: [way.id], onClick: function(context) { var id = this.issue.entityIds[0]; - context.perform(actionReverse(id), t('operations.reverse.annotation')); + context.perform(actionReverse(id), t('operations.reverse.annotation.line', { n: 1 })); } })); } diff --git a/modules/validations/unsquare_way.js b/modules/validations/unsquare_way.js index 6b608243c..7a9ff52c3 100644 --- a/modules/validations/unsquare_way.js +++ b/modules/validations/unsquare_way.js @@ -67,7 +67,7 @@ export function validationUnsquareWay(context) { // use same degree threshold as for detection var autoAction = actionOrthogonalize(entity.id, context.projection, undefined, degreeThreshold); autoAction.transitionable = false; // when autofixing, do it instantly - autoArgs = [autoAction, t('operations.orthogonalize.annotation.feature.single')]; + autoArgs = [autoAction, t('operations.orthogonalize.annotation.feature', { n: 1 })]; } return [new validationIssue({ @@ -92,7 +92,7 @@ export function validationUnsquareWay(context) { // use same degree threshold as for detection context.perform( actionOrthogonalize(entityId, context.projection, undefined, degreeThreshold), - t('operations.orthogonalize.annotation.feature.single') + t('operations.orthogonalize.annotation.feature', { n: 1 }) ); // run after the squaring transition (currently 150ms) window.setTimeout(function() { completionHandler(); }, 175); From ed14595784a0407c913dabd5fb9ffc63feb54b53 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:37:52 -0400 Subject: [PATCH 33/37] Adjust styling --- css/80_app.css | 20 +++----------------- modules/ui/feature_list.js | 2 +- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 6cde02f2c..80a8cd1d3 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -946,33 +946,18 @@ a.hide-toggle { } .no-results-item { padding: 10px; + font-weight: bold; } .geocode-item { width: 100%; max-width: 200px; - background-color: #ccc; margin: 30px auto; - padding: 5px; min-height: 40px; } -.ideditor[dir='rtl'] .geocode-item { - left: -25%; -} -.geocode-item:active, -.geocode-item:focus { - background-color: #aaa; -} -@media (hover: hover) { - .geocode-item:hover { - background-color: #aaa; - } -} - .feature-list-item { background-color: #fff; - font-weight: bold; display: flex; } .feature-list-item:active, @@ -1014,6 +999,7 @@ a.hide-toggle { } .feature-list-item .entity-type { color: #7092ff; + font-weight: bold; } .feature-list-item:active .entity-type, .feature-list-item:focus .entity-type { @@ -1025,7 +1011,6 @@ a.hide-toggle { } } .feature-list-item .entity-name { - font-weight: normal; color: #666; padding-left: 10px; } @@ -5495,6 +5480,7 @@ li.hide + li.version .badge .tooltip .popover-arrow { .intro-nav-wrap button.chapter { flex: 1 1 100%; padding: 0px 5px; + font-weight: bold; } .intro-nav-wrap button.chapter.next { diff --git a/modules/ui/feature_list.js b/modules/ui/feature_list.js index 0efee6019..070ba3ec3 100644 --- a/modules/ui/feature_list.js +++ b/modules/ui/feature_list.js @@ -263,7 +263,7 @@ export function uiFeatureList(context) { .data([0]) .enter() .append('button') - .attr('class', 'geocode-item') + .attr('class', 'geocode-item secondary-action') .on('click', geocoderSearch) .append('div') .attr('class', 'label') From b1a2e11a6b4896ad4e932fe27b468521f81b4ad7 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Tue, 22 Sep 2020 09:42:03 -0400 Subject: [PATCH 34/37] Fix extract fix annotation --- modules/validations/mismatched_geometry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/validations/mismatched_geometry.js b/modules/validations/mismatched_geometry.js index e4e7fac02..9f262f472 100644 --- a/modules/validations/mismatched_geometry.js +++ b/modules/validations/mismatched_geometry.js @@ -208,7 +208,7 @@ export function validationMismatchedGeometry() { var action = actionExtract(entityId); context.perform( action, - t('operations.extract.annotation.single') + t('operations.extract.annotation', { n: 1 }) ); // re-enter mode to trigger updates context.enter(modeSelect(context, [action.getExtractedNodeID()])); From 651c41cdd811537724ea15f219a65fa596b6fd7e Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Tue, 22 Sep 2020 10:05:03 -0400 Subject: [PATCH 35/37] Fix active issue hover styling --- css/80_app.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/css/80_app.css b/css/80_app.css index 80a8cd1d3..6201a8fcf 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -3958,6 +3958,9 @@ li.issue-fix-item button:not(.actionable) .fix-icon { .inspector-hover .section-entity-issues .issue-container.active .issue-label { border-bottom: 0; } +.inspector-hover .section-entity-issues .issue-container.active .issue-label button.issue-text { + font-weight: normal; +} /* Styles for raw tag inspector on hover */ From b466a96c18c614b6f78d675b6b2248a62962fc86 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Tue, 22 Sep 2020 10:13:33 -0400 Subject: [PATCH 36/37] Make the help pane keyboard-navigable (re: #8004) --- modules/ui/panes/help.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/ui/panes/help.js b/modules/ui/panes/help.js index a77ef0c81..559dac57c 100644 --- a/modules/ui/panes/help.js +++ b/modules/ui/panes/help.js @@ -286,6 +286,7 @@ export function uiPaneHelp(context) { if (i < docs.length - 1) { var nextLink = selection .append('a') + .attr('href', '#') .attr('class', 'next') .on('click', function() { clickHelp(docs[i + 1], i + 1); @@ -303,6 +304,7 @@ export function uiPaneHelp(context) { if (i > 0) { var prevLink = selection .append('a') + .attr('href', '#') .attr('class', 'previous') .on('click', function() { clickHelp(docs[i - 1], i - 1); @@ -337,6 +339,7 @@ export function uiPaneHelp(context) { .enter() .append('li') .append('a') + .attr('href', '#') .html(function(d) { return d.title; }) .on('click', clickHelp); @@ -349,6 +352,7 @@ export function uiPaneHelp(context) { .placement('top') ) .append('a') + .attr('href', '#') .on('click', clickShortcuts); shortcuts @@ -359,6 +363,7 @@ export function uiPaneHelp(context) { .append('li') .attr('class', 'walkthrough') .append('a') + .attr('href', '#') .on('click', clickWalkthrough); walkthrough From 983c01d4074e54f21896831f9c82c317fd6ccf70 Mon Sep 17 00:00:00 2001 From: Quincy Morgan <2046746+quincylvania@users.noreply.github.com> Date: Tue, 22 Sep 2020 10:37:54 -0400 Subject: [PATCH 37/37] Make the keyboard shortcuts modal keyboard-navigable (re: #8004) Prevent default hash behavior when clicking help pane internal links --- css/80_app.css | 16 ++++++++-------- modules/ui/panes/help.js | 7 +++++++ modules/ui/shortcuts.js | 6 ++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 6201a8fcf..a0ebcd792 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -4890,30 +4890,30 @@ img.tile-debug { } .modal-shortcuts .tabs-bar { - text-align: center; padding-bottom: 5px; - font-size: 16px; - font-weight: bold; + text-align: center; } -.modal-shortcuts .tab { +.modal-shortcuts a.tab { display: inline-block; padding: 5px 10px; margin: 0 5px; cursor: pointer; color: #666; + font-size: 16px; + font-weight: bold; } -.modal-shortcuts .tab.active { +.modal-shortcuts a.tab.active { color: #7092ff; border-bottom: 2px solid; } -.modal-shortcuts .tab:focus, -.modal-shortcuts .tab:active { +.modal-shortcuts a.tab:focus, +.modal-shortcuts a.tab:active { color: #597be7; background-color: #efefef; } @media (hover: hover) { - .modal-shortcuts .tab:hover { + .modal-shortcuts a.tab:hover { color: #597be7; background-color: #efefef; } diff --git a/modules/ui/panes/help.js b/modules/ui/panes/help.js index 559dac57c..e6a0ca17c 100644 --- a/modules/ui/panes/help.js +++ b/modules/ui/panes/help.js @@ -1,4 +1,6 @@ +import { event as d3_event } from 'd3-selection'; + import marked from 'marked'; import { svgIcon } from '../../svg/icon'; import { uiIntro } from '../intro/intro'; @@ -263,6 +265,7 @@ export function uiPaneHelp(context) { helpPane.renderContent = function(content) { function clickHelp(d, i) { + if (d3_event) d3_event.preventDefault(); var rtl = (localizer.textDirection() === 'rtl'); content.property('scrollTop', 0); helpPane.selection().select('.pane-heading h2').html(d.title); @@ -289,6 +292,7 @@ export function uiPaneHelp(context) { .attr('href', '#') .attr('class', 'next') .on('click', function() { + d3_event.preventDefault(); clickHelp(docs[i + 1], i + 1); }); @@ -307,6 +311,7 @@ export function uiPaneHelp(context) { .attr('href', '#') .attr('class', 'previous') .on('click', function() { + d3_event.preventDefault(); clickHelp(docs[i - 1], i - 1); }); @@ -320,6 +325,7 @@ export function uiPaneHelp(context) { function clickWalkthrough() { + d3_event.preventDefault(); if (context.inIntro()) return; context.container().call(uiIntro(context)); context.ui().togglePanes(); @@ -327,6 +333,7 @@ export function uiPaneHelp(context) { function clickShortcuts() { + d3_event.preventDefault(); context.container().call(uiShortcuts(context), true); } diff --git a/modules/ui/shortcuts.js b/modules/ui/shortcuts.js index 461268280..cde602c52 100644 --- a/modules/ui/shortcuts.js +++ b/modules/ui/shortcuts.js @@ -1,4 +1,4 @@ -import { select as d3_select } from 'd3-selection'; +import { event as d3_event, select as d3_select } from 'd3-selection'; import { fileFetcher } from '../core/file_fetcher'; import { t } from '../core/localizer'; @@ -74,9 +74,11 @@ export function uiShortcuts(context) { var tabsEnter = tabs .enter() - .append('div') + .append('a') .attr('class', 'tab') + .attr('href', '#') .on('click', function (d, i) { + d3_event.preventDefault(); _activeTab = i; render(selection, dataShortcuts); });