diff --git a/css/app.css b/css/app.css index 2be1b819b..1a880ad02 100644 --- a/css/app.css +++ b/css/app.css @@ -33,6 +33,7 @@ div, textarea, input, span, ul, li, ol, a, button { a, button, input, textarea { -webkit-tap-highlight-color:rgba(0,0,0,0); -webkit-touch-callout:none; + cursor:url(../img/cursor-pointer.png) 6 1, auto; } h2 { @@ -186,6 +187,7 @@ ul.toggle-list li a { display:block; border-top: 1px solid rgba(0, 0, 0, .5); } +ul.toggle-list li a:hover { background-color: #ececec;} ul.toggle-list .icon { float: left; @@ -253,7 +255,6 @@ button { font-size:12px; display: inline-block; height:40px; - cursor:url(../img/cursor-pointer.png) 6 1, auto; border-radius:4px; -webkit-transition: background 100ms; -moz-transition: background 100ms; @@ -440,7 +441,7 @@ button[disabled] .label { .icon.geolocate { background-position: -360px 0px;} .icon.warning { background-position: -380px 0px;} -.icon.close-modal { background-position: -200px -40px;} +.icon.close-modal { background-position: -200px 0px;} .fillD .icon.avatar { background-position: -320px -20px;} .fillD .icon.nearby { background-position: -340px -20px;} @@ -620,6 +621,7 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} background: rgba(0,0,0,.5); border-radius: 0 0 4px 4px; } + .inspector-inner .add-tag:hover { background: rgba(0,0,0,.8); } @@ -635,25 +637,25 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} position:absolute; } -.map-control button { - width: 40px; +.map-control > button { + width: 30px; background: rgba(0,0,0,.5); border-radius: 0; border-bottom: 1px solid rgba(0, 0, 0, 1); } -.map-control button:hover { +.map-control > button:hover { background: rgba(0, 0, 0, .8); } -.map-control button.active:hover { +.map-control > button.active:hover { background: #6bc641; } .map-overlay { width: 150px; position:absolute; - left:50px; + left:40px; top:0; display: block; border-radius: 4px; @@ -663,7 +665,7 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} .zoombuttons { top:70px; - width: 40px; + width: 30px; } .zoombuttons button.zoom-in { @@ -680,24 +682,102 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} top:190px; } +.nudge-container { + margin-top: 10px; +} + .layerswitcher-control .adjustments button { - opacity:0.5; - height:20px; + height:30px; font-size:10px; - font-weight:normal; padding:0 5px 3px 5px; background: white; - border: 1px solid #ddd; - border-radius: 0; + border:0; + text-transform: uppercase; + font-weight: bold; + } .layerswitcher-control .adjustments button:hover { - opacity: 1; + background:#ececec; +} + +.layerswitcher-control .alignment-toggle { + display: block; + padding-left: 12px; + position: relative; +} + +.layerswitcher-control .alignment-toggle:before { + content: ''; + display: block; + position: absolute; + height: 0; + width: 0; + left: 0; + top: 4px; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-left: 8px solid #7092ff; +} + +.layerswitcher-control .alignment-toggle.expanded:before { + border-top: 8px solid #7092ff; + border-bottom: 0; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + } .layerswitcher-control .nudge { + text-indent: -9999px; + overflow: hidden; width:20px; - margin-right:2px; + border-radius: 0; + margin-right:1px; + position: relative; +} + +.layerswitcher-control .nudge::after { + content: ''; + display: block; + position: absolute; + margin: auto; + left: 0; right: 0; top: 0; bottom: 0; + height: 0; + width: 0; +} + +.layerswitcher-control .nudge.left::after { + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #222; +} + +.layerswitcher-control .nudge.right::after { + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #222; +} + +.layerswitcher-control .nudge.top::after { + border-right: 5px solid transparent; + border-left: 5px solid transparent; + border-bottom: 5px solid #222; +} + +.layerswitcher-control .nudge.bottom::after { + border-right: 5px solid transparent; + border-left: 5px solid transparent; + border-top: 5px solid #222; +} + +.layerswitcher-control .nudge:first-child { + border-radius: 4px 0 0 4px; +} + +.layerswitcher-control .reset { + width: 45px; + border-radius: 0 4px 4px 0; } .opacity-options-wrapper { @@ -711,6 +791,7 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} position: absolute; right: 10px; top: 10px; + border: 1px solid #ddd; } .opacity-options li { @@ -723,7 +804,7 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} .opacity-options li .select-box{ position: absolute; width:20px; - height:20px; + height:18px; z-index: 9999; } @@ -742,7 +823,7 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} background:#222; display:inline-block; width:20px; - height:20px; + height:18px; } /* Geocoder */ @@ -911,10 +992,14 @@ div.typeahead a:first-child { position: absolute; right:5px; top:5px; - border:0; + opacity: .5; + -webkit-transition: opacity 100ms; + -moz-transition: opacity 100ms; + transition: opacity 100ms; } .modal button.close-modal:hover { background-color: transparent; + opacity: 1; } .shaded { @@ -932,7 +1017,7 @@ div.typeahead a:first-child { padding: 20px; } -.modal-section.header { +.modal-section:first-child { border-radius: 4px 4px 0 0; } @@ -940,6 +1025,10 @@ div.typeahead a:first-child { border-radius: 0 0 4px 4px; } +.modal-section:only-child { + border-radius: 4px; +} + .modal-section .buttons { padding-top: 10px; width: 100%; @@ -966,10 +1055,25 @@ div.typeahead a:first-child { text-align: center; } +/* Splash Modal +------------------------------------------------------- */ + +.modal-splash { + width: 33.3333%; + left: 33.3333%; +} + +.logo { + height: 100px; + width: 100px; + margin: 0 auto 20px auto; + background: url(../img/logo.png) 0 0 repeat; +} + /* Commit Modal ------------------------------------------------------- */ -.commit-modal .user-info { +.commit-modal a.user-info { display: inline-block; } @@ -1012,11 +1116,38 @@ div.typeahead a:first-child { .commit-section.modal-section:last-child { padding-bottom: 20px;} -.changeset-list li { +.commit-modal .changeset-list li { + position: relative; border-top:1px solid #ccc; padding:5px 10px; } +.modal-section { + padding: 20px; +} + +.modal-section .buttons { + padding-top: 10px; + width: 100%; +} + +.modal-section img.wiki-image { + max-width: 100%; + max-height: 300px; + display: block; +} + +.modal-flash .content { + box-shadow: none; + border-radius: 4px; + background: #111; + color: #eee; +} + +.modal-flash .close-modal { + display:none; +} + .changeset-list li span.count { font-size:10px; color:#555; @@ -1265,7 +1396,7 @@ a.success-action { span.label {display: none;} /* override hide for save button */ .icon.icon-pre-text { margin-right: 0px;} - .save .label, .apply .label { display: block;} + .save .label, .apply .label, .cancel .label { display: block;} } diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 000000000..6afa01f1b Binary files /dev/null and b/img/logo.png differ diff --git a/img/source/logo.svg b/img/source/logo.svg new file mode 100644 index 000000000..bf3841f90 --- /dev/null +++ b/img/source/logo.svg @@ -0,0 +1,1205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + iD + + + + + + + + + + + + + + + + + + + + + + + + + A javascript OpenStreetMap Editor + + + + + + + + + + + iD + + + + + + + + + + + + + + + + + + + + + + + A Javascript OpenStreetMap Editor + + + + + + + + + + + + + + + + + + + + + + + D3.js + + + + + + iD + + + + + + + + + + + iD + + + diff --git a/img/source/sprite.svg b/img/source/sprite.svg index 01a28e513..6248e28cc 100644 --- a/img/source/sprite.svg +++ b/img/source/sprite.svg @@ -7,6 +7,7 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="420" @@ -38,9 +39,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="4" - inkscape:cx="332.2911" - inkscape:cy="175.13176" + inkscape:zoom="1" + inkscape:cx="581.64693" + inkscape:cy="71.693021" inkscape:document-units="px" inkscape:current-layer="layer12" showgrid="false" @@ -53,10 +54,10 @@ fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" - showguides="true" + showguides="false" inkscape:guide-bbox="true" inkscape:snap-bbox="true" - inkscape:snap-nodes="true"> + inkscape:snap-nodes="false"> + + + + + + + + + + + + + fix misalignment + + + + + RESET diff --git a/img/sprite.png b/img/sprite.png index 5922c06c1..f14b74ac9 100644 Binary files a/img/sprite.png and b/img/sprite.png differ diff --git a/index.html b/index.html index 4fe1bd621..c8ddd7562 100644 --- a/index.html +++ b/index.html @@ -38,7 +38,6 @@ - @@ -68,6 +67,7 @@ + @@ -93,6 +93,7 @@ + diff --git a/js/id/renderer/hash.js b/js/id/behavior/hash.js similarity index 68% rename from js/id/renderer/hash.js rename to js/id/behavior/hash.js index f4204531f..65e748e28 100644 --- a/js/id/renderer/hash.js +++ b/js/id/behavior/hash.js @@ -1,9 +1,6 @@ -iD.Hash = function() { - var hash = { hadHash: false }, - s0 = null, // cached location.hash - lat = 90 - 1e-8, // allowable latitude range - controller, - map; +iD.behavior.Hash = function(controller, map) { + var s0 = null, // cached location.hash + lat = 90 - 1e-8; // allowable latitude range var parser = function(map, s) { var q = iD.util.stringQs(s); @@ -61,32 +58,29 @@ iD.Hash = function() { map.on('drawn.hash', null); } - hash.controller = function(_) { - if (!arguments.length) return controller; - controller = _; - return hash; - }; + function hash() { + map.on('move.hash', move); - hash.map = function(x) { - if (!arguments.length) return map; - if (map) { - map.on("move.hash", null); - window.removeEventListener("hashchange", hashchange, false); - } - map = x; - if (x) { - map.on("move.hash", move); - window.addEventListener("hashchange", hashchange, false); - if (location.hash) { - var q = iD.util.stringQs(location.hash.substring(1)); - if (q.id) { - willselect(q.id); - } - hashchange(); - hash.hadHash = true; + d3.select(window) + .on('hashchange.hash', hashchange); + + if (location.hash) { + var q = iD.util.stringQs(location.hash.substring(1)); + if (q.id) { + willselect(q.id); } + hashchange(); + hash.hadHash = true; } - return hash; + } + + hash.off = function() { + map.on('move.hash', null); + + d3.select(window) + .on('hashchange.hash', null); + + location.hash = ""; }; return hash; diff --git a/js/id/id.js b/js/id/id.js index 69e64e5fe..3e8aabcc3 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -234,7 +234,9 @@ window.iD = function(container) { d3.select(document) .call(keybinding); - var hash = iD.Hash().controller(controller).map(map); + var hash = iD.behavior.Hash(controller, map); + + hash(); if (!hash.hadHash) { map.centerZoom([-77.02271, 38.90085], 20); @@ -245,6 +247,11 @@ window.iD = function(container) { .on('login.editor', connection.authenticate)); controller.enter(iD.modes.Browse()); + + if (!localStorage.sawSplash) { + iD.ui.splash(); + localStorage.sawSplash = true; + } } editor.connection = function(_) { diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index a2c4781ef..cd99de738 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -55,7 +55,6 @@ iD.Map = function() { function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; } function drawVector(difference) { - if (surface.style(transformProp) != 'none') return; var filter, all, extent = map.extent(), graph = history.graph(); @@ -369,24 +368,6 @@ iD.Map = function() { return map; }; - map.hint = function (_) { - if (_ === false) { - d3.select('div.inspector-wrap') - .style('opacity', 0) - .style('display', 'none'); - } else { - d3.select('div.inspector-wrap') - .html('') - .style('display', 'block') - .transition() - .style('opacity', 1); - d3.select('div.inspector-wrap') - .append('div') - .attr('class','inspector-inner') - .text(_); - } - }; - map.editable = function() { return map.zoom() >= 16; }; diff --git a/js/id/ui/layerswitcher.js b/js/id/ui/layerswitcher.js index ea87cb7a9..298c469e0 100644 --- a/js/id/ui/layerswitcher.js +++ b/js/id/ui/layerswitcher.js @@ -17,12 +17,12 @@ iD.ui.layerswitcher = function(map) { }, { name: 'MapBox', source: iD.BackgroundSource.MapBox, - description: 'Satellite and Aerial Imagery', + description: 'Satellite and aerial imagery.', link: 'http://mapbox.com' }, { name: 'Custom', source: iD.BackgroundSource.Custom, - description: 'A custom layer (requires configuration)' + description: 'A custom layer (requires configuration).' }], opacities = [1, 0.5, 0]; @@ -139,10 +139,10 @@ iD.ui.layerswitcher = function(map) { .attr('class', 'adjustments pad1'); var directions = [ - ['←', [-1, 0]], - ['↑', [0, -1]], - ['→', [1, 0]], - ['↓', [0, 1]]]; + ['left', [-1, 0]], + ['top', [0, -1]], + ['right', [1, 0]], + ['bottom', [0, 1]]]; function nudge(d) { map.background.nudge(d[1]); @@ -150,17 +150,16 @@ iD.ui.layerswitcher = function(map) { } adjustments.append('a') - .text('▶ fix misalignment') + .text('Fix misalignment') .attr('href', '#') + .classed('alignment-toggle', true) .classed('expanded', false) .on('click', function() { var exp = d3.select(this).classed('expanded'); if (!exp) { nudge_container.style('display', 'block'); - d3.select(this).text('▼ fix misalignment'); } else { nudge_container.style('display', 'none'); - d3.select(this).text('▶ fix misalignment'); } d3.select(this).classed('expanded', !exp); d3.event.preventDefault(); @@ -174,7 +173,7 @@ iD.ui.layerswitcher = function(map) { nudge_container.selectAll('button') .data(directions).enter() .append('button') - .attr('class', 'nudge') + .attr('class', function(d) { return d[0] + ' nudge'; }) .text(function(d) { return d[0]; }) .on('click', nudge); diff --git a/js/id/ui/splash.js b/js/id/ui/splash.js new file mode 100644 index 000000000..43489fab1 --- /dev/null +++ b/js/id/ui/splash.js @@ -0,0 +1,16 @@ +iD.ui.splash = function() { + var modal = iD.ui.modal(); + + modal.select('.modal') + .attr('class', 'modal-splash modal') + + var introModal = modal.select('.content') + .append('div') + .attr('class', 'modal-section fillL'); + + introModal.append('div').attr('class','logo'); + + introModal.append('div').html("

Welcome to the iD OpenStreetMap editor

This is development version 0.0.0-alpha1. For more information see ideditor.com and report bugs at github.com.systemed/iD.

"); + + return modal; +}; \ No newline at end of file diff --git a/test/index.html b/test/index.html index 370b238fe..b85eb1b56 100644 --- a/test/index.html +++ b/test/index.html @@ -41,7 +41,6 @@ - @@ -66,6 +65,7 @@ + @@ -89,6 +89,7 @@ + @@ -149,6 +150,7 @@ + @@ -163,7 +165,6 @@ - diff --git a/test/index_packaged.html b/test/index_packaged.html index 007392f3b..60979e236 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -44,6 +44,7 @@ + @@ -58,7 +59,6 @@ - diff --git a/test/spec/renderer/hash.js b/test/spec/behavior/hash.js similarity index 51% rename from test/spec/renderer/hash.js rename to test/spec/behavior/hash.js index b0e5b567f..7616bf536 100644 --- a/test/spec/renderer/hash.js +++ b/test/spec/behavior/hash.js @@ -1,60 +1,41 @@ -describe("iD.Hash", function () { +describe("iD.behavior.Hash", function () { var hash, map, controller; beforeEach(function () { - hash = iD.Hash(); map = { on: 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; } }; + + hash = iD.behavior.Hash(controller, map); }); afterEach(function () { - hash.map(null); - location.hash = ""; + hash.off(); }); - describe("#map()", function () { - it("gets and sets map", function () { - expect(hash.controller(controller).map(map)).to.equal(hash); - expect(hash.map()).to.equal(map); - }); + it("sets hadHash if location.hash is present", function () { + location.hash = "map=20.00/38.87952/-77.02405"; + hash(); + expect(hash.hadHash).to.be.true; + }); - it("sets hadHash if location.hash is present", function () { - location.hash = "map=20.00/38.87952/-77.02405"; - hash.map(map); - expect(hash.hadHash).to.be.true; - }); - - it("centerZooms map to requested level", function () { - location.hash = "map=20.00/38.87952/-77.02405"; - sinon.spy(map, 'centerZoom'); - hash.map(map); - expect(map.centerZoom).to.have.been.calledWith([-77.02405,38.87952], 20.0); - }); - - it("binds the map's move event", function () { - sinon.spy(map, 'on'); - hash.map(map); - 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'); - hash.map(map); - hash.map(null); - expect(map.on).to.have.been.calledWith('move.hash', null); - }); + it("centerZooms map to requested level", function () { + location.hash = "map=20.00/38.87952/-77.02405"; + sinon.spy(map, 'centerZoom'); + hash(); + expect(map.centerZoom).to.have.been.calledWith([-77.02405,38.87952], 20.0); }); describe("on window hashchange events", function () { beforeEach(function () { - hash.map(map); + hash(); }); function onhashchange(fn) { @@ -77,7 +58,7 @@ describe("iD.Hash", function () { sinon.stub(map, 'on') .withArgs("move.hash", sinon.match.instanceOf(Function)) .yields(); - hash.map(map); + hash(); expect(location.hash).to.equal("#map=0.00/0/0"); }); });