diff --git a/data/core.yaml b/data/core.yaml index 213f77374..e99c8ba5c 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -425,7 +425,9 @@ en: choose: Select feature type results: "{n} results for {search}" reference: View on OpenStreetMap Wiki - edit_reference: Edit or translate on OSM Wiki + edit_reference: Edit or translate description + wiki_reference: View documentation + wiki_en_reference: View documentation in English back_tooltip: Change feature remove: Remove search: Search diff --git a/dist/locales/en.json b/dist/locales/en.json index 5e4259715..0d282ba18 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -520,7 +520,9 @@ "choose": "Select feature type", "results": "{n} results for {search}", "reference": "View on OpenStreetMap Wiki", - "edit_reference": "Edit or translate on OSM Wiki", + "edit_reference": "Edit or translate description", + "wiki_reference": "View documentation", + "wiki_en_reference": "View documentation in English", "back_tooltip": "Change feature", "remove": "Remove", "search": "Search", diff --git a/modules/services/osm_wikibase.js b/modules/services/osm_wikibase.js index 1ef3637d7..b6f44a87b 100644 --- a/modules/services/osm_wikibase.js +++ b/modules/services/osm_wikibase.js @@ -88,6 +88,21 @@ export default { }, + /** + * Convert monolingual property into a key-value object (language -> value) + * @param entity object from wikibase + * @param property string e.g. 'P31' for monolingual wiki page title + */ + monolingualClaimToValueObj: function(entity, property) { + if (!entity || !entity.claims[property]) return undefined; + return entity.claims[property].reduce(function(acc, obj) { + var value = obj.mainsnak.datavalue.value; + acc[value.language] = value.text; + return acc; + }, {}); + }, + + toSitelink: function(key, value) { var result = value ? 'Tag:' + key + '=' + value : 'Key:' + key; return result.replace(/_/g, ' ').trim(); diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index 6215250b9..85567be49 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -51,6 +51,31 @@ export function uiTagReference(tag) { } } + // Helper method to get wiki info if a given language exists + function getWikiInfo(wiki, langCode, msg) { + if (wiki && wiki[langCode]) { + return {title: wiki[langCode], text: t(msg)}; + } + } + + // Try to get a wiki page from tag data item first, followed by the corresponding key data item. + // If neither tag nor key data item contain a wiki page in the needed language nor English, + // get the first found wiki page from either the tag or the key item. + var tagWiki = wikibase.monolingualClaimToValueObj(data.tag, 'P31'); + var keyWiki = wikibase.monolingualClaimToValueObj(data.key, 'P31'); + + // If exact language code does not exist, try to find the first part before the '-' + // BUG: in some cases, a more elaborate fallback logic might be needed + var langPrefix = langCode.split('-', 2)[0]; + + result.wiki = + getWikiInfo(tagWiki, langCode, 'inspector.wiki_reference') || + getWikiInfo(tagWiki, langPrefix, 'inspector.wiki_reference') || + getWikiInfo(tagWiki, 'en', 'inspector.wiki_en_reference') || + getWikiInfo(keyWiki, langCode, 'inspector.wiki_reference') || + getWikiInfo(keyWiki, langPrefix, 'inspector.wiki_reference') || + getWikiInfo(keyWiki, 'en', 'inspector.wiki_en_reference'); + return result; } @@ -110,6 +135,18 @@ export function uiTagReference(tag) { .append('span') .text(t('inspector.edit_reference')); + if (docs.wiki) { + _body + .append('a') + .attr('class', 'tag-reference-link') + .attr('target', '_blank') + .attr('tabindex', -1) + .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.wiki.title) + .call(svgIcon('#iD-icon-out-link', 'inline')) + .append('span') + .text(docs.wiki.text); + } + // Add link to info about "good changeset comments" - #2923 if (param.key === 'comment') { _body diff --git a/test/spec/services/osm_wikibase.js b/test/spec/services/osm_wikibase.js index 61951abba..dc58ae094 100644 --- a/test/spec/services/osm_wikibase.js +++ b/test/spec/services/osm_wikibase.js @@ -246,7 +246,15 @@ describe('iD.serviceOsmWikibase', function () { type: 'statement', rank: 'normal' } - ] + ], + P31: [ + {mainsnak: {datavalue: {value: {text: 'Cs:Key:bridge:movable', language: 'cs'}}}}, + {mainsnak: {datavalue: {value: {text: 'DE:Key:bridge:movable', language: 'de'}}}}, + {mainsnak: {datavalue: {value: {text: 'FR:Key:bridge:movable', language: 'fr'}}}}, + {mainsnak: {datavalue: {value: {text: 'JA:Key:bridge:movable', language: 'ja'}}}}, + {mainsnak: {datavalue: {value: {text: 'Pl:Key:bridge:movable', language: 'pl'}}}}, + {mainsnak: {datavalue: {value: {text: 'Key:bridge:movable', language: 'en'}}}}, + ], }, sitelinks: { wiki: { @@ -319,4 +327,15 @@ describe('iD.serviceOsmWikibase', function () { expect(wikibase.claimToValue(keyData(), 'P6', 'de')).to.eql('Q14'); }); + it('gets monolingual value from entity as an object', function () { + expect(wikibase.monolingualClaimToValueObj(tagData(), 'P31')).to.eql({ + cs: 'Cs:Key:bridge:movable', + de: 'DE:Key:bridge:movable', + fr: 'FR:Key:bridge:movable', + ja: 'JA:Key:bridge:movable', + pl: 'Pl:Key:bridge:movable', + en: 'Key:bridge:movable', + }); + }); + });