Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a link next to foreign keys #9988

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/envs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const envs = {

ENV__ID_TAGINFO_API_URL: JSON.stringify(process.env.ENV__ID_TAGINFO_API_URL || null),
ENV__ID_NOMINATIM_API_URL: JSON.stringify(process.env.ENV__ID_NOMINATIM_API_URL || null),
ENV__ID_TAG2LINK_URL: JSON.stringify(process.env.ENV__ID_TAG2LINK_URL || null),
};

export default envs;
3 changes: 3 additions & 0 deletions config/id.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const wmfSitematrixCdnUrl = ENV__ID_WMF_SITEMATRIX_CDN_URL
|| 'https://cdn.jsdelivr.net/npm/wmf-sitematrix@{version}/';
const nsiCdnUrl = ENV__ID_NSI_CDN_URL
|| 'https://cdn.jsdelivr.net/npm/name-suggestion-index@{version}/';
const tag2LinkUrl = ENV__ID_TAG2LINK_URL
|| 'https://cdn.jsdelivr.net/gh/JOSM/tag2link@master/index.json';

// api urls and settings
const defaultOsmApiConnections = {
Expand Down Expand Up @@ -61,4 +63,5 @@ export {
osmApiConnections,
taginfoApiUrl,
nominatimApiUrl,
tag2LinkUrl,
};
4 changes: 3 additions & 1 deletion css/80_app.css
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@

/* Utility Classes
------------------------------------------------------- */
.fillL {

Check failure on line 282 in css/80_app.css

View workflow job for this annotation

GitHub Actions / Check for spelling errors

fillL ==> fill
background: #fff;
color: #333;
}
Expand Down Expand Up @@ -369,7 +369,7 @@
border-right: none;
}

.fillL .joined > * {

Check failure on line 372 in css/80_app.css

View workflow job for this annotation

GitHub Actions / Check for spelling errors

fillL ==> fill
border-right: 1px solid #fff;
}
.joined > *:first-child {
Expand Down Expand Up @@ -2645,7 +2645,9 @@
width: 100%;
position: relative;
}
.tag-row .key-wrap,
.tag-row .key-wrap {
flex: 1 0 40%;
}
.tag-row .value-wrap {
flex: 1 1 50%;
}
Expand Down
3 changes: 2 additions & 1 deletion modules/core/file_fetcher.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import parseVersion from 'vparse';
import { presetsCdnUrl, ociCdnUrl, wmfSitematrixCdnUrl } from '../../config/id.js';
import { presetsCdnUrl, ociCdnUrl, wmfSitematrixCdnUrl, tag2LinkUrl } from '../../config/id.js';

import packageJSON from '../../package.json';

Expand Down Expand Up @@ -39,6 +39,7 @@ export function coreFileFetcher() {
'preset_defaults': presetsCdnUrl + 'dist/preset_defaults.min.json',
'preset_fields': presetsCdnUrl + 'dist/fields.min.json',
'preset_presets': presetsCdnUrl + 'dist/presets.min.json',
'tag2link': tag2LinkUrl,
'wmf_sitematrix': wmfSitematrixCdnUrl.replace('{version}', '0.1') + 'wikipedia.min.json'
};

Expand Down
36 changes: 36 additions & 0 deletions modules/services/tag2Link.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// @ts-check
import { fileFetcher } from '../core';

/**
* @typedef {{
* key: `Key:${string}`;
* url: string;
* source: string;
* rank: "normal" | "preferred";
* }} Tag2LinkItem
*/

const RANKS = ['deprecated', 'normal', 'preferred'];

/** fetch the tag2link definitions from JOSM, and convert it to an object. */
export async function loadTag2Link() {
/** @type {Tag2LinkItem[]} */
const array = await fileFetcher.get('tag2link');

/** @type {Map<string, string>} */
const map = new Map();

const allKeys = new Set(array.map(item => item.key));

for (const key of allKeys) {
// find an item with the best rank
const bestDefinition = array
.filter(item => item.key === key)
.sort((a, b) => RANKS.indexOf(b.rank) - RANKS.indexOf(a.rank))[0];

map.set(key.replace('Key:', ''), bestDefinition.url);
}

return map;
}

37 changes: 37 additions & 0 deletions modules/ui/sections/raw_tag_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,28 @@ import { utilGetSetValue, utilNoAuto, utilRebind, utilTagDiff } from '../../util
import { uiTooltip } from '..';
import { allowUpperCaseTagValues } from '../../osm/tags';
import { fileFetcher } from '../../core';
import { loadTag2Link } from '../../services/tag2Link';


/** @type {Map<string, string> | undefined} */
let tag2Link;

// singleton request
loadTag2Link()
.then((result) => { tag2Link = result; })
.catch(() => undefined); // no-op

/** @param {string} key */
export function getUrlHost(key) {
const url = tag2Link?.get(key);
if (!url) return undefined;
try {
return new URL(url).host.replace(/^www\./, '');
} catch {
return undefined;
}
}

export function uiSectionRawTagEditor(id, context) {

var section = uiSection(id, context)
Expand Down Expand Up @@ -227,6 +247,13 @@ export function uiSectionRawTagEditor(id, context) {
.on('change', valueChange)
.on('keydown.push-more', pushMore);

innerWrap
.append('button')
.attr('class', 'form-field-button foreignKey')
.attr('title', d => t('icons.view_on', { domain: getUrlHost(d.key) }))
.style('display', d => tag2Link?.get(d.key) ? 'block' : 'none')
.call(svgIcon('#iD-icon-out-link'));

innerWrap
.append('button')
.attr('class', 'form-field-button remove')
Expand Down Expand Up @@ -264,6 +291,7 @@ export function uiSectionRawTagEditor(id, context) {

row.call(reference.body);

row.select('button.foreignKey'); // propagate bound data
row.select('button.remove'); // propagate bound data
});

Expand Down Expand Up @@ -291,6 +319,15 @@ export function uiSectionRawTagEditor(id, context) {
return isReadOnly(d) || null;
});

items.selectAll('button.foreignKey')
.on(('PointerEvent' in window ? 'pointer' : 'mouse') + 'down', // 'click' fires too late - #5878
(d3_event, d) => {
if (d3_event.button !== 0) return;
const url = tag2Link?.get(d.key)?.replace(/\$1/g, d.value);
if (!url) return; // this should be impossible
window.open(url, '_blank');
});

items.selectAll('button.remove')
.on(('PointerEvent' in window ? 'pointer' : 'mouse') + 'down', // 'click' fires too late - #5878
(d3_event, d) => {
Expand Down
Loading