mirror of
https://github.com/FoggedLens/iD.git
synced 2026-06-04 14:08:13 +02:00
Extract hover behavior
This commit is contained in:
@@ -68,6 +68,7 @@
|
||||
<script src='js/id/behavior/drag_accuracy_handle.js'></script>
|
||||
<script src='js/id/behavior/drag_node.js'></script>
|
||||
<script src='js/id/behavior/drag_way.js'></script>
|
||||
<script src='js/id/behavior/hover.js'></script>
|
||||
|
||||
<script src='js/id/modes.js'></script>
|
||||
<script src='js/id/modes/add_area.js'></script>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
The hover behavior adds the `.hover` class on mouseover to all elements to which
|
||||
the identical datum is bound, and removes it on mouseout.
|
||||
|
||||
The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
|
||||
representation may consist of several elements scattered throughout the DOM hierarchy.
|
||||
Only one of these elements can have the :hover pseudo-class, but all of them will
|
||||
have the .hover class.
|
||||
*/
|
||||
iD.behavior.Hover = function () {
|
||||
var hover = function(selection) {
|
||||
selection.on('mouseover.hover', function () {
|
||||
var datum = d3.event.target.__data__;
|
||||
if (datum) {
|
||||
selection.selectAll('*')
|
||||
.filter(function (d) { return d === datum; })
|
||||
.classed('hover', true);
|
||||
}
|
||||
});
|
||||
|
||||
selection.on('mouseout.hover', function () {
|
||||
selection.selectAll('.hover')
|
||||
.classed('hover', false);
|
||||
});
|
||||
};
|
||||
|
||||
hover.off = function(selection) {
|
||||
selection.on('mouseover.hover', null)
|
||||
.on('mouseout.hover', null);
|
||||
};
|
||||
|
||||
return hover;
|
||||
};
|
||||
@@ -12,7 +12,6 @@ iD.modes.AddArea = function() {
|
||||
controller = mode.controller;
|
||||
|
||||
map.dblclickEnable(false)
|
||||
.hoverEnable(false)
|
||||
.hint('Click on the map to start drawing an area, like a park, lake, or building.');
|
||||
|
||||
map.surface.on('click.addarea', function() {
|
||||
@@ -48,8 +47,7 @@ iD.modes.AddArea = function() {
|
||||
|
||||
mode.exit = function() {
|
||||
window.setTimeout(function() {
|
||||
mode.map.dblclickEnable(true)
|
||||
.hoverEnable(true);
|
||||
mode.map.dblclickEnable(true);
|
||||
}, 1000);
|
||||
mode.map.hint(false);
|
||||
mode.map.surface.on('click.addarea', null);
|
||||
|
||||
@@ -13,7 +13,6 @@ iD.modes.AddLine = function() {
|
||||
controller = mode.controller;
|
||||
|
||||
map.dblclickEnable(false)
|
||||
.hoverEnable(false)
|
||||
.hint('Click on the map to start drawing an road, path, or route.');
|
||||
|
||||
map.surface.on('click.addline', function() {
|
||||
@@ -69,7 +68,7 @@ iD.modes.AddLine = function() {
|
||||
};
|
||||
|
||||
mode.exit = function() {
|
||||
mode.map.dblclickEnable(true).hoverEnable(true);
|
||||
mode.map.dblclickEnable(true);
|
||||
mode.map.hint(false);
|
||||
mode.map.surface.on('click.addline', null);
|
||||
mode.map.keybinding().on('⎋.addline', null);
|
||||
|
||||
@@ -10,8 +10,6 @@ iD.modes.AddPoint = function() {
|
||||
history = mode.history,
|
||||
controller = mode.controller;
|
||||
|
||||
map.hoverEnable(false);
|
||||
|
||||
map.hint('Click on the map to add a point.');
|
||||
|
||||
map.surface.on('click.addpoint', function() {
|
||||
@@ -30,7 +28,6 @@ iD.modes.AddPoint = function() {
|
||||
};
|
||||
|
||||
mode.exit = function() {
|
||||
mode.map.hoverEnable(true);
|
||||
mode.map.hint(false);
|
||||
mode.map.surface.on('click.addpoint', null);
|
||||
mode.map.keybinding().on('⎋.addpoint', null);
|
||||
|
||||
@@ -12,6 +12,7 @@ iD.modes.Browse = function() {
|
||||
var surface = mode.map.surface;
|
||||
|
||||
behaviors = [
|
||||
iD.behavior.Hover(),
|
||||
iD.behavior.DragNode(mode),
|
||||
iD.behavior.DragAccuracyHandle(mode)];
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ iD.modes.DrawArea = function(wayId) {
|
||||
node = iD.Node({loc: map.mouseCoordinates()});
|
||||
|
||||
map.dblclickEnable(false)
|
||||
.hoverEnable(false)
|
||||
.fastEnable(false);
|
||||
map.hint('Click on the map to add points to your area. Finish the ' +
|
||||
'area by clicking on your first point');
|
||||
@@ -126,8 +125,7 @@ iD.modes.DrawArea = function(wayId) {
|
||||
|
||||
mode.exit = function() {
|
||||
mode.map.hint(false);
|
||||
mode.map.fastEnable(true)
|
||||
.hoverEnable(true);
|
||||
mode.map.fastEnable(true);
|
||||
|
||||
mode.map.surface
|
||||
.on('mousemove.drawarea', null)
|
||||
|
||||
@@ -16,7 +16,6 @@ iD.modes.DrawLine = function(wayId, direction) {
|
||||
|
||||
map.dblclickEnable(false)
|
||||
.fastEnable(false)
|
||||
.hoverEnable(false)
|
||||
.hint('Click to add more points to the line. ' +
|
||||
'Click on other lines to connect to them, and double-click to ' +
|
||||
'end the line.');
|
||||
@@ -122,8 +121,7 @@ iD.modes.DrawLine = function(wayId, direction) {
|
||||
|
||||
mode.exit = function() {
|
||||
mode.map.hint(false);
|
||||
mode.map.fastEnable(true)
|
||||
.hoverEnable(true);
|
||||
mode.map.fastEnable(true);
|
||||
|
||||
mode.map.surface
|
||||
.on('mousemove.drawline', null)
|
||||
|
||||
@@ -30,6 +30,7 @@ iD.modes.Select = function (entity) {
|
||||
var surface = mode.map.surface;
|
||||
|
||||
behaviors = [
|
||||
iD.behavior.Hover(),
|
||||
iD.behavior.DragNode(mode),
|
||||
iD.behavior.DragWay(mode),
|
||||
iD.behavior.DragAccuracyHandle(mode)];
|
||||
|
||||
+3
-38
@@ -2,7 +2,6 @@ iD.Map = function() {
|
||||
var connection, history,
|
||||
dimensions = [],
|
||||
dispatch = d3.dispatch('move'),
|
||||
hover = null,
|
||||
translateStart,
|
||||
keybinding = d3.keybinding(),
|
||||
projection = d3.geo.mercator().scale(1024),
|
||||
@@ -12,7 +11,6 @@ iD.Map = function() {
|
||||
.scaleExtent([1024, 256 * Math.pow(2, 24)])
|
||||
.on('zoom', zoomPan),
|
||||
dblclickEnabled = true,
|
||||
hoverEnabled = true,
|
||||
fastEnabled = true,
|
||||
notice,
|
||||
background = iD.Background()
|
||||
@@ -43,8 +41,6 @@ iD.Map = function() {
|
||||
.attr({ x: 0, y: 0 });
|
||||
|
||||
r = surface.append('g')
|
||||
.on('mouseover', hoverIn)
|
||||
.on('mouseout', hoverOut)
|
||||
.attr('clip-path', 'url(#clip)');
|
||||
|
||||
g = ['fill', 'casing', 'stroke', 'text', 'hit', 'temp'].reduce(function(mem, i) {
|
||||
@@ -66,7 +62,6 @@ iD.Map = function() {
|
||||
}
|
||||
|
||||
function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; }
|
||||
function classHover(d) { return d.id === hover; }
|
||||
function getline(d) { return d._line; }
|
||||
function key(d) { return d.id; }
|
||||
function nodeline(d) {
|
||||
@@ -163,8 +158,7 @@ iD.Map = function() {
|
||||
.attr('r', 4);
|
||||
|
||||
circles.attr('transform', pointTransform)
|
||||
.classed('shared', shared)
|
||||
.classed('hover', classHover);
|
||||
.classed('shared', shared);
|
||||
}
|
||||
|
||||
function drawAccuracyHandles(waynodes, filter) {
|
||||
@@ -191,13 +185,11 @@ iD.Map = function() {
|
||||
.filter(filter)
|
||||
.data(data, key);
|
||||
lines.exit().remove();
|
||||
lines.enter().append('path')
|
||||
.classed('hover', classHover);
|
||||
lines.enter().append('path');
|
||||
lines
|
||||
.order()
|
||||
.attr('d', getline)
|
||||
.attr('class', class_gen)
|
||||
.classed('hover', classHover);
|
||||
.attr('class', class_gen);
|
||||
return lines;
|
||||
}
|
||||
|
||||
@@ -210,7 +202,6 @@ iD.Map = function() {
|
||||
}
|
||||
|
||||
function drawPoints(points, filter) {
|
||||
|
||||
var groups = g.hit.selectAll('g.point')
|
||||
.filter(filter)
|
||||
.data(points, key);
|
||||
@@ -234,7 +225,6 @@ iD.Map = function() {
|
||||
|
||||
groups.attr('transform', pointTransform);
|
||||
|
||||
groups.classed('hover', classHover);
|
||||
groups.select('image').attr('xlink:href', iD.Style.pointImage);
|
||||
}
|
||||
|
||||
@@ -276,25 +266,6 @@ iD.Map = function() {
|
||||
redraw(Object.keys(result.entities));
|
||||
}
|
||||
|
||||
function hoverIn() {
|
||||
if (!hoverEnabled) return;
|
||||
var datum = d3.select(d3.event.target).datum();
|
||||
if (datum instanceof iD.Entity) {
|
||||
hover = datum.id;
|
||||
redraw([hover]);
|
||||
d3.select('.messages').text(datum.tags.name || '#' + datum.id);
|
||||
}
|
||||
}
|
||||
|
||||
function hoverOut() {
|
||||
if (hoverEnabled && hover) {
|
||||
var oldHover = hover;
|
||||
hover = null;
|
||||
redraw([oldHover]);
|
||||
d3.select('.messages').text('');
|
||||
}
|
||||
}
|
||||
|
||||
function zoomPan() {
|
||||
if (d3.event && d3.event.sourceEvent.type === 'dblclick') {
|
||||
if (!dblclickEnabled) {
|
||||
@@ -363,12 +334,6 @@ iD.Map = function() {
|
||||
return map;
|
||||
};
|
||||
|
||||
map.hoverEnable = function(_) {
|
||||
if (!arguments.length) return hoverEnabled;
|
||||
hoverEnabled = _;
|
||||
return map;
|
||||
};
|
||||
|
||||
map.fastEnable = function(_) {
|
||||
if (!arguments.length) return fastEnabled;
|
||||
fastEnabled = _;
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
<script src='../js/id/behavior/drag_accuracy_handle.js'></script>
|
||||
<script src='../js/id/behavior/drag_node.js'></script>
|
||||
<script src='../js/id/behavior/drag_way.js'></script>
|
||||
<script src='../js/id/behavior/hover.js'></script>
|
||||
|
||||
<script src='../js/id/modes.js'></script>
|
||||
<script src='../js/id/modes/add_area.js'></script>
|
||||
@@ -111,6 +112,8 @@
|
||||
<script src="spec/actions/remove_relation_member.js"></script>
|
||||
<script src="spec/actions/reverse_way.js"></script>
|
||||
|
||||
<script src="spec/behavior/hover.js"></script>
|
||||
|
||||
<script src="spec/format/geojson.js"></script>
|
||||
<script src="spec/format/xml.js"></script>
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
<script src="spec/actions/remove_relation_member.js"></script>
|
||||
<script src="spec/actions/reverse_way.js"></script>
|
||||
|
||||
<script src="spec/behavior/hover.js"></script>
|
||||
|
||||
<script src="spec/format/geojson.js"></script>
|
||||
<script src="spec/format/xml.js"></script>
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
describe("iD.behavior.Hover", function() {
|
||||
var container;
|
||||
|
||||
beforeEach(function() {
|
||||
container = d3.select('body').append('div');
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
container.remove();
|
||||
});
|
||||
|
||||
describe("mouseover", function () {
|
||||
it("adds the 'hover' class to all elements to which the same datum is bound", function () {
|
||||
container.selectAll('span')
|
||||
.data(['a', 'b', 'a', 'b'])
|
||||
.enter().append('span').attr('class', Object);
|
||||
|
||||
container.call(iD.behavior.Hover());
|
||||
container.selectAll('.a').trigger('mouseover');
|
||||
|
||||
expect(container.selectAll('.a.hover')[0]).to.have.length(2);
|
||||
expect(container.selectAll('.b.hover')[0]).to.have.length(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("mouseout", function () {
|
||||
it("removes the 'hover' class from all elements", function () {
|
||||
container.append('span').attr('class', 'hover');
|
||||
|
||||
container.call(iD.behavior.Hover());
|
||||
container.selectAll('.hover').trigger('mouseout');
|
||||
|
||||
expect(container.selectAll('.hover')[0]).to.have.length(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user