mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
138 lines
4.2 KiB
JavaScript
138 lines
4.2 KiB
JavaScript
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
|
import { select as d3_select } from 'd3-selection';
|
|
|
|
import { utilRebind } from '../../util';
|
|
import { uiFieldCombo } from './combo';
|
|
|
|
|
|
export function uiFieldDirectionalCombo(field, context) {
|
|
var dispatch = d3_dispatch('change');
|
|
var items = d3_select(null);
|
|
var wrap = d3_select(null);
|
|
var _tags;
|
|
|
|
var _combos = {};
|
|
|
|
// fallback for schema-builder v5's cycleway field type: can be removed eventually
|
|
if (field.type === 'cycleway') {
|
|
field = {
|
|
...field,
|
|
key: field.keys[0],
|
|
keys: field.keys.slice(1)
|
|
};
|
|
}
|
|
|
|
function directionalCombo(selection) {
|
|
|
|
function stripcolon(s) {
|
|
return s.replace(':', '');
|
|
}
|
|
|
|
|
|
wrap = selection.selectAll('.form-field-input-wrap')
|
|
.data([0]);
|
|
|
|
wrap = wrap.enter()
|
|
.append('div')
|
|
.attr('class', 'form-field-input-wrap form-field-input-' + field.type)
|
|
.merge(wrap);
|
|
|
|
|
|
var div = wrap.selectAll('ul')
|
|
.data([0]);
|
|
|
|
div = div.enter()
|
|
.append('ul')
|
|
.attr('class', 'rows rows-table')
|
|
.merge(div);
|
|
|
|
items = div.selectAll('li')
|
|
.data(field.keys);
|
|
|
|
var enter = items.enter()
|
|
.append('li')
|
|
.attr('class', function(d) { return 'labeled-input preset-directionalcombo-' + stripcolon(d); });
|
|
|
|
enter
|
|
.append('div')
|
|
.attr('class', 'label preset-label-directionalcombo')
|
|
.attr('for', function(d) { return 'preset-input-directionalcombo-' + stripcolon(d); })
|
|
.html(function(d) { return field.t.html('types.' + d); });
|
|
|
|
enter
|
|
.append('div')
|
|
.attr('class', 'preset-input-directionalcombo-wrap form-field-input-wrap')
|
|
.each(function(key) {
|
|
const subField = {
|
|
...field,
|
|
type: 'combo',
|
|
key
|
|
};
|
|
const combo = uiFieldCombo(subField, context);
|
|
combo.on('change', t => change(key, t[key]));
|
|
_combos[key] = combo;
|
|
d3_select(this).call(combo);
|
|
});
|
|
|
|
items = items.merge(enter);
|
|
|
|
// Update
|
|
wrap.selectAll('.preset-input-directionalcombo')
|
|
.on('change', change)
|
|
.on('blur', change);
|
|
}
|
|
|
|
|
|
function change(key, newValue) {
|
|
const commonKey = field.key;
|
|
/** if commonKey ends with :both, this is the key without :both. and vice-verca */
|
|
const otherCommonKey = field.key.endsWith(':both')
|
|
? field.key.replace(/:both$/, '')
|
|
: `${field.key}:both`;
|
|
|
|
const otherKey = key === field.keys[0] ? field.keys[1] : field.keys[0];
|
|
|
|
dispatch.call('change', this, tags => {
|
|
const otherValue = tags[otherKey] || tags[commonKey] || tags[otherCommonKey];
|
|
if (newValue === otherValue) {
|
|
// both tags match, use the common tag to tag both sides the same way
|
|
tags[commonKey] = newValue;
|
|
delete tags[key];
|
|
delete tags[otherKey];
|
|
delete tags[otherCommonKey];
|
|
} else {
|
|
// Always set both left and right as changing one can affect the other
|
|
tags[key] = newValue;
|
|
delete tags[commonKey];
|
|
delete tags[otherCommonKey];
|
|
tags[otherKey] = otherValue;
|
|
}
|
|
return tags;
|
|
});
|
|
}
|
|
|
|
|
|
directionalCombo.tags = function(tags) {
|
|
_tags = tags;
|
|
|
|
const commonKey = field.key.replace(/:both$/, '');
|
|
for (let key in _combos) {
|
|
const uniqueValues = [... new Set([]
|
|
.concat(_tags[commonKey])
|
|
.concat(_tags[`${commonKey}:both`])
|
|
.concat(_tags[key])
|
|
.filter(Boolean))];
|
|
_combos[key].tags({ [key]: uniqueValues.length > 1 ? uniqueValues : uniqueValues[0] });
|
|
}
|
|
};
|
|
|
|
|
|
directionalCombo.focus = function() {
|
|
var node = wrap.selectAll('input').node();
|
|
if (node) node.focus();
|
|
};
|
|
|
|
|
|
return utilRebind(directionalCombo, dispatch, 'on');
|
|
}
|