diff --git a/css/map.css b/css/map.css
index 80916685d..3dd66afae 100644
--- a/css/map.css
+++ b/css/map.css
@@ -3,16 +3,26 @@ path {
fill: none;
}
+/* points */
+
g.point circle {
fill:#fff;
}
-g.pointer circle.stroke,
-g.point.selected circle.stroke {
- fill:#333;
- -webkit-transform:scale(1.2, 1.2);
- -moz-transform:scale(1.2, 1.2);
- transform:scale(1.2, 1.2);
+g.point .shadow {
+ fill: none;
+ pointer-events: all;
+ -webkit-transition: -webkit-transform 100ms linear;
+ transition: transform 100ms linear;
+ -moz-transition: fill 100ms linear;
+}
+g.point.hover .shadow {
+ fill: #E96666;
+ fill-opacity: 0.3;
+}
+g.point.selected .shadow {
+ fill: #E96666;
+ fill-opacity: 0.7;
}
/* vertices */
diff --git a/js/id/id.js b/js/id/id.js
index 3c33ae912..4e13a3cfc 100644
--- a/js/id/id.js
+++ b/js/id/id.js
@@ -37,25 +37,25 @@ window.iD = function(container) {
.attr('class', function (mode) { return mode.title + ' add-button col3'; })
.attr('data-original-title', function (mode) { return mode.description; })
.call(bootstrap.tooltip().placement('bottom'))
- .on('click', function (mode) { controller.enter(mode); });
+ .on('click.editor', function (mode) { controller.enter(mode); });
function disableTooHigh() {
- if (map.zoom() < 16) {
+ if (map.editable()) {
+ notice.message('');
+ buttons.attr('disabled', null);
+ } else {
buttons.attr('disabled', 'disabled');
notice.message('Zoom in to edit the map');
controller.enter(iD.modes.Browse());
- } else {
- notice.message('');
- buttons.attr('disabled', null);
}
}
var notice = iD.ui.notice(limiter).message(null);
- map.on('move.disable-buttons', disableTooHigh)
- .on('move.contributors', _.debounce(function() {
- contributors.call(iD.ui.contributors(map));
- }, 1000));
+ map.on('move.editor', _.debounce(function() {
+ disableTooHigh();
+ contributors.call(iD.ui.contributors(map));
+ }, 500));
buttons.append('span')
.attr('class', function(d) {
@@ -64,12 +64,12 @@ window.iD = function(container) {
buttons.append('span').attr('class', 'label').text(function (mode) { return mode.title; });
- controller.on('enter', function (entered) {
+ controller.on('enter.editor', function (entered) {
buttons.classed('active', function (mode) { return entered.button === mode.button; });
container.classed("mode-" + entered.id, true);
});
- controller.on('exit', function (exited) {
+ controller.on('exit.editor', function (exited) {
container.classed("mode-" + exited.id, false);
});
@@ -81,21 +81,21 @@ window.iD = function(container) {
.attr({ id: 'undo', 'class': 'col6' })
.property('disabled', true)
.html("")
- .on('click', history.undo)
+ .on('click.editor', history.undo)
.call(undo_tooltip);
undo_buttons.append('button')
.attr({ id: 'redo', 'class': 'col6' })
.property('disabled', true)
.html("")
- .on('click', history.redo)
+ .on('click.editor', history.redo)
.call(undo_tooltip);
var save_button = limiter.append('div').attr('class','button-wrap col1').append('button')
.attr('class', 'save col12')
.call(iD.ui.save().map(map).controller(controller));
- history.on('change.warn-unload', function() {
+ history.on('change.editor', function() {
window.onbeforeunload = history.hasChanges() ? function() {
return 'You have unsaved changes.';
} : null;
@@ -109,7 +109,7 @@ window.iD = function(container) {
.append('button')
.attr('class', function(d) { return d[0]; })
.attr('title', function(d) { return d[3]; })
- .on('click', function(d) { return d[2](); })
+ .on('click.editor', function(d) { return d[2](); })
.append('span')
.attr('class', function(d) {
return d[0] + ' icon';
@@ -157,7 +157,7 @@ window.iD = function(container) {
aboutList.append('li').attr('class', 'source-switch').append('a').attr('href', '#')
.text('dev')
- .on('click', function() {
+ .on('click.editor', function() {
d3.event.preventDefault();
if (d3.select(this).classed('live')) {
map.flush().connection()
@@ -183,7 +183,7 @@ window.iD = function(container) {
contributors.append('span')
.attr('class', 'contributor-count');
- history.on('change.buttons', function() {
+ history.on('change.editor', function() {
var undo = history.undoAnnotation(),
redo = history.redoAnnotation();
@@ -204,14 +204,14 @@ window.iD = function(container) {
.call(redo ? refreshTooltip : undo_tooltip.hide);
});
- d3.select(window).on('resize.map-size', function() {
+ d3.select(window).on('resize.editor', function() {
map.size(m.size());
});
var keybinding = d3.keybinding('main')
- .on('P', function() { controller.enter(iD.modes.AddPoint()); })
- .on('L', function() { controller.enter(iD.modes.AddLine()); })
- .on('A', function() { controller.enter(iD.modes.AddArea()); })
+ .on('P', function() { if (map.editable()) controller.enter(iD.modes.AddPoint()); })
+ .on('L', function() { if (map.editable()) controller.enter(iD.modes.AddLine()); })
+ .on('A', function() { if (map.editable()) controller.enter(iD.modes.AddArea()); })
.on('⌘+Z', function() { history.undo(); })
.on('⌃+Z', function() { history.undo(); })
.on('⌘+⇧+Z', function() { history.redo(); })
@@ -228,8 +228,8 @@ window.iD = function(container) {
}
d3.select('.user-container').call(iD.ui.userpanel(connection)
- .on('logout', connection.logout)
- .on('login', connection.authenticate));
+ .on('logout.editor', connection.logout)
+ .on('login.editor', connection.authenticate));
controller.enter(iD.modes.Browse());
}
diff --git a/js/id/renderer/hash.js b/js/id/renderer/hash.js
index 81da12d90..c71d02e08 100644
--- a/js/id/renderer/hash.js
+++ b/js/id/renderer/hash.js
@@ -45,20 +45,20 @@ iD.Hash = function() {
// do so before any features are loaded. thus wait for the feature to
// be loaded and then select
function willselect(id) {
- map.on('drawn.after-draw-select', function() {
+ map.on('drawn.hash', function() {
var entity = map.history().graph().entity(id);
if (entity === undefined) return;
else selectoff();
controller.enter(iD.modes.Select(entity));
- map.on('drawn.after-draw-select', null);
+ map.on('drawn.hash', null);
});
- controller.on('enter', function() {
+ controller.on('enter.hash', function() {
if (controller.mode.id !== 'browse') selectoff();
});
}
function selectoff() {
- map.on('drawn.after-draw-select', null);
+ map.on('drawn.hash', null);
}
hash.controller = function(_) {
@@ -70,12 +70,12 @@ iD.Hash = function() {
hash.map = function(x) {
if (!arguments.length) return map;
if (map) {
- map.off("move", move);
+ map.on("move.hash", null);
window.removeEventListener("hashchange", hashchange, false);
}
map = x;
if (x) {
- map.on("move", move);
+ map.on("move.hash", move);
window.addEventListener("hashchange", hashchange, false);
if (location.hash) {
var q = iD.util.stringQs(location.hash.substring(1));
diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js
index f5f2a2dd5..28b60c385 100644
--- a/js/id/renderer/map.js
+++ b/js/id/renderer/map.js
@@ -161,7 +161,7 @@ iD.Map = function() {
dispatch.move(map);
surface.attr('data-zoom', ~~map.zoom());
tilegroup.call(background);
- if (map.zoom() >= 16) {
+ if (map.editable()) {
connection.loadTiles(projection);
drawVector(difference);
} else {
@@ -331,6 +331,10 @@ iD.Map = function() {
}
};
+ map.editable = function() {
+ return map.zoom() >= 16;
+ };
+
map.minzoom = function(_) {
if (!arguments.length) return minzoom;
minzoom = _;
diff --git a/js/id/svg/points.js b/js/id/svg/points.js
index 3af99e0da..471bc4b4d 100644
--- a/js/id/svg/points.js
+++ b/js/id/svg/points.js
@@ -33,12 +33,12 @@ iD.svg.Points = function(projection) {
.attr('class', 'node point');
group.append('circle')
- .attr('class', 'stroke')
- .attr({ r: 10 });
+ .attr('r', 13)
+ .attr('class', 'shadow');
group.append('circle')
- .attr('class', 'fill')
- .attr({ r: 10 });
+ .attr('class', 'stroke')
+ .attr('r', 9);
group.append('image')
.attr({ width: 16, height: 16 })
diff --git a/test/spec/renderer/hash.js b/test/spec/renderer/hash.js
index bece2e155..b0e5b567f 100644
--- a/test/spec/renderer/hash.js
+++ b/test/spec/renderer/hash.js
@@ -5,14 +5,12 @@ describe("iD.Hash", function () {
hash = iD.Hash();
map = {
on: function () { return map; },
- off: function () { return map; },
zoom: function () { return arguments.length ? map : 0; },
center: function () { return arguments.length ? map : [0, 0]; },
centerZoom: function () { return arguments.length ? map : [0, 0]; }
};
controller = {
- on: function () { return controller; },
- off: function () { return controller; }
+ on: function () { return controller; }
};
});
@@ -43,15 +41,14 @@ describe("iD.Hash", function () {
it("binds the map's move event", function () {
sinon.spy(map, 'on');
hash.map(map);
- expect(map.on).to.have.been.calledWith('move', sinon.match.instanceOf(Function));
+ expect(map.on).to.have.been.calledWith('move.hash', sinon.match.instanceOf(Function));
});
it("unbinds the map's move event", function () {
sinon.spy(map, 'on');
- sinon.spy(map, 'off');
hash.map(map);
hash.map(null);
- expect(map.off).to.have.been.calledWith('move', map.on.firstCall.args[1]);
+ expect(map.on).to.have.been.calledWith('move.hash', null);
});
});
@@ -77,7 +74,9 @@ describe("iD.Hash", function () {
describe("on map move events", function () {
it("stores the current zoom and coordinates in location.hash", function () {
- sinon.stub(map, 'on').yields();
+ sinon.stub(map, 'on')
+ .withArgs("move.hash", sinon.match.instanceOf(Function))
+ .yields();
hash.map(map);
expect(location.hash).to.equal("#map=0.00/0/0");
});