modules/operations/disconnect.js (111 lines of code) (raw):
import { t } from '../util/locale';
import { actionDisconnect } from '../actions/disconnect';
import { behaviorOperation } from '../behavior/operation';
import { utilGetAllNodes } from '../util/index';
export function operationDisconnect(selectedIDs, context) {
var vertexIDs = [];
var wayIDs = [];
var otherIDs = [];
var actions = [];
selectedIDs.forEach(function(id) {
if (context.geometry(id) === 'vertex') {
vertexIDs.push(id);
} else if (context.entity(id).type === 'way'){
wayIDs.push(id);
} else {
otherIDs.push(id);
}
});
var disconnectingWayID = (vertexIDs.length === 0 && wayIDs.length === 1 && wayIDs[0]);
var extent, nodes, coords;
if (disconnectingWayID) { // disconnecting a way
var way = context.entity(disconnectingWayID);
extent = way.extent(context.graph());
nodes = utilGetAllNodes([disconnectingWayID], context.graph());
coords = nodes.map(function(n) { return n.loc; });
way.nodes.forEach(function(vertexID) {
var action = actionDisconnect(vertexID).limitWays(wayIDs);
if (action.disabled(context.graph()) !== 'not_connected') {
actions.push(action);
}
});
} else { // disconnecting a vertex
vertexIDs.forEach(function(vertexID) {
var action = actionDisconnect(vertexID);
if (wayIDs.length > 0) {
var waysIDsForVertex = wayIDs.filter(function(wayID) {
var way = context.entity(wayID);
return way.nodes.indexOf(vertexID) !== -1;
});
action.limitWays(waysIDsForVertex);
}
actions.push(action);
});
}
var operation = function() {
context.perform(function(graph) {
return actions.reduce(function(graph, action) { return action(graph); }, graph);
}, operation.annotation());
context.validator().validate();
};
operation.available = function(situation) {
if (actions.length === 0) return false;
if (otherIDs.length !== 0) return false;
if (vertexIDs.length !== 0 && wayIDs.length !== 0 && !wayIDs.every(function(wayID) {
return vertexIDs.some(function(vertexID) {
var way = context.entity(wayID);
return way.nodes.indexOf(vertexID) !== -1;
});
})) return false;
if (situation === 'toolbar' &&
actions.every(function(action) {
return action.disabled(context.graph()) === 'not_connected';
})) return false;
return true;
};
operation.disabled = function() {
var reason;
for (var actionIndex in actions) {
reason = actions[actionIndex].disabled(context.graph());
if (reason) return reason;
}
if (disconnectingWayID && extent.percentContainedIn(context.extent()) < 0.8) {
return 'too_large.single';
} else if (disconnectingWayID && someMissing()) {
return 'not_downloaded';
} else if (selectedIDs.some(context.hasHiddenConnections)) {
return 'connected_to_hidden';
}
return false;
function someMissing() {
if (context.inIntro()) return false;
var osm = context.connection();
if (osm) {
var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); });
if (missing.length) {
missing.forEach(function(loc) { context.loadTileAtLoc(loc); });
return true;
}
}
return false;
}
};
operation.tooltip = function() {
var disable = operation.disabled();
if (disable) {
return t('operations.disconnect.' + disable);
}
if (disconnectingWayID) {
return t('operations.disconnect.' + context.geometry(disconnectingWayID) + '.description');
}
return t('operations.disconnect.description');
};
operation.annotation = function() {
return t('operations.disconnect.annotation');
};
operation.id = 'disconnect';
operation.keys = [t('operations.disconnect.key')];
operation.title = t('operations.disconnect.title');
operation.behavior = behaviorOperation(context).which(operation);
return operation;
}