mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-21 07:46:58 +02:00
+30
-18
@@ -353,13 +353,6 @@ button:hover {
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
button[disabled],
|
||||
button.disabled {
|
||||
background-color: rgba(255,255,255,.25);
|
||||
color: rgba(0,0,0,.4);
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
button.active {
|
||||
background: #7092ff;
|
||||
}
|
||||
@@ -380,6 +373,15 @@ button.minor:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
button[disabled],
|
||||
button.disabled,
|
||||
button.minor[disabled],
|
||||
button.minor.disabled {
|
||||
background-color: rgba(255,255,255,.25);
|
||||
color: rgba(0,0,0,.4);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.joined button {
|
||||
border-radius: 0;
|
||||
border-right: 1px solid rgba(0,0,0,.5);
|
||||
@@ -1235,9 +1237,10 @@ a.hide-toggle {
|
||||
.form-label {
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
background: #f6f6f6;
|
||||
border: 1px solid #cfcfcf;
|
||||
padding: 5px 0 5px 10px;
|
||||
background: #f6f6f6;
|
||||
display: block;
|
||||
border-radius: 4px 4px 0 0;
|
||||
overflow: hidden;
|
||||
@@ -1774,15 +1777,15 @@ input[type=number] {
|
||||
|
||||
/* Field - Localized Name
|
||||
------------------------------------------------------- */
|
||||
.form-field .localized-main {
|
||||
.localized-main {
|
||||
padding-right: 12%;
|
||||
}
|
||||
[dir='rtl'] .form-field .localized-main {
|
||||
[dir='rtl'] .localized-main {
|
||||
padding-left: 12%;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.form-field .button-input-action {
|
||||
button.localized-add {
|
||||
position: relative;
|
||||
right: 1px;
|
||||
width: 32px;
|
||||
@@ -1794,22 +1797,22 @@ input[type=number] {
|
||||
height: 30px;
|
||||
vertical-align: top;
|
||||
}
|
||||
[dir='rtl'] .form-field .button-input-action {
|
||||
[dir='rtl'] button.localized-add {
|
||||
margin-left: 0;
|
||||
margin-right: -32px;
|
||||
border-right-width: 1px;
|
||||
border-radius: 0 0 0 4px;
|
||||
}
|
||||
|
||||
.form-field .localized-wrap {
|
||||
.localized-wrap {
|
||||
padding: 0 10px;
|
||||
}
|
||||
.form-field .localized-wrap .entry {
|
||||
.localized-wrap .entry {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-field .localized-wrap .entry::before {
|
||||
.localized-wrap .entry::before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
@@ -1822,18 +1825,27 @@ input[type=number] {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form-field .localized-wrap .entry .localized-lang {
|
||||
.localized-wrap .entry .localized-lang {
|
||||
border-radius: 0;
|
||||
border-top-width: 0;
|
||||
}
|
||||
.form-field .localized-wrap .entry .localized-value {
|
||||
.localized-wrap .entry .localized-value {
|
||||
border-top-width: 0;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
.form-field .localized-wrap .form-label button {
|
||||
.localized-wrap .form-label button {
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
button.localized-add[disabled],
|
||||
.localized-wrap .form-label button[disabled],
|
||||
.localized-wrap .localized-lang[disabled],
|
||||
.localized-wrap .localized-value[disabled] {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
|
||||
/* Field - Address
|
||||
------------------------------------------------------- */
|
||||
|
||||
@@ -23,10 +23,13 @@ export function uiFieldText(field, context) {
|
||||
var dispatch = d3_dispatch('change');
|
||||
var nominatim = services.geocoder;
|
||||
var input;
|
||||
var entity;
|
||||
var _entity;
|
||||
|
||||
|
||||
function i(selection) {
|
||||
var preset = _entity && context.presets().match(_entity, context.graph());
|
||||
var isSuggestion = preset && preset.suggestion && field.id === 'brand';
|
||||
|
||||
var fieldId = 'preset-input-' + field.safeid;
|
||||
|
||||
input = selection.selectAll('input')
|
||||
@@ -41,12 +44,14 @@ export function uiFieldText(field, context) {
|
||||
.merge(input);
|
||||
|
||||
input
|
||||
.property('disabled', !!isSuggestion)
|
||||
.on('input', change(true))
|
||||
.on('blur', change())
|
||||
.on('change', change());
|
||||
|
||||
if (field.type === 'tel' && nominatim && entity) {
|
||||
var center = entity.extent(context.graph()).center();
|
||||
|
||||
if (field.type === 'tel' && nominatim && _entity) {
|
||||
var center = _entity.extent(context.graph()).center();
|
||||
nominatim.countryCode(center, function (err, countryCode) {
|
||||
if (err || !dataPhoneFormats[countryCode]) return;
|
||||
selection.selectAll('#' + fieldId)
|
||||
@@ -86,6 +91,16 @@ export function uiFieldText(field, context) {
|
||||
input.node().value = parsed(input.node().value) + d;
|
||||
change()();
|
||||
});
|
||||
|
||||
} else if (preset && field.id === 'brand') {
|
||||
var pTag = preset.id.split('/', 2);
|
||||
var pKey = pTag[0];
|
||||
if (isSuggestion) {
|
||||
// A "suggestion" preset (brand name)
|
||||
// Put suggestion keys in `field.keys` so delete button can remove them all.
|
||||
field.keys = Object.keys(preset.removeTags)
|
||||
.filter(function(k) { return k !== pKey; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,9 +139,9 @@ export function uiFieldText(field, context) {
|
||||
}
|
||||
|
||||
|
||||
i.entity = function(_) {
|
||||
if (!arguments.length) return entity;
|
||||
entity = _;
|
||||
i.entity = function(val) {
|
||||
if (!arguments.length) return _entity;
|
||||
_entity = val;
|
||||
return i;
|
||||
};
|
||||
|
||||
|
||||
+136
-114
@@ -28,11 +28,15 @@ export function uiFieldLocalized(field, context) {
|
||||
var wikipedia = services.wikipedia;
|
||||
var input = d3_select(null);
|
||||
var localizedInputs = d3_select(null);
|
||||
var wikiTitles;
|
||||
var _wikiTitles;
|
||||
var _entity;
|
||||
|
||||
|
||||
function localized(selection) {
|
||||
var presets = context.presets();
|
||||
var preset = _entity && presets.match(_entity, context.graph());
|
||||
var isSuggestion = preset && preset.suggestion && field.id === 'name';
|
||||
|
||||
input = selection.selectAll('.localized-main')
|
||||
.data([0]);
|
||||
|
||||
@@ -46,58 +50,60 @@ export function uiFieldLocalized(field, context) {
|
||||
.call(utilNoAuto)
|
||||
.merge(input);
|
||||
|
||||
var presets = context.presets();
|
||||
var preset = presets.match(_entity, context.graph());
|
||||
var isSuggestion = preset.suggestion;
|
||||
|
||||
if (field.id === 'name' && isSuggestion) {
|
||||
// field.keys = Object.keys(preset.removeTags)
|
||||
|
||||
} else if (field.id === 'name' && !isSuggestion) {
|
||||
var isFallback = preset.isFallback();
|
||||
if (preset && field.id === 'name') {
|
||||
var pTag = preset.id.split('/', 2);
|
||||
var pKey = pTag[0];
|
||||
var pValue = pTag[1];
|
||||
|
||||
var allSuggestions = presets.collection.filter(function(p) {
|
||||
return p.suggestion === true;
|
||||
});
|
||||
if (isSuggestion) {
|
||||
// A "suggestion" preset (brand name)
|
||||
// Put suggestion keys in `field.keys` so delete button can remove them all.
|
||||
field.keys = Object.keys(preset.removeTags)
|
||||
.filter(function(k) { return k !== pKey; });
|
||||
|
||||
// This code attempts to determine if the matched preset is the
|
||||
// kind of preset that even can benefit from name suggestions..
|
||||
// - true = shops, cafes, hotels, etc. (also generic and fallback presets)
|
||||
// - false = churches, parks, hospitals, etc. (things not in the index)
|
||||
var goodSuggestions = allSuggestions.filter(function(s) {
|
||||
if (isFallback) return true;
|
||||
var sTag = s.id.split('/', 2);
|
||||
var sKey = sTag[0];
|
||||
var sValue = sTag[1];
|
||||
return pKey === sKey && (!pValue || pValue === sValue);
|
||||
});
|
||||
} else {
|
||||
// Not a suggestion preset - Add a suggestions dropdown if it makes sense to.
|
||||
var allSuggestions = presets.collection.filter(function(p) {
|
||||
return p.suggestion === true;
|
||||
});
|
||||
|
||||
// Show the suggestions.. If the user picks one, change the tags..
|
||||
if (allSuggestions.length && goodSuggestions.length) {
|
||||
input
|
||||
.call(d3_combobox()
|
||||
.container(context.container())
|
||||
.fetcher(suggestNames(preset, allSuggestions))
|
||||
.minItems(1)
|
||||
.on('accept', function(d) {
|
||||
var tags = _entity.tags;
|
||||
var geometry = _entity.geometry(context.graph());
|
||||
var removed = preset.unsetTags(tags, geometry);
|
||||
for (var k in tags) {
|
||||
tags[k] = removed[k]; // set removed tags to `undefined`
|
||||
}
|
||||
tags = d.suggestion.setTags(tags, geometry);
|
||||
dispatch.call('change', this, tags);
|
||||
})
|
||||
);
|
||||
// This code attempts to determine if the matched preset is the
|
||||
// kind of preset that even can benefit from name suggestions..
|
||||
// - true = shops, cafes, hotels, etc. (also generic and fallback presets)
|
||||
// - false = churches, parks, hospitals, etc. (things not in the index)
|
||||
var isFallback = preset.isFallback();
|
||||
var goodSuggestions = allSuggestions.filter(function(s) {
|
||||
if (isFallback) return true;
|
||||
var sTag = s.id.split('/', 2);
|
||||
var sKey = sTag[0];
|
||||
var sValue = sTag[1];
|
||||
return pKey === sKey && (!pValue || pValue === sValue);
|
||||
});
|
||||
|
||||
// Show the suggestions.. If the user picks one, change the tags..
|
||||
if (allSuggestions.length && goodSuggestions.length) {
|
||||
input
|
||||
.call(d3_combobox()
|
||||
.container(context.container())
|
||||
.fetcher(suggestNames(preset, allSuggestions))
|
||||
.minItems(1)
|
||||
.on('accept', function(d) {
|
||||
var tags = _entity.tags;
|
||||
var geometry = _entity.geometry(context.graph());
|
||||
var removed = preset.unsetTags(tags, geometry);
|
||||
for (var k in tags) {
|
||||
tags[k] = removed[k]; // set removed tags to `undefined`
|
||||
}
|
||||
tags = d.suggestion.setTags(tags, geometry);
|
||||
dispatch.call('change', this, tags);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input
|
||||
.property('disabled', isSuggestion)
|
||||
.property('disabled', !!isSuggestion)
|
||||
.on('input', change(true))
|
||||
.on('blur', change())
|
||||
.on('change', change());
|
||||
@@ -117,73 +123,82 @@ export function uiFieldLocalized(field, context) {
|
||||
.merge(translateButton);
|
||||
|
||||
translateButton
|
||||
.property('disabled', !!isSuggestion)
|
||||
.on('click', addNew);
|
||||
|
||||
|
||||
localizedInputs = selection.selectAll('.localized-wrap')
|
||||
.data([0]);
|
||||
|
||||
localizedInputs = localizedInputs.enter().append('div')
|
||||
localizedInputs = localizedInputs.enter()
|
||||
.append('div')
|
||||
.attr('class', 'localized-wrap')
|
||||
.merge(localizedInputs);
|
||||
}
|
||||
|
||||
localizedInputs.selectAll('button, input')
|
||||
.property('disabled', !!isSuggestion);
|
||||
|
||||
|
||||
function suggestNames(preset, suggestions) {
|
||||
var pTag = preset.id.split('/', 2);
|
||||
var pKey = pTag[0];
|
||||
var pValue = pTag[1];
|
||||
function suggestNames(preset, suggestions) {
|
||||
var pTag = preset.id.split('/', 2);
|
||||
var pKey = pTag[0];
|
||||
var pValue = pTag[1];
|
||||
|
||||
return function(value, callback) {
|
||||
var results = [];
|
||||
if (value && value.length > 2) {
|
||||
for (var i = 0; i < suggestions.length; i++) {
|
||||
var s = suggestions[i];
|
||||
var sTag = s.id.split('/', 2);
|
||||
var sKey = sTag[0];
|
||||
var sValue = sTag[1];
|
||||
var name = s.name();
|
||||
var dist = utilEditDistance(value, name.substring(0, value.length));
|
||||
var matchesPreset = (pKey === sKey && (!pValue || pValue === sValue));
|
||||
return function(value, callback) {
|
||||
var results = [];
|
||||
if (value && value.length > 2) {
|
||||
for (var i = 0; i < suggestions.length; i++) {
|
||||
var s = suggestions[i];
|
||||
var sTag = s.id.split('/', 2);
|
||||
var sKey = sTag[0];
|
||||
var sValue = sTag[1];
|
||||
var name = s.name();
|
||||
var dist = utilEditDistance(value, name.substring(0, value.length));
|
||||
var matchesPreset = (pKey === sKey && (!pValue || pValue === sValue));
|
||||
|
||||
if (dist < 1 || (matchesPreset && dist < 3)) {
|
||||
var obj = {
|
||||
title: name,
|
||||
value: name,
|
||||
suggestion: s,
|
||||
dist: dist + (matchesPreset ? 0 : 1) // penalize if not matched preset
|
||||
};
|
||||
results.push(obj);
|
||||
if (dist < 1 || (matchesPreset && dist < 3)) {
|
||||
var obj = {
|
||||
title: name,
|
||||
value: name,
|
||||
suggestion: s,
|
||||
dist: dist + (matchesPreset ? 0 : 1) // penalize if not matched preset
|
||||
};
|
||||
results.push(obj);
|
||||
}
|
||||
}
|
||||
results.sort(function(a, b) { return a.dist - b.dist; });
|
||||
}
|
||||
results.sort(function(a, b) { return a.dist - b.dist; });
|
||||
}
|
||||
results = results.slice(0, 10);
|
||||
callback(results);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function addNew() {
|
||||
d3_event.preventDefault();
|
||||
var data = localizedInputs.selectAll('div.entry').data();
|
||||
var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
|
||||
var langExists = _find(data, function(datum) { return datum.lang === defaultLang;});
|
||||
var isLangEn = defaultLang.indexOf('en') > -1;
|
||||
if (isLangEn || langExists) {
|
||||
defaultLang = '';
|
||||
results = results.slice(0, 10);
|
||||
callback(results);
|
||||
};
|
||||
}
|
||||
data.push({ lang: defaultLang, value: '' });
|
||||
localizedInputs.call(render, data);
|
||||
}
|
||||
|
||||
|
||||
function change(onInput) {
|
||||
return function() {
|
||||
var t = {};
|
||||
t[field.key] = utilGetSetValue(d3_select(this)) || undefined;
|
||||
dispatch.call('change', this, t, onInput);
|
||||
};
|
||||
function addNew() {
|
||||
d3_event.preventDefault();
|
||||
if (isSuggestion) return;
|
||||
|
||||
var data = localizedInputs.selectAll('div.entry').data();
|
||||
var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
|
||||
var langExists = _find(data, function(datum) { return datum.lang === defaultLang;});
|
||||
var isLangEn = defaultLang.indexOf('en') > -1;
|
||||
if (isLangEn || langExists) {
|
||||
defaultLang = '';
|
||||
}
|
||||
data.push({ lang: defaultLang, value: '' });
|
||||
|
||||
localizedInputs
|
||||
.call(renderMultilingual, data);
|
||||
}
|
||||
|
||||
|
||||
function change(onInput) {
|
||||
return function() {
|
||||
var t = {};
|
||||
t[field.key] = utilGetSetValue(d3_select(this)) || undefined;
|
||||
dispatch.call('change', this, t, onInput);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,8 +226,8 @@ export function uiFieldLocalized(field, context) {
|
||||
|
||||
if (lang && value) {
|
||||
t[key(lang)] = value;
|
||||
} else if (lang && wikiTitles && wikiTitles[d.lang]) {
|
||||
t[key(lang)] = wikiTitles[d.lang];
|
||||
} else if (lang && _wikiTitles && _wikiTitles[d.lang]) {
|
||||
t[key(lang)] = _wikiTitles[d.lang];
|
||||
}
|
||||
|
||||
d.lang = lang;
|
||||
@@ -241,16 +256,20 @@ export function uiFieldLocalized(field, context) {
|
||||
}
|
||||
|
||||
|
||||
function render(selection, data) {
|
||||
function renderMultilingual(selection, data) {
|
||||
var presets = context.presets();
|
||||
var preset = _entity && presets.match(_entity, context.graph());
|
||||
var isSuggestion = preset && preset.suggestion && field.id === 'name';
|
||||
|
||||
var wraps = selection.selectAll('div.entry')
|
||||
.data(data, function(d) { return d.lang; });
|
||||
|
||||
wraps.exit()
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('max-height','0px')
|
||||
.style('max-height', '0px')
|
||||
.style('opacity', '0')
|
||||
.style('top','-10px')
|
||||
.style('top', '-10px')
|
||||
.remove();
|
||||
|
||||
var innerWrap = wraps.enter()
|
||||
@@ -267,24 +286,26 @@ export function uiFieldLocalized(field, context) {
|
||||
|
||||
var label = wrap
|
||||
.append('label')
|
||||
.attr('class','form-label')
|
||||
.attr('class', 'form-label')
|
||||
.text(t('translate.localized_translation_label'))
|
||||
.attr('for','localized-lang');
|
||||
.attr('for', 'localized-lang');
|
||||
|
||||
label
|
||||
.append('button')
|
||||
.attr('class', 'minor remove')
|
||||
.on('click', function(d){
|
||||
.property('disabled', !!isSuggestion)
|
||||
.on('click', function(d) {
|
||||
if (isSuggestion) return;
|
||||
d3_event.preventDefault();
|
||||
var t = {};
|
||||
t[key(d.lang)] = undefined;
|
||||
dispatch.call('change', this, t);
|
||||
d3_select(this.parentNode.parentNode)
|
||||
.style('top','0')
|
||||
.style('max-height','240px')
|
||||
.style('top', '0')
|
||||
.style('max-height', '240px')
|
||||
.transition()
|
||||
.style('opacity', '0')
|
||||
.style('max-height','0px')
|
||||
.style('max-height', '0px')
|
||||
.remove();
|
||||
})
|
||||
.call(svgIcon('#iD-operation-delete'));
|
||||
@@ -293,18 +314,20 @@ export function uiFieldLocalized(field, context) {
|
||||
.append('input')
|
||||
.attr('class', 'localized-lang')
|
||||
.attr('type', 'text')
|
||||
.attr('placeholder',t('translate.localized_translation_language'))
|
||||
.attr('placeholder', t('translate.localized_translation_language'))
|
||||
.property('disabled', !!isSuggestion)
|
||||
.on('blur', changeLang)
|
||||
.on('change', changeLang)
|
||||
.call(langcombo);
|
||||
|
||||
wrap
|
||||
.append('input')
|
||||
.on('blur', changeValue)
|
||||
.on('change', changeValue)
|
||||
.attr('type', 'text')
|
||||
.attr('placeholder', t('translate.localized_translation_name'))
|
||||
.attr('class', 'localized-value');
|
||||
.attr('class', 'localized-value')
|
||||
.property('disabled', !!isSuggestion)
|
||||
.on('blur', changeValue)
|
||||
.on('change', changeValue);
|
||||
});
|
||||
|
||||
innerWrap
|
||||
@@ -337,13 +360,11 @@ export function uiFieldLocalized(field, context) {
|
||||
|
||||
localized.tags = function(tags) {
|
||||
// Fetch translations from wikipedia
|
||||
if (tags.wikipedia && !wikiTitles) {
|
||||
wikiTitles = {};
|
||||
if (tags.wikipedia && !_wikiTitles) {
|
||||
_wikiTitles = {};
|
||||
var wm = tags.wikipedia.match(/([^:]+):(.+)/);
|
||||
if (wm && wm[0] && wm[1]) {
|
||||
wikipedia.translations(wm[1], wm[2], function(d) {
|
||||
wikiTitles = d;
|
||||
});
|
||||
wikipedia.translations(wm[1], wm[2], function(d) { _wikiTitles = d; });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,7 +378,8 @@ export function uiFieldLocalized(field, context) {
|
||||
}
|
||||
}
|
||||
|
||||
localizedInputs.call(render, postfixed.reverse());
|
||||
localizedInputs
|
||||
.call(renderMultilingual, postfixed.reverse());
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user