mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-19 20:23:12 +00:00
Merge remote-tracking branch 'refs/remotes/openstreetmap/master'
This commit is contained in:
@@ -152,7 +152,9 @@ export function behaviorBreathe() {
|
||||
|
||||
breathe.off = function() {
|
||||
done = true;
|
||||
timer.stop();
|
||||
if (timer) {
|
||||
timer.stop();
|
||||
}
|
||||
selected
|
||||
.interrupt()
|
||||
.call(reset);
|
||||
|
||||
@@ -26,6 +26,9 @@ export function coreHistory(context) {
|
||||
annotation = actions.pop();
|
||||
}
|
||||
|
||||
stack[index].transform = context.projection.transform();
|
||||
stack[index].selectedIDs = context.selectedIDs();
|
||||
|
||||
var graph = stack[index].graph;
|
||||
for (var i = 0; i < actions.length; i++) {
|
||||
graph = actions[i](graph);
|
||||
@@ -129,7 +132,7 @@ export function coreHistory(context) {
|
||||
if (stack[index].annotation) break;
|
||||
}
|
||||
|
||||
dispatch.call('undone');
|
||||
dispatch.call('undone', this, stack[index]);
|
||||
return change(previous);
|
||||
},
|
||||
|
||||
@@ -142,7 +145,7 @@ export function coreHistory(context) {
|
||||
if (stack[index].annotation) break;
|
||||
}
|
||||
|
||||
dispatch.call('redone');
|
||||
dispatch.call('redone', this, stack[index]);
|
||||
return change(previous);
|
||||
},
|
||||
|
||||
|
||||
@@ -71,6 +71,23 @@ export function modeSelect(context, selectedIDs) {
|
||||
}
|
||||
|
||||
|
||||
function checkSelectedIDs() {
|
||||
var ids = [];
|
||||
if (Array.isArray(selectedIDs)) {
|
||||
ids = selectedIDs.filter(function(id) {
|
||||
return context.hasEntity(id);
|
||||
});
|
||||
}
|
||||
|
||||
if (ids.length) {
|
||||
selectedIDs = ids;
|
||||
} else {
|
||||
context.enter(modeBrowse(context));
|
||||
}
|
||||
return !!ids.length;
|
||||
}
|
||||
|
||||
|
||||
// find the common parent ways for nextVertex, previousVertex
|
||||
function commonParents() {
|
||||
var graph = context.graph(),
|
||||
@@ -171,6 +188,8 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
|
||||
mode.reselect = function() {
|
||||
if (!checkSelectedIDs()) return;
|
||||
|
||||
var surfaceNode = context.surface().node();
|
||||
if (surfaceNode.focus) { // FF doesn't support it
|
||||
surfaceNode.focus();
|
||||
@@ -206,10 +225,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
function update() {
|
||||
closeMenu();
|
||||
if (_.some(selectedIDs, function(id) { return !context.hasEntity(id); })) {
|
||||
// Exit mode if selected entity gets undone
|
||||
context.enter(modeBrowse(context));
|
||||
}
|
||||
checkSelectedIDs();
|
||||
}
|
||||
|
||||
|
||||
@@ -236,6 +252,8 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
|
||||
function selectElements(drawn) {
|
||||
if (!checkSelectedIDs()) return;
|
||||
|
||||
var surface = context.surface(),
|
||||
entity = singular();
|
||||
|
||||
@@ -283,7 +301,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
if (parent) {
|
||||
var way = context.entity(parent);
|
||||
context.enter(
|
||||
modeSelect(context, [way.first()]).follow(true)
|
||||
modeSelect(context, [way.first()]).follow(true).suppressMenu(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -295,7 +313,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
if (parent) {
|
||||
var way = context.entity(parent);
|
||||
context.enter(
|
||||
modeSelect(context, [way.last()]).follow(true)
|
||||
modeSelect(context, [way.last()]).follow(true).suppressMenu(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -319,7 +337,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
if (index !== -1) {
|
||||
context.enter(
|
||||
modeSelect(context, [way.nodes[index]]).follow(true)
|
||||
modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -343,7 +361,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
if (index !== -1) {
|
||||
context.enter(
|
||||
modeSelect(context, [way.nodes[index]]).follow(true)
|
||||
modeSelect(context, [way.nodes[index]]).follow(true).suppressMenu(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -372,6 +390,8 @@ export function modeSelect(context, selectedIDs) {
|
||||
}
|
||||
|
||||
|
||||
if (!checkSelectedIDs()) return;
|
||||
|
||||
behaviors.forEach(function(behavior) {
|
||||
context.install(behavior);
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export function operationDelete(selectedIDs, context) {
|
||||
annotation = t('operations.delete.annotation.' + geometry);
|
||||
|
||||
// Select the next closest node in the way.
|
||||
if (geometry === 'vertex' && parents.length === 1 && parent.nodes.length > 2) {
|
||||
if (geometry === 'vertex' && parent.nodes.length > 2) {
|
||||
var nodes = parent.nodes,
|
||||
i = nodes.indexOf(id);
|
||||
|
||||
@@ -44,13 +44,16 @@ export function operationDelete(selectedIDs, context) {
|
||||
}
|
||||
}
|
||||
|
||||
context.perform(action, annotation);
|
||||
|
||||
if (nextSelectedID && context.hasEntity(nextSelectedID)) {
|
||||
context.enter(modeSelect(context, [nextSelectedID]));
|
||||
context.enter(
|
||||
modeSelect(context, [nextSelectedID]).follow(true).suppressMenu(true)
|
||||
);
|
||||
} else {
|
||||
context.enter(modeBrowse(context));
|
||||
}
|
||||
|
||||
context.perform(action, annotation);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from '../svg/index';
|
||||
|
||||
import { geoExtent } from '../geo/index';
|
||||
import { modeSelect } from '../modes/select';
|
||||
|
||||
import {
|
||||
utilFastMouse,
|
||||
@@ -44,9 +45,9 @@ export function rendererMap(context) {
|
||||
drawAreas = svgAreas(projection, context),
|
||||
drawMidpoints = svgMidpoints(projection, context),
|
||||
drawLabels = svgLabels(projection, context),
|
||||
supersurface,
|
||||
wrapper,
|
||||
surface,
|
||||
supersurface = d3.select(null),
|
||||
wrapper = d3.select(null),
|
||||
surface = d3.select(null),
|
||||
mouse,
|
||||
mousemove;
|
||||
|
||||
@@ -65,14 +66,31 @@ export function rendererMap(context) {
|
||||
|
||||
context
|
||||
.on('change.map', immediateRedraw);
|
||||
|
||||
context.connection()
|
||||
.on('change.map', immediateRedraw);
|
||||
|
||||
context.history()
|
||||
.on('change.map', immediateRedraw);
|
||||
.on('change.map', immediateRedraw)
|
||||
.on('undone.context redone.context', function(stack) {
|
||||
var followSelected = false;
|
||||
if (Array.isArray(stack.selectedIDs)) {
|
||||
followSelected = (stack.selectedIDs.length === 1 && stack.selectedIDs[0][0] === 'n');
|
||||
context.enter(
|
||||
modeSelect(context, stack.selectedIDs).suppressMenu(true).follow(followSelected)
|
||||
);
|
||||
}
|
||||
if (!followSelected && stack.transform) {
|
||||
map.transformEase(stack.transform);
|
||||
}
|
||||
});
|
||||
|
||||
context.background()
|
||||
.on('change.map', immediateRedraw);
|
||||
|
||||
context.features()
|
||||
.on('redraw.map', immediateRedraw);
|
||||
|
||||
drawLayers
|
||||
.on('change.map', function() {
|
||||
context.background().updateImagery();
|
||||
@@ -300,7 +318,7 @@ export function rendererMap(context) {
|
||||
|
||||
|
||||
function redraw(difference, extent) {
|
||||
if (!surface || !redrawEnabled) return;
|
||||
if (surface.empty() || !redrawEnabled) return;
|
||||
|
||||
// If we are in the middle of a zoom/pan, we can't do differenced redraws.
|
||||
// It would result in artifacts where differenced entities are redrawn with
|
||||
@@ -389,6 +407,26 @@ export function rendererMap(context) {
|
||||
};
|
||||
|
||||
|
||||
function setTransform(t2, duration, force) {
|
||||
var t = projection.transform();
|
||||
if (!force && t2.k === t.k && t2.x === t.x && t2.y === t.y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (duration) {
|
||||
_selection
|
||||
.transition()
|
||||
.duration(duration)
|
||||
.on('start', function() { map.startEase(); })
|
||||
.call(zoom.transform, d3.zoomIdentity.translate(t2.x, t2.y).scale(t2.k));
|
||||
} else {
|
||||
projection.transform(t2);
|
||||
transformStart = t2;
|
||||
_selection.call(zoom.transform, transformStart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function setZoom(z2, force, duration) {
|
||||
if (z2 === map.zoom() && !force) {
|
||||
return false;
|
||||
@@ -582,6 +620,13 @@ export function rendererMap(context) {
|
||||
};
|
||||
|
||||
|
||||
map.transformEase = function(t2, duration) {
|
||||
duration = duration || 250;
|
||||
setTransform(t2, duration, false);
|
||||
return map;
|
||||
};
|
||||
|
||||
|
||||
map.startEase = function() {
|
||||
utilBindOnce(surface, 'mousedown.ease', function() {
|
||||
map.cancelEase();
|
||||
|
||||
@@ -615,7 +615,8 @@ export function svgLabels(projection, context) {
|
||||
|
||||
// hide labels along selected ways, or near selected vertices
|
||||
for (var i = 0; i < selectedIDs.length; i++) {
|
||||
var entity = graph.entity(selectedIDs[i]);
|
||||
var entity = graph.hasEntity(selectedIDs[i]);
|
||||
if (!entity) continue;
|
||||
var geometry = entity.geometry(graph);
|
||||
|
||||
if (geometry === 'line') {
|
||||
|
||||
@@ -5,14 +5,12 @@ describe('iD.behaviorHash', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context.container(d3.select(document.createElement('div')));
|
||||
|
||||
// Neuter connection
|
||||
context.connection().loadTiles = function () {};
|
||||
context.connection().loadTiles = function () {}; // Neuter connection
|
||||
|
||||
var container = d3.select(document.createElement('div'));
|
||||
context.container(container);
|
||||
container.call(context.map());
|
||||
hash = iD.behaviorHash(context);
|
||||
d3.select(document.createElement('div'))
|
||||
.call(context.map());
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
describe('iD.behaviorLasso', function () {
|
||||
var lasso, context;
|
||||
var context, lasso;
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context.container(d3.select(document.createElement('div')));
|
||||
|
||||
// Neuter connection
|
||||
context.connection().loadTiles = function () {};
|
||||
|
||||
lasso = iD.behaviorLasso(context);
|
||||
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
lasso = iD.behaviorLasso(context);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
@@ -31,6 +31,18 @@ describe('iD.behaviorSelect', function() {
|
||||
container.remove();
|
||||
});
|
||||
|
||||
specify('refuse to enter select mode with no ids', function() {
|
||||
context.enter(iD.modeSelect(context, []));
|
||||
expect(context.mode().id, 'empty array').to.eql('browse');
|
||||
context.enter(iD.modeSelect(context, undefined));
|
||||
expect(context.mode().id, 'undefined').to.eql('browse');
|
||||
});
|
||||
|
||||
specify('refuse to enter select mode with nonexistent ids', function() {
|
||||
context.enter(iD.modeSelect(context, ['w-1']));
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
});
|
||||
|
||||
specify('click on entity selects the entity', function() {
|
||||
happen.click(context.surface().selectAll('.' + a.id).node());
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
describe('iD.Features', function() {
|
||||
var dimensions = [1000, 1000],
|
||||
context,
|
||||
features;
|
||||
context, features;
|
||||
|
||||
beforeEach(function() {
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
context.map().zoom(16);
|
||||
features = iD.Features(context);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user