mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-14 09:42:56 +00:00
Better support for delete/restore
This commit is contained in:
@@ -63,31 +63,44 @@ iD.actions.MergeRemoteChanges = function(id, localGraph, remoteGraph, formatUser
|
||||
}
|
||||
|
||||
|
||||
function mergeChildNodes(target, children, updates, graph) {
|
||||
function mergeChildren(target, children, updates, graph) {
|
||||
function isUsed(node) {
|
||||
return node.hasInterestingTags() ||
|
||||
graph.parentWays(node).length > 0 ||
|
||||
graph.parentRelations(node).length > 0;
|
||||
}
|
||||
|
||||
var ccount = conflicts.length;
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var id = children[i],
|
||||
node = graph.hasEntity(id);
|
||||
|
||||
// remove unwanted.
|
||||
// remove unused childNodes.
|
||||
if (target.nodes.indexOf(id) === -1) {
|
||||
if (node && !node.hasInterestingTags()) updates.removeIds.push(id);
|
||||
if (node && !isUsed(node)) {
|
||||
updates.removeIds.push(id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// restore used childNodes..
|
||||
var localNode = localGraph.hasEntity(id),
|
||||
remoteNode = remoteGraph.hasEntity(id);
|
||||
remoteNode = remoteGraph.hasEntity(id),
|
||||
targetNode;
|
||||
|
||||
// restore wanted..
|
||||
if (option === 'force_remote') {
|
||||
if (remoteNode) updates.replacements.push(remoteNode);
|
||||
} else if (localNode && remoteNode) {
|
||||
var targetNode = iD.Entity(localNode, { version: remoteNode.version });
|
||||
if (option !== 'force_local') {
|
||||
targetNode = mergeLocation(remoteNode, targetNode);
|
||||
if (conflicts.length !== ccount) break;
|
||||
}
|
||||
if (remoteNode && option === 'force_remote') {
|
||||
updates.replacements.push(remoteNode);
|
||||
|
||||
} else if (localNode && option === 'force_local') {
|
||||
targetNode = iD.Entity(localNode,
|
||||
{ version: (remoteNode ? remoteNode.version : localNode.version + 1) });
|
||||
updates.replacements.push(targetNode);
|
||||
|
||||
} else if (localNode && remoteNode && option === 'safe') {
|
||||
targetNode = iD.Entity(localNode, { version: remoteNode.version });
|
||||
targetNode = mergeLocation(remoteNode, targetNode);
|
||||
if (conflicts.length !== ccount) break;
|
||||
updates.replacements.push(targetNode);
|
||||
}
|
||||
}
|
||||
@@ -96,6 +109,17 @@ iD.actions.MergeRemoteChanges = function(id, localGraph, remoteGraph, formatUser
|
||||
}
|
||||
|
||||
|
||||
function updateChildren(updates, graph) {
|
||||
for (var i = 0; i < updates.replacements.length; i++) {
|
||||
graph = graph.replace(updates.replacements[i]);
|
||||
}
|
||||
if (updates.removeIds.length) {
|
||||
graph = iD.actions.DeleteMultiple(updates.removeIds)(graph);
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
||||
function mergeMembers(remote, target) {
|
||||
if (option === 'force_local' || _.isEqual(target.members, remote.members)) {
|
||||
return target;
|
||||
@@ -157,19 +181,42 @@ iD.actions.MergeRemoteChanges = function(id, localGraph, remoteGraph, formatUser
|
||||
// `graph.base()` --- ... --- `remoteGraph`
|
||||
//
|
||||
var action = function(graph) {
|
||||
var base = graph.base().entities[id],
|
||||
var updates = { replacements: [], removeIds: [] },
|
||||
base = graph.base().entities[id],
|
||||
local = localGraph.entity(id),
|
||||
remote = remoteGraph.entity(id),
|
||||
target = iD.Entity(local, { version: remote.version }),
|
||||
updates = { replacements: [], removeIds: [] };
|
||||
remote = remoteGraph.hasEntity(id),
|
||||
target;
|
||||
|
||||
// delete/undelete
|
||||
if (!remote) {
|
||||
if (option === 'force_remote') {
|
||||
return iD.actions.DeleteMultiple([id])(graph);
|
||||
|
||||
} else if (option === 'force_local') {
|
||||
target = iD.Entity(local, { version: local.version + 1 });
|
||||
if (target.type === 'way') {
|
||||
target = mergeChildren(target, _.uniq(local.nodes), updates, graph);
|
||||
graph = updateChildren(updates, graph);
|
||||
}
|
||||
return graph.replace(target);
|
||||
|
||||
} else {
|
||||
return graph; // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
// merge
|
||||
target = iD.Entity(local, { version: remote.version });
|
||||
|
||||
if (target.type === 'node') {
|
||||
target = mergeLocation(remote, target);
|
||||
|
||||
} else if (target.type === 'way') {
|
||||
// pull in any child nodes that may not be present locally..
|
||||
graph.rebase(remoteGraph.childNodes(remote), [graph], false);
|
||||
target = mergeNodes(base, remote, target);
|
||||
target = mergeChildNodes(target, _.union(local.nodes, remote.nodes), updates, graph);
|
||||
target = mergeChildren(target, _.union(local.nodes, remote.nodes), updates, graph);
|
||||
|
||||
} else if (target.type === 'relation') {
|
||||
target = mergeMembers(remote, target);
|
||||
}
|
||||
@@ -177,13 +224,7 @@ iD.actions.MergeRemoteChanges = function(id, localGraph, remoteGraph, formatUser
|
||||
target = mergeTags(base, remote, target);
|
||||
|
||||
if (!conflicts.length) {
|
||||
graph = graph.replace(target);
|
||||
for (var i = 0; i < updates.replacements.length; i++) {
|
||||
graph = graph.replace(updates.replacements[i]);
|
||||
}
|
||||
if (updates.removeIds.length) {
|
||||
graph = iD.actions.DeleteMultiple(updates.removeIds)(graph);
|
||||
}
|
||||
graph = updateChildren(updates, graph).replace(target);
|
||||
}
|
||||
|
||||
return graph;
|
||||
|
||||
@@ -15,7 +15,6 @@ iD.modes.Save = function(context) {
|
||||
remoteGraph = iD.Graph(history.base(), true),
|
||||
modified = _.filter(history.difference().summary(), {changeType: 'modified'}),
|
||||
toCheck = _.pluck(_.pluck(modified, 'entity'), 'id'),
|
||||
deletedIds = [],
|
||||
conflicts = [],
|
||||
errors = [];
|
||||
|
||||
@@ -36,6 +35,7 @@ iD.modes.Save = function(context) {
|
||||
|
||||
if (err) {
|
||||
if (err.status === 410) { // Status: Gone (contains no responseText)
|
||||
remoteGraph.remove(remoteGraph.hasEntity(id));
|
||||
addDeleteConflict(id);
|
||||
} else {
|
||||
errors.push({
|
||||
@@ -58,10 +58,10 @@ iD.modes.Save = function(context) {
|
||||
|
||||
|
||||
function addDeleteConflict(id) {
|
||||
if (deletedIds.indexOf(id) !== -1) return;
|
||||
else deletedIds.push(id);
|
||||
|
||||
var local = localGraph.entity(id);
|
||||
var local = localGraph.entity(id),
|
||||
action = iD.actions.MergeRemoteChanges,
|
||||
forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
|
||||
forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote');
|
||||
|
||||
conflicts.push({
|
||||
id: id,
|
||||
@@ -69,17 +69,10 @@ iD.modes.Save = function(context) {
|
||||
details: [ t('save.conflict.deleted') ],
|
||||
chosen: 1,
|
||||
choices: [
|
||||
choice(id, t('save.conflict.restore'), undelete(local)),
|
||||
choice(id, t('save.conflict.delete'), iD.actions.DeleteMultiple([id]))
|
||||
choice(id, t('save.conflict.restore'), forceLocal),
|
||||
choice(id, t('save.conflict.delete'), forceRemote)
|
||||
],
|
||||
});
|
||||
|
||||
function undelete(entity) {
|
||||
return function(graph) {
|
||||
var target = iD.Entity(entity, { version: +entity.version + 1 });
|
||||
return graph.replace(target);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,8 +88,8 @@ iD.modes.Save = function(context) {
|
||||
|
||||
if (diff.length()) return; // merged safely
|
||||
|
||||
var forceLocal = action(id, localGraph, remoteGraph, formatUser).withOption('force_local'),
|
||||
forceRemote = action(id, localGraph, remoteGraph, formatUser).withOption('force_remote');
|
||||
var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
|
||||
forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote');
|
||||
|
||||
conflicts.push({
|
||||
id: id,
|
||||
@@ -308,7 +301,7 @@ iD.modes.Save = function(context) {
|
||||
(i === 1 && index === conflicts.length - 1) || null;
|
||||
})
|
||||
.on('click', function(d, i) {
|
||||
var container = parent.select('.conflict-container'), //d3.select(this.parentElement.parentElement.parentElement.parentElement),
|
||||
var container = parent.select('.conflict-container'),
|
||||
sign = (i === 0 ? -1 : 1);
|
||||
|
||||
container
|
||||
|
||||
Reference in New Issue
Block a user