Files
iD/modules/ui/sections/validation_rules.js
2021-11-18 18:53:33 +01:00

195 lines
5.6 KiB
JavaScript

import {
select as d3_select
} from 'd3-selection';
import { prefs } from '../../core/preferences';
import { t } from '../../core/localizer';
import { utilGetSetValue, utilNoAuto } from '../../util';
import { uiTooltip } from '../tooltip';
import { uiSection } from '../section';
export function uiSectionValidationRules(context) {
var MINSQUARE = 0;
var MAXSQUARE = 20;
var DEFAULTSQUARE = 5; // see also unsquare_way.js
var section = uiSection('issues-rules', context)
.disclosureContent(renderDisclosureContent)
.label(t.html('issues.rules.title'));
var _ruleKeys = context.validator().getRuleKeys()
.filter(function(key) { return key !== 'maprules'; })
.sort(function(key1, key2) {
// alphabetize by localized title
return t('issues.' + key1 + '.title') < t('issues.' + key2 + '.title') ? -1 : 1;
});
function renderDisclosureContent(selection) {
var container = selection.selectAll('.issues-rulelist-container')
.data([0]);
var containerEnter = container.enter()
.append('div')
.attr('class', 'issues-rulelist-container');
containerEnter
.append('ul')
.attr('class', 'layer-list issue-rules-list');
var ruleLinks = containerEnter
.append('div')
.attr('class', 'issue-rules-links section-footer');
ruleLinks
.append('a')
.attr('class', 'issue-rules-link')
.attr('href', '#')
.html(t.html('issues.disable_all'))
.on('click', function(d3_event) {
d3_event.preventDefault();
context.validator().disableRules(_ruleKeys);
});
ruleLinks
.append('a')
.attr('class', 'issue-rules-link')
.attr('href', '#')
.html(t.html('issues.enable_all'))
.on('click', function(d3_event) {
d3_event.preventDefault();
context.validator().disableRules([]);
});
// Update
container = container
.merge(containerEnter);
container.selectAll('.issue-rules-list')
.call(drawListItems, _ruleKeys, 'checkbox', 'rule', toggleRule, isRuleEnabled);
}
function drawListItems(selection, data, type, name, change, active) {
var items = selection.selectAll('li')
.data(data);
// Exit
items.exit()
.remove();
// Enter
var enter = items.enter()
.append('li');
if (name === 'rule') {
enter
.call(uiTooltip()
.title(function(d) { return t.html('issues.' + d + '.tip'); })
.placement('top')
);
}
var label = enter
.append('label');
label
.append('input')
.attr('type', type)
.attr('name', name)
.on('change', change);
label
.append('span')
.html(function(d) {
var params = {};
if (d === 'unsquare_way') {
params.val = { html: '<span class="square-degrees"></span>' };
}
return t.html('issues.' + d + '.title', params);
});
// Update
items = items
.merge(enter);
items
.classed('active', active)
.selectAll('input')
.property('checked', active)
.property('indeterminate', false);
// user-configurable square threshold
var degStr = prefs('validate-square-degrees');
if (degStr === null) {
degStr = DEFAULTSQUARE.toString();
}
var span = items.selectAll('.square-degrees');
var input = span.selectAll('.square-degrees-input')
.data([0]);
// enter / update
input.enter()
.append('input')
.attr('type', 'number')
.attr('min', MINSQUARE.toString())
.attr('max', MAXSQUARE.toString())
.attr('step', '0.5')
.attr('class', 'square-degrees-input')
.call(utilNoAuto)
.on('click', function (d3_event) {
d3_event.preventDefault();
d3_event.stopPropagation();
this.select();
})
.on('keyup', function (d3_event) {
if (d3_event.keyCode === 13) { // ↩ Return
this.blur();
this.select();
}
})
.on('blur', changeSquare)
.merge(input)
.property('value', degStr);
}
function changeSquare() {
var input = d3_select(this);
var degStr = utilGetSetValue(input).trim();
var degNum = parseFloat(degStr, 10);
if (!isFinite(degNum)) {
degNum = DEFAULTSQUARE;
} else if (degNum > MAXSQUARE) {
degNum = MAXSQUARE;
} else if (degNum < MINSQUARE) {
degNum = MINSQUARE;
}
degNum = Math.round(degNum * 10 ) / 10; // round to 1 decimal
degStr = degNum.toString();
input
.property('value', degStr);
prefs('validate-square-degrees', degStr);
context.validator().revalidateUnsquare();
}
function isRuleEnabled(d) {
return context.validator().isRuleEnabled(d);
}
function toggleRule(d3_event, d) {
context.validator().toggleRule(d);
}
context.validator().on('validated.uiSectionValidationRules', function() {
window.requestIdleCallback(section.reRender);
});
return section;
}