Skip to content

Commit

Permalink
Update to id-tagging-schema v3.0.0
Browse files Browse the repository at this point in the history
Add UI for translatable combo fields
  • Loading branch information
quincylvania committed Dec 8, 2020
1 parent bc9679d commit cb7f1c2
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 77 deletions.
17 changes: 17 additions & 0 deletions css/80_app.css
Original file line number Diff line number Diff line change
Expand Up @@ -1601,6 +1601,13 @@ a.hide-toggle {
display: none;
}

.form-field-input-combo input.raw-value {
font-family: monospace;
}
.form-field-input-combo input.known-value {
color: #7092ff;
}

.form-field-input-multicombo ul.chiplist {
padding: 5px 8px 5px 8px;
background: #fff;
Expand Down Expand Up @@ -1628,6 +1635,7 @@ a.hide-toggle {
background-color: #eff2f7;
border: 1px solid #ccd5e3;
max-width: 100%;
color: #7092ff;
}
.ideditor[dir='ltr'] .form-field-input-multicombo li.chip {
padding: 2px 0px 2px 5px;
Expand All @@ -1643,6 +1651,10 @@ a.hide-toggle {
z-index: 3000;
cursor: grabbing;
}
.form-field-input-multicombo li.chip.raw-value {
font-family: monospace;
color: #333;
}
.form-field-input-multicombo li.mixed {
border-color: #eff2f7;
color: #888;
Expand Down Expand Up @@ -2226,6 +2238,11 @@ div.combobox {
border-right: 5px solid transparent;
}

.combobox .combobox-option.raw-option {
font-family: monospace;
color: #333;
}


/* Field Help
------------------------------------------------------- */
Expand Down
12 changes: 6 additions & 6 deletions modules/core/file_fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export function coreFileFetcher() {
let _inflight = {};
let _fileMap = {
'address_formats': 'data/address_formats.min.json',
'deprecated': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/deprecated.min.json',
'discarded': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/discarded.min.json',
'deprecated': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/deprecated.min.json',
'discarded': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/discarded.min.json',
'imagery': 'data/imagery.min.json',
'intro_graph': 'data/intro_graph.min.json',
'keepRight': 'data/keepRight.min.json',
Expand All @@ -23,10 +23,10 @@ export function coreFileFetcher() {
'nsi_filters': 'https://cdn.jsdelivr.net/npm/name-suggestion-index@4/dist/filters.min.json',
'oci_features': 'https://cdn.jsdelivr.net/npm/osm-community-index@2/dist/features.min.json',
'oci_resources': 'https://cdn.jsdelivr.net/npm/osm-community-index@2/dist/resources.min.json',
'preset_categories': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/preset_categories.min.json',
'preset_defaults': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/preset_defaults.min.json',
'preset_fields': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/fields.min.json',
'preset_presets': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/presets.min.json',
'preset_categories': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/preset_categories.min.json',
'preset_defaults': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/preset_defaults.min.json',
'preset_fields': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/fields.min.json',
'preset_presets': 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/presets.min.json',
'phone_formats': 'data/phone_formats.min.json',
'qa_data': 'data/qa_data.min.json',
'shortcuts': 'data/shortcuts.min.json',
Expand Down
6 changes: 5 additions & 1 deletion modules/core/localizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function coreLocalizer() {

const localeDirs = {
general: 'locales',
tagging: 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/translations'
tagging: 'https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/translations'
};

let fileMap = fileFetcher.fileMap();
Expand Down Expand Up @@ -338,6 +338,10 @@ export function coreLocalizer() {
};
};

localizer.hasTextForStringId = function(stringId) {
return !!localizer.tInfo(stringId, { default: 'nothing found'}).locale;
};

// Returns only the localized text, discarding the locale info
localizer.t = function(stringId, replacements, locale) {
return localizer.tInfo(stringId, replacements, locale).text;
Expand Down
3 changes: 2 additions & 1 deletion modules/presets/field.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { t } from '../core/localizer';
import { localizer, t } from '../core/localizer';
import { utilSafeClassName } from '../util/util';


Expand All @@ -22,6 +22,7 @@ export function presetField(fieldID, field) {

_this.t = (scope, options) => t(`_tagging.presets.fields.${fieldID}.${scope}`, options);
_this.t.html = (scope, options) => t.html(`_tagging.presets.fields.${fieldID}.${scope}`, options);
_this.hasTextForStringId = (scope) => localizer.hasTextForStringId(`_tagging.presets.fields.${fieldID}.${scope}`);

_this.title = () => _this.overrideLabel || _this.t('label', { 'default': fieldID });
_this.label = () => _this.overrideLabel || _this.t.html('label', { 'default': fieldID });
Expand Down
4 changes: 3 additions & 1 deletion modules/ui/combobox.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,9 @@ export function uiCombobox(context, klass) {
// enter/update
options.enter()
.append('a')
.attr('class', 'combobox-option')
.attr('class', function(d) {
return 'combobox-option ' + (d.klass || '');
})
.attr('title', function(d) { return d.title; })
.html(function(d) { return d.display || d.value; })
.on('mouseenter', _mouseEnterHandler)
Expand Down
2 changes: 1 addition & 1 deletion modules/ui/fields/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export function uiFieldAddress(field, context) {
}
if (_countryCode) {
var localkey = subfield.id + '!' + _countryCode;
var tkey = addrField.strings.placeholders[localkey] ? localkey : subfield.id;
var tkey = addrField.hasTextForStringId('placeholders.' + localkey) ? localkey : subfield.id;
return addrField.t('placeholders.' + tkey);
}
});
Expand Down
9 changes: 5 additions & 4 deletions modules/ui/fields/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export { uiFieldCheck as uiFieldOnewayCheck };

export function uiFieldCheck(field, context) {
var dispatch = d3_dispatch('change');
var options = field.strings && field.strings.options;
var options = field.options;
var values = [];
var texts = [];

Expand All @@ -33,9 +33,10 @@ export function uiFieldCheck(field, context) {


if (options) {
for (var k in options) {
values.push(k === 'undefined' ? undefined : k);
texts.push(field.t.html('options.' + k, { 'default': options[k] }));
for (var i in options) {
var v = options[i];
values.push(v === 'undefined' ? undefined : v);
texts.push(field.t.html('options.' + v, { 'default': v }));
}
} else {
values = [undefined, 'yes'];
Expand Down
103 changes: 46 additions & 57 deletions modules/ui/fields/combo.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ export function uiFieldCombo(field, context) {
var _isMulti = (field.type === 'multiCombo' || field.type === 'manyCombo');
var _isNetwork = (field.type === 'networkCombo');
var _isSemi = (field.type === 'semiCombo');
var _optstrings = field.strings && field.strings.options;
var _optarray = field.options;
var _showTagInfoSuggestions = field.type !== 'manyCombo' && field.autoSuggestions !== false;
var _allowCustomValues = field.type !== 'manyCombo' && field.customValues !== false;
var _snake_case = (field.snake_case || (field.snake_case === undefined));
var _combobox = uiCombobox(context, 'combo-' + field.safeid)
.caseSensitive(field.caseSensitive)
Expand Down Expand Up @@ -57,10 +58,6 @@ export function uiFieldCombo(field, context) {
return s.replace(/\s+/g, '_');
}

function unsnake(s) {
return s.replace(/_+/g, ' ');
}

function clean(s) {
return s.split(';')
.map(function(s) { return s.trim(); })
Expand All @@ -73,14 +70,10 @@ export function uiFieldCombo(field, context) {
function tagValue(dval) {
dval = clean(dval || '');

if (_optstrings) {
var found = _comboData.find(function(o) {
return o.key && clean(o.value) === dval;
});
if (found) {
return found.key;
}
}
var found = _comboData.find(function(o) {
return o.key && clean(o.value) === dval;
});
if (found) return found.key;

if (field.type === 'typeCombo' && !dval) {
return 'yes';
Expand All @@ -95,20 +88,15 @@ export function uiFieldCombo(field, context) {
function displayValue(tval) {
tval = tval || '';

if (_optstrings) {
var found = _comboData.find(function(o) {
return o.key === tval && o.value;
});
if (found) {
return found.value;
}
if (field.hasTextForStringId('options.' + tval)) {
return field.t('options.' + tval, { default: tval });
}

if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
return '';
}

return _snake_case ? unsnake(tval) : tval;
return tval;
}


Expand All @@ -127,46 +115,33 @@ export function uiFieldCombo(field, context) {


function initCombo(selection, attachTo) {
if (_optstrings) {
if (!_allowCustomValues) {
selection.attr('readonly', 'readonly');
selection.call(_combobox, attachTo);
setStaticValues(setPlaceholder);

} else if (_optarray) {
selection.call(_combobox, attachTo);
setStaticValues(setPlaceholder);
}

} else if (services.taginfo) {
if (_showTagInfoSuggestions && services.taginfo) {
selection.call(_combobox.fetcher(setTaginfoValues), attachTo);
setTaginfoValues('', setPlaceholder);

} else {
selection.call(_combobox, attachTo);
setStaticValues(setPlaceholder);
}
}


function setStaticValues(callback) {
if (!(_optstrings || _optarray)) return;

if (_optstrings) {
_comboData = Object.keys(_optstrings).map(function(k) {
var v = field.t('options.' + k, { 'default': _optstrings[k] });
return {
key: k,
value: v,
title: v,
display: field.t.html('options.' + k, { 'default': _optstrings[k] })
};
});

} else if (_optarray) {
_comboData = _optarray.map(function(k) {
var v = _snake_case ? unsnake(k) : k;
return {
key: k,
value: v,
title: v
};
});
}
if (!_optarray) return;

_comboData = _optarray.map(function(v) {
return {
key: v,
value: field.t('options.' + v, { default: v }),
title: v,
display: field.t.html('options.' + v, { default: v }),
klass: field.hasTextForStringId('options.' + v) ? '' : 'raw-option'
};
});

_combobox.data(objectDifference(_comboData, _multiData));
if (callback) callback(_comboData);
Expand Down Expand Up @@ -225,11 +200,13 @@ export function uiFieldCombo(field, context) {
_comboData = data.map(function(d) {
var k = d.value;
if (_isMulti) k = k.replace(field.key, '');
var v = _snake_case ? unsnake(k) : k;
var label = field.t('options.' + k, { default: k });
return {
key: k,
value: v,
title: _isMulti ? v : d.title
value: label,
display: field.t.html('options.' + k, { default: k }),
title: d.title || label,
klass: field.hasTextForStringId('options.' + k) ? '' : 'raw-option'
};
});

Expand Down Expand Up @@ -507,9 +484,9 @@ export function uiFieldCombo(field, context) {
_combobox.data(available);

// Hide 'Add' button if this field uses fixed set of
// translateable _optstrings and they're all currently used,
// options and they're all currently used,
// or if the field is already at its character limit
var hideAdd = (_optstrings && !available.length) || maxLength <= 0;
var hideAdd = (!_allowCustomValues && !available.length) || maxLength <= 0;
_container.selectAll('.chiplist .input-wrap')
.style('display', hideAdd ? 'none' : null);

Expand All @@ -530,6 +507,11 @@ export function uiFieldCombo(field, context) {

chips = chips.merge(enter)
.order()
.classed('raw-value', function(d) {
var k = d.key;
if (_isMulti) k = k.replace(field.key, '');
return !field.hasTextForStringId('options.' + k);
})
.classed('draggable', allowDragAndDrop)
.classed('mixed', function(d) {
return d.isMixed;
Expand Down Expand Up @@ -558,7 +540,14 @@ export function uiFieldCombo(field, context) {
return displayValue(val);
}).filter(Boolean);

var showsValue = !isMixed && tags[field.key] && !(field.type === 'typeCombo' && tags[field.key] === 'yes');
var isRawValue = showsValue && !field.hasTextForStringId('options.' + tags[field.key]);
var isKnownValue = showsValue && !isRawValue;

utilGetSetValue(_input, !isMixed ? displayValue(tags[field.key]) : '')
.classed('raw-value', isRawValue)
.classed('known-value', isKnownValue)
.attr('readonly', (!_allowCustomValues || isKnownValue) ? 'readonly' : undefined)
.attr('title', isMixed ? mixedValues.join('\n') : undefined)
.attr('placeholder', isMixed ? t('inspector.multiple_values') : _staticPlaceholder || '')
.classed('mixed', isMixed);
Expand Down
2 changes: 1 addition & 1 deletion modules/ui/fields/cycleway.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function uiFieldCycleway(field, context) {


cycleway.options = function() {
return Object.keys(field.strings.options).map(function(option) {
return field.options.map(function(option) {
return {
title: field.t('options.' + option + '.description'),
value: option
Expand Down
1 change: 1 addition & 0 deletions modules/ui/fields/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export var uiFields = {
lanes: uiFieldLanes,
localized: uiFieldLocalized,
roadspeed: uiFieldRoadspeed,
roadheight: uiFieldText,
manyCombo: uiFieldManyCombo,
multiCombo: uiFieldMultiCombo,
networkCombo: uiFieldNetworkCombo,
Expand Down
2 changes: 1 addition & 1 deletion modules/ui/fields/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function uiFieldText(field, context) {

input = input.enter()
.append('input')
.attr('type', field.type === 'identifier' ? 'text' : field.type)
.attr('type', field.type === 'identifier' || field.type === 'roadheight' ? 'text' : field.type)
.attr('id', field.domId)
.classed(field.type, true)
.call(utilNoAuto)
Expand Down
2 changes: 1 addition & 1 deletion modules/ui/fields/radio.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function uiFieldRadio(field, context) {
var wrap = d3_select(null);
var labels = d3_select(null);
var radios = d3_select(null);
var radioData = (field.options || (field.strings && field.strings.options && Object.keys(field.strings.options)) || field.keys).slice(); // shallow copy
var radioData = (field.options || field.keys).slice(); // shallow copy
var typeField;
var layerField;
var _oldType = {};
Expand Down
6 changes: 3 additions & 3 deletions scripts/build_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ function buildData() {
minifyJSON('data/territory_languages.json', 'dist/data/territory_languages.min.json'),
Promise.all([
// Fetch the icons that are needed by the expected tagging schema version
fetch('https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/presets.min.json'),
fetch('https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/preset_categories.min.json'),
fetch('https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@2/dist/fields.min.json'),
fetch('https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/presets.min.json'),
fetch('https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/preset_categories.min.json'),
fetch('https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/fields.min.json'),
// WARNING: we fetch the bleeding edge data too to make sure we're always hosting the
// latest icons, but note that the format could break at any time
fetch('https://raw.githubusercontent.com/openstreetmap/id-tagging-schema/main/dist/presets.min.json'),
Expand Down

0 comments on commit cb7f1c2

Please sign in to comment.