Merge remote-tracking branch 'refs/remotes/openstreetmap/master'

This commit is contained in:
Mikołaj "Natsuyasumi" Kuranowski
2017-01-02 17:51:27 +01:00
10 changed files with 117 additions and 36 deletions

View File

@@ -152,7 +152,9 @@ export function behaviorBreathe() {
breathe.off = function() {
done = true;
timer.stop();
if (timer) {
timer.stop();
}
selected
.interrupt()
.call(reset);

View File

@@ -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);
},

View File

@@ -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);
});

View File

@@ -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);
};

View File

@@ -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();

View File

@@ -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') {

View File

@@ -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 () {

View File

@@ -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 () {

View File

@@ -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]);

View File

@@ -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);
});