mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-27 18:32:25 +02:00
Merge branch 'master' of github.com:systemed/iD
This commit is contained in:
@@ -39,6 +39,8 @@ all: \
|
||||
js/id/format/*.js \
|
||||
js/id/graph/*.js \
|
||||
js/id/renderer/*.js \
|
||||
js/id/svg.js \
|
||||
js/id/svg/*.js \
|
||||
js/id/ui/*.js \
|
||||
js/id/end.js
|
||||
|
||||
|
||||
@@ -302,7 +302,6 @@ text.tag-oneway {
|
||||
}
|
||||
|
||||
.mode-browse .line,
|
||||
.mode-browse .oneway,
|
||||
.mode-select .line {
|
||||
cursor: url(../img/cursor-select-line.png), pointer;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
<script src="js/id/svg/midpoints.js"></script>
|
||||
<script src="js/id/svg/points.js"></script>
|
||||
<script src="js/id/svg/vertices.js"></script>
|
||||
<script src="js/id/svg/tag_classes.js"></script>
|
||||
|
||||
<script src='js/id/ui/inspector.js'></script>
|
||||
<script src='js/id/ui/modal.js'></script>
|
||||
|
||||
@@ -35,17 +35,6 @@ iD.Graph.prototype = {
|
||||
return transients[key] = fn.call(entity);
|
||||
},
|
||||
|
||||
parentStructure: function(ways) {
|
||||
var nodes = {};
|
||||
ways.forEach(function(w) {
|
||||
_.uniq(w.nodes).forEach(function(n) {
|
||||
if (typeof nodes[n.id] === 'undefined') nodes[n.id] = 0;
|
||||
nodes[n.id]++;
|
||||
});
|
||||
});
|
||||
return nodes;
|
||||
},
|
||||
|
||||
parentWays: function(entity) {
|
||||
var graph = this;
|
||||
return this.transient(entity, 'parentWays',
|
||||
@@ -63,7 +52,6 @@ iD.Graph.prototype = {
|
||||
},
|
||||
|
||||
parentRelations: function(entity) {
|
||||
// This is slow and a bad hack.
|
||||
var graph = this;
|
||||
return this.transient(entity, 'parentRelations',
|
||||
function generateParentRelations() {
|
||||
|
||||
@@ -41,22 +41,8 @@ iD.modes.DrawArea = function(wayId) {
|
||||
function click() {
|
||||
var datum = d3.select(d3.event.target).datum() || {};
|
||||
|
||||
if (datum.id === tailId) {
|
||||
history.replace(
|
||||
iD.actions.DeleteNode(node.id),
|
||||
iD.actions.AddWayNode(way.id, tailId, -1),
|
||||
'added to an area');
|
||||
|
||||
controller.enter(iD.modes.Select(way));
|
||||
|
||||
} else if (datum.id === headId) {
|
||||
|
||||
// finish the way
|
||||
history.replace(
|
||||
iD.actions.DeleteNode(node.id),
|
||||
iD.actions.AddWayNode(way.id, tailId, -1),
|
||||
'added to an area');
|
||||
|
||||
if (datum.id === tailId || datum.id === headId) {
|
||||
history.replace(iD.actions.DeleteNode(node.id));
|
||||
controller.enter(iD.modes.Select(way));
|
||||
|
||||
} else if (datum.type === 'node' && datum.id !== node.id) {
|
||||
@@ -77,13 +63,6 @@ iD.modes.DrawArea = function(wayId) {
|
||||
}
|
||||
}
|
||||
|
||||
function esc() {
|
||||
history.replace(
|
||||
iD.actions.DeleteNode(node.id));
|
||||
|
||||
controller.enter(iD.modes.Browse());
|
||||
}
|
||||
|
||||
function backspace() {
|
||||
d3.event.preventDefault();
|
||||
|
||||
@@ -109,11 +88,8 @@ iD.modes.DrawArea = function(wayId) {
|
||||
|
||||
function ret() {
|
||||
d3.event.preventDefault();
|
||||
history.replace(
|
||||
iD.actions.DeleteNode(node.id),
|
||||
iD.actions.AddWayNode(way.id, tailId, -1),
|
||||
'added to an area');
|
||||
controller.enter(iD.modes.Browse());
|
||||
history.replace(iD.actions.DeleteNode(node.id));
|
||||
controller.enter(iD.modes.Select(way));
|
||||
}
|
||||
|
||||
surface
|
||||
@@ -122,9 +98,9 @@ iD.modes.DrawArea = function(wayId) {
|
||||
.on('click.drawarea', click);
|
||||
|
||||
map.keybinding()
|
||||
.on('⎋.drawarea', esc)
|
||||
.on('⌫.drawarea', backspace)
|
||||
.on('⌦.drawarea', del)
|
||||
.on('⎋.drawarea', ret)
|
||||
.on('↩.drawarea', ret);
|
||||
};
|
||||
|
||||
|
||||
@@ -90,13 +90,6 @@ iD.modes.DrawLine = function(wayId, direction) {
|
||||
}
|
||||
}
|
||||
|
||||
function esc() {
|
||||
history.replace(
|
||||
iD.actions.DeleteNode(node.id));
|
||||
|
||||
controller.enter(iD.modes.Browse());
|
||||
}
|
||||
|
||||
function backspace() {
|
||||
d3.event.preventDefault();
|
||||
|
||||
@@ -121,7 +114,7 @@ iD.modes.DrawLine = function(wayId, direction) {
|
||||
function ret() {
|
||||
d3.event.preventDefault();
|
||||
history.replace(iD.actions.DeleteNode(node.id));
|
||||
controller.enter(iD.modes.Browse());
|
||||
controller.enter(iD.modes.Select(way));
|
||||
}
|
||||
|
||||
function undo() {
|
||||
@@ -134,9 +127,9 @@ iD.modes.DrawLine = function(wayId, direction) {
|
||||
.on('click.drawline', click);
|
||||
|
||||
map.keybinding()
|
||||
.on('⎋.drawline', esc)
|
||||
.on('⌫.drawline', backspace)
|
||||
.on('⌦.drawline', del)
|
||||
.on('⎋.drawline', ret)
|
||||
.on('↩.drawline', ret)
|
||||
.on('z.drawline', function(evt, mods) {
|
||||
if (mods === '⌘' || mods === '⌃') undo();
|
||||
|
||||
@@ -36,32 +36,3 @@ iD.Style.waystack = function(a, b) {
|
||||
}
|
||||
return as - bs;
|
||||
};
|
||||
|
||||
iD.Style.TAG_CLASSES = iD.util.trueObj([
|
||||
'highway', 'railway', 'motorway', 'amenity', 'natural',
|
||||
'landuse', 'building', 'oneway', 'bridge'
|
||||
]);
|
||||
|
||||
iD.Style.styleClasses = function() {
|
||||
var tagClassRe = /^tag-/;
|
||||
return function(selection) {
|
||||
selection.each(function(d, i) {
|
||||
var classes, value = this.className;
|
||||
|
||||
if (value.baseVal !== undefined) value = value.baseVal;
|
||||
|
||||
classes = value.trim().split(/\s+/).filter(function(name) {
|
||||
return name.length && !tagClassRe.test(name);
|
||||
});
|
||||
|
||||
var tags = d.tags;
|
||||
for (var k in tags) {
|
||||
if (!iD.Style.TAG_CLASSES[k]) continue;
|
||||
classes.push('tag-' + k);
|
||||
classes.push('tag-' + k + '-' + tags[k]);
|
||||
}
|
||||
|
||||
return d3.select(this).attr('class', classes.join(' '));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ iD.svg.Areas = function() {
|
||||
paths
|
||||
.order()
|
||||
.attr('d', lineString)
|
||||
.call(iD.Style.styleClasses());
|
||||
.call(iD.svg.TagClasses());
|
||||
|
||||
paths.exit()
|
||||
.remove();
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ iD.svg.Lines = function() {
|
||||
paths
|
||||
.order()
|
||||
.attr('d', lineString)
|
||||
.call(iD.Style.styleClasses());
|
||||
.call(iD.svg.TagClasses());
|
||||
|
||||
paths.exit()
|
||||
.remove();
|
||||
|
||||
+3
-2
@@ -8,7 +8,7 @@ iD.svg.Points = function() {
|
||||
}
|
||||
}
|
||||
return 'icons/unknown.png';
|
||||
};
|
||||
}
|
||||
|
||||
return function(surface, graph, entities, filter, projection) {
|
||||
var points = [];
|
||||
@@ -40,7 +40,8 @@ iD.svg.Points = function() {
|
||||
.attr({ width: 16, height: 16 })
|
||||
.attr('transform', 'translate(-8, -8)');
|
||||
|
||||
groups.attr('transform', iD.svg.PointTransform(projection));
|
||||
groups.attr('transform', iD.svg.PointTransform(projection))
|
||||
.call(iD.svg.TagClasses());
|
||||
|
||||
// Selecting the following implicitly
|
||||
// sets the data (point entity) on the element
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
iD.svg.TagClasses = function() {
|
||||
var keys = iD.util.trueObj([
|
||||
'highway', 'railway', 'motorway', 'amenity', 'natural',
|
||||
'landuse', 'building', 'oneway', 'bridge'
|
||||
]), tagClassRe = /^tag-/;
|
||||
|
||||
return function(selection) {
|
||||
selection.each(function(d, i) {
|
||||
var classes, value = this.className;
|
||||
|
||||
if (value.baseVal !== undefined) value = value.baseVal;
|
||||
|
||||
classes = value.trim().split(/\s+/).filter(function(name) {
|
||||
return name.length && !tagClassRe.test(name);
|
||||
});
|
||||
|
||||
var tags = d.tags;
|
||||
for (var k in tags) {
|
||||
if (!keys[k]) continue;
|
||||
classes.push('tag-' + k);
|
||||
classes.push('tag-' + k + '-' + tags[k]);
|
||||
}
|
||||
|
||||
return d3.select(this).attr('class', classes.join(' '));
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -9,8 +9,6 @@ iD.svg.Vertices = function() {
|
||||
}
|
||||
}
|
||||
|
||||
var parentStructure = graph.parentStructure(vertices);
|
||||
|
||||
var groups = surface.select('.layer-hit').selectAll('g.vertex')
|
||||
.filter(filter)
|
||||
.data(vertices, iD.Entity.key);
|
||||
@@ -28,7 +26,8 @@ iD.svg.Vertices = function() {
|
||||
.attr('r', 4);
|
||||
|
||||
groups.attr('transform', iD.svg.PointTransform(projection))
|
||||
.classed('shared', function(d) { return parentStructure[d.id] > 1; });
|
||||
.call(iD.svg.TagClasses())
|
||||
.classed('shared', function(entity) { return graph.parentWays(entity).length > 1; });
|
||||
|
||||
// Selecting the following implicitly
|
||||
// sets the data (vertix entity) on the elements
|
||||
|
||||
+7
-1
@@ -45,6 +45,7 @@
|
||||
<script src="../js/id/svg/midpoints.js"></script>
|
||||
<script src="../js/id/svg/points.js"></script>
|
||||
<script src="../js/id/svg/vertices.js"></script>
|
||||
<script src="../js/id/svg/tag_classes.js"></script>
|
||||
|
||||
<script src='../js/id/ui/inspector.js'></script>
|
||||
<script src='../js/id/ui/commit.js'></script>
|
||||
@@ -105,6 +106,8 @@
|
||||
var expect = chai.expect;
|
||||
</script>
|
||||
|
||||
<script src="spec/spec_helpers.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script src="spec/actions/add_node.js"></script>
|
||||
<script src="spec/actions/add_way.js"></script>
|
||||
@@ -137,7 +140,10 @@
|
||||
<script src="spec/renderer/background.js"></script>
|
||||
<script src="spec/renderer/hash.js"></script>
|
||||
<script src="spec/renderer/map.js"></script>
|
||||
<script src="spec/renderer/style.js"></script>
|
||||
|
||||
<script src="spec/svg/points.js"></script>
|
||||
<script src="spec/svg/vertices.js"></script>
|
||||
<script src="spec/svg/tag_classes.js"></script>
|
||||
|
||||
<script src="spec/ui/inspector.js"></script>
|
||||
<script src="spec/ui/geocoder.js"></script>
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
var expect = chai.expect;
|
||||
</script>
|
||||
|
||||
<script src="spec/spec_helpers.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script src="spec/actions/add_node.js"></script>
|
||||
<script src="spec/actions/add_way.js"></script>
|
||||
@@ -56,7 +58,10 @@
|
||||
<script src="spec/renderer/background.js"></script>
|
||||
<script src="spec/renderer/hash.js"></script>
|
||||
<script src="spec/renderer/map.js"></script>
|
||||
<script src="spec/renderer/style.js"></script>
|
||||
|
||||
<script src="spec/svg/points.js"></script>
|
||||
<script src="spec/svg/vertices.js"></script>
|
||||
<script src="spec/svg/tag_classes.js"></script>
|
||||
|
||||
<script src="spec/ui/inspector.js"></script>
|
||||
<script src="spec/connection.js"></script>
|
||||
|
||||
@@ -14,50 +14,4 @@ describe('iD.Style', function() {
|
||||
expect(iD.Style.waystack(b, a)).to.equal(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#styleClasses', function() {
|
||||
var selection;
|
||||
|
||||
beforeEach(function () {
|
||||
selection = d3.select(document.createElement('div'));
|
||||
});
|
||||
|
||||
it('adds no classes to elements whose datum has no tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity())
|
||||
.call(iD.Style.styleClasses());
|
||||
expect(selection.attr('class')).to.equal('');
|
||||
});
|
||||
|
||||
it('adds classes for highway tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'primary'}}))
|
||||
.call(iD.Style.styleClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary');
|
||||
});
|
||||
|
||||
it('removes classes for tags that are no longer present', function() {
|
||||
selection
|
||||
.attr('class', 'tag-highway tag-highway-primary')
|
||||
.datum(iD.Entity())
|
||||
.call(iD.Style.styleClasses());
|
||||
expect(selection.attr('class')).to.equal('');
|
||||
});
|
||||
|
||||
it('preserves existing non-"tag-"-prefixed classes', function() {
|
||||
selection
|
||||
.attr('class', 'selected')
|
||||
.datum(iD.Entity())
|
||||
.call(iD.Style.styleClasses());
|
||||
expect(selection.attr('class')).to.equal('selected');
|
||||
});
|
||||
|
||||
it('works on SVG elements', function() {
|
||||
selection = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
|
||||
selection
|
||||
.datum(iD.Entity())
|
||||
.call(iD.Style.styleClasses());
|
||||
expect(selection.attr('class')).to.equal('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
chai.use(function (chai, utils) {
|
||||
var flag = utils.flag;
|
||||
|
||||
chai.Assertion.addMethod('classed', function (className) {
|
||||
this.assert(
|
||||
flag(this, 'object').classed(className)
|
||||
, 'expected #{this} to be classed #{exp}'
|
||||
, 'expected #{this} not to be classed #{exp}'
|
||||
, className
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
describe("iD.svg.Points", function () {
|
||||
var surface,
|
||||
projection = d3.geo.mercator(),
|
||||
filter = d3.functor(true);
|
||||
|
||||
beforeEach(function () {
|
||||
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'));
|
||||
|
||||
surface.append('g')
|
||||
.attr('class', 'layer-hit');
|
||||
});
|
||||
|
||||
it("adds tag classes", function () {
|
||||
var node = iD.Node({tags: {amenity: "cafe"}, loc: [0, 0], _poi: true}),
|
||||
graph = iD.Graph([node]);
|
||||
|
||||
surface.call(iD.svg.Points(), graph, [node], filter, projection);
|
||||
|
||||
expect(surface.select('.point')).to.be.classed('tag-amenity');
|
||||
expect(surface.select('.point')).to.be.classed('tag-amenity-cafe');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
describe("iD.svg.TagClasses", function () {
|
||||
var selection;
|
||||
|
||||
beforeEach(function () {
|
||||
selection = d3.select(document.createElement('div'));
|
||||
});
|
||||
|
||||
it('adds no classes to elements whose datum has no tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity())
|
||||
.call(iD.svg.TagClasses());
|
||||
expect(selection.attr('class')).to.equal('');
|
||||
});
|
||||
|
||||
it('adds classes for highway tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'primary'}}))
|
||||
.call(iD.svg.TagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary');
|
||||
});
|
||||
|
||||
it('removes classes for tags that are no longer present', function() {
|
||||
selection
|
||||
.attr('class', 'tag-highway tag-highway-primary')
|
||||
.datum(iD.Entity())
|
||||
.call(iD.svg.TagClasses());
|
||||
expect(selection.attr('class')).to.equal('');
|
||||
});
|
||||
|
||||
it('preserves existing non-"tag-"-prefixed classes', function() {
|
||||
selection
|
||||
.attr('class', 'selected')
|
||||
.datum(iD.Entity())
|
||||
.call(iD.svg.TagClasses());
|
||||
expect(selection.attr('class')).to.equal('selected');
|
||||
});
|
||||
|
||||
it('works on SVG elements', function() {
|
||||
selection = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
|
||||
selection
|
||||
.datum(iD.Entity())
|
||||
.call(iD.svg.TagClasses());
|
||||
expect(selection.attr('class')).to.equal('');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
describe("iD.svg.Vertices", function () {
|
||||
var surface,
|
||||
projection = d3.geo.mercator(),
|
||||
filter = d3.functor(true);
|
||||
|
||||
beforeEach(function () {
|
||||
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'));
|
||||
|
||||
surface.append('g')
|
||||
.attr('class', 'layer-hit');
|
||||
});
|
||||
|
||||
it("adds tag classes", function () {
|
||||
var node = iD.Node({tags: {highway: "traffic_signals"}, loc: [0, 0]}),
|
||||
graph = iD.Graph([node]);
|
||||
|
||||
surface.call(iD.svg.Vertices(), graph, [node], filter, projection);
|
||||
|
||||
expect(surface.select('.vertex')).to.be.classed('tag-highway');
|
||||
expect(surface.select('.vertex')).to.be.classed('tag-highway-traffic_signals');
|
||||
});
|
||||
|
||||
it("adds the .shared class to vertices that are members of two or more ways", function () {
|
||||
var node = iD.Node({loc: [0, 0]}),
|
||||
way1 = iD.Way({nodes: [node.id]}),
|
||||
way2 = iD.Way({nodes: [node.id]}),
|
||||
graph = iD.Graph([node, way1, way2]);
|
||||
|
||||
surface.call(iD.svg.Vertices(), graph, [node], filter, projection);
|
||||
|
||||
expect(surface.select('.vertex')).to.be.classed('shared');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user