mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-24 00:54:03 +02:00
Prepare to use Osmose issue detail strings
- Remove translation description strings, will be using supplied translations once the API is updated - Change the way elements and details are presented since they can't be easily integrated into the 3rd party description strings
This commit is contained in:
+45
-47
@@ -3,7 +3,7 @@ import RBush from 'rbush';
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { json as d3_json } from 'd3-fetch';
|
||||
|
||||
import { currentLocale, t } from '../util/locale';
|
||||
import { currentLocale } from '../util/locale';
|
||||
import { geoExtent, geoVecAdd } from '../geo';
|
||||
import { qaError } from '../osm';
|
||||
import { utilRebind, utilTiler, utilQsString } from '../util';
|
||||
@@ -47,10 +47,6 @@ function updateRtree(item, replace) {
|
||||
}
|
||||
}
|
||||
|
||||
function linkEntity(d) {
|
||||
return `<a class="error_entity_link">${d}</a>`;
|
||||
}
|
||||
|
||||
// Errors shouldn't obscure eachother
|
||||
function preventCoincident(loc) {
|
||||
let coincident = false;
|
||||
@@ -139,22 +135,9 @@ export default {
|
||||
item // category of the issue for styling
|
||||
});
|
||||
|
||||
// Special handling for some error types
|
||||
switch (d.item) {
|
||||
case 8300:
|
||||
case 8360: {
|
||||
let k = error_class;
|
||||
|
||||
// First 17 classes are all speed limits
|
||||
if (item === 8300 && error_class <= 17) {
|
||||
k = 1;
|
||||
}
|
||||
|
||||
// Setting elems here prevents UI error detail requests
|
||||
d.replacements = [t(`QA.osmose.error_types.${d.item}.parts.${k}`)];
|
||||
d.elems = [];
|
||||
break;
|
||||
}
|
||||
// Setting elems here prevents UI error detail requests
|
||||
if (d.item === 8300 || d.item === 8360) {
|
||||
d.elems = [];
|
||||
}
|
||||
|
||||
_erCache.data[d.id] = d;
|
||||
@@ -187,35 +170,50 @@ export default {
|
||||
// Assign directly for immediate use in the callback
|
||||
d.elems = data.elems.map(e => e.type.substring(0,1) + e.id);
|
||||
|
||||
// Element links used in the error description
|
||||
d.replacements = d.elems.map(linkEntity);
|
||||
|
||||
// Some error types have details in their subtitle
|
||||
const special = {
|
||||
'3040-3040': /Bad value for (.+)/i,
|
||||
'3090-3090': /Incorrect date "(.+)"/i,
|
||||
'4010-4010': /Tag (.+) is deprecated: (.+)/i,
|
||||
'4010-40102': /Tag (.+) is deprecated: (.+)/i,
|
||||
'4030-900': /Conflict between tags: (.+), (.+)/i,
|
||||
'5070-50703': /"(.+)"=".+" unexpected symbol char \(.+, (.+)\)/i,
|
||||
'5070-50704': /Umbalanced (.+)/i,
|
||||
'5070-50705': /Unexpected char (.+)/i,
|
||||
'9010-9010003': /(.+)/
|
||||
tags: {
|
||||
'3040-3040': /Bad tag value: "(.+)"/i,
|
||||
'4010-4010': /Tag (.+) is deprecated/i,
|
||||
'4010-40102': /Tag (.+) is deprecated/i,
|
||||
'4030-900': /Conflict between tags: (.+), (.+)/i,
|
||||
'5070-50703': /"(.+)"=".+" unexpected/i,
|
||||
'9010-9010001': /(.+) is unnecessary/i
|
||||
},
|
||||
values: {
|
||||
'3090-3090': /Incorrect date "(.+)"/i,
|
||||
'9010-9010003': /(.+)/
|
||||
},
|
||||
chars: {
|
||||
'5070-50703': /unexpected symbol char \(.+, (.+)\)/i,
|
||||
'5070-50704': /Umbalanced (.+)/i,
|
||||
'5070-50705': /Unexpected char (.+)/i
|
||||
},
|
||||
sug_tags: {
|
||||
'4010-4010': /Tag .+ is deprecated: (.+)/i,
|
||||
'4010-40102': /Tag .+ is deprecated: (.+)/i,
|
||||
}
|
||||
};
|
||||
if (d.error_type in special) {
|
||||
let [, ...details] = special[d.error_type].exec(data.subtitle);
|
||||
d.replacements.push(...details);
|
||||
for (let type in special) {
|
||||
if (d.error_type in special[type]) {
|
||||
// Destructuring doesn't work if no match returns null, hence []
|
||||
let [, ...details] = special[type][d.error_type].exec(data.subtitle) || [];
|
||||
|
||||
if (d.error_type === '5070-50703') {
|
||||
d.replacements[2] = String.fromCharCode(details[1]);
|
||||
if (
|
||||
d.error_type === '5070-50703'
|
||||
&& type === 'chars'
|
||||
&& details
|
||||
) {
|
||||
details[0] = String.fromCharCode(details[0]);
|
||||
}
|
||||
|
||||
// This error has a rare subtitle variant
|
||||
if (d.error_type === '9010-9010001' && !details) {
|
||||
[, ...details] = /\. Remove (.+)/i.exec(data.subtitle) || [];
|
||||
}
|
||||
|
||||
if (details) d[type] = details;
|
||||
}
|
||||
} else if (d.error_type === '9010-9010001') {
|
||||
// This error has a rare subtitle variant
|
||||
let details = /(.+) is unnecessary/i.exec(data.subtitle);
|
||||
if (details == null) {
|
||||
details = /\. Remove (.+)/i.exec(data.subtitle);
|
||||
}
|
||||
d.replacements.push(details[1]);
|
||||
}
|
||||
|
||||
this.replaceError(d);
|
||||
@@ -235,7 +233,7 @@ export default {
|
||||
const langs = { [locale]: true };
|
||||
|
||||
// Need English strings if not already fetched for fallback values
|
||||
if (locale != 'en' && !('en' in _stringCache)) {
|
||||
if (locale !== 'en' && !('en' in _stringCache)) {
|
||||
langs.en = true;
|
||||
}
|
||||
|
||||
@@ -284,7 +282,7 @@ export default {
|
||||
|
||||
getStrings(issueType, locale=currentLocale) {
|
||||
const l = (locale in _stringCache) ? _stringCache[locale][issueType] : {};
|
||||
const en = ('en' in _stringCache) ? _stringCache['en'][issueType] : {};
|
||||
const en = ('en' in _stringCache) ? _stringCache.en[issueType] : {};
|
||||
|
||||
// Fallback to English if string is untranslated
|
||||
return Object.assign({}, en, l);
|
||||
|
||||
@@ -64,6 +64,8 @@ export function svgOsmose(projection, context, dispatch) {
|
||||
// Enable the layer. This shows the errors and transitions them to visible.
|
||||
function layerOn() {
|
||||
// Strings supplied by Osmose fetched before showing layer for first time
|
||||
// TODO: If layer is toggled quickly multiple requests are sent
|
||||
// TODO: No error handling in place
|
||||
getService().loadStrings(editOn);
|
||||
|
||||
drawLayer
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
|
||||
import { dataEn } from '../../data';
|
||||
import { modeSelect } from '../modes/select';
|
||||
import { t } from '../util/locale';
|
||||
import { services } from '../services';
|
||||
@@ -14,23 +13,14 @@ export function uiOsmoseDetails(context) {
|
||||
var _error;
|
||||
|
||||
|
||||
function errorDetail(d) {
|
||||
function issueDetail(d) {
|
||||
var unknown = t('inspector.unknown');
|
||||
|
||||
if (!d) return unknown;
|
||||
|
||||
// Some errors fall back to their category for strings
|
||||
var i, et;
|
||||
var keys = [d.error_type, d.item];
|
||||
for (i = 0; i < 2; i++) {
|
||||
et = dataEn.QA.osmose.error_types[keys[i]];
|
||||
|
||||
if (et && et.description) {
|
||||
return t('QA.osmose.error_types.' + keys[i] + '.description', d.replacements);
|
||||
}
|
||||
}
|
||||
|
||||
return unknown;
|
||||
// Issue description supplied by Osmose
|
||||
var s = services.osmose.getStrings(d.error_type);
|
||||
return ('description' in s) ? s.description : unknown;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,16 +48,30 @@ export function uiOsmoseDetails(context) {
|
||||
.append('h4')
|
||||
.text(function() { return t('QA.keepRight.detail_description'); });
|
||||
|
||||
descriptionEnter
|
||||
.append('div')
|
||||
.attr('class', 'error-details-description-text')
|
||||
.html(issueDetail);
|
||||
|
||||
descriptionEnter
|
||||
.append('h4')
|
||||
.attr('class', 'error-details-subtitle')
|
||||
.text(function() { return t('QA.osmose.elems_title'); });
|
||||
|
||||
var elementList = descriptionEnter
|
||||
.append('ul')
|
||||
.attr('class', 'error-details-elements');
|
||||
|
||||
services.osmose.loadErrorDetail(_error, function(err, d) {
|
||||
if (d.elems === undefined) { return; }
|
||||
if (d.elems === undefined) return;
|
||||
|
||||
descriptionEnter
|
||||
.append('div')
|
||||
.attr('class', 'error-details-description-text')
|
||||
.html(errorDetail);
|
||||
|
||||
// If there are entity links in the error message..
|
||||
descriptionEnter.selectAll('.error_entity_link, .error_object_link')
|
||||
elementList.selectAll('.error_entity_link')
|
||||
.data(d.elems)
|
||||
.enter()
|
||||
.append('li')
|
||||
.append('a')
|
||||
.attr('class', 'error_entity_link')
|
||||
.text(function(d) { return d; })
|
||||
.each(function() {
|
||||
var link = d3_select(this);
|
||||
var entityID = this.textContent;
|
||||
@@ -117,6 +121,26 @@ export function uiOsmoseDetails(context) {
|
||||
}
|
||||
});
|
||||
|
||||
// Things like keys and values are dynamic details
|
||||
const special = { tags: true, values: true, chars: true, sug_tags: true };
|
||||
for (let type in special) {
|
||||
if (type in d) {
|
||||
descriptionEnter
|
||||
.append('h4')
|
||||
.attr('class', 'error-details-subtitle')
|
||||
.text(function() { return t(`QA.osmose.details.${type}`); });
|
||||
|
||||
descriptionEnter
|
||||
.append('ul')
|
||||
.attr('class', 'error-details-list')
|
||||
.selectAll('li')
|
||||
.data(d[type])
|
||||
.enter()
|
||||
.append('li')
|
||||
.html(function(d) { return d; });
|
||||
}
|
||||
}
|
||||
|
||||
// Don't hide entities related to this error - #5880
|
||||
context.features().forceVisible(d.elems);
|
||||
context.map().pan([0,0]); // trigger a redraw
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { services } from '../services';
|
||||
import { currentLocale, t } from '../util/locale';
|
||||
import { t } from '../util/locale';
|
||||
|
||||
|
||||
export function uiOsmoseHeader() {
|
||||
@@ -13,11 +13,7 @@ export function uiOsmoseHeader() {
|
||||
|
||||
// Issue titles supplied by Osmose
|
||||
var s = services.osmose.getStrings(d.error_type);
|
||||
if ('title' in s) {
|
||||
return s.title;
|
||||
}
|
||||
|
||||
return unknown;
|
||||
return ('title' in s) ? s.title : unknown;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user