mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-22 03:36:37 +02:00
Replace validator tooltip with reference function, add tag diff
This commit is contained in:
+25
-1
@@ -3360,12 +3360,36 @@ li.issue-fix-item:not(.actionable) .fix-icon {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
padding: 10px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.issue-info.expanded {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.issue-info .issue-reference {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.issue-info .tagDiff-table {
|
||||
min-width: 60%;
|
||||
width: unset;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.issue-info .tagDiff-row {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.issue-info .tagDiff-cell {
|
||||
padding: 2px 5px;
|
||||
font-family: monospace;
|
||||
font-size: 10px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.issue-info .tagDiff-cell-add {
|
||||
background: #dfd;
|
||||
}
|
||||
.issue-info .tagDiff-cell-remove {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
|
||||
/* Background - Display Options Sliders
|
||||
------------------------------------------------------- */
|
||||
|
||||
@@ -1269,6 +1269,7 @@ en:
|
||||
title: "Where:"
|
||||
visible: "In View"
|
||||
all: "Everywhere"
|
||||
suggested: "Suggested updates:"
|
||||
almost_junction:
|
||||
title: Almost Junctions
|
||||
message: "{feature} is very close but not connected to {feature2}"
|
||||
|
||||
Vendored
+1
@@ -1548,6 +1548,7 @@
|
||||
"all": "Everywhere"
|
||||
}
|
||||
},
|
||||
"suggested": "Suggested updates:",
|
||||
"almost_junction": {
|
||||
"title": "Almost Junctions",
|
||||
"message": "{feature} is very close but not connected to {feature2}",
|
||||
|
||||
@@ -334,7 +334,7 @@ export function validationIssue(attrs) {
|
||||
this.type = attrs.type; // required
|
||||
this.severity = attrs.severity; // required - 'warning' or 'error'
|
||||
this.message = attrs.message; // required - localized string
|
||||
this.tooltip = attrs.tooltip; // required - localized string
|
||||
this.reference = attrs.reference; // required - function(selection) to render reference info
|
||||
this.entities = attrs.entities; // optional - array of entities
|
||||
this.loc = attrs.loc; // optional - expect a [lon, lat] array
|
||||
this.data = attrs.data; // optional - object containing extra data for the fixes
|
||||
|
||||
@@ -159,7 +159,10 @@ export function uiEntityIssues(context) {
|
||||
.attr('class', 'issue-info')
|
||||
.style('max-height', '0')
|
||||
.style('opacity', '0')
|
||||
.html(function(d) { return d.tooltip; });
|
||||
.each(function(d) {
|
||||
d3_select(this)
|
||||
.call(d.reference);
|
||||
});
|
||||
|
||||
|
||||
// Update
|
||||
|
||||
@@ -93,11 +93,8 @@ export function uiIssues(context) {
|
||||
.on('click', function(d) {
|
||||
var extent = d.extent(context.graph());
|
||||
if (extent) {
|
||||
var extent = d.extent(context.graph());
|
||||
if (extent) {
|
||||
var setZoom = Math.max(context.map().zoom(), 19);
|
||||
context.map().centerZoomEase(extent.center(), setZoom);
|
||||
}
|
||||
var setZoom = Math.max(context.map().zoom(), 19);
|
||||
context.map().centerZoomEase(extent.center(), setZoom);
|
||||
|
||||
// select the first entity
|
||||
if (d.entities && d.entities.length) {
|
||||
@@ -134,7 +131,7 @@ export function uiIssues(context) {
|
||||
var iconName = '#iD-icon-' + (d.severity === 'warning' ? 'alert' : 'error');
|
||||
d3_select(this)
|
||||
.call(svgIcon(iconName));
|
||||
})
|
||||
});
|
||||
|
||||
textEnter
|
||||
.append('span')
|
||||
|
||||
@@ -7,7 +7,7 @@ import { geoRawMercator, geoScaleToZoom, geoVecSubtract, geoVecScale, geoZoomToS
|
||||
import { rendererTileLayer } from '../renderer';
|
||||
import { svgDebug, svgData } from '../svg';
|
||||
import { utilSetTransform } from '../util';
|
||||
import { utilGetDimensions } from '../util/dimensions';
|
||||
// import { utilGetDimensions } from '../util/dimensions';
|
||||
|
||||
|
||||
export function uiMapInMap(context) {
|
||||
|
||||
@@ -91,7 +91,7 @@ export function validationAlmostJunction() {
|
||||
feature: utilDisplayLabel(entity, context),
|
||||
feature2: utilDisplayLabel(edgeHighway, context)
|
||||
}),
|
||||
tooltip: t('issues.almost_junction.highway-highway.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity, node, edgeHighway],
|
||||
loc: extendableNodeInfo.node.loc,
|
||||
data: {
|
||||
@@ -105,6 +105,15 @@ export function validationAlmostJunction() {
|
||||
return issues;
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.almost_junction.highway-highway.tip'));
|
||||
}
|
||||
|
||||
|
||||
function isExtendableCandidate(node, way) {
|
||||
// can not accurately test vertices on tiles not downloaded from osm - #5938
|
||||
|
||||
@@ -224,7 +224,6 @@ export function validationCrossingWays() {
|
||||
|
||||
|
||||
function findCrossingsByWay(way1, graph, tree) {
|
||||
|
||||
var edgeCrossInfos = [];
|
||||
if (way1.type !== 'way') return edgeCrossInfos;
|
||||
|
||||
@@ -467,6 +466,7 @@ export function validationCrossingWays() {
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
var useFixIcon = 'iD-icon-layers';
|
||||
var useFixID;
|
||||
if (isCrossingIndoors) {
|
||||
@@ -496,11 +496,12 @@ export function validationCrossingWays() {
|
||||
icon: 'iD-operation-move',
|
||||
title: t('issues.fix.reposition_features.title')
|
||||
}));
|
||||
|
||||
return new validationIssue({
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.crossing_ways.message', messageDict),
|
||||
tooltip: t('issues.crossing_ways.' + crossingTypeID + '.tip'),
|
||||
reference: showReference,
|
||||
entities: entities,
|
||||
data: {
|
||||
edges: crossing.edges,
|
||||
@@ -509,6 +510,15 @@ export function validationCrossingWays() {
|
||||
loc: crossing.crossPoint,
|
||||
fixes: fixes
|
||||
});
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.crossing_ways.' + crossingTypeID + '.tip'));
|
||||
}
|
||||
}
|
||||
|
||||
function makeChangeLayerFix(higherOrLower, context) {
|
||||
|
||||
@@ -77,12 +77,22 @@ export function validationDisconnectedWay() {
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.disconnected_way.highway.message', { highway: entityLabel }),
|
||||
tooltip: t('issues.disconnected_way.highway.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.disconnected_way.highway.tip'));
|
||||
}
|
||||
|
||||
|
||||
function vertexIsDisconnected(way, vertex, relation) {
|
||||
// can not accurately test vertices on tiles not downloaded from osm - #5938
|
||||
var osm = context.connection();
|
||||
|
||||
@@ -58,7 +58,7 @@ export function validationGenericName() {
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.generic_name.message', {feature: preset.name(), name: generic}),
|
||||
tooltip: t('issues.generic_name.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
@@ -76,6 +76,16 @@ export function validationGenericName() {
|
||||
})
|
||||
]
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.generic_name.tip'));
|
||||
}
|
||||
};
|
||||
|
||||
validation.type = type;
|
||||
|
||||
@@ -21,7 +21,7 @@ export function validationIncompatibleSource() {
|
||||
message: t('issues.incompatible_source.' + invalidSource.id + '.feature.message', {
|
||||
feature: utilDisplayLabel(entity, context),
|
||||
}),
|
||||
tooltip: t('issues.incompatible_source.' + invalidSource.id + '.tip'),
|
||||
reference: getReference(invalidSource.id),
|
||||
entities: [entity],
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
@@ -32,7 +32,20 @@ export function validationIncompatibleSource() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return issues;
|
||||
|
||||
|
||||
function getReference(id) {
|
||||
return function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.incompatible_source.' + id + '.tip'));
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
validation.type = type;
|
||||
|
||||
@@ -43,14 +43,25 @@ export function validationManyDeletions() {
|
||||
'issues.many_deletions.'+messageType+'.message',
|
||||
{ n: totalFeatures, p: points, l: lines, a:areas, r: relations }
|
||||
),
|
||||
tooltip: t('issues.many_deletions.tip'),
|
||||
reference: showReference,
|
||||
hash: [points, lines, areas, relations].join()
|
||||
})];
|
||||
}
|
||||
|
||||
return [];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.many_deletions.tip'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
validation.type = type;
|
||||
validation.inputType = 'changes';
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ export function validationMissingRole() {
|
||||
return !member.role || !member.role.trim().length;
|
||||
}
|
||||
|
||||
|
||||
function makeIssue(way, relation, member, context) {
|
||||
return new validationIssue({
|
||||
type: type,
|
||||
@@ -43,7 +44,7 @@ export function validationMissingRole() {
|
||||
member: utilDisplayLabel(way, context),
|
||||
relation: utilDisplayLabel(relation, context),
|
||||
}),
|
||||
tooltip: t('issues.missing_role.multipolygon.tip'),
|
||||
reference: showReference,
|
||||
entities: [relation, way],
|
||||
data: {
|
||||
member: member
|
||||
@@ -63,8 +64,19 @@ export function validationMissingRole() {
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.missing_role.multipolygon.tip'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function makeAddRoleFix(role, context) {
|
||||
return new validationIssueFix({
|
||||
title: t('issues.fix.set_as_' + role + '.title'),
|
||||
|
||||
@@ -87,12 +87,23 @@ export function validationMissingTag() {
|
||||
type: type,
|
||||
severity: isError ? 'error' : 'warning',
|
||||
message: t('issues.missing_tag.' + missingTagType + '.message', messageObj),
|
||||
tooltip: t('issues.missing_tag.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.missing_tag.tip'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
validation.type = type;
|
||||
|
||||
return validation;
|
||||
|
||||
@@ -24,12 +24,13 @@ export function validationOldMultipolygon() {
|
||||
}
|
||||
|
||||
if (!multipolygon || !outerWay) return [];
|
||||
|
||||
var multipolygonLabel = utilDisplayLabel(multipolygon, context);
|
||||
return [new validationIssue({
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.old_multipolygon.message', { multipolygon: multipolygonLabel }),
|
||||
tooltip: t('issues.old_multipolygon.tip'),
|
||||
reference: showReference,
|
||||
entities: [outerWay, multipolygon],
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
@@ -51,8 +52,19 @@ export function validationOldMultipolygon() {
|
||||
})
|
||||
]
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.old_multipolygon.tip'));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
validation.type = type;
|
||||
|
||||
return validation;
|
||||
|
||||
@@ -57,19 +57,13 @@ export function validationOutdatedTags() {
|
||||
|
||||
if (!tagDiff.length) return [];
|
||||
|
||||
|
||||
// debugging (sorta)
|
||||
var tooltip = '<pre>\n' + tagDiff.join('\n') + '</pre>';
|
||||
|
||||
|
||||
return [new validationIssue({
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.outdated_tags.message', { feature: utilDisplayLabel(entity, context) }),
|
||||
tooltip: tooltip, // t('issues.outdated_tags.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
data: {
|
||||
tagDiff: tagDiff,
|
||||
newTags: newTags
|
||||
},
|
||||
fixes: [
|
||||
@@ -87,6 +81,37 @@ export function validationOutdatedTags() {
|
||||
})
|
||||
]
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
var enter = selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter();
|
||||
|
||||
enter
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.outdated_tags.tip'));
|
||||
|
||||
enter
|
||||
.append('strong')
|
||||
.text(t('issues.suggested'));
|
||||
|
||||
enter
|
||||
.append('table')
|
||||
.attr('class', 'tagDiff-table')
|
||||
.selectAll('.tagDiff-row')
|
||||
.data(tagDiff)
|
||||
.enter()
|
||||
.append('tr')
|
||||
.attr('class', 'tagDiff-row')
|
||||
.append('td')
|
||||
.attr('class', function(d) {
|
||||
var klass = d.charAt(0) === '+' ? 'add' : 'remove';
|
||||
return 'tagDiff-cell tagDiff-cell-' + klass;
|
||||
})
|
||||
.text(function(d) { return d; });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export function validationPrivateData() {
|
||||
};
|
||||
|
||||
// but they might be public if they have one of these other tags
|
||||
var okayModifierKeys = {
|
||||
var publicKeys = {
|
||||
amenity: true,
|
||||
craft: true,
|
||||
historic: true,
|
||||
@@ -39,55 +39,87 @@ export function validationPrivateData() {
|
||||
website: true
|
||||
};
|
||||
|
||||
function privateDataKeys(entity) {
|
||||
var tags = entity.tags;
|
||||
if (!tags.building || !privateBuildingValues[tags.building]) return [];
|
||||
var privateKeys = [];
|
||||
for (var key in tags) {
|
||||
if (okayModifierKeys[key]) return [];
|
||||
if (personalTags[key]) privateKeys.push(key);
|
||||
}
|
||||
return privateKeys;
|
||||
}
|
||||
|
||||
var validation = function checkPrivateData(entity, context) {
|
||||
var privateKeys = privateDataKeys(entity);
|
||||
if (privateKeys.length === 0) return [];
|
||||
var tags = entity.tags;
|
||||
var keepTags = {};
|
||||
var tagDiff = [];
|
||||
if (!tags.building || !privateBuildingValues[tags.building]) return [];
|
||||
|
||||
for (var k in tags) {
|
||||
if (publicKeys[k]) return []; // probably a public feature
|
||||
|
||||
if (personalTags[k]) {
|
||||
tagDiff.push('- ' + k + '=' + tags[k]);
|
||||
} else {
|
||||
keepTags[k] = tags[k];
|
||||
}
|
||||
}
|
||||
|
||||
if (!tagDiff.length) return [];
|
||||
|
||||
var fixID = tagDiff.length === 1 ? 'remove_tag' : 'remove_tags';
|
||||
|
||||
var fixID = privateKeys.length === 1 ? 'remove_tag' : 'remove_tags';
|
||||
return [new validationIssue({
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.private_data.contact.message', {
|
||||
feature: utilDisplayLabel(entity, context),
|
||||
}),
|
||||
tooltip: t('issues.private_data.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
data: {
|
||||
privateKeys: privateKeys
|
||||
newTags: keepTags
|
||||
},
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
auto: true,
|
||||
icon: 'iD-operation-delete',
|
||||
title: t('issues.fix.' + fixID + '.title'),
|
||||
onClick: function() {
|
||||
var entity = this.issue.entities[0];
|
||||
var tags = Object.assign({}, entity.tags); // shallow copy
|
||||
var privateKeys = this.issue.data.privateKeys;
|
||||
for (var index in privateKeys) {
|
||||
delete tags[privateKeys[index]];
|
||||
}
|
||||
var entityID = this.issue.entities[0].id;
|
||||
var newTags = this.issue.data.newTags;
|
||||
context.perform(
|
||||
actionChangeTags(entity.id, tags),
|
||||
t('issues.fix.remove_private_info.annotation')
|
||||
actionChangeTags(entityID, newTags),
|
||||
t('issues.fix.upgrade_tags.annotation')
|
||||
);
|
||||
}
|
||||
})
|
||||
]
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
var enter = selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter();
|
||||
|
||||
enter
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.private_data.tip'));
|
||||
|
||||
enter
|
||||
.append('strong')
|
||||
.text(t('issues.suggested'));
|
||||
|
||||
enter
|
||||
.append('table')
|
||||
.attr('class', 'tagDiff-table')
|
||||
.selectAll('.tagDiff-row')
|
||||
.data(tagDiff)
|
||||
.enter()
|
||||
.append('tr')
|
||||
.attr('class', 'tagDiff-row')
|
||||
.append('td')
|
||||
.attr('class', function(d) {
|
||||
var klass = d.charAt(0) === '+' ? 'add' : 'remove';
|
||||
return 'tagDiff-cell tagDiff-cell-' + klass;
|
||||
})
|
||||
.text(function(d) { return d; });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
validation.type = type;
|
||||
|
||||
return validation;
|
||||
|
||||
@@ -95,10 +95,20 @@ export function validationTagSuggestsArea() {
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.tag_suggests_area.message', { feature: featureLabel, tag: tagText }),
|
||||
tooltip: t('issues.tag_suggests_area.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.tag_suggests_area.tip'));
|
||||
}
|
||||
};
|
||||
|
||||
validation.type = type;
|
||||
|
||||
@@ -42,10 +42,20 @@ export function validationUnknownRoad() {
|
||||
message: t('issues.unknown_road.message', {
|
||||
feature: utilDisplayLabel(entity, context),
|
||||
}),
|
||||
tooltip: t('issues.unknown_road.tip'),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(t('issues.unknown_road.tip'));
|
||||
}
|
||||
};
|
||||
|
||||
validation.type = type;
|
||||
|
||||
Reference in New Issue
Block a user