From 5eabb931ffe9fd6b565de0832984d5123697e55d Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 23 Jan 2013 18:18:48 -0500 Subject: [PATCH 1/4] Namespace events Fixes an issue where cursor sometimes stopped working. --- js/id/id.js | 32 ++++++++++++++++---------------- js/id/renderer/hash.js | 12 ++++++------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/js/id/id.js b/js/id/id.js index 3c33ae912..60c7a37bf 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -37,7 +37,7 @@ 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) { @@ -52,10 +52,10 @@ window.iD = function(container) { 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,7 +204,7 @@ 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()); }); @@ -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)); From 2b799ddd7b55afc7cd127de3011fc05588212a10 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 23 Jan 2013 18:18:58 -0500 Subject: [PATCH 2/4] Improve point rendering --- css/map.css | 22 ++++++++++++++++------ js/id/svg/points.js | 8 ++++---- 2 files changed, 20 insertions(+), 10 deletions(-) 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/svg/points.js b/js/id/svg/points.js index 5862a5cb9..c788a61e9 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 }) From f7a10c1ab68199f3117bd4c887ef02326044c433 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 23 Jan 2013 18:39:18 -0500 Subject: [PATCH 3/4] Fix tests --- test/spec/renderer/hash.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) 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"); }); From 1eedbecee4c2d69d2095a81cdbbbf821aa937577 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 23 Jan 2013 18:59:04 -0500 Subject: [PATCH 4/4] Disable edit modes when zoomed out (fixes #473) --- js/id/id.js | 14 +++++++------- js/id/renderer/map.js | 6 +++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/js/id/id.js b/js/id/id.js index 60c7a37bf..4e13a3cfc 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -40,13 +40,13 @@ window.iD = function(container) { .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); } } @@ -209,9 +209,9 @@ window.iD = function(container) { }); 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(); }) 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 = _;