mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-19 23:14:47 +02:00
Merge branch 'develop' into accessible_ui
This commit is contained in:
@@ -288,7 +288,7 @@ export function uiFieldAddress(field, context) {
|
||||
})
|
||||
.attr('title', function(subfield) {
|
||||
var val = tags[field.key + ':' + subfield.id];
|
||||
return val && Array.isArray(val) && val.filter(Boolean).join('\n');
|
||||
return (val && Array.isArray(val)) ? val.filter(Boolean).join('\n') : undefined;
|
||||
})
|
||||
.classed('mixed', function(subfield) {
|
||||
return Array.isArray(tags[field.key + ':' + subfield.id]);
|
||||
|
||||
@@ -83,7 +83,8 @@ export function uiFieldCheck(field, context) {
|
||||
var icon = pseudoDirection ? '#iD-icon-forward' : '#iD-icon-backward';
|
||||
|
||||
selection.selectAll('.reverser-span')
|
||||
.html(t.html('inspector.check.reverser'))
|
||||
.html('')
|
||||
.call(t.append('inspector.check.reverser'))
|
||||
.call(svgIcon(icon, 'inline'));
|
||||
|
||||
return selection;
|
||||
|
||||
@@ -527,13 +527,13 @@ export function uiFieldCombo(field, context) {
|
||||
}
|
||||
|
||||
chips.select('span')
|
||||
.html(function(d) { return d.value; });
|
||||
.text(function(d) { return d.value; });
|
||||
|
||||
chips.select('a')
|
||||
.attr('href', '#')
|
||||
.on('click', removeMultikey)
|
||||
.attr('class', 'remove')
|
||||
.html('×');
|
||||
.text('×');
|
||||
|
||||
} else {
|
||||
var isMixed = Array.isArray(tags[field.key]);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
import _debounce from 'lodash-es/debounce';
|
||||
import * as countryCoder from '@ideditor/country-coder';
|
||||
|
||||
import { presetManager } from '../../presets';
|
||||
@@ -21,6 +22,7 @@ export function uiFieldText(field, context) {
|
||||
var dispatch = d3_dispatch('change');
|
||||
var input = d3_select(null);
|
||||
var outlinkButton = d3_select(null);
|
||||
var wrap = d3_select(null);
|
||||
var _entityIDs = [];
|
||||
var _tags;
|
||||
var _phoneFormats = {};
|
||||
@@ -62,7 +64,7 @@ export function uiFieldText(field, context) {
|
||||
calcLocked();
|
||||
var isLocked = field.locked();
|
||||
|
||||
var wrap = selection.selectAll('.form-field-input-wrap')
|
||||
wrap = selection.selectAll('.form-field-input-wrap')
|
||||
.data([0]);
|
||||
|
||||
wrap = wrap.enter()
|
||||
@@ -171,9 +173,67 @@ export function uiFieldText(field, context) {
|
||||
if (value) window.open(value, '_blank');
|
||||
})
|
||||
.merge(outlinkButton);
|
||||
} else if (field.key.split(':').includes('colour')) {
|
||||
input.attr('type', 'text');
|
||||
|
||||
updateColourPreview();
|
||||
}
|
||||
}
|
||||
|
||||
function isColourValid(colour) {
|
||||
if (!colour.match(/^(#([0-9a-fA-F]{3}){1,2}|\w+)$/)) {
|
||||
// OSM only supports hex or named colors
|
||||
return false;
|
||||
} else if (!CSS.supports('color', colour) || ['unset', 'inherit', 'initial', 'revert'].includes(colour)) {
|
||||
// see https://stackoverflow.com/a/68217760/1627467
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function updateColourPreview() {
|
||||
wrap.selectAll('.colour-preview')
|
||||
.remove();
|
||||
|
||||
const colour = utilGetSetValue(input);
|
||||
|
||||
if (!isColourValid(colour) && colour !== '') return;
|
||||
|
||||
var colourSelector = wrap.selectAll('.colour-selector')
|
||||
.data([0]);
|
||||
outlinkButton = wrap.selectAll('.colour-preview')
|
||||
.data([colour]);
|
||||
|
||||
colourSelector
|
||||
.enter()
|
||||
.append('input')
|
||||
.attr('type', 'color')
|
||||
.attr('class', 'form-field-button colour-selector')
|
||||
.attr('value', colour)
|
||||
.on('input', _debounce(function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
var colour = this.value;
|
||||
if (!isColourValid(colour)) return;
|
||||
utilGetSetValue(input, this.value);
|
||||
change()();
|
||||
updateColourPreview();
|
||||
}, 100));
|
||||
|
||||
outlinkButton = outlinkButton
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'form-field-button colour-preview')
|
||||
.append('div')
|
||||
.style('background-color', d => d)
|
||||
.attr('class', 'colour-box');
|
||||
if (colour === '') {
|
||||
outlinkButton = outlinkButton
|
||||
.call(svgIcon('#iD-icon-edit'));
|
||||
}
|
||||
outlinkButton
|
||||
.on('click', () => wrap.select('.colour-selector').node().click())
|
||||
.merge(outlinkButton);
|
||||
}
|
||||
|
||||
|
||||
function updatePhonePlaceholder() {
|
||||
if (input.empty() || !Object.keys(_phoneFormats).length) return;
|
||||
@@ -186,11 +246,17 @@ export function uiFieldText(field, context) {
|
||||
|
||||
|
||||
function validIdentifierValueForLink() {
|
||||
const value = utilGetSetValue(input).trim().split(';')[0];
|
||||
const value = utilGetSetValue(input).trim();
|
||||
|
||||
if (field.type === 'url' && value) return value;
|
||||
if (field.type === 'url' && value) {
|
||||
try {
|
||||
return (new URL(value)).href;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (field.type === 'identifier' && field.pattern) {
|
||||
return value && value.match(new RegExp(field.pattern));
|
||||
return value && value.match(new RegExp(field.pattern))[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -251,6 +317,8 @@ export function uiFieldText(field, context) {
|
||||
.attr('placeholder', isMixed ? t('inspector.multiple_values') : (field.placeholder() || t('inspector.unknown')))
|
||||
.classed('mixed', isMixed);
|
||||
|
||||
if (field.key.split(':').includes('colour')) updateColourPreview();
|
||||
|
||||
if (outlinkButton && !outlinkButton.empty()) {
|
||||
var disabled = !validIdentifierValueForLink();
|
||||
outlinkButton.classed('disabled', disabled);
|
||||
|
||||
@@ -77,7 +77,7 @@ export function uiFieldLanes(field, context) {
|
||||
.append('text')
|
||||
.attr('y', 40)
|
||||
.attr('x', 14)
|
||||
.html('▲');
|
||||
.text('▲');
|
||||
|
||||
enter
|
||||
.append('g')
|
||||
@@ -85,7 +85,7 @@ export function uiFieldLanes(field, context) {
|
||||
.append('text')
|
||||
.attr('y', 40)
|
||||
.attr('x', 14)
|
||||
.html('▲▼');
|
||||
.text('▲▼');
|
||||
|
||||
enter
|
||||
.append('g')
|
||||
@@ -93,7 +93,7 @@ export function uiFieldLanes(field, context) {
|
||||
.append('text')
|
||||
.attr('y', 40)
|
||||
.attr('x', 14)
|
||||
.html('▼');
|
||||
.text('▼');
|
||||
|
||||
|
||||
lane = lane
|
||||
|
||||
@@ -374,7 +374,7 @@ export function uiFieldLocalized(field, context) {
|
||||
text
|
||||
.append('span')
|
||||
.attr('class', 'label-textvalue')
|
||||
.html(t.html('translate.localized_translation_label'));
|
||||
.call(t.append('translate.localized_translation_label'));
|
||||
|
||||
text
|
||||
.append('span')
|
||||
|
||||
@@ -129,7 +129,7 @@ export function uiFieldRadio(field, context) {
|
||||
.append('span')
|
||||
.attr('class', 'label structure-label-type')
|
||||
.attr('for', 'preset-input-' + selected)
|
||||
.html(t.html('inspector.radio.structure.type'));
|
||||
.call(t.append('inspector.radio.structure.type'));
|
||||
|
||||
typeEnter
|
||||
.append('div')
|
||||
@@ -174,7 +174,7 @@ export function uiFieldRadio(field, context) {
|
||||
.append('span')
|
||||
.attr('class', 'label structure-label-layer')
|
||||
.attr('for', 'preset-input-layer')
|
||||
.html(t.html('inspector.radio.structure.layer'));
|
||||
.call(t.append('inspector.radio.structure.layer'));
|
||||
|
||||
layerEnter
|
||||
.append('div')
|
||||
@@ -302,9 +302,9 @@ export function uiFieldRadio(field, context) {
|
||||
var selection = radios.filter(function() { return this.checked; });
|
||||
|
||||
if (selection.empty()) {
|
||||
placeholder.html(t.html('inspector.none'));
|
||||
placeholder.call(t.append('inspector.none'));
|
||||
} else {
|
||||
placeholder.html(selection.attr('value'));
|
||||
placeholder.text(selection.attr('value'));
|
||||
_oldType[selection.datum()] = tags[selection.datum()];
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
distControlEnter
|
||||
.append('span')
|
||||
.attr('class', 'restriction-control-label restriction-distance-label')
|
||||
.html(t.html('restriction.controls.distance') + ':');
|
||||
.call(t.append('restriction.controls.distance', { suffix: ':' }));
|
||||
|
||||
distControlEnter
|
||||
.append('input')
|
||||
@@ -151,7 +151,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
});
|
||||
|
||||
selection.selectAll('.restriction-distance-text')
|
||||
.html(displayMaxDistance(_maxDistance));
|
||||
.call(displayMaxDistance(_maxDistance));
|
||||
|
||||
|
||||
var viaControl = selection.selectAll('.restriction-via-way')
|
||||
@@ -167,7 +167,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
viaControlEnter
|
||||
.append('span')
|
||||
.attr('class', 'restriction-control-label restriction-via-way-label')
|
||||
.html(t.html('restriction.controls.via') + ':');
|
||||
.call(t.append('restriction.controls.via', { suffix: ':' }));
|
||||
|
||||
viaControlEnter
|
||||
.append('input')
|
||||
@@ -193,7 +193,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
});
|
||||
|
||||
selection.selectAll('.restriction-via-way-text')
|
||||
.html(displayMaxVia(_maxViaWay));
|
||||
.call(displayMaxVia(_maxViaWay));
|
||||
}
|
||||
|
||||
|
||||
@@ -463,7 +463,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
var placeholders = {};
|
||||
['from', 'via', 'to'].forEach(function(k) {
|
||||
placeholders[k] = '<span class="qualifier">' + t('restriction.help.' + k) + '</span>';
|
||||
placeholders[k] = { html: '<span class="qualifier">' + t('restriction.help.' + k) + '</span>' };
|
||||
});
|
||||
|
||||
var entity = datum && datum.properties && datum.properties.entity;
|
||||
@@ -553,7 +553,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
if (!indirect) {
|
||||
help
|
||||
.append('div') // Click for "No Right Turn"
|
||||
.html(t.html('restriction.help.toggle', { turn: nextText.trim() }));
|
||||
.html(t.html('restriction.help.toggle', { turn: { html: nextText.trim() } }));
|
||||
}
|
||||
|
||||
highlightPathsFrom(null);
|
||||
@@ -589,26 +589,33 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
|
||||
function displayMaxDistance(maxDist) {
|
||||
var isImperial = !localizer.usesMetric();
|
||||
var opts;
|
||||
return selection => {
|
||||
var isImperial = !localizer.usesMetric();
|
||||
var opts;
|
||||
|
||||
if (isImperial) {
|
||||
var distToFeet = { // imprecise conversion for prettier display
|
||||
20: 70, 25: 85, 30: 100, 35: 115, 40: 130, 45: 145, 50: 160
|
||||
}[maxDist];
|
||||
opts = { distance: t('units.feet', { quantity: distToFeet }) };
|
||||
} else {
|
||||
opts = { distance: t('units.meters', { quantity: maxDist }) };
|
||||
}
|
||||
if (isImperial) {
|
||||
var distToFeet = { // imprecise conversion for prettier display
|
||||
20: 70, 25: 85, 30: 100, 35: 115, 40: 130, 45: 145, 50: 160
|
||||
}[maxDist];
|
||||
opts = { distance: t('units.feet', { quantity: distToFeet }) };
|
||||
} else {
|
||||
opts = { distance: t('units.meters', { quantity: maxDist }) };
|
||||
}
|
||||
|
||||
return t.html('restriction.controls.distance_up_to', opts);
|
||||
return selection
|
||||
.html('')
|
||||
.call(t.append('restriction.controls.distance_up_to', opts));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function displayMaxVia(maxVia) {
|
||||
return maxVia === 0 ? t.html('restriction.controls.via_node_only')
|
||||
: maxVia === 1 ? t.html('restriction.controls.via_up_to_one')
|
||||
: t.html('restriction.controls.via_up_to_two');
|
||||
return selection => {
|
||||
selection = selection.html('');
|
||||
return maxVia === 0 ? selection.call(t.append('restriction.controls.via_node_only'))
|
||||
: maxVia === 1 ? selection.call(t.append('restriction.controls.via_up_to_one'))
|
||||
: selection.call(t.append('restriction.controls.via_up_to_two'));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user