From: John Firebaugh Date: Tue, 19 Nov 2013 17:42:47 +0000 (-0800) Subject: Merge branch 'master' into redesign X-Git-Tag: live~4615^2~40 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/44629832dd0207d7b0f50b93f1d00b4373dd4d49?hp=0b7deb6375af706f0b7832f359f4b0d082a697e7 Merge branch 'master' into redesign Conflicts: vendor/assets/leaflet/leaflet.hash.js vendor/assets/leaflet/leaflet.js --- diff --git a/Vendorfile b/Vendorfile index 4fc1e5348..2d728ab1e 100644 --- a/Vendorfile +++ b/Vendorfile @@ -31,10 +31,6 @@ folder 'vendor/assets' do from 'git://github.com/jfirebaugh/leaflet-osm.git' do file 'leaflet.osm.js', 'leaflet-osm.js' end - - from 'git://github.com/mlevans/leaflet-hash.git' do - file 'leaflet.hash.js', 'leaflet-hash.js' - end end folder 'ohauth' do @@ -53,4 +49,8 @@ folder 'vendor/assets' do file 'iD.js', 'dist/iD.js' end end + + folder 'javascripts' do + file 'html5shiv.js', 'https://raw.github.com/aFarkas/html5shiv/master/src/html5shiv.js' + end end diff --git a/app/assets/images/about/osm.png b/app/assets/images/about/osm.png new file mode 100644 index 000000000..d5479eea3 Binary files /dev/null and b/app/assets/images/about/osm.png differ diff --git a/app/assets/images/about/sprite.png b/app/assets/images/about/sprite.png new file mode 100644 index 000000000..bc76ee097 Binary files /dev/null and b/app/assets/images/about/sprite.png differ diff --git a/app/assets/images/about/sprite@2x.png b/app/assets/images/about/sprite@2x.png new file mode 100644 index 000000000..65d09d73d Binary files /dev/null and b/app/assets/images/about/sprite@2x.png differ diff --git a/app/assets/images/menu-icon.png b/app/assets/images/menu-icon.png new file mode 100644 index 000000000..da3f92c5d Binary files /dev/null and b/app/assets/images/menu-icon.png differ diff --git a/app/assets/images/searching.gif b/app/assets/images/searching.gif index 5b33f7e54..b1451fd7d 100644 Binary files a/app/assets/images/searching.gif and b/app/assets/images/searching.gif differ diff --git a/app/assets/images/sprite.png b/app/assets/images/sprite.png index 108c38c87..e7490c84c 100644 Binary files a/app/assets/images/sprite.png and b/app/assets/images/sprite.png differ diff --git a/app/assets/images/sprite.svg b/app/assets/images/sprite.svg index 3641c68ab..b61018d13 100644 --- a/app/assets/images/sprite.svg +++ b/app/assets/images/sprite.svg @@ -13,7 +13,7 @@ height="200" id="svg2" version="1.1" - inkscape:version="0.48.4 r9939" + inkscape:version="0.48.2 r9819" inkscape:export-filename="/Users/tmcw/src/openstreetmap-website/app/assets/images/sprite.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -27,17 +27,17 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="2" - inkscape:cx="141.24705" - inkscape:cy="185.81774" + inkscape:zoom="4" + inkscape:cx="210.42032" + inkscape:cy="175.54808" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" - inkscape:window-width="1280" - inkscape:window-height="756" - inkscape:window-x="0" + inkscape:window-width="1436" + inkscape:window-height="856" + inkscape:window-x="4" inkscape:window-y="0" - inkscape:window-maximized="0" + inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" inkscape:object-paths="true" @@ -122,7 +122,7 @@ image/svg+xml - + @@ -257,5 +257,13 @@ d="M 185 6 L 183 8 L 183 12 L 185 14 L 187 14 L 185 12 L 185 8 L 190 8 L 190 11 L 192 11 L 192 8 L 190 6 L 187 6 L 185 6 z M 192 6 L 194 8 L 194 12 L 189 12 L 189 9 L 187 9 L 187 12 L 189 14 L 194 14 L 196 12 L 196 8 L 194 6 L 192 6 z " transform="translate(0,852.36218)" id="path4118" /> + diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 2b8bc5d26..2c186c909 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -9,17 +9,13 @@ //= require osm //= require leaflet //= require leaflet.osm -//= require leaflet.hash +//= require leaflet.map //= require leaflet.zoom -//= require leaflet.extend //= require leaflet.locationfilter //= require i18n/translations //= require oauth //= require piwik -//= require map -//= require sidebar //= require richtext -//= require geocoder //= require querystring var querystring = require('querystring-component'); @@ -28,13 +24,6 @@ function zoomPrecision(zoom) { return Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)); } -function normalBounds(bounds) { - if (bounds instanceof L.LatLngBounds) return bounds; - return new L.LatLngBounds( - new L.LatLng(bounds[0][0], bounds[0][1]), - new L.LatLng(bounds[1][0], bounds[1][1])); -} - function remoteEditHandler(bbox, select) { var loaded = false, query = { @@ -69,31 +58,29 @@ function remoteEditHandler(bbox, select) { * Called as the user scrolls/zooms around to maniplate hrefs of the * view tab and various other links */ -function updatelinks(loc, zoom, layers, bounds, object) { +function updatelinks(loc, zoom, layers, object) { $(".geolink").each(function(index, link) { var href = link.href.split(/[?#]/)[0], - args = querystring.parse(link.search.substring(1)); + args = querystring.parse(link.search.substring(1)), + editlink = $(link).hasClass("editlink"); - if (bounds && $(link).hasClass("bbox")) args.bbox = normalBounds(bounds).toBBoxString(); - if (object && $(link).hasClass("object")) args[object.type] = object.id; + if (object && editlink) args[object.type] = object.id; var query = querystring.stringify(args); if (query) href += '?' + query; - if ($(link).hasClass("llz")) { - args = { - lat: loc.lat, - lon: loc.lon || loc.lng, - zoom: zoom - }; - - if (layers && $(link).hasClass("layers")) { - args.layers = layers; - } + args = { + lat: loc.lat, + lon: loc.lon || loc.lng, + zoom: zoom + }; - href += OSM.formatHash(args); + if (layers && !editlink) { + args.layers = layers; } + href += OSM.formatHash(args); + link.href = href; }); @@ -105,15 +92,6 @@ function updatelinks(loc, zoom, layers, bounds, object) { .toggleClass('disabled', editDisabled) .attr('data-original-title', editDisabled ? I18n.t('javascripts.site.edit_disabled_tooltip') : ''); - - var historyDisabled = zoom < 11; - $('#history_tab') - .tooltip({placement: 'bottom'}) - .off('click.minzoom') - .on('click.minzoom', function() { return !historyDisabled; }) - .toggleClass('disabled', historyDisabled) - .attr('data-original-title', historyDisabled ? - I18n.t('javascripts.site.history_disabled_tooltip') : ''); } // generate a cookie-safe string of map state @@ -135,6 +113,14 @@ function escapeHTML(string) { }); } +function maximiseMap() { + $("#content").addClass("maximised"); +} + +function minimiseMap() { + $("#content").removeClass("maximised"); +} + /* * Forms which have been cached by rails may have the wrong * authenticity token, so patch up any forms with the correct @@ -143,4 +129,13 @@ function escapeHTML(string) { $(document).ready(function () { var auth_token = $("meta[name=csrf-token]").attr("content"); $("form input[name=authenticity_token]").val(auth_token); + + $("#menu-icon").on("click", function(e) { + e.preventDefault(); + $("header").toggleClass("closed"); + }); + + $("nav.primary li a").on("click", function() { + $("header").toggleClass("closed"); + }); }); diff --git a/app/assets/javascripts/browse.js b/app/assets/javascripts/browse.js deleted file mode 100644 index 565af41af..000000000 --- a/app/assets/javascripts/browse.js +++ /dev/null @@ -1,84 +0,0 @@ -$(document).ready(function () { - - var map = L.map("small_map", { - attributionControl: false, - zoomControl: false - }).addLayer(new L.OSM.Mapnik()); - - L.OSM.zoom() - .addTo(map); - - var params = $("#small_map").data(); - var object, bbox; - if (params.type == "changeset") { - bbox = L.latLngBounds([params.minlat, params.minlon], - [params.maxlat, params.maxlon]); - - map.fitBounds(bbox); - - L.rectangle(bbox, { - weight: 2, - color: '#e90', - fillOpacity: 0 - }).addTo(map); - - $("#loading").hide(); - $("#browse_map .secondary-actions").show(); - - $("a[data-editor=remote]").click(function () { - return remoteEditHandler(bbox); - }); - - updatelinks(map.getCenter(), 16, null, [[params.minlat, params.minlon], - [params.maxlat, params.maxlon]]); - } else if (params.type == "note") { - object = {type: params.type, id: params.id}; - - map.setView([params.lat, params.lon], 16); - - L.marker([params.lat, params.lon], { icon: getUserIcon() }).addTo(map); - - bbox = map.getBounds(); - - $("#loading").hide(); - $("#browse_map .secondary-actions").show(); - - $("a[data-editor=remote]").click(function () { - return remoteEditHandler(bbox); - }); - - updatelinks(params, 16, null, bbox, object); - } else { - $("#object_larger_map, #object_edit").hide(); - - object = {type: params.type, id: params.id}; - - if (!params.visible) { - object.version = params.version - 1; - } - - map.addObject(object, { - zoom: true, - callback: function(extent) { - $("#loading").hide(); - - if (extent && extent.isValid()) { - $("#browse_map .secondary-actions").show(); - - $("a.bbox[data-editor=remote]").click(function () { - return remoteEditHandler(extent); - }); - - $("a.object[data-editor=remote]").click(function () { - return remoteEditHandler(extent, params.type + params.id); - }); - - $("#object_larger_map").show(); - $("#object_edit").show(); - - updatelinks(map.getCenter(), 16, null, extent, object); - } - } - }); - } -}); diff --git a/app/assets/javascripts/changeset.js b/app/assets/javascripts/changeset.js deleted file mode 100644 index d9c09bab4..000000000 --- a/app/assets/javascripts/changeset.js +++ /dev/null @@ -1,73 +0,0 @@ -$(document).ready(function () { - var changesets = [], rects = {}; - - var map = L.map("changeset_list_map", { - attributionControl: false, - zoomControl: false - }).addLayer(new L.OSM.Mapnik()); - - L.OSM.zoom() - .addTo(map); - - var group = L.featureGroup().addTo(map); - - $("[data-changeset]").each(function () { - var changeset = $(this).data('changeset'); - if (changeset.bbox) { - changeset.bounds = L.latLngBounds([changeset.bbox.minlat, changeset.bbox.minlon], - [changeset.bbox.maxlat, changeset.bbox.maxlon]); - changesets.push(changeset); - } - }); - - changesets.sort(function (a, b) { - return b.bounds.getSize() - a.bounds.getSize(); - }); - - for (var i = 0; i < changesets.length; ++i) { - var changeset = changesets[i], - rect = L.rectangle(changeset.bounds, - {weight: 2, color: "#ee9900", fillColor: "#ffff55", fillOpacity: 0}); - rect.id = changeset.id; - rects[changeset.id] = rect; - rect.addTo(group); - } - - function highlightChangeset(id) { - rects[id].setStyle({fillOpacity: 0.5}); - $("#changeset_" + id).addClass("selected"); - } - - function unHighlightChangeset(id) { - rects[id].setStyle({fillOpacity: 0}); - $("#changeset_" + id).removeClass("selected"); - } - - group.on({ - mouseover: function (e) { - highlightChangeset(e.layer.id); - }, - mouseout: function (e) { - unHighlightChangeset(e.layer.id); - } - }); - - $("[data-changeset]").on({ - mouseover: function () { - highlightChangeset($(this).data("changeset").id); - }, - mouseout: function () { - unHighlightChangeset($(this).data("changeset").id); - } - }); - - $(window).scroll(function() { - if ($(window).scrollTop() > $('.content-heading').outerHeight() + $('#top-bar').outerHeight() ) { - $('#changeset_list_map_wrapper').addClass('scrolled'); - } else { - $('#changeset_list_map_wrapper').removeClass('scrolled'); - } - }); - - map.fitBounds(OSM.mapParams().bounds || group.getBounds()); -}); diff --git a/app/assets/javascripts/diary_entry.js b/app/assets/javascripts/diary_entry.js index 1aa728ea0..5a19cb4d6 100644 --- a/app/assets/javascripts/diary_entry.js +++ b/app/assets/javascripts/diary_entry.js @@ -21,13 +21,14 @@ $(document).ready(function () { var params = $("#map").data(); var centre = [params.lat, params.lon]; + var position = $('html').attr('dir') === 'rtl' ? 'topleft' : 'topright'; map = L.map("map", { attributionControl: false, zoomControl: false }).addLayer(new L.OSM.Mapnik()); - L.OSM.zoom() + L.OSM.zoom({position: position}) .addTo(map); map.setView(centre, params.zoom); diff --git a/app/assets/javascripts/edit.js b/app/assets/javascripts/edit.js deleted file mode 100644 index 7de65190e..000000000 --- a/app/assets/javascripts/edit.js +++ /dev/null @@ -1,31 +0,0 @@ -function maximiseMap() { - $("#content").addClass("maximised"); -} - -function minimiseMap() { - $("#content").removeClass("maximised"); -} - -$(document).ready(function () { - $("#search_form").submit(function (e) { - e.preventDefault(); - - $("#sidebar_title").html(I18n.t('site.sidebar.search_results')); - $("#sidebar_content").load($(this).attr("action"), { - query: $("#query").val() - }, openSidebar); - }); - - $("#describe_location").click(function (e) { - e.preventDefault(); - - var mapParams = OSM.mapParams(); - - $("#sidebar_title").html(I18n.t('site.sidebar.search_results')); - $("#sidebar_content").load($(this).attr("href"), { - lat: mapParams.lat, - lon: mapParams.lon, - zoom: mapParams.zoom - }, openSidebar); - }); -}); diff --git a/app/assets/javascripts/geocoder.js b/app/assets/javascripts/geocoder.js deleted file mode 100644 index 0809bef78..000000000 --- a/app/assets/javascripts/geocoder.js +++ /dev/null @@ -1,14 +0,0 @@ -$(document).ready(function () { - $("body").on("click", ".search_more a", function (e) { - e.preventDefault(); - - var div = $(this).parents(".search_more"); - - div.find(".search_results_entry").hide(); - div.find(".search_searching").show(); - - $.get($(this).attr("href"), function(data) { - div.replaceWith(data); - }); - }); -}); diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index d84b8ae24..59e231381 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -9,75 +9,61 @@ //= require index/browse //= require index/export //= require index/notes +//= require index/history +//= require index/note +//= require index/new_note +//= require router + +(function() { + var loaderTimeout; + + OSM.loadSidebarContent = function(path, callback) { + clearTimeout(loaderTimeout); + + loaderTimeout = setTimeout(function() { + $('#sidebar_loader').show(); + }, 200); + + // IE<10 doesn't respect Vary: X-Requested-With header, so + // prevent caching the XHR response as a full-page URL. + if (path.indexOf('?') >= 0) { + path += '&xhr=1' + } else { + path += '?xhr=1' + } + + $('#sidebar_content') + .empty(); + + $.ajax({ + url: path, + dataType: "html", + complete: function(xhr) { + clearTimeout(loaderTimeout); + $('#sidebar_loader').hide(); + $('#sidebar_content').html(xhr.responseText); + if (xhr.getResponseHeader('X-Page-Title')) { + document.title = xhr.getResponseHeader('X-Page-Title'); + } + if (callback) { + callback(); + } + } + }); + }; +})(); $(document).ready(function () { var params = OSM.mapParams(); - var map = L.map("map", { + var map = new L.OSM.Map("map", { zoomControl: false, layerControl: false }); map.attributionControl.setPrefix(''); - map.hash = L.hash(map); - - var copyright = I18n.t('javascripts.map.copyright', {copyright_url: '/copyright'}); - - var layers = [ - new L.OSM.Mapnik({ - attribution: copyright, - code: "M", - keyid: "mapnik", - name: I18n.t("javascripts.map.base.standard") - }), - new L.OSM.CycleMap({ - attribution: copyright + ". Tiles courtesy of Andy Allan", - code: "C", - keyid: "cyclemap", - name: I18n.t("javascripts.map.base.cycle_map") - }), - new L.OSM.TransportMap({ - attribution: copyright + ". Tiles courtesy of Andy Allan", - code: "T", - keyid: "transportmap", - name: I18n.t("javascripts.map.base.transport_map") - }), - new L.OSM.MapQuestOpen({ - attribution: copyright + ". Tiles courtesy of MapQuest ", - code: "Q", - keyid: "mapquest", - name: I18n.t("javascripts.map.base.mapquest") - }), - new L.OSM.HOT({ - attribution: copyright + ". Tiles courtesy of Humanitarian OpenStreetMap Team", - code: "H", - keyid: "hot", - name: I18n.t("javascripts.map.base.hot") - }) - ]; - - function updateLayers(params) { - var layerParam = params.layers || "M"; - var layersAdded = ""; - - for (var i = layers.length - 1; i >= 0; i--) { - if (layerParam.indexOf(layers[i].options.code) >= 0) { - map.addLayer(layers[i]); - layersAdded = layersAdded + layers[i].options.code; - } else if (i == 0 && layersAdded == "") { - map.addLayer(layers[i]); - } else { - map.removeLayer(layers[i]); - } - } - } - - updateLayers(params); - - $(window).on("hashchange", function () { - updateLayers(OSM.mapParams()); - }); + map.updateLayers(params.layers); map.on("baselayerchange", function (e) { if (map.getZoom() > e.layer.options.maxZoom) { @@ -85,16 +71,6 @@ $(document).ready(function () { } }); - map.noteLayer = new L.LayerGroup(); - map.noteLayer.options = {code: 'N'}; - - map.dataLayer = new L.OSM.DataLayer(null); - map.dataLayer.options.code = 'D'; - - $("#sidebar").on("opened closed", function () { - map.invalidateSize(); - }); - var position = $('html').attr('dir') === 'rtl' ? 'topleft' : 'topright'; L.OSM.zoom({position: position}) @@ -113,7 +89,7 @@ $(document).ready(function () { L.OSM.layers({ position: position, - layers: layers, + layers: map.baseLayers, sidebar: sidebar }).addTo(map); @@ -136,9 +112,31 @@ $(document).ready(function () { L.control.scale() .addTo(map); + if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') { + initializeNotes(map); + if (params.layers.indexOf(map.noteLayer.options.code) >= 0) { + map.addLayer(map.noteLayer); + } + + initializeBrowse(map); + if (params.layers.indexOf(map.dataLayer.options.code) >= 0) { + map.addLayer(map.dataLayer); + } + } + $('.leaflet-control .control-button').tooltip({placement: 'left', container: 'body'}); - map.on('moveend layeradd layerremove', updateLocation); + map.on('moveend layeradd layerremove', function() { + updatelinks( + map.getCenter().wrap(), + map.getZoom(), + map.getLayersCode(), + map._object); + + var expiry = new Date(); + expiry.setYear(expiry.getFullYear() + 10); + $.cookie("_osm_location", cookieContent(map), { expires: expiry }); + }); if (OSM.PIWIK) { map.on('layeradd', function (e) { @@ -152,32 +150,18 @@ $(document).ready(function () { }); } - var marker = L.marker([0, 0], {icon: getUserIcon()}); - - if (!params.object_zoom) { - if (params.bounds) { - map.fitBounds(params.bounds); - } else { - map.setView([params.lat, params.lon], params.zoom); - } + if (params.bounds) { + map.fitBounds(params.bounds); + } else { + map.setView([params.lat, params.lon], params.zoom); } - if (params.box) { - L.rectangle(params.box, { - weight: 2, - color: '#e90', - fillOpacity: 0 - }).addTo(map); - } + var marker = L.marker([0, 0], {icon: getUserIcon()}); if (params.marker) { marker.setLatLng([params.mlat, params.mlon]).addTo(map); } - if (params.object) { - map.addObject(params.object, { zoom: params.object_zoom }); - } - $("#homeanchor").on("click", function(e) { e.preventDefault(); @@ -211,22 +195,95 @@ $(document).ready(function () { }); } - initializeSearch(map); - initializeExport(map); - initializeBrowse(map, params); - initializeNotes(map, params); -}); + OSM.Index = function(map) { + var page = {}; + + page.pushstate = function(path) { + $("#content").addClass("overlay-sidebar"); + map.invalidateSize({pan: false}) + .panBy([-350, 0], {animate: false}); + OSM.loadSidebarContent(path); + page.load(); + }; + + page.load = function() { + return map.getState(); + }; + + page.popstate = function(path) { + $("#content").addClass("overlay-sidebar"); + map.invalidateSize({pan: false}); + OSM.loadSidebarContent(path); + }; + + page.unload = function() { + map.panBy([350, 0], {animate: false}); + $("#content").removeClass("overlay-sidebar"); + map.invalidateSize({pan: false}); + }; + + return page; + }; + + OSM.Browse = function(map) { + var page = {}; + + page.pushstate = page.popstate = function(path, type, id) { + OSM.loadSidebarContent(path, function() { + page.load(path, type, id); + }); + }; + + page.load = function(path, type, id) { + map.addObject({type: type, id: parseInt(id)}); + }; + + page.unload = function() { + map.removeObject(); + }; + + return page; + }; + + var history = OSM.History(map), + note = OSM.Note(map); + + OSM.route = OSM.Router(map, { + "/": OSM.Index(map), + "/search": OSM.Search(map), + "/export": OSM.Export(map), + "/history": history, + "/new_note": OSM.NewNote(map), + "/user/:display_name/edits": history, + "/browse/friends": history, + "/browse/nearby": history, + "/browse/note/:id": note, + "/browse/:type/:id(/history)": OSM.Browse(map) + }); -function updateLocation() { - updatelinks(this.getCenter().wrap(), - this.getZoom(), - this.getLayersCode(), - this.getBounds().wrap()); + OSM.route.load(); - var expiry = new Date(); - expiry.setYear(expiry.getFullYear() + 10); - $.cookie("_osm_location", cookieContent(this), { expires: expiry }); + $(document).on("click", "a", function(e) { + if (e.isDefaultPrevented() || e.isPropagationStopped()) return; + if (this.host === window.location.host && OSM.route(this.pathname + this.search + this.hash)) e.preventDefault(); + }); - // Trigger hash update on layer changes. - this.hash.onMapMove(); -} + $(".search_form").on("submit", function(e) { + e.preventDefault(); + $("header").addClass("closed"); + var query = $(this).find("input[name=query]").val(); + if (query) { + OSM.route("/search?query=" + encodeURIComponent(query) + OSM.formatHash(map)); + } else { + OSM.route("/" + OSM.formatHash(map)); + } + }); + + $(".describe_location").on("click", function(e) { + e.preventDefault(); + var precision = zoomPrecision(map.getZoom()); + OSM.route("/search?query=" + encodeURIComponent( + map.getCenter().lat.toFixed(precision) + "," + + map.getCenter().lng.toFixed(precision))); + }); +}); diff --git a/app/assets/javascripts/index/browse.js b/app/assets/javascripts/index/browse.js index d8de69974..752c84fec 100644 --- a/app/assets/javascripts/index/browse.js +++ b/app/assets/javascripts/index/browse.js @@ -1,15 +1,6 @@ -//= require templates/browse/feature -//= require templates/browse/feature_list -//= require templates/browse/feature_history - -function initializeBrowse(map, params) { +function initializeBrowse(map) { var browseBounds; - var layersById; var selectedLayer; - var browseObjectList; - var areasHidden = false; - var locationFilter; - var dataLayer = map.dataLayer; dataLayer.setStyle({ @@ -28,7 +19,7 @@ function initializeBrowse(map, params) { }); dataLayer.isWayArea = function () { - return !areasHidden && L.OSM.DataLayer.prototype.isWayArea.apply(this, arguments); + return false; }; dataLayer.on("click", function (e) { @@ -37,127 +28,48 @@ function initializeBrowse(map, params) { map.on('layeradd', function (e) { if (e.layer === dataLayer) { - $.ajax({ url: "/browse/start", success: function (sidebarHtml) { - startBrowse(sidebarHtml); - }}); + map.on("moveend", updateData); + updateData(); } }); map.on('layerremove', function (e) { if (e.layer === dataLayer) { - closeSidebar(); + map.off("moveend", updateData); + $('#browse_status').empty(); } }); - if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') { - if (params.layers.indexOf(dataLayer.options.code) >= 0) { - map.addLayer(dataLayer); - } - } - - function startBrowse(sidebarHtml) { - locationFilter = new L.LocationFilter({ - enableButton: false, - adjustButton: false - }).addTo(map); - - locationFilter.on("change", getData); - - $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title')); - $("#sidebar_content").html(sidebarHtml); - - openSidebar(); - - if (browseObjectList) loadObjectList(); - - map.on("moveend", updateData); - updateData(); - - $("#browse_filter_toggle").click(toggleFilter); - - $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas')); - $("#browse_hide_areas_box").click(toggleAreas); - - $("#sidebar").one("closed", function () { - map.removeLayer(dataLayer); - map.removeLayer(locationFilter); - map.off("moveend", updateData); - locationFilter.off("change", getData); - }); - } - function updateData() { - if (!locationFilter.isEnabled()) { - if (map.getZoom() >= 15) { - var bounds = map.getBounds(); - if (!browseBounds || !browseBounds.contains(bounds)) { - browseBounds = bounds; - getData(); - } - } else { - setStatus(I18n.t('browse.start_rjs.zoom_or_select')); - } - } - } - - function toggleFilter() { - if (locationFilter.isEnabled()) { - $("#browse_filter_toggle").html(I18n.t('browse.start_rjs.manually_select')); - locationFilter.disable(); - } else { - $("#browse_filter_toggle").html(I18n.t('browse.start_rjs.view_data')); - locationFilter.setBounds(map.getBounds().pad(-0.2)); - locationFilter.enable(); - } - - getData(); - } - - function toggleAreas(e) { - e.preventDefault(); - - if (areasHidden) { - $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas')); - areasHidden = false; - } else { - $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas')); - areasHidden = true; - } - - getData(); + var bounds = map.getBounds(); + getData(!browseBounds || !browseBounds.contains(bounds)); + browseBounds = bounds; } function displayFeatureWarning(count, limit, callback) { - clearStatus(); - - var div = document.createElement("div"); - - var p = document.createElement("p"); - p.appendChild(document.createTextNode(I18n.t("browse.start_rjs.loaded_an_area_with_num_features", { num_features: count, max_features: limit }))); - div.appendChild(p); - - var input = document.createElement("input"); - input.type = "submit"; - input.value = I18n.t('browse.start_rjs.load_data'); - input.onclick = callback; - div.appendChild(input); - - $("#browse_content").html(""); - $("#browse_content").append(div); + $('#browse_status').html( + $("

") + .text(I18n.t("browse.start_rjs.loaded_an_area_with_num_features", { num_features: count, max_features: limit })) + .append( + $("") + .val(I18n.t('browse.start_rjs.load_data')) + .click(callback))); } var dataLoader; - function getData() { - var bounds = locationFilter.isEnabled() ? locationFilter.getBounds() : map.getBounds(); + function getData(inPrevious) { + var bounds = map.getBounds(); var size = bounds.getSize(); if (size > OSM.MAX_REQUEST_AREA) { - setStatus(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size })); + $('#browse_status').html( + $("

") + .text(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size.toFixed(2) }))); return; } - setStatus(I18n.t('browse.start_rjs.loading')); + if (inPrevious) return; var url = "/api/" + OSM.API_VERSION + "/map?bbox=" + bounds.toBBoxString(); @@ -181,35 +93,14 @@ function initializeBrowse(map, params) { dataLoader = $.ajax({ url: url, success: function (xml) { - clearStatus(); - - $("#browse_content").empty(); dataLayer.clearLayers(); selectedLayer = null; var features = dataLayer.buildFeatures(xml); function addFeatures() { + $('#browse_status').empty(); dataLayer.addData(features); - - layersById = {}; - - dataLayer.eachLayer(function (layer) { - var feature = layer.feature; - layersById[feature.id] = layer; - $.extend(feature, { - typeName: featureTypeName(feature), - url: "/browse/" + feature.type + "/" + feature.id, - name: featureName(feature) - }); - }); - - browseObjectList = $(JST["templates/browse/feature_list"]({ - features: features, - url: url - }))[0]; - - loadObjectList(); } if (features.length < maxFeatures) { @@ -223,25 +114,6 @@ function initializeBrowse(map, params) { }); } - function viewFeatureLink() { - var layer = layersById[$(this).data("feature-id")]; - - onSelect(layer); - - if (locationFilter.isEnabled()) { - map.panTo(layer.getBounds().getCenter()); - } - - return false; - } - - function loadObjectList() { - $("#browse_content").html(browseObjectList); - $("#browse_content").find("a[data-feature-id]").click(viewFeatureLink); - - return false; - } - function onSelect(layer) { // Unselect previously selected feature if (selectedLayer) { @@ -252,91 +124,9 @@ function initializeBrowse(map, params) { layer.originalStyle = layer.options; layer.setStyle({color: '#0000ff', weight: 8}); - // If the current object is the list, don't innerHTML="", since that could clear it. - if ($("#browse_content").firstChild == browseObjectList) { - $("#browse_content").removeChild(browseObjectList); - } else { - $("#browse_content").empty(); - } - - var feature = layer.feature; - - $("#browse_content").html(JST["templates/browse/feature"]({ - name: featureNameSelect(feature), - url: "/browse/" + feature.type + "/" + feature.id, - attributes: feature.tags - })); - - $("#browse_content").find("a.browse_show_list").click(loadObjectList); - $("#browse_content").find("a.browse_show_history").click(loadHistory); + OSM.route('/browse/' + layer.feature.type + '/' + layer.feature.id); // Stash the currently drawn feature selectedLayer = layer; } - - function loadHistory() { - $(this).attr("href", "").text(I18n.t('browse.start_rjs.wait')); - - var feature = selectedLayer.feature; - - $.ajax({ - url: "/api/" + OSM.API_VERSION + "/" + feature.type + "/" + feature.id + "/history", - success: function (xml) { - if (selectedLayer.feature != feature || $("#browse_content").firstChild == browseObjectList) { - return; - } - - $(this).remove(); - - var history = []; - var nodes = xml.getElementsByTagName(feature.type); - for (var i = nodes.length - 1; i >= 0; i--) { - history.push({ - user: nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'), - timestamp: nodes[i].getAttribute("timestamp") - }); - } - - $("#browse_content").append(JST["templates/browse/feature_history"]({ - name: featureNameHistory(feature), - url: "/browse/" + feature.type + "/" + feature.id, - history: history - })); - }.bind(this) - }); - - return false; - } - - function featureTypeName(feature) { - return I18n.t('browse.start_rjs.object_list.type.' + feature.type); - } - - function featureName(feature) { - return feature.tags['name:' + $('html').attr('lang')] || - feature.tags.name || - feature.id; - } - - function featureNameSelect(feature) { - return feature.tags['name:' + $('html').attr('lang')] || - feature.tags.name || - I18n.t("browse.start_rjs.object_list.selected.type." + feature.type, { id: feature.id }); - } - - function featureNameHistory(feature) { - return feature.tags['name:' + $('html').attr('lang')] || - feature.tags.name || - I18n.t("browse.start_rjs.object_list.history.type." + feature.type, { id: feature.id }); - } - - function setStatus(status) { - $("#browse_status").html(status); - $("#browse_status").show(); - } - - function clearStatus() { - $("#browse_status").html(""); - $("#browse_status").hide(); - } } diff --git a/app/assets/javascripts/index/export.js b/app/assets/javascripts/index/export.js index aec35ed2b..053f5169f 100644 --- a/app/assets/javascripts/index/export.js +++ b/app/assets/javascripts/index/export.js @@ -1,73 +1,78 @@ -function initializeExport(map) { - if (window.location.pathname == "/export") { - startExport(); +OSM.Export = function(map) { + var page = {}; + + var locationFilter = new L.LocationFilter({ + enableButton: false, + adjustButton: false + }).on("change", update); + + function getBounds() { + return L.latLngBounds( + L.latLng($("#minlat").val(), $("#minlon").val()), + L.latLng($("#maxlat").val(), $("#maxlon").val())); } - function startExport() { - var locationFilter = new L.LocationFilter({ - enableButton: false, - adjustButton: false - }).addTo(map); - - locationFilter.on("change", update); - - map.on("moveend", update); - - $("#sidebar_title").html(I18n.t('export.start_rjs.export')); - - $("#maxlat,#minlon,#maxlon,#minlat").change(boundsChanged); + function boundsChanged() { + var bounds = getBounds(); + map.fitBounds(bounds); + locationFilter.setBounds(bounds); + locationFilter.enable(); + validateControls(); + } - $("#drag_box").click(enableFilter); + function enableFilter(e) { + e.preventDefault(); - openSidebar(); + $("#drag_box").hide(); - setBounds(map.getBounds()); + locationFilter.setBounds(map.getBounds().pad(-0.2)); + locationFilter.enable(); + validateControls(); + } - $("#sidebar").one("closed", function () { - map.removeLayer(locationFilter); - map.off("moveend", update); - locationFilter.off("change", update); - }); + function update() { + setBounds(locationFilter.isEnabled() ? locationFilter.getBounds() : map.getBounds()); + validateControls(); + } - function getBounds() { - return L.latLngBounds(L.latLng($("#minlat").val(), $("#minlon").val()), - L.latLng($("#maxlat").val(), $("#maxlon").val())); - } + function setBounds(bounds) { + var precision = zoomPrecision(map.getZoom()); + $("#minlon").val(bounds.getWest().toFixed(precision)); + $("#minlat").val(bounds.getSouth().toFixed(precision)); + $("#maxlon").val(bounds.getEast().toFixed(precision)); + $("#maxlat").val(bounds.getNorth().toFixed(precision)); + } - function boundsChanged() { - var bounds = getBounds(); + function validateControls() { + $("#export_osm_too_large").toggle(getBounds().getSize() > OSM.MAX_REQUEST_AREA); + $("#export_commit").toggle(getBounds().getSize() < OSM.MAX_REQUEST_AREA); + } - map.fitBounds(bounds); - locationFilter.setBounds(bounds); + page.pushstate = page.popstate = function(path) { + $("#export_tab").addClass("current"); + OSM.loadSidebarContent(path, page.load); + }; - enableFilter(); - validateControls(); - } + page.load = function() { + map + .addLayer(locationFilter) + .on("moveend", update); - function enableFilter() { - if (!locationFilter.getBounds().isValid()) { - locationFilter.setBounds(map.getBounds().pad(-0.2)); - } + $("#maxlat, #minlon, #maxlon, #minlat").change(boundsChanged); + $("#drag_box").click(enableFilter); + $("#sidebar_content .close").on("click", page.minimizeSidebar); - $("#drag_box").hide(); - locationFilter.enable(); - } + update(); + return map.getState(); + }; - function update() { - setBounds(locationFilter.isEnabled() ? locationFilter.getBounds() : map.getBounds()); - validateControls(); - } + page.unload = function() { + map + .removeLayer(locationFilter) + .off("moveend", update); - function setBounds(bounds) { - var precision = zoomPrecision(map.getZoom()); - $("#minlon").val(bounds.getWest().toFixed(precision)); - $("#minlat").val(bounds.getSouth().toFixed(precision)); - $("#maxlon").val(bounds.getEast().toFixed(precision)); - $("#maxlat").val(bounds.getNorth().toFixed(precision)); - } + $("#export_tab").removeClass("current"); + }; - function validateControls() { - $("#export_osm_too_large").toggle(getBounds().getSize() > OSM.MAX_REQUEST_AREA); - } - } -} + return page; +}; diff --git a/app/assets/javascripts/index/history.js b/app/assets/javascripts/index/history.js new file mode 100644 index 000000000..75b02ec07 --- /dev/null +++ b/app/assets/javascripts/index/history.js @@ -0,0 +1,123 @@ +OSM.History = function(map) { + var page = {}; + + $("#sidebar_content") + .on("click", ".changeset_more a", loadMore) + .on("mouseover", "[data-changeset]", function () { + highlightChangeset($(this).data("changeset").id); + }) + .on("mouseout", "[data-changeset]", function () { + unHighlightChangeset($(this).data("changeset").id); + }) + .on("click", "[data-changeset]", function () { + clickChangeset($(this).data("changeset").id); + }); + + var group = L.featureGroup() + .on("mouseover", function (e) { + highlightChangeset(e.layer.id); + }) + .on("mouseout", function (e) { + unHighlightChangeset(e.layer.id); + }) + .on("click", function (e) { + clickChangeset(e.layer.id); + }); + + group.getLayerId = function(layer) { + return layer.id; + }; + + function highlightChangeset(id) { + group.getLayer(id).setStyle({fillOpacity: 0.3}); + $("#changeset_" + id).addClass("selected"); + } + + function unHighlightChangeset(id) { + group.getLayer(id).setStyle({fillOpacity: 0}); + $("#changeset_" + id).removeClass("selected"); + } + + function clickChangeset(id) { + OSM.route($("#changeset_" + id).find(".changeset_id").attr("href")); + } + + function loadData() { + $.ajax({ + url: window.location.pathname, + method: "GET", + data: {bbox: map.getBounds().wrap().toBBoxString()}, + success: function(html, status, xhr) { + $('#sidebar_content .changesets').html(html); + updateMap(); + } + }); + } + + function loadMore(e) { + e.preventDefault(); + e.stopPropagation(); + + var div = $(this).parents(".changeset_more"); + + $(this).hide(); + div.find(".loader").show(); + + $.get($(this).attr("href"), function(data) { + div.replaceWith(data); + updateMap(); + }); + } + + function updateMap() { + group.clearLayers(); + + var changesets = []; + + $("[data-changeset]").each(function () { + var changeset = $(this).data('changeset'); + if (changeset.bbox) { + changeset.bounds = L.latLngBounds( + [changeset.bbox.minlat, changeset.bbox.minlon], + [changeset.bbox.maxlat, changeset.bbox.maxlon]); + changesets.push(changeset); + } + }); + + changesets.sort(function (a, b) { + return b.bounds.getSize() - a.bounds.getSize(); + }); + + for (var i = 0; i < changesets.length; ++i) { + var changeset = changesets[i], + rect = L.rectangle(changeset.bounds, + {weight: 2, color: "#FF9500", opacity: 1, fillColor: "#FFFFBF", fillOpacity: 0}); + rect.id = changeset.id; + rect.addTo(group); + } + } + + page.pushstate = page.popstate = function(path) { + $("#history_tab").addClass("current"); + OSM.loadSidebarContent(path, page.load); + }; + + page.load = function() { + map + .on("moveend", loadData) + .addLayer(group); + + loadData(); + }; + + page.unload = function() { + map + .off("moveend", loadData) + .removeLayer(group); + + group.clearLayers(); + $("#history_tab").removeClass("current"); + }; + + return page; +}; diff --git a/app/assets/javascripts/index/new_note.js.erb b/app/assets/javascripts/index/new_note.js.erb new file mode 100644 index 000000000..29977cd57 --- /dev/null +++ b/app/assets/javascripts/index/new_note.js.erb @@ -0,0 +1,163 @@ +OSM.NewNote = function(map) { + var noteLayer = map.noteLayer, + content = $('#sidebar_content'), + page = {}, + addNoteButton = $(".control-note .control-button"), + newNote, + halo; + + var noteIcons = { + "new": L.icon({ + iconUrl: "<%= image_path 'new_note_marker.png' %>", + iconSize: [25, 40], + iconAnchor: [12, 40] + }), + "open": L.icon({ + iconUrl: "<%= image_path 'open_note_marker.png' %>", + iconSize: [25, 40], + iconAnchor: [12, 40] + }), + "closed": L.icon({ + iconUrl: "<%= image_path 'closed_note_marker.png' %>", + iconSize: [25, 40], + iconAnchor: [12, 40] + }) + }; + + addNoteButton.on("click", function (e) { + e.preventDefault(); + e.stopPropagation(); + + if ($(this).hasClass('disabled')) return; + + OSM.route('/new_note'); + }); + + function createNote(marker, form, url) { + var location = marker.getLatLng().wrap(); + + marker.options.draggable = false; + marker.dragging.disable(); + + $(form).find("input[type=submit]").prop("disabled", true); + + $.ajax({ + url: url, + type: "POST", + oauth: true, + data: { + lat: location.lat, + lon: location.lng, + text: $(form.text).val() + }, + success: function (feature) { + noteCreated(feature, marker); + } + }); + + function noteCreated(feature, marker) { + content.find("textarea").val(""); + updateMarker(feature); + newNote = null; + noteLayer.removeLayer(marker); + addNoteButton.removeClass("active"); + OSM.route('/browse/note/' + feature.properties.id); + } + } + + function updateMarker(feature) { + var marker = L.marker(feature.geometry.coordinates.reverse(), { + icon: noteIcons[feature.properties.status], + opacity: 0.9, + clickable: true + }); + marker.id = feature.properties.id; + marker.addTo(noteLayer); + return marker; + } + + page.pushstate = page.popstate = function (path) { + OSM.loadSidebarContent(path, page.load); + }; + + function newHalo(loc, a) { + if (a == 'dragstart' && map.hasLayer(halo)) { + map.removeLayer(halo); + } else { + if (map.hasLayer(halo)) map.removeLayer(halo); + + halo = L.circleMarker(loc, { + weight: 2.5, + radius: 20, + fillOpacity: 0.5, + color: "#FF6200" + }); + + map.addLayer(halo); + } + } + + page.load = function () { + if (addNoteButton.hasClass("disabled")) return; + if (addNoteButton.hasClass("active")) return; + + addNoteButton.addClass("active"); + + map.addLayer(noteLayer); + + var mapSize = map.getSize(); + var markerPosition; + + if (mapSize.y > 800) { + markerPosition = [mapSize.x / 2, mapSize.y / 2]; + } else if (mapSize.y > 400) { + markerPosition = [mapSize.x / 2, 400]; + } else { + markerPosition = [mapSize.x / 2, mapSize.y]; + } + + newNote = L.marker(map.containerPointToLatLng(markerPosition), { + icon: noteIcons["new"], + opacity: 0.9, + draggable: true + }); + + newNote.on("dragstart dragend", function(a) { + newHalo(newNote.getLatLng(), a.type); + }); + + newNote.addTo(noteLayer); + newHalo(newNote.getLatLng()); + + newNote.on("remove", function () { + addNoteButton.removeClass("active"); + }).on("dragstart",function () { + $(newNote).stopTime("removenote"); + }).on("dragend", function () { + content.find("textarea").focus(); + }); + + content.find("textarea") + .on("input", disableWhenBlank) + .focus(); + + function disableWhenBlank(e) { + $(e.target.form.add).prop("disabled", $(e.target).val() === ""); + } + + content.find('input[type=submit]').on('click', function (e) { + e.preventDefault(); + createNote(newNote, e.target.form, '/api/0.6/notes.json'); + }); + + return map.getState(); + }; + + page.unload = function () { + noteLayer.removeLayer(newNote); + map.removeLayer(halo); + addNoteButton.removeClass("active"); + }; + + return page; +}; diff --git a/app/assets/javascripts/index/note.js.erb b/app/assets/javascripts/index/note.js.erb new file mode 100644 index 000000000..09044bf0e --- /dev/null +++ b/app/assets/javascripts/index/note.js.erb @@ -0,0 +1,98 @@ +OSM.Note = function (map) { + var noteLayer = map.noteLayer, + content = $('#sidebar_content'), + page = {}, + noteState = map.hasLayer(noteLayer), + halo; + + var noteIcons = { + "new": L.icon({ + iconUrl: "<%= image_path('new_note_marker.png') %>", + iconSize: [25, 40], + iconAnchor: [12, 40] + }), + "open": L.icon({ + iconUrl: "<%= image_path('open_note_marker.png') %>", + iconSize: [25, 40], + iconAnchor: [12, 40] + }), + "closed": L.icon({ + iconUrl: "<%= image_path('closed_note_marker.png') %>", + iconSize: [25, 40], + iconAnchor: [12, 40] + }) + }; + + function updateNote(marker, form, method, url) { + $(form).find("input[type=submit]").prop("disabled", true); + + $.ajax({ + url: url, + type: method, + oauth: true, + data: {text: $(form.text).val()}, + success: function (feature) { + marker = noteLayer.getLayer(marker); + if (feature.properties.status == "hidden") { + noteLayer.removeLayer(marker); + } else if (marker) { + marker.setIcon(noteIcons[feature.properties.status]); + } + OSM.loadSidebarContent(window.location.pathname, page.load); + } + }); + } + + page.pushstate = page.popstate = function (path) { + OSM.loadSidebarContent(path, page.load); + }; + + page.load = function () { + content.find("input[type=submit]").on("click", function (e) { + e.preventDefault(); + var data = $(e.target).data(); + updateNote(data.noteId, e.target.form, data.method, data.url); + }); + + content.find("textarea").on("input", function (e) { + var form = e.target.form; + + if ($(e.target).val() == "") { + $(form.close).val(I18n.t("javascripts.notes.show.resolve")); + $(form.comment).prop("disabled", true); + } else { + $(form.close).val(I18n.t("javascripts.notes.show.comment_and_resolve")); + $(form.comment).prop("disabled", false); + } + }); + + content.find("textarea").val('').trigger("input"); + + var data = $('.details').data(); + if (!noteState) map.addLayer(noteLayer); + if (!window.location.hash) { + var coords = data.coordinates.split(','); + OSM.route.moveListenerOff(); + map.once('moveend', OSM.route.moveListenerOn); + + map.getZoom() > 15 ? map.panTo(coords) : map.setView(coords, 16); + } + + if (!map.hasLayer(halo)) { + halo = L.circleMarker(data.coordinates.split(','), { + weight: 2.5, + radius: 20, + fillOpacity: 0.5, + color: "#FF6200" + }); + map.addLayer(halo); + } + }; + + page.unload = function () { + if (map.hasLayer(halo)) map.removeLayer(halo); + if (!noteState) map.removeLayer(noteLayer); + }; + + return page; +}; diff --git a/app/assets/javascripts/index/notes.js.erb b/app/assets/javascripts/index/notes.js.erb index 8972d6bf9..3bcdd4a19 100644 --- a/app/assets/javascripts/index/notes.js.erb +++ b/app/assets/javascripts/index/notes.js.erb @@ -1,10 +1,6 @@ -//= require templates/notes/show -//= require templates/notes/new - -function initializeNotes(map, params) { +function initializeNotes(map) { var noteLayer = map.noteLayer, - notes = {}, - newNote; + notes = {}; var noteIcons = { "new": L.icon({ @@ -35,57 +31,31 @@ function initializeNotes(map, params) { noteLayer.clearLayers(); notes = {}; } - }).on("popupclose", function (e) { - if (newNote && e.popup == newNote._popup) { - $(newNote).oneTime(10, "removenote", function () { - map.removeLayer(newNote); - newNote = null; - }); - } - }).on("popupopen", function (e) { - if (!('ontouchstart' in document.documentElement)) { - $(e.popup._container).find(".comment").focus(); - } }); - if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') { - if (params.layers.indexOf(noteLayer.options.code) >= 0) { - map.addLayer(noteLayer); - } - - if (params.note) { - $.ajax({ - url: "/api/" + OSM.API_VERSION + "/notes/" + params.note + ".json", - success: function (feature) { - var marker = updateMarker(notes[feature.properties.id], feature); - notes[feature.properties.id] = marker; - map.addLayer(noteLayer); - marker.openPopup(); - } - }); - } - } + noteLayer.on('click', function(e) { + OSM.route('/browse/note/' + e.layer.id); + }); function updateMarker(marker, feature) { if (marker) { marker.setIcon(noteIcons[feature.properties.status]); - marker.setPopupContent(createPopupContent( - marker, feature.properties, - $(marker._popup._content).find("textarea").val() - )); } else { marker = L.marker(feature.geometry.coordinates.reverse(), { icon: noteIcons[feature.properties.status], - opacity: 0.9 + opacity: 0.9, + clickable: true }); - marker.addTo(noteLayer).bindPopup( - createPopupContent(marker, feature.properties), - popupOptions() - ); + marker.id = feature.properties.id; + marker.addTo(noteLayer); } return marker; } + noteLayer.getLayerId = function(marker) { + return marker.id; + }; + var noteLoader; function loadNotes() { @@ -114,160 +84,11 @@ function initializeNotes(map, params) { notes[feature.properties.id] = updateMarker(marker, feature); } - for (id in oldNotes) { + for (var id in oldNotes) { noteLayer.removeLayer(oldNotes[id]); } noteLoader = null; } - }; - - function popupOptions() { - var mapSize = map.getSize(); - - return { - minWidth: 320, - maxWidth: mapSize.y * 1 / 3, - maxHeight: mapSize.y * 2 / 3, - offset: new L.Point(0, -40), - autoPanPadding: new L.Point(60, 40) - }; - } - - function createPopupContent(marker, properties, comment) { - var content = $(JST["templates/notes/show"]({ note: properties })); - - content.find("textarea").on("input", function (e) { - var form = e.target.form; - - if ($(e.target).val() == "") { - $(form.close).val(I18n.t("javascripts.notes.show.resolve")); - $(form.comment).prop("disabled", true); - } else { - $(form.close).val(I18n.t("javascripts.notes.show.comment_and_resolve")); - $(form.comment).prop("disabled", false); - } - }); - - content.find("input[type=submit]").on("click", function (e) { - e.preventDefault(); - var data = $(e.target).data(); - updateNote(marker, e.target.form, data.method, data.url); - }); - - if (comment) { - content.find("textarea").val(comment).trigger("input"); - } - - return content[0]; - } - - var addNoteButton = $(".control-note .control-button"); - - function createNote(marker, form, url) { - var location = marker.getLatLng(); - - marker.options.draggable = false; - marker.dragging.disable(); - - $(form).find("input[type=submit]").prop("disabled", true); - - $.ajax({ - url: url, - type: "POST", - oauth: true, - data: { - lat: location.lat, - lon: location.lng, - text: $(form.text).val() - }, - success: noteCreated - }); - - function noteCreated(feature) { - $(marker._popup._content).find("textarea").val(""); - - notes[feature.properties.id] = updateMarker(marker, feature); - newNote = null; - - addNoteButton.removeClass("active").addClass("geolink"); - } } - - function updateNote(marker, form, method, url) { - $(form).find("input[type=submit]").prop("disabled", true); - - $.ajax({ - url: url, - type: method, - oauth: true, - data: { - text: $(form.text).val() - }, - success: function (feature) { - if (feature.properties.status == "hidden") { - noteLayer.removeLayer(marker); - - delete notes[feature.properties.id]; - } else { - var popupContent = createPopupContent(marker, feature.properties); - - marker.setIcon(noteIcons[feature.properties.status]); - marker.setPopupContent(popupContent); - } - } - }); - } - - addNoteButton.on("click", function (e) { - e.preventDefault(); - e.stopPropagation(); - - if (addNoteButton.hasClass("disabled")) return; - if (addNoteButton.hasClass("active")) return; - - addNoteButton.removeClass("geolink").addClass("active"); - - map.addLayer(noteLayer); - - var mapSize = map.getSize(); - var markerPosition; - - if (mapSize.y > 800) { - markerPosition = [mapSize.x / 2, mapSize.y / 2]; - } else if (mapSize.y > 400) { - markerPosition = [mapSize.x / 2, 400]; - } else { - markerPosition = [mapSize.x / 2, mapSize.y]; - } - - newNote = L.marker(map.containerPointToLatLng(markerPosition), { - icon: noteIcons["new"], - opacity: 0.9, - draggable: true - }); - - var popupContent = $(JST["templates/notes/new"]()); - - popupContent.find("textarea").on("input", disableWhenBlank); - - function disableWhenBlank(e) { - $(e.target.form.add).prop("disabled", $(e.target).val() === ""); - } - - popupContent.find("input[type=submit]").on("click", function (e) { - e.preventDefault(); - createNote(newNote, e.target.form, '/api/0.6/notes.json'); - }); - - newNote.addTo(noteLayer).bindPopup(popupContent[0], popupOptions()).openPopup(); - - newNote.on("remove", function (e) { - addNoteButton.removeClass("active").addClass("geolink"); - }).on("dragstart", function (e) { - $(newNote).stopTime("removenote"); - }).on("dragend", function (e) { - e.target.openPopup(); - }); - }); } diff --git a/app/assets/javascripts/index/search.js b/app/assets/javascripts/index/search.js index dc4df821e..6efba746e 100644 --- a/app/assets/javascripts/index/search.js +++ b/app/assets/javascripts/index/search.js @@ -1,77 +1,84 @@ -function initializeSearch(map) { - $("#search_form").submit(submitSearch); - $("#describe_location").click(describeLocation); - - if ($("#query").val()) { - $("#search_form").submit(); - } - - // Focus the search field for browsers that don't support - // the HTML5 'autofocus' attribute - if (!("autofocus" in document.createElement("input"))) { - $("#query").focus(); - } +OSM.Search = function(map) { + $(".search_form input[name=query]") + .on("focus", function() { + $(".describe_location").fadeOut(100); + }) + .on("blur", function() { + $(".describe_location").fadeIn(100); + }); - $("#sidebar_content").on("click", ".search_results_entry a.set_position", clickSearchResult); + $("#sidebar_content") + .on("click", ".search_more a", clickSearchMore) + .on("click", ".search_results_entry a.set_position", clickSearchResult); - var marker = L.marker([0, 0], {icon: getUserIcon()}); - - function submitSearch(e) { + function clickSearchMore(e) { e.preventDefault(); + e.stopPropagation(); - var bounds = map.getBounds(); - - $("#sidebar_title").html(I18n.t('site.sidebar.search_results')); - $("#sidebar_content").load($(this).attr("action"), { - query: $("#query").val(), - zoom: map.getZoom(), - minlon: bounds.getWest(), - minlat: bounds.getSouth(), - maxlon: bounds.getEast(), - maxlat: bounds.getNorth() - }); + var div = $(this).parents(".search_more"); - openSidebar(); + $(this).hide(); + div.find(".loader").show(); - $("#sidebar").one("closed", function () { - map.removeLayer(marker); - map.removeObject(); + $.get($(this).attr("href"), function(data) { + div.replaceWith(data); }); } function clickSearchResult(e) { - e.preventDefault(); - var data = $(this).data(), center = L.latLng(data.lat, data.lon); + if (data.type && data.id) return; // Browse link + + e.preventDefault(); + e.stopPropagation(); + if (data.minLon && data.minLat && data.maxLon && data.maxLat) { map.fitBounds([[data.minLat, data.minLon], - [data.maxLat, data.maxLon]]); + [data.maxLat, data.maxLon]]); } else { map.setView(center, data.zoom); } + } - marker - .setLatLng(center) - .addTo(map); + var marker = L.marker([0, 0], {icon: getUserIcon()}); - if (data.type && data.id) { - map.addObject(data, { zoom: false, style: { opacity: 0.2, fill: false } }); - } - } + var page = {}; + + page.pushstate = page.popstate = function(path) { + var params = querystring.parse(path.substring(path.indexOf('?') + 1)); + $(".search_form input[name=query]").val(params.query); + OSM.loadSidebarContent(path, page.load); + }; + + page.load = function() { + $(".search_results_entry").each(function() { + var entry = $(this); + $.ajax({ + url: entry.data("href"), + method: 'GET', + data: { + zoom: map.getZoom(), + minlon: map.getBounds().getWest(), + minlat: map.getBounds().getSouth(), + maxlon: map.getBounds().getEast(), + maxlat: map.getBounds().getNorth() + }, + success: function(html) { + entry.html(html); + } + }); + }); - function describeLocation(e) { - e.preventDefault(); + return map.getState(); + }; - var center = map.getCenter(), - zoom = map.getZoom(); + page.unload = function() { + map.removeLayer(marker); + map.removeObject(); + $(".search_form input[name=query]").val(""); + }; - $("#sidebar_title").html(I18n.t('site.sidebar.search_results')); - $("#sidebar_content").load($(this).attr("href"), { - lat: center.lat, - lon: center.lng, - zoom: zoom - }, openSidebar); - } -} + return page; +}; diff --git a/app/assets/javascripts/leaflet.key.js b/app/assets/javascripts/leaflet.key.js index cc86736ef..58bfbf6d2 100644 --- a/app/assets/javascripts/leaflet.key.js +++ b/app/assets/javascripts/leaflet.key.js @@ -19,10 +19,9 @@ L.OSM.key = function (options) { .attr('class', 'sidebar_heading') .appendTo($ui) .append( - $('') + $('') .text(I18n.t('javascripts.close')) - .attr('class', 'sidebar_close') - .attr('href', '#') + .attr('class', 'icon close') .bind('click', toggle)) .append( $('

') @@ -57,6 +56,7 @@ L.OSM.key = function (options) { if (!button.hasClass('disabled')) { options.sidebar.togglePane($ui, button); } + $('.leaflet-control .control-button').tooltip('hide'); } function updateButton() { diff --git a/app/assets/javascripts/leaflet.layers.js b/app/assets/javascripts/leaflet.layers.js index 2534a91c2..7703529b8 100644 --- a/app/assets/javascripts/leaflet.layers.js +++ b/app/assets/javascripts/leaflet.layers.js @@ -22,10 +22,9 @@ L.OSM.layers = function(options) { .attr('class', 'sidebar_heading') .appendTo($ui) .append( - $('') + $('') .text(I18n.t('javascripts.close')) - .attr('class', 'sidebar_close') - .attr('href', '#') + .attr('class', 'icon close') .bind('click', toggle)) .append( $('

') @@ -85,9 +84,9 @@ L.OSM.layers = function(options) { .appendTo(item); var input = $('') - .attr('type', 'radio') - .prop('checked', map.hasLayer(layer)) - .appendTo(label); + .attr('type', 'radio') + .prop('checked', map.hasLayer(layer)) + .appendTo(label); label.append(layer.options.name); @@ -115,13 +114,19 @@ L.OSM.layers = function(options) { $('

') .text(I18n.t('javascripts.map.layers.overlays')) + .attr("class", "deemphasize") .appendTo(overlaySection); var list = $('

    ') .appendTo(overlaySection); - function addOverlay(layer, name) { + function addOverlay(layer, name, maxArea) { + var refName = name.split(' ').join('_').toLowerCase(); var item = $('
  • ') + .attr('class', refName) + .tooltip({ + placement: 'top' + }) .appendTo(list); var label = $('Andy Allan", + code: "C", + keyid: "cyclemap", + name: I18n.t("javascripts.map.base.cycle_map") + }), + new L.OSM.TransportMap({ + attribution: copyright + ". Tiles courtesy of Andy Allan", + code: "T", + keyid: "transportmap", + name: I18n.t("javascripts.map.base.transport_map") + }), + new L.OSM.MapQuestOpen({ + attribution: copyright + ". Tiles courtesy of MapQuest ", + code: "Q", + keyid: "mapquest", + name: I18n.t("javascripts.map.base.mapquest") + }), + new L.OSM.HOT({ + attribution: copyright + ". Tiles courtesy of Humanitarian OpenStreetMap Team", + code: "H", + keyid: "hot", + name: I18n.t("javascripts.map.base.hot") + }) + ]; + + this.noteLayer = new L.FeatureGroup(); + this.noteLayer.options = {code: 'N'}; + + this.dataLayer = new L.OSM.DataLayer(null); + this.dataLayer.options.code = 'D'; + }, + + updateLayers: function(layerParam) { + layerParam = layerParam || "M"; + var layersAdded = ""; + + for (var i = this.baseLayers.length - 1; i >= 0; i--) { + if (layerParam.indexOf(this.baseLayers[i].options.code) >= 0) { + this.addLayer(this.baseLayers[i]); + layersAdded = layersAdded + this.baseLayers[i].options.code; + } else if (i == 0 && layersAdded == "") { + this.addLayer(this.baseLayers[i]); + } else { + this.removeLayer(this.baseLayers[i]); + } + } + }, + getLayersCode: function () { var layerConfig = ''; for (var i in this._layers) { // TODO: map.eachLayer @@ -107,7 +169,22 @@ L.extend(L.Map.prototype, { return str; }, - addObject: function(object, options) { + addObject: function(object) { + var objectStyle = { + color: "#FF6200", + weight: 4, + opacity: 1, + fillOpacity: 0.5 + }; + + var changesetStyle = { + weight: 4, + color: '#FF9500', + opacity: 1, + fillOpacity: 0, + clickable: false + }; + this._object = object; if (this._objectLoader) this._objectLoader.abort(); @@ -120,9 +197,10 @@ L.extend(L.Map.prototype, { success: function (xml) { map._objectLayer = new L.OSM.DataLayer(null, { styles: { - node: options.style, - way: options.style, - area: options.style + node: objectStyle, + way: objectStyle, + area: objectStyle, + changeset: changesetStyle } }); @@ -139,13 +217,16 @@ L.extend(L.Map.prototype, { }; map._objectLayer.addData(xml); - - var bounds = map._objectLayer.getBounds(); - - if (options.zoom && bounds.isValid()) map.fitBounds(bounds); - if (options.callback) options.callback(bounds); - map._objectLayer.addTo(map); + + if (!window.location.hash) { + var bounds = map._objectLayer.getBounds(); + if (bounds.isValid()) { + OSM.route.moveListenerOff(); + map.once('moveend', OSM.route.moveListenerOn); + map.fitBounds(bounds); + } + } } }); }, @@ -154,6 +235,14 @@ L.extend(L.Map.prototype, { this._object = null; if (this._objectLoader) this._objectLoader.abort(); if (this._objectLayer) this.removeLayer(this._objectLayer); + }, + + getState: function() { + return { + center: this.getCenter().wrap(), + zoom: this.getZoom(), + layers: this.getLayersCode() + } } }); @@ -175,5 +264,13 @@ L.extend(L.Icon.Default.prototype, { } }); -L.Hash.prototype.parseHash = OSM.parseHash; -L.Hash.prototype.formatHash = OSM.formatHash; +function getUserIcon(url) { + return L.icon({ + iconUrl: url || <%= asset_path('marker-red.png').to_json %>, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowUrl: <%= asset_path('images/marker-shadow.png').to_json %>, + shadowSize: [41, 41] + }); +} diff --git a/app/assets/javascripts/leaflet.share.js b/app/assets/javascripts/leaflet.share.js index 01fc0c80a..d4c829532 100644 --- a/app/assets/javascripts/leaflet.share.js +++ b/app/assets/javascripts/leaflet.share.js @@ -25,10 +25,9 @@ L.OSM.share = function (options) { .attr('class', 'sidebar_heading') .appendTo($ui) .append( - $('') + $('') .text(I18n.t('javascripts.close')) - .attr('class', 'sidebar_close') - .attr('href', '#') + .attr('class', 'icon close') .bind('click', toggle)) .append( $('

    ') @@ -231,6 +230,7 @@ L.OSM.share = function (options) { update(); options.sidebar.togglePane($ui, button); + $('.leaflet-control .control-button').tooltip('hide'); } function toggleMarker() { diff --git a/app/assets/javascripts/map.js.erb b/app/assets/javascripts/map.js.erb deleted file mode 100644 index 98299070d..000000000 --- a/app/assets/javascripts/map.js.erb +++ /dev/null @@ -1,10 +0,0 @@ -function getUserIcon(url) { - return L.icon({ - iconUrl: url || <%= asset_path('marker-red.png').to_json %>, - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - shadowUrl: <%= asset_path('images/marker-shadow.png').to_json %>, - shadowSize: [41, 41] - }); -} diff --git a/app/assets/javascripts/osm.js.erb b/app/assets/javascripts/osm.js.erb index 5c555a25a..4c5faa829 100644 --- a/app/assets/javascripts/osm.js.erb +++ b/app/assets/javascripts/osm.js.erb @@ -12,7 +12,7 @@ OSM = { apiUrl: function (object) { var url = "/api/" + OSM.API_VERSION + "/" + object.type + "/" + object.id; - if (object.type != "node") { + if (object.type === "way" || object.type === "relation") { url += "/full"; } else if (object.version) { url += "/" + object.version; @@ -38,7 +38,7 @@ OSM = { }, mapParams: function (search) { - var params = OSM.params(search), mapParams = {}, bounds, loc; + var params = OSM.params(search), mapParams = {}, loc, match; if (params.mlon && params.mlat) { mapParams.marker = true; @@ -46,35 +46,12 @@ OSM = { mapParams.mlat = parseFloat(params.mlat); } - if (params.node || params.way || params.relation) { - mapParams.object_zoom = true; - - if (params.node) { - mapParams.object = {type: 'node', id: parseInt(params.node)}; - } else if (params.way) { - mapParams.object = {type: 'way', id: parseInt(params.way)}; - } else if (params.relation) { - mapParams.object = {type: 'relation', id: parseInt(params.relation)}; - } - } - - if (params.bbox) { - params.bbox = params.bbox.split(','); - bounds = L.latLngBounds( - [parseFloat(params.bbox[1]), - parseFloat(params.bbox[0])], - [parseFloat(params.bbox[3]), - parseFloat(params.bbox[2])]); - } else if (params.minlon && params.minlat && params.maxlon && params.maxlat) { - bounds = L.latLngBounds( - [parseFloat(params.minlat), - parseFloat(params.minlon)], - [parseFloat(params.maxlat), - parseFloat(params.maxlon)]); - } - - if (params.box === 'yes') { - mapParams.box = bounds; + if (params.node) { + mapParams.object = {type: 'node', id: parseInt(params.node)}; + } else if (params.way) { + mapParams.object = {type: 'way', id: parseInt(params.way)}; + } else if (params.relation) { + mapParams.object = {type: 'relation', id: parseInt(params.relation)}; } var hash = OSM.parseHash(location.hash); @@ -84,22 +61,14 @@ OSM = { mapParams.lon = hash.center.lng; mapParams.lat = hash.center.lat; mapParams.zoom = hash.zoom; - mapParams.object_zoom = false; - } else if (bounds) { - mapParams.lon = bounds.getCenter().lng; // Not used by main map, but - mapParams.lat = bounds.getCenter().lat; // are used by iD/Potlatch. - mapParams.bounds = bounds; - mapParams.object_zoom = false; } else if (params.lon && params.lat) { mapParams.lon = parseFloat(params.lon); mapParams.lat = parseFloat(params.lat); mapParams.zoom = parseInt(params.zoom || 5); - mapParams.object_zoom = false; } else if (params.mlon && params.mlat) { mapParams.lon = parseFloat(params.mlon); mapParams.lat = parseFloat(params.mlat); mapParams.zoom = parseInt(params.zoom || 12); - mapParams.object_zoom = false; } else if (loc = $.cookie('_osm_location')) { loc = loc.split("|"); mapParams.lon = parseFloat(loc[0]); @@ -123,10 +92,6 @@ OSM = { mapParams.layers = hash.layers || (loc && loc[3]) || ''; - if (params.note) { - mapParams.note = parseInt(params.note); - } - var scale = parseFloat(params.scale); if (scale > 0) { mapParams.zoom = Math.log(360.0 / (scale * 512.0)) / Math.log(2.0); @@ -136,12 +101,41 @@ OSM = { }, parseHash: function(hash) { - if (hash.indexOf('#') === 0) { - hash = hash.substr(1); + var i = hash.indexOf('#'); + if (i < 0) { + return false; + } + + hash = hash.substr(i + 1); + + if (hash === '') { + return false; } + hash = querystring.parse(hash); - var args = L.Hash.parseHash(hash.map || '') || {}; - if (hash.layers) args.layers = hash.layers; + + var args = hash.map.split("/"); + if (args.length !== 3) { + return false; + } + + var zoom = parseInt(args[0], 10), + lat = parseFloat(args[1]), + lon = parseFloat(args[2]); + + if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) { + return false; + } + + args = { + center: new L.LatLng(lat, lon), + zoom: zoom + }; + + if (hash.layers) { + args.layers = hash.layers; + } + return args; }, @@ -153,7 +147,7 @@ OSM = { zoom = args.getZoom(); layers = args.getLayersCode(); } else { - center = L.latLng(args.lat, args.lon); + center = args.center || L.latLng(args.lat, args.lon); zoom = args.zoom; layers = args.layers || ''; } diff --git a/app/assets/javascripts/router.js b/app/assets/javascripts/router.js new file mode 100644 index 000000000..cbd418895 --- /dev/null +++ b/app/assets/javascripts/router.js @@ -0,0 +1,133 @@ +OSM.Router = function(map, rts) { + var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; + var optionalParam = /\((.*?)\)/g; + var namedParam = /(\(\?)?:\w+/g; + var splatParam = /\*\w+/g; + + function Route(path, controller) { + var regexp = new RegExp('^' + + path.replace(escapeRegExp, '\\$&') + .replace(optionalParam, '(?:$1)?') + .replace(namedParam, function(match, optional){ + return optional ? match : '([^\/]+)'; + }) + .replace(splatParam, '(.*?)') + '(?:\\?.*)?$'); + + var route = {}; + + route.match = function(path) { + return regexp.test(path); + }; + + route.run = function(action, path) { + var params = []; + + if (path) { + params = regexp.exec(path).map(function(param, i) { + return (i > 0 && param) ? decodeURIComponent(param) : param; + }); + } + + return (controller[action] || $.noop).apply(controller, params); + }; + + return route; + } + + var routes = []; + for (var r in rts) + routes.push(Route(r, rts[r])); + + routes.recognize = function(path) { + for (var i = 0; i < this.length; i++) { + if (this[i].match(path)) return this[i]; + } + }; + + var currentPath = window.location.pathname + window.location.search, + currentRoute = routes.recognize(currentPath), + currentHash = location.hash || OSM.formatHash(map); + + var router, stateChange; + + if (window.history && window.history.pushState) { + $(window).on('popstate', function(e) { + if (!e.originalEvent.state) return; // Is it a real popstate event or just a hash change? + var path = window.location.pathname + window.location.search; + if (path === currentPath) return; + currentRoute.run('unload'); + currentPath = path; + currentRoute = routes.recognize(currentPath); + currentRoute.run('popstate', currentPath); + var state = e.originalEvent.state; + if (state.center) { + map.setView(state.center, state.zoom, {animate: false}); + map.updateLayers(state.layers); + } + }); + + router = function (url) { + var path = url.replace(/#.*/, ''), + route = routes.recognize(path); + if (!route) return false; + window.history.pushState(OSM.parseHash(url) || {}, document.title, url); + currentRoute.run('unload'); + currentPath = path; + currentRoute = route; + currentRoute.run('pushstate', currentPath); + return true; + }; + + router.stateChange = function(state) { + if (state.center) { + window.history.replaceState(state, document.title, OSM.formatHash(state)); + } else { + window.history.replaceState(state, document.title, window.location); + } + }; + } else { + router = function (url) { + window.location.assign(url); + }; + + router.stateChange = function(state) { + if (state.center) window.location.replace(OSM.formatHash(state)); + }; + } + + router.updateHash = function() { + var hash = OSM.formatHash(map); + if (hash === currentHash) return; + currentHash = hash; + router.stateChange(OSM.parseHash(hash)); + }; + + router.hashUpdated = function() { + var hash = location.hash; + if (hash === currentHash) return; + currentHash = hash; + var state = OSM.parseHash(hash); + if (!state) return; + map.setView(state.center, state.zoom); + map.updateLayers(state.layers); + router.stateChange(state, hash); + }; + + router.moveListenerOn = function() { + map.on('moveend', router.updateHash); + }; + + router.moveListenerOff = function() { + map.off('moveend', router.updateHash); + }; + + router.load = function() { + var loadState = currentRoute.run('load', currentPath); + router.stateChange(loadState || {}); + }; + + map.on('moveend baselayerchange overlaylayerchange', router.updateHash); + $(window).on('hashchange', router.hashUpdated); + + return router; +}; diff --git a/app/assets/javascripts/sidebar.js b/app/assets/javascripts/sidebar.js deleted file mode 100644 index 912197b9f..000000000 --- a/app/assets/javascripts/sidebar.js +++ /dev/null @@ -1,21 +0,0 @@ -function openSidebar(options) { - options = options || {}; - - $("#sidebar").trigger("closed"); - - if (options.title) { $("#sidebar_title").html(options.title); } - - $("#sidebar").width(options.width || "30%"); - $("#sidebar").css("display", "block").trigger("opened"); -} - -function closeSidebar() { - $("#sidebar").css("display", "none").trigger("closed"); -} - -$(document).ready(function () { - $(".sidebar_close").click(function (e) { - closeSidebar(); - e.preventDefault(); - }); -}); diff --git a/app/assets/javascripts/templates/browse/feature.jst.ejs b/app/assets/javascripts/templates/browse/feature.jst.ejs deleted file mode 100644 index d80c68922..000000000 --- a/app/assets/javascripts/templates/browse/feature.jst.ejs +++ /dev/null @@ -1,15 +0,0 @@ -
    - -

    <%- name %>

    -
    <%- I18n.t('browse.start_rjs.object_list.details') %> - - - -
    - -<%- I18n.t('browse.start_rjs.object_list.back') %> \ No newline at end of file diff --git a/app/assets/javascripts/templates/browse/feature_history.jst.ejs b/app/assets/javascripts/templates/browse/feature_history.jst.ejs deleted file mode 100644 index c579070e1..000000000 --- a/app/assets/javascripts/templates/browse/feature_history.jst.ejs +++ /dev/null @@ -1,10 +0,0 @@ -
    -

    <%- I18n.t("browse.start_rjs.history_for_feature", {feature: name}) %>

    - <%- I18n.t('browse.start_rjs.details') %> - -
      - <% for (var i = 0; i < history.length; i++) { %> -
    • <%- I18n.t("browse.start_rjs.edited_by_user_at_timestamp", history[i]) %>
    • - <% } %> -
    -
    diff --git a/app/assets/javascripts/templates/browse/feature_list.jst.ejs b/app/assets/javascripts/templates/browse/feature_list.jst.ejs deleted file mode 100644 index 7b8a193ad..000000000 --- a/app/assets/javascripts/templates/browse/feature_list.jst.ejs +++ /dev/null @@ -1,13 +0,0 @@ -
    -

    <%- I18n.t('browse.start_rjs.object_list.heading') %>

    -
    -
      - <% for (var i = 0; i < features.length; i++) { %> -
    • <%- features[i].typeName %> <%- features[i].name %>
    • - <% } %> -
    -
    - - - -
    diff --git a/app/assets/javascripts/templates/notes/new.jst.ejs b/app/assets/javascripts/templates/notes/new.jst.ejs deleted file mode 100644 index 003971088..000000000 --- a/app/assets/javascripts/templates/notes/new.jst.ejs +++ /dev/null @@ -1,12 +0,0 @@ -
    -

    <%- I18n.t('javascripts.notes.new.intro') %>

    -
    - - - -
    -
    - -
    -
    -
    diff --git a/app/assets/javascripts/templates/notes/show.jst.ejs b/app/assets/javascripts/templates/notes/show.jst.ejs deleted file mode 100644 index bea60ed4a..000000000 --- a/app/assets/javascripts/templates/notes/show.jst.ejs +++ /dev/null @@ -1,41 +0,0 @@ -
    - - <% if (note.comments.some(function (comment) { return !comment.user })) { %> - <%- I18n.t('javascripts.notes.show.anonymous_warning') %> - <% } %> - <% note.comments.forEach(function (comment) { %> -
    - - <% if (comment.user) { %> - <%= I18n.t('javascripts.notes.show.' + comment.action + '_by', { - user: comment.user, user_url: comment.user_url, - time: I18n.l("time.formats.long", comment.date) - }) %> - <% } else { %> - <%- I18n.t('javascripts.notes.show.' + comment.action + '_by_anonymous', { - time: I18n.l("time.formats.long", comment.date) - }) %> - <% } %> - -
    <%= comment.html %>
    -
    - <% }) %> - <% if (note.status == "open") { %> -
    - -
    - - - -
    -
    - <% } else { %> -
    - -
    - - -
    -
    - <% } %> -
    diff --git a/app/assets/javascripts/user.js b/app/assets/javascripts/user.js index d31f5bb82..6a0d38dd5 100644 --- a/app/assets/javascripts/user.js +++ b/app/assets/javascripts/user.js @@ -1,12 +1,24 @@ +//= require leaflet.locate + $(document).ready(function () { var map = L.map("map", { attributionControl: false, zoomControl: false }).addLayer(new L.OSM.Mapnik()); - L.OSM.zoom() + var position = $('html').attr('dir') === 'rtl' ? 'topleft' : 'topright'; + + L.OSM.zoom({position: position}) .addTo(map); + L.control.locate({ + position: position, + strings: { + title: I18n.t('javascripts.map.locate.title'), + popup: I18n.t('javascripts.map.locate.popup') + } + }).addTo(map); + if (OSM.home) { map.setView([OSM.home.lat, OSM.home.lon], 12); } else { diff --git a/app/assets/javascripts/welcome.js b/app/assets/javascripts/welcome.js index 56c454ac4..88b153af2 100644 --- a/app/assets/javascripts/welcome.js +++ b/app/assets/javascripts/welcome.js @@ -16,7 +16,7 @@ $(document).ready(function() { $('.start-mapping').attr('href', url); - } else if (navigator.geolocation) { + } else { function geoSuccess(position) { window.location = '/edit' + OSM.formatHash({ zoom: 17, @@ -27,21 +27,19 @@ $(document).ready(function() { $('.start-mapping').on('click', function(e) { e.preventDefault(); - - $('.start-mapping') - .addClass('loading'); + $('.start-mapping').addClass('loading'); // handle firefox's weird implementation // https://bugzilla.mozilla.org/show_bug.cgi?id=675533 window.setTimeout(manualEdit, 4000); - navigator.geolocation.getCurrentPosition(geoSuccess, manualEdit); + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(geoSuccess, manualEdit); + } }); - } else { - manualEdit(); } function manualEdit() { - window.location = '/?edit_help=1' + window.location = '/?edit_help=1'; } }); diff --git a/app/assets/stylesheets/browse.css.scss b/app/assets/stylesheets/browse.css.scss index 179f0c102..ff9dad9b4 100644 --- a/app/assets/stylesheets/browse.css.scss +++ b/app/assets/stylesheets/browse.css.scss @@ -1,14 +1,5 @@ /* Make space for icons */ -li.node::before, -li.way::before, -li.relation::before, -a.node:first-child::before, -a.way:first-child::before, -a.relation:first-child::before { - margin-left: -25px; -} - .node::before, .way::before, .relation::before { diff --git a/app/assets/stylesheets/common.css.scss b/app/assets/stylesheets/common.css.scss index 42467adb3..a7591ba21 100644 --- a/app/assets/stylesheets/common.css.scss +++ b/app/assets/stylesheets/common.css.scss @@ -1,13 +1,4 @@ -/* Parameters */ -$lineheight: 20px; -$typeheight: 14px; - -$offwhite: #f4f4ff; -$blue: #7092FF; -$lightblue: #B8C5F0; -$grey: #AAA; -$lightgrey: #CCC; -$hovercolor: 20%; +@import "parameters"; /* Styles common to large and small screens */ @@ -45,6 +36,11 @@ abbr, acronym { cursor: help; } +strong { + font-weight: bold; + font-weight: 500; +} + /* Micro Clearfix | Details: http://nicolasgallagher.com/micro-clearfix-hack/ */ .clearfix:before, @@ -88,12 +84,13 @@ abbr, acronym { .margin12 { margin-left:100.0000%; } .fillL { background-color: white; } + /* Default rules for the body of every page */ * { - -moz-box-sizing: border-box; -webkit-box-sizing: border-box; - box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } body { @@ -105,6 +102,7 @@ body { margin: 0px; padding: 0px; text-align: left; + height: 100%; } body.slim { @@ -112,36 +110,22 @@ body.slim { } h1, h2, h3 { - margin-top: $lineheight/2; - margin-bottom: $lineheight; font-weight: bold; + font-weight: 500; line-height: 1.2; } -h1, h2 { - font-size: 32px; -} - -#content h2 { - font-size: 21px; -} - -h3 { - font-size: 21px; - margin-top: $lineheight/2; - margin-bottom: $lineheight; +h4, h5 { + font-weight: bold; + font-weight: 500; } -h4,h5,h6 { - font-size: $typeheight; - margin-top: $lineheight/2; - margin-bottom: $lineheight/2; - font-weight: bold; - line-height: 1.5; +h1 { + font-size: 18px; } -p, ul { - margin-bottom: $lineheight; +h2, h3 { + font-size: 16px; } p > img { @@ -153,14 +137,7 @@ small, aside { font-size: 12px; } -h1:first-child, -h2:first-child, -h3:first-child, -h4:first-child, -h5:first-child, -h6:first-child { - margin-top: 0; -} +#container { position: relative; } .column-1 { width: 50%; @@ -172,6 +149,8 @@ h6:first-child { margin-right: $lineheight/4; } +.red { color: $red; } + /* Rules for icons */ .icon { @@ -182,10 +161,6 @@ h6:first-child { background:transparent image-url("sprite.png") no-repeat 0 0; text-indent:-9999px; overflow:hidden; - } - -.icon-pre-text { - margin-right: 5px; } .icon.search { background-position: 0 0; } @@ -200,6 +175,7 @@ h6:first-child { .icon.clipboard { background-position: -160px 0; } .icon.link { background-position: -180px 0; } .icon.close { background-position: -200px 0; } +.icon.close:hover { background-position: -200px -20px; } .icon.check { background-position: -220px 0; } .icon.note { background-position: -240px 0; } .icon.gear { background-position: -260px 0; } @@ -207,8 +183,10 @@ h6:first-child { /* Rules for links */ a { - color: #00f; + color: #24d; text-decoration: none; + -webkit-appearance: none; + outline: 0; &:hover { text-decoration: underline; } @@ -235,6 +213,7 @@ table { } th { font-weight: bold; + font-weight: 500; vertical-align: top; } td { @@ -242,364 +221,216 @@ table { } } -/* Rules for the whole left sidebar, including the logo */ +/* Utility for de-emphasizing content */ -#left { - position: absolute; - height: 100%; - width: 185px; - font-size: 11px; - line-height: 1.1; - z-index: 100; - border-right: 1px solid #ccc; +.deemphasize { + color: #999; + a { + color: $blue; + } } -/* Rules for the OpenStreetMap logo in the top left corner */ +/* Rules for the header */ -#logo { +#menu-icon { + display: none !important; + float: right; + background: image-url("menu-icon.png") no-repeat; + background-size: 30px 30px; display: block; - width: 170px; - min-width: 170px; - padding: $lineheight $lineheight/4; - text-align: center; - margin: auto; -} - -#logo h1 { - font-size: 18px; - line-height: 1; - text-align: center; - margin: 0; -} - -#logo h2 { - font-size: $lineheight/2; - line-height: 15px; - margin: 0; -} - -/* Rules for the site name */ - -#small-title { - display: none; - - img { - vertical-align: text-bottom; - } + width: 30px; + height: 30px; + margin: 14px 10px 0 0; + opacity: 0.6; } -/* Rules for the introductory text displayed in the left sidebar to new users */ +header { + height: $headerHeight; + position: relative; + z-index: 1001; + font-size: 14px; -.sidebar-copy { - padding: $lineheight/4 $lineheight/2; - p { - margin: $lineheight/4 0; + h1, nav, nav > ul, nav > ul > li, .dropdown { + display: inline-block; } -} -.sidebar-copy.intro { - border-top: 1px solid #ccc; -} - -/* - * Rules for alert boxes shown in the left sidebar when important - * information needs to be conveyed such as when the site is - * undergoing maintenance. - */ -.sidebar-alert { - padding: $lineheight/4; - border-top: 1px solid #ccc; - margin-top: 4px; - margin-bottom: -5px; - background: #e00; - font-size: 12px; - font-weight: bold; - p { - margin: $lineheight/4; + > * { + height: 100%; + padding: $lineheight/2; } -} - -/* - * Rules for notice boxes shown in the left sidebar when important, but - * non-critical information needs to be conveyed such as notices about - * donation drives. - */ -.sidebar-notice { - padding: $lineheight/4; - border-top: 1px solid #ccc; - margin-top: 4px; - margin-bottom: -5px; - background: #ea0; - font-size: 12px; - p { - margin: $lineheight/4; + h1, nav.primary { + float: left; } -} -/* Rules for the menu displayed in the left sidebar */ - -.left_menu { - left: 0px; - margin: 0; - padding: $lineheight/4 $lineheight/2 $lineheight/2 $lineheight/2; - font-size: 12px; - line-height: 1.25; - list-style-type: none; - border-bottom: 1px solid #ccc; - border-top: 1px solid #ccc; - img { - margin: $lineheight/2 0px; + a, a:hover { + text-decoration: none; } - ul { - padding: 0; - margin: 0; + img.logo { + width: 30px; + height: 30px; + margin-top: -2px; + vertical-align: middle; } - li { - list-style-type: none; - padding: 0; + h1 { margin: 0; - } + padding-top: 15px; - h4 { - padding: $lineheight/4 0 $lineheight/4 0; - font-size: 12px; - margin: 0; + a { + color: #000; + } } } -/* - * Rules for "optional boxes" which appear in the left sidebar on - * certain pages. Current users are the seach box on the main page - * and the tag cloud on the traces pages. - */ - -.optionalbox { - left: 0px; - padding: $lineheight/4 $lineheight/2; - margin: $lineheight/4 0; - text-align: left; -} - -/* Rules for the search box */ - -#search_field { - position: relative; - - form { - width: 165px; - } - - input[type="text"] { - width: 165px; - padding: 3px; - font-size: $typeheight; - line-height: 1.1; - height: 25px; - padding: 2px 0px 2px $lineheight/4; - box-shadow: inset #DDD 0px 1px 3px; - - transition: 300ms linear; - -webkit-transition: 300ms linear; - -moz-transition: 300ms linear; - } +nav.primary { + > ul { + $border: 1px solid $green; - input[type="text"]:focus { - box-shadow: 0px 0px 7px #9ED485; - outline: none; - } + border: $border; + border-radius: $border-radius; - input[type="submit"] { - border: 0; - margin: 0; - padding: 0; - width: 15px; - height: 15px; - min-width: 0; - text-indent: -1000px; - overflow: hidden; - background: image-url("sprite.png") -2px -2px no-repeat; - position: absolute; - top: $lineheight/4; - right: $lineheight/4; - cursor: pointer; + > li { + border-right: $border; + float: left; + &:last-child { + border-right: 0; + } + > a:hover { background: lighten($green, 30%); } + &.current > a:hover { background: $green; } + &.disabled > a:hover { background: lighten($green, 38%); } + &.dropdown { + > a.tab { border-right: 1px solid lighten($green, 30%); } + &.current > a.tab { border-right: 1px solid lighten($green, 10%); } + } + } } -} - -.search_help { - margin: $lineheight/4 0 0 0; -} - -/* Utility for de-emphasizing content */ -.deemphasize { - color: #999; - a { - color: $blue; + a.tab, + .dropdown-toggle { + display: inline-block; + font-weight: bold; + font-weight: 500; + color: $green; + padding: 5px 15px; } -} - -/* Rules for donation request box */ - -a.donate { - display: block; - width: 163px; - padding: $lineheight/4; - border: 1px solid #AED1A0; - background: #cbeea7; - font-size: $typeheight; - line-height: 1.4; - text-align: center; - border-radius: 2px; - color: #222; - margin: $lineheight/2 $lineheight/2 0px $lineheight/2; - &:hover { - background: #9ed485; - text-decoration: none; + .dropdown-toggle { + padding: 5px 6px; } -} - -/* Rules for Creative Commons logo button */ - -#cclogo { - margin: $lineheight/2 0; - float: right; -} - -/* Rules for tabbed navigation bar */ - -#top-bar { - position: relative; - margin-left: 185px; - height: 30px; - border-bottom: 1px solid #ccc; - background: white; - z-index: 1001; .caret { + border-top-color: $green; margin-top: 10px; } -} - -.site-edit #top-bar, -.site-index #top-bar, -.site-export #top-bar { - position: fixed; - top: 0; - left: 0; - right: 0; -} - -#tabnav { - height: 29px; - margin-bottom: 0; - > li { - float: left; + .disabled a { + color: #ccc; + cursor: default; - > * { - padding: 3px $lineheight/2; + .caret { + border-top-color: #ccc; } } - a.tab { - display: inline-block; - font-weight: bold; - text-decoration: none; - color: #333; + > ul li.current { + background-color: $green; - -webkit-transition: color 200ms ease-in; - -moz-transition: color 200ms ease-in; - -o-transition: color 200ms ease-in; - transition: color 200ms ease-in; + .tab { + color: #fff; + } - &:hover { - text-decoration: underline; + .caret { + border-top-color: #fff; } } +} - .disabled a { - color: #ccc; - cursor: default; +nav.secondary { + position: absolute; + right: 0; - &:hover { + > ul { + vertical-align: middle; + a, .dropdown-toggle { + display: inline-block; text-decoration: none; - } + color: $darkgrey; + padding: 3px 5px 5px 5px; - .caret { - border-top-color: #ccc; + &:hover { color: darken($darkgrey, 25%); } } } - .dropdown { - height: 29px; + > ul li.current a { + color: darken($darkgrey, 25%); } -} -.site-index #view_tab, -.site-edit #edit_tab, -.changeset-list #history_tab { - background: #9ed485; - color: #000; -} + .user-menu { + $border: 1px solid $grey; + border: $border; + border-radius: $border-radius; + margin-left: 10px; -/* Utility for styling notification numbers */ + > li { + border-right: $border; + float: left; + &:last-child { + border-right: 0; -.count-number { - padding: 2px $lineheight/4; - border-radius: 2px; - background: #d7d7ff; - margin: 0 2px; - font-size: 11px; - color: #333; -} + > a { + border-radius: 0 $border-radius $border-radius 0; + } + } + &:first-child > a { border-radius: $border-radius 0 0 $border-radius; } + &:hover a { background: lighten($darkgrey, 30%); } + } -/* Rules for greeting bar in the top right corner */ + a { + padding: 5px 15px; -#greeting { - float: right; - height: 100%; + } - &.secondary-actions { - padding: 3px $lineheight/2; + &.logged-in > a { + padding: 0; + > .user-button { + line-height: 1.8; + padding: 5px 10px 3px 6px; + display: inline-block; + color: $darkgrey; + } + &:hover > .user-button { color: darken($darkgrey, 5%); } + } } - &.dropdown { - background-color: #EEE; - &:hover { - background-color: #CCC; - } + .caret { + border-top-color: $grey; + margin-top: 9px; } - img { + img.user_thumbnail_tiny { + border: 0; vertical-align: top; - border-radius: 2px 0 0 2px; - margin-right: 5px; + margin-top: 0px; + margin: 4px 0 0 4px; + border-radius: 2px; } #inboxanchor { display: inline-block; - position: relative; - height: 20px; - top: -2px; - margin: 0 2px 0 0; - padding: 0 5px 0 0; - border-radius: 2px; - } - - .dropdown-toggle { - display: block; - padding: 3px 7px; - color: #000; - text-decoration: none; + vertical-align: top; + height: 25px; + margin: 3px 0 3px 3px; + background-color: lighten($grey, 10%); + line-height: 20px; + border-radius: 2; } .dropdown-menu { left: auto; - right: 0; + right: -1px; + border-radius: 3px 0 3px 3px; .count-number { float: right; @@ -609,13 +440,42 @@ a.donate { } } -/* Rules for the message shown in place of the map when javascript is disabled */ +#compact-secondary-nav { + display: none; + ul li a { + width: 100%; + color: #333; + &:hover { color: #fff; } + } +} -#noscript { - z-index: 20000000; - position: absolute; - top: 15px; - left: 15px; +@media only screen and (max-width:960px) { + #compact-secondary-nav { + display: inline-block; + } + .compact-hide { + display: none; + } +} + +/* Utility for styling notification numbers */ + +.count-number { + padding: 2px $lineheight/4; + border-radius: 2px; + background: lighten($green, 30%); + margin: 0 2px; + font-size: 11px; + color: #333; +} + +/* Rules for the message shown in place of the map when javascript is disabled */ + +#noscript { + z-index: 20000000; + position: absolute; + top: 15px; + left: 15px; } /* Rules for bootstrap tooltips */ @@ -710,7 +570,6 @@ a.donate { width: 40px; background-color: #333; background-color: rgba(0,0,0,.6); - -bottom: 1px solid #333; border-radius: 4px 0 0 4px; margin-bottom: 10px; outline: none; @@ -740,83 +599,179 @@ a.donate { border-radius: 4px 0 0 0; } -.site .leaflet-control .zoomout, +.leaflet-control .zoomout, .control-key .control-button { margin-bottom: 0; border-radius: 0; } -.leaflet-control .zoomout, // For non-main page maps .control-locate .control-button, .control-share .control-button { border-radius: 0 0 0 4px; } -/* Rules for the home page */ +/* Rules for the sidebar and main map area */ -.site-export #map, -.site-index #map, -.site-edit #map { - height: 100%; - overflow: hidden; -} +.map-layout { + #content { + overflow: hidden; + position: absolute; + top: $headerHeight; + bottom: 0; + width: 100%; + } -#map-ui { - display: none; - position: relative; - float: right; - width: 250px; - height: 100%; - background: white; - border-left: 1px solid #CCC; - overflow: auto; + #sidebar, #map { + position: relative; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + } + + #sidebar { + float: left; + width: $sidebarWidth; + background: #fff; + font-size: 13px; + + h2 { + padding: $lineheight $lineheight $lineheight/2; + } + + h3, h4 { + margin-top: $lineheight; + margin-bottom: $lineheight/2; + } - .section { - border-bottom: 1px solid #DDD; - padding: 15px; + .icon.close { + float: right; + cursor: pointer; + } } - a.close-button { - float: right; - padding:5px; - font-size:20px; - line-height:10px; - color:#222; - border:1px solid #ddd; + .overlay-sidebar #sidebar { + position: absolute; + z-index: 1000; + height: auto; + border-bottom-right-radius: 5px; + overflow: hidden; } -} -.layers-ui, -.share-ui { - ul, li:last-child, p:last-child { - margin-bottom: 0; + .welcome { + p { + padding: $lineheight/2 $lineheight $lineheight; + font-size: 110%; + font-weight: normal; + font-weight: 300; + } + + .button { + width: 50%; + float: left; + margin: 0; + border-radius: 0; + font-weight: normal; + padding: .6em; + + &.learn-more { + border-right: 1px solid #fff; + } + } } -} -.layers-ui { - li { - border-radius: 4px; + #map { + height: 100%; overflow: hidden; - margin-bottom: 10px; } - label { - display: block; - padding: 5px 5px 5px 7px; - background-color: #eee; - cursor: pointer; + #map-ui { + display: none; + position: relative; + float: right; + width: 250px; + height: 100%; + background: white; + overflow: auto; + + .section { + border-bottom: 1px solid #DDD; + padding: 10px 20px; + } + + a.close-button { + float: right; + padding:5px; + font-size:20px; + line-height:10px; + color:#222; + border:1px solid #ddd; + } + + .tooltip { + opacity: 1; + border: 1px solid #ccc; + .tooltip-arrow { + border-top-color: #ccc; + } + } } +} - li.active label { - background-color: #ccc; +.layers-ui, +.share-ui { + li:last-child { + margin-bottom: 0; } +} +.layers-ui { .base-layers { .leaflet-container { width: 100%; height: 50px; cursor: pointer; } + + li { + overflow: hidden; + border-radius: 3px; + border: 2px solid #fff; + margin-bottom: 8px; + position: relative; + transition: border-color 0.08s ease-in; + + label { + position: absolute; + top: 0; + left: 0; + padding: 2px 6px; + border-bottom-right-radius: 3px; + cursor: pointer; + font-weight: bold; + font-weight: 500; + font-size: 16px; + text-stroke: 2px #fff; + background: rgba(255,255,255,.9); + z-index: 2; // For IE9 + input[type="radio"] { + display: none; + } + } + + &.active { border-color: darken($green, 10%); } + &:hover { + border-color: $grey; + &.active { border-color: darken($green, 20%); } + } + } + } + + .overlay-layers { + p { + font-size: 13px; + margin-bottom: 8px; + } + li.disabled { color: #999; } } } @@ -875,7 +830,7 @@ a.donate { } } -.leaflet-top.leaflet-right { +.leaflet-top { top: $lineheight/2 !important; .leaflet-control { margin-right: 0px !important; @@ -894,34 +849,6 @@ a.donate { -webkit-border-radius: 4px !important; } -/* Rules for edit menu */ - -.menuicon { - padding: 0 $lineheight/4; - font-weight: normal; - display: inline-block; - &:hover { - text-decoration: none !important; - } -} - -.menu { - display: none; - z-index: 10000; - position: absolute; - background-color: #ffffff; - border: 1px solid $lightgrey; - border-top: 0px; - ul { - margin: 0px; - } - li { - padding: 2px $lineheight/4; - border-top: 1px solid #eee; - white-space: nowrap; - } -} - /* Rules for attribution text under the main map shown on printouts */ #attribution { @@ -937,59 +864,84 @@ a.donate { text-align: center; } -/* Rules for the popout map sidebar */ +.donate-attr { color: darken($green, 10%) !important; } -#sidebar { - display: none; - position: relative; - float: left; - border-right: 1px solid $lightgrey; - width: 33.3333%; - height: 100%; - ul { - margin-bottom: 0; - &:last-child { - border-bottom: 1px solid #ccc; - } - li { - margin-bottom: $lineheight/4; - &:last-child { - margin-bottom: 0; - } - } - } -} +/* Rules for the sidebar */ .sidebar_heading { position: relative; padding: $lineheight/2 $lineheight; - background: $offwhite; - border-bottom: 1px solid #ccc; - h4 { - margin: 0; + // background: $offwhite; + // border-bottom: 1px solid #ccc; + > .close { + float: right; + margin-top: 2px; + cursor: pointer; } } -.sidebar_close { - position: absolute; - height: $lineheight; - top: 0px; - bottom: 0; - right: $lineheight; - margin: auto; +#browse_status { + p { + padding: $lineheight; + } } -#sidebar_content { +#sidebar { + #sidebar_loader, + .loader, + .load_more { + text-align: center; + margin: $lineheight auto; + width: 40px; + display: block; + } +} + +/* Rules for the search box */ + +header .search_form { + display: none; +} + +.search_form { position: relative; - margin-bottom: 20px; - overflow: auto; - height: 100%; - width: 100%; - h4 { - padding: 0 $lineheight $lineheight/2 $lineheight; - margin-top: $lineheight/2; - margin-bottom: 0; - border-bottom: 1px solid #ddd; + padding: $lineheight/2; + background-color: $lightgrey; + + .query_wrapper { + position: relative; + overflow: hidden; + border-radius: 2px 0 0 2px; + } + + input[type=text] { + width: 100%; + height: 30px; + border-right: none; + + transition: 300ms linear; + -webkit-transition: 300ms linear; + -moz-transition: 300ms linear; + } + + input:focus { + outline: none; + box-shadow: 0px 0px 7px #9ED485; + } + + input[type=submit] { + float: right; + width: auto; + min-width: 0; + border-radius: 0 2px 2px 0; + } + + .describe_location { + position: absolute; + top: 6px; + right: 6px; + font-size: 10px; + color: $blue; } } @@ -1006,15 +958,13 @@ a.donate { } } -/* Rules for search results which appear in the popout sidebar */ - -.search_searching { - margin-top: $lineheight/4; - margin-bottom: $lineheight/4; -} +/* Rules for search sidebar */ .search_results_entry { - margin-bottom: 0; + ul li { + border-bottom: $keyline; + &:first-child { border-top: $keyline; } + } .search_details { display: block; @@ -1025,92 +975,244 @@ a.donate { } } -.search_results_entry .search_searching { - text-align: center; - margin: $lineheight auto; - width: $lineheight; - display: block; -} - -ul.results-list li { border-bottom: 1px solid #ccc; } - .search_results_error { color: #f00; } -/* Rules for data browser information which appears in the popout sidebar */ +/* Rules for entity history */ -#browse_content { - position: relative; - .browse_show_list.button { - position: absolute; - left: $lineheight; - right: $lineheight; - bottom: -40px; - margin-bottom: 0; +#sidebar_content { + .browse_details { + position: relative; + border-bottom: $keyline; } - a.more-details { - position: absolute; - top: 0; - right: $lineheight; +} + +.browse_status { + display: none; +} + +/* Rules for the history sidebar */ + +#sidebar .changesets { + li { + padding: 15px 20px; + border-bottom: 1px solid #ddd; + cursor: pointer; + + &.selected { background: #FFFFE6; } + /* color is derived from changeset bbox fillColor in history.js */ } - ul li { - margin-bottom: 0; + + h4 { + margin: 0; + a { + color: #000; + } } } -.browse_details { - position: relative; -} +/* Rules for the browse sidebar */ -.browse_status { - display: none; +#sidebar_content { + .browse-section { + padding: $lineheight/2 $lineheight; + border-bottom: 1px solid #ddd; + + h4:first-child { + margin-top: 0; + } + } + + :last-child { + border-bottom: none; + } + + .paginate { + float: right; + padding: 1px 6px; + border: 1px solid #eee; + border-radius: 3px; + } + + .paginate ul { + padding-left: 20px; + } + + .browse-field { + margin-bottom: 10px; + + h4 { + padding: 5px 0 5px 10px; + font-size: 12px; + border: 1px solid #CCC; + border-radius: 4px 4px 0 0; + background-color: #F6F6F6; + } + + p { + padding: 7px 10px; + font-size: 12px; + background-color: #FFF; + border: 1px solid #CCC; + border-top: 0; + border-radius: 0 0 4px 4px; + } + } + + .browse-tag-list { + background-color: #F6F6F6; + border: 1px solid #ddd; + border-radius: 3px; + font-size: 12px; + + li { + border-bottom: 1px solid #ddd; + } + + li:last-child { + border-bottom: 0; + } + + .browse-tag-k, + .browse-tag-v { + display: inline-block; + width: 50%; + float: left; + padding: 6px 10px; + } + + .browse-tag-k { + font-weight: bold; + font-weight: 500; + background-color: #F6F6F6; + } + + .browse-tag-v { + border-left: 1px solid #ddd; + background-color: #fff; + } + } + + .warning { + margin: $lineheight/2 0; + padding: $lineheight/2; + font-size: 90%; + } + + .note-comments li { + margin: $lineheight/2 0; + + p { + margin-left: 10px; + } + } + + .note-description { + margin: 0 0 10px 10px; + } } -/* Rules for export information which appears in the popout sidebar */ +/* Rules for export sidebar */ -.export_bounds { - text-align: center; +.export_form { + padding: $lineheight; + + .export_area_inputs, + .export_button { + text-align: center; + } + + .export_area_inputs { + margin-bottom: $lineheight/2; + input[type="text"] { + width: 80px; + text-align: center; + margin-bottom: 5px; + } + } + + .export_boxy { + background: #eee; + border: 1px solid #ccc; + border-radius: 3px; + + #maxlat { margin-top: -1px; } + #minlon { + float: left; + margin-left: -1px; + } + #maxlon { + float: right; + margin-right: -1px; + } + #minlat { margin-bottom: 0; } + } + + .export_bound { + margin: $lineheight/4; + } + + .export_button { + margin-top: $lineheight; + } + + dl { + padding-left: $lineheight/2; + dd { + margin-left: 0; + margin-bottom: 10px; + } + } } -.export_area_inputs { - margin-bottom: $lineheight/2; - input[type="text"] { - width: 80px; - margin-bottom: 5px; +/* Rules for edit pages */ + +.site-edit { + #content { + position: absolute; + top: $headerHeight; + bottom: 0; + width: 100%; + } + + #map { + height: 100%; } } -.export_bound { - margin: $lineheight/4; +/* Rules for non-map content pages */ + +.content-heading { + background: $lightgrey; + + h1 { font-size: 22px; } } -/* Rules for the main content area */ +.content-body { + h1, h2, h3, p { + margin-bottom: $lineheight; + } -#content { - position: relative; - padding: $lineheight; + h1, h2, h3 { + margin-top: $lineheight/2; + } } -.site-edit #content, -.site-index #content, -.site-export #content { - position: fixed; - padding: 0; - top: 30px; bottom: 0; - left: 184px; right: 0; - border-left: 1px solid #ccc; +.content-inner { + position: relative; + max-width: 900px; + margin: auto; + padding: $lineheight; } /* Overrides for pages that use new layout conventions */ + .user-new, .user-create, -.user-terms, -.user-confirm, -.site-copyright, -.site-welcome { - #content { - max-width: 740px; +.user-terms { + .content-body .content-inner { + padding: 0; } } @@ -1118,19 +1220,11 @@ ul.results-list li { border-bottom: 1px solid #ccc; } .user-create, .user-terms, .user-confirm { - .content-heading { + .content-heading .content-inner { height: 200px; } } -.user-new, -.user-create, -.user-terms { - #content { - padding: 0; - } -} - .header-illustration { background-position: 0 0; background-repeat: no-repeat; @@ -1158,202 +1252,64 @@ ul.results-list li { border-bottom: 1px solid #ccc; } left: 260px; top: 160px; background-image: image-url("sign-up-illustration-arm.png"); - } -} - -@media only screen and (max-width:900px) { - .header-illustration.new-user-arm { display: none;} -} - -.wrapper { - margin-left: 184px; - border-left: 1px solid #ccc; - text-align: left; -} - -#content.maximised { - top: 0; - left: 0; - right: 0; - bottom: 0; - border: 0; - z-index: 1000; -} - -#slim_container { - width: 100%; -} - -#slim_container_content { - max-width: 50em; - background-color: #FFFFFF; - margin: $lineheight/2 auto; - padding: 3px; - border-radius: 25px; - -moz-border-radius: 25px; - border: 1px solid #e6e6e6; -} - -#slim_content { - margin: $lineheight/2; - margin-top: 95px; - max-width: 50em; - - .content-heading { - margin-bottom: 15px; - } -} - -#slim_header { - margin: 30px $lineheight/2; - position: absolute; - top: 0px; - margin-right: $lineheight/4; - img { - vertical-align: middle; - margin-bottom: $lineheight/4; - margin-right: $lineheight/4; - } -} - -.content-heading { - position: relative; - padding: $lineheight; - background: $offwhite; - z-index: 2; - h1, h2 { - margin-bottom: $lineheight/2; - line-height: 100%; - &:last-child { - margin-bottom: 0; - } - } - p { - margin-top: $lineheight/2; - margin-bottom: 0px; - } -} - -/* Rules for small maps in content areas */ - -.content_map { - position: relative; - width: 45%; - height: 400px; - border: 1px solid #ccc; - margin-bottom: $lineheight; - float: right; -} - -.content_map #small_map { - height: 100%; - width: 100%; - margin-bottom: $lineheight; -} - -/* Rules for the changeset list shown by the history tab etc */ - -#changeset_list { - width: 100%; - ul { - padding: $lineheight/2 0; - margin-bottom: 0px; - border-top: 1px solid #ccc; - &:last-child { - border-bottom: 1px solid #ccc; - } - } - .selected { - background: #FFFFC0; - } - .date, - .user { - border-left: 1px solid #ccc; - padding-left: $lineheight/4; - margin-right: $lineheight/4; - } -} - -#changeset_list_map_wrapper { - position: absolute; - width: 50%; - height: 490px; - top: 0; - right: 0; + z-index: 100; + } } -#changeset_list_map_wrapper.scrolled { - position: fixed; +#content.maximised { + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 0; + z-index: 1000; } -#changeset_list_map { - position: absolute; - bottom: $lineheight; - top: $lineheight; - right: $lineheight; - left: $lineheight; - border: 1px solid #ccc; +#slim_container { + width: 100%; } -#changeset_list_map_wrapper.scrolled #changeset_list_map { - margin-left: 93px; +#slim_container_content { + max-width: 50em; + background-color: #FFFFFF; + margin: $lineheight/2 auto; + padding: 3px; + border-radius: 25px; + -moz-border-radius: 25px; + border: 1px solid #e6e6e6; } -/* Rules for the data browser */ +#slim_content { + margin: $lineheight/2; + margin-top: 95px; + max-width: 50em; -.browse-section { - border-top: 1px solid #ccc; - margin-top: $lineheight/2; - padding-top: $lineheight/2; - &:first-child { - margin-top: 0; - } - .warning { - background-color: #ffe0cc; - margin: 0px; - padding: 4px 6px; - max-width: 100%; - } - h4, p { - margin-bottom: $lineheight/4; - } - ul, .bbox, .geo { - display: inline-block; - vertical-align: top; - max-width: 65%; - } - ul p { - margin-left: 0; - margin-bottom: 0; - } - h4 { - float: left; - width: 33.3333%; - display: inline-block; - vertical-align: top; + .content-heading { + margin-bottom: 15px; } } -.bbox { - div { - width: 33.3333%; - text-align: center; - padding: $lineheight/4 0; - overflow: hidden; - text-overflow: ellipsis; - float: left; - } - .max_lat, - .min_lat { - margin-left: auto; - margin-right: auto; - width: 100%; +#slim_header { + margin: 30px $lineheight/2; + position: absolute; + top: 0px; + margin-right: $lineheight/4; + img { + vertical-align: middle; + margin-bottom: $lineheight/4; + margin-right: $lineheight/4; } } -#browse_map .secondary-actions { - display: none; - margin-bottom: $lineheight/2; +/* Rules for small maps in content areas */ + +.content_map { + position: relative; + width: 45%; + height: 400px; + border: 1px solid #ccc; + margin-bottom: $lineheight; + float: right; } /* Rules for the trace list shown by the traces tab etc */ @@ -1440,6 +1396,10 @@ ul.results-list li { border-bottom: 1px solid #ccc; } } .user-view { + // Silly exception; remove when user page is redesigned. + .content-inner { + max-width: none; + } p#no_home_location { margin: $lineheight; } @@ -1494,46 +1454,40 @@ ul.results-list li { border-bottom: 1px solid #ccc; } /* Rules for the diary list page */ -.diary_entry-list img.user_thumbnail { - float: left; -} - .diary_post { - max-width: 740px; position: relative; margin-top: $lineheight/2; padding-top: $lineheight; border-top: 1px solid #ccc; - &:first-child { - margin-top: 0; - border-top: 0; - padding-top: 0; + .post_heading { + margin-bottom: $lineheight; + + h2 { + margin-top: 0; + margin-bottom: $lineheight/2; + font-size: 24px; + } } - h1, h2 { - font-size: 21px; - line-height: 1em; + + img.user_thumbnail { + float: left; } + small.deemphasize { float: left; display: block; } - ul.secondary-actions { display: inline-block;} + + ul.secondary-actions { + display: inline-block; + } } .content-heading .hide_unless_logged_in { // hacky selector, better to just add a new class to this div display: inline; } -#content .post_heading { - margin-bottom: $lineheight; - h2 { - margin-top: 0; - margin-bottom: $lineheight/2; - font-size: 24px; - } -} - /* Rules for the diary entry page */ .diary_entry { @@ -1595,20 +1549,7 @@ ul.results-list li { border-bottom: 1px solid #ccc; } padding: $lineheight; margin-bottom: $lineheight; overflow: auto; - height: 10em; - - &:p#last { - margin-bottom: 0px; - } - - &:ol { - margin-bottom: 0px; - } - - &:img { - display: block; - margin: $lineheight auto inherit auto; - } + height: 20em; } #decline { @@ -1617,11 +1558,6 @@ ul.results-list li { border-bottom: 1px solid #ccc; } background: darken($lightblue, $hovercolor); } } - - .form-row { - margin: auto; - max-width: 370px; - } } /* Rules for the account settings page */ @@ -1754,17 +1690,19 @@ ul.results-list li { border-bottom: 1px solid #ccc; } /* Rules for "flash" notice boxes shown at the top of the content area */ -.flash { - padding: $lineheight; - &#error { - background-color: #ff7070; - } - &#warning { - background-color: #ffe0cc; - } - &#notice { - background-color: #CBEEA7; - } +.error { + padding: $lineheight; + background-color: #ff7070; +} + +.warning { + padding: $lineheight; + background-color: #ffe0cc; +} + +.notice { + padding: $lineheight; + background-color: #CBEEA7; } /* Rules for highlighting fields with rails validation errors */ @@ -1798,6 +1736,7 @@ ul.results-list li { border-bottom: 1px solid #ccc; } margin: 0 -10px 10px -10px; padding: $lineheight/4 $lineheight/4 $lineheight/4 15px; font-weight: bold; + font-weight: 500; font-size: 12px; background-color: #c00; color: #fff; @@ -1831,6 +1770,7 @@ ul.results-list li { border-bottom: 1px solid #ccc; } margin-bottom: $lineheight/4; font-size: $typeheight; font-weight: bold; + font-weight: 500; line-height: 1.5; } label.standard-label.secondary { @@ -1918,12 +1858,6 @@ img.user_thumbnail_tiny { border: 1px solid #ccc; } -/* Rule for "nowrap" class that can be applied to anything to stop wrapping */ - -.nowrap { - white-space: nowrap; -} - /* Rules for geo microformats */ abbr.geo { @@ -1934,7 +1868,7 @@ abbr.geo { .rsssmall { position: relative; - top: 5px; + top: 3px; } /* General styles for action lists / subnavs / pager navs */ @@ -1952,8 +1886,8 @@ ul.secondary-actions { float: left; list-style: none; border-left: 1px solid #ccc; - padding-left: $lineheight/4; - margin-right: $lineheight/4; + padding-left: $lineheight/2; + margin-right: $lineheight/2; &:first-child { border-left: 0; padding-left: 0; @@ -1962,10 +1896,11 @@ ul.secondary-actions { margin-right: 0px; } } - .dropdown-menu { - left: auto; - right: 0; - } +} + +div.secondary-actions { + padding: 10px; + text-align: center; } /* Utility for managing inner content areas */ @@ -2030,7 +1965,7 @@ a.button { float: left; border-radius: 0; margin:0; - min-width: 100px; + min-width: 75px; max-width: 180px; border-right:1px solid white; text-overflow: ellipsis; @@ -2063,7 +1998,7 @@ a.button { *[value="Hide"] + input:nth-child(2):not(:last-child), *[value="Hide"] + .button:nth-child(2):not(:last-child) { border-radius:2px 0 0 2px; - border-right-width: 1px solid white; + border-right-width: 1px; } } @@ -2245,113 +2180,13 @@ a.button { } } -/* Rules for the notes interface */ - -.leaflet-popup-content .note { - padding-top: $lineheight/2; -} - -.leaflet-popup-content .note { - h2 { - margin-bottom: $lineheight/2; - } - - div { - margin-top: $lineheight/2; - } - - .permalink { - position: absolute; - top: $lineheight/4; - left: $lineheight/4; - min-width: 15px; - min-height: 15px; - } - - .permalink span { - display: none; - padding-left: $lineheight; - } - - .permalink:hover span { - display: block; - } - - .warning { - display: block; - background-color: #ffe0cc; - padding: 4px 6px; - margin-bottom: $lineheight/2; - } - - .comment_body { - margin-top: 2px; - margin-bottom: 2px; - - p { - margin-top: 0px; - margin-bottom: 0px; - } - } - - .comment { - width: 100%; - height: 100px; - } - - .buttons { - margin-top: $lineheight/4; - text-align: right; - } -} - -/* - * Rules for the iD editor - */ - -.site-edit-id { - #left, - #large-title { - display: none; - } - - #small-title { - display: inline-block; - width: 185px; - height: 30px; - font-size: 14px; - margin: 0; - background-color: #eee; - border-bottom: 1px solid #ccc; - text-align: center; - padding-top: 7px; - } - - #content { - left: 0; - } -} +/* Rules for the iD editor */ .id-embed { width: 100%; height: 100%; } -/* Rules for rotating sidebar ads */ -.ad-container { - display: block; - height: 120px; - overflow: hidden; - position: relative; - border-bottom: 1px solid #ccc; -} - -.ad { - height: 100px; - border: 0; - background: #fff; -} - /* Rules for dropdown menus */ .dropdown { @@ -2386,7 +2221,7 @@ a.button { .dropdown-menu { position: absolute; top: 100%; - left: 0; + left: -1px; z-index: 1000; display: none; float: left; @@ -2396,6 +2231,7 @@ a.button { list-style: none; background-color: #ffffff; border: 1px solid #ccc; + border-radius: 0 3px 3px; *border-right-width: 2px; *border-bottom-width: 2px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); @@ -2437,7 +2273,7 @@ a.button { .dropdown-submenu:focus > a { color: #ffffff; text-decoration: none; - background-color: #0081c2; + background-color: $green; } .dropdown-menu > .active > a, @@ -2445,7 +2281,7 @@ a.button { .dropdown-menu > .active > a:focus { color: #ffffff; text-decoration: none; - background-color: #0081c2; + background-color: $green; outline: 0; } @@ -2559,3 +2395,153 @@ a.button { border-radius: 4px; } } + +.site-about #content { + //background-color: #000; + background-color: #eee; + background-position: 50% 50%; + background-repeat: no-repeat; + background-size: cover; + background-attachment: fixed; + + &.photo-0 { background-image: image-url('about/0.jpg'); .photo-0 { display: block; } } + &.photo-1 { background-image: image-url('about/1.jpg'); .photo-1 { display: block; } } + &.photo-2 { background-image: image-url('about/2.jpg'); .photo-2 { display: block; } } + &.photo-3 { background-image: image-url('about/4.jpg'); .photo-3 { display: block; } } + &.photo-4 { background-image: image-url('about/4.jpg'); .photo-4 { display: block; } } + &.photo-5 { background-image: image-url('about/5.jpg'); .photo-5 { display: block; } } + + .caption { + max-width: 200px; + font: 13px/20px Helvetica, Arial, sans-serif; + position: fixed; + text-align: right; + right: 20px; + bottom: 60px; + text-shadow: #000 0px 1px 5px; + color: #eee; + opacity: 0.8; + display: none; + } + + .caption a { + color: white; + white-space: nowrap; + text-decoration: none; + } + + a.next { + display: block; + position: fixed; + right: 10px; + bottom: 10px; + width: 40px; + height: 40px; + border-radius: 5px; + text-indent: -9999px; + overflow: hidden; + background: image-url('about/sprite.png') -120px 0px no-repeat; + background-color: #000; + background-color: rgba(0, 0, 0, 0.5); + } + + .content-inner { + position: relative; + color: #333; + min-width: 320px; + max-width: 640px; + + .section { + margin-bottom: 30px; + } + + .section:last-child { + margin-bottom: 0; + } + } + + .text { + background: white; + padding: 40px; + } + + .attr { + position: relative; + padding: 170px 40px 20px; + background: #333; + background: rgba(0, 0, 0, .8); + margin-bottom: 0; + margin-top: -20px; + + h1 { + display: block; + color: white; + font-weight: normal; + font-weight: 300; + font-size: 34px; + span { + color: #76c551; + } + } + + .user-image { + position: absolute; + top: 0px; + right: 240px; + left: 0px; + height: 150px; + background-position: 0 50%; + background-repeat: no-repeat; + background-image: image-url('about/osm.png'); + background-size: cover; + background-color: #76c551; + } + + .byosm { + position: absolute; + top: 0px; + right: 0px; + z-index: 1; + width: 240px; + height: 150px; + padding: 20px 20px 20px 40px; + font: 500 20px/24px Helvetica, Arial, sans-serif; + white-space: nowrap; + color: #fff; + background: #76c551; + } + + .byosm span { + display: inline-block; + width: 20px; + margin-left: -20px; + } + } + + h2 { + margin-bottom: 10px; + } + + .icon { + width: 30px; + height: 30px; + margin-right: 10px; + vertical-align: middle; + background: 40px 40px image-url('about/sprite.png') no-repeat; + + &.local { background-position: 0px 0px; } + &.community { background-position: 0px -40px; } + &.open { background-position: 0px -80px; } + &.partners { background-position: 0px -120px; } + &.infringement { background-position: 0px -160px; } + } +} + +@import 'browse'; + +@media only screen and (max-width:960px) { + .header-illustration.new-user-arm { + display: none; + } +} + diff --git a/app/assets/stylesheets/parameters.scss b/app/assets/stylesheets/parameters.scss new file mode 100644 index 000000000..b26b29105 --- /dev/null +++ b/app/assets/stylesheets/parameters.scss @@ -0,0 +1,17 @@ +/* Parameters */ +$lineheight: 20px; +$typeheight: 14px; + +$offwhite: #f4f4ff; +$blue: #7092FF; +$lightblue: #B8C5F0; +$green: #7ebc6f; +$grey: #CCC; +$red: red; +$lightgrey: #EEE; +$darkgrey: #888; +$hovercolor: 20%; +$headerHeight: 55px; +$sidebarWidth: 350px; +$keyline: 1px solid $lightgrey; +$border-radius: 3px; diff --git a/app/assets/stylesheets/print.css b/app/assets/stylesheets/print.css index 84efa0e2e..fa04314b1 100644 --- a/app/assets/stylesheets/print.css +++ b/app/assets/stylesheets/print.css @@ -1,7 +1,4 @@ -#small-title, -#left, -#greeting, -#tabnav, +header, #sidebar, #permalink, .leaflet-control { diff --git a/app/assets/stylesheets/small.css.scss b/app/assets/stylesheets/small.css.scss index 419abeac4..39b946af0 100644 --- a/app/assets/stylesheets/small.css.scss +++ b/app/assets/stylesheets/small.css.scss @@ -1,96 +1,133 @@ -/* Styles specific to a small screen, such as iPhone, Android, etc... */ +@import "parameters"; -/* Default rules for the body of every page */ +/* Styles specific to a small screen, such as iPhone, Android, etc... */ -body { - font-size: 10px; +input[type="submit"], +input[type="text"] { + -webkit-appearance: none; } -h1 { - font-size: 12px; +.column-1 { + width: 100%; } -h2, h3, h4 { - font-size: 12px; +#menu-icon { + display: inline-block !important; } -.wrapper { - margin: 0; +nav.primary, +nav.secondary { + float: none !important; + position: relative; + display: block; + clear: both; } -.site-edit #content, -.site-index #content, -.site-export #content { - left: 0; -} +header { + height: auto; + min-height: $headerHeight; + background: #fff; -.site-edit #top-bar, -.site-index #top-bar, -.site-export #top-bar { - position: relative; -} + h1 { + padding-bottom: 15px; + } + + &.closed nav { + display: none; + } -.site-edit #content, .site-index #content, .site-export #content { - position: absolute; + .search_form { + display: block; + } } -.column-1 { - width: 100%; +#sidebar .search_form, +#edit_tab, +#export_tab { + display: none; } -/* Rules for the whole left sidebar, including the logo */ +nav.primary { + padding: 0; -#left { - display: none; + ul, li { + border: none; + border-radius: 0; + width: 100%; + } + + ul { + border-top: 1px solid #eee; + li { + border-bottom: 1px solid #eee; + border-right: none; + > a { + border-radius: 0; + width: 100%; + text-align: center; + font-size: 15px; + } + } + } } -/* Rules for tabbed navigation bar */ +nav.secondary { + border-bottom: 1px solid #eee; -#top-bar { - left: 0; - margin: 0px; - height: 24px; - position: static; + .user-menu { + display: block; + width: 100%; + margin-left: 0; + > li { + width: 49%; + > a { + width: 100%; + text-align: center; + } + } + } } -#tabnav { - height: 19px; - margin: 0px; - padding-top: 5px; - margin-top: 26px; - font-size: 10px; - line-height: 10px; +#compact-secondary-nav { + display: none; } -#tabnav a, #tabnav a:link, #tabnav a:visited { - font-size: 10px; - line-height: 10px; - padding: 5px; - margin-right: 1px; +.compact-hide { + display: inline-block; } -.menuicon { line-height: 10px;} +.map-layout { + #sidebar, #map { + position: relative; + overflow-x: hidden; + width: 100%; + height: 50%; + } -/* Rules for the site name - shown when left sidebar is hidden */ + .overlay-sidebar { + #sidebar { + width: 300px; + } -#small-title { - font-size: 10px; - display: block; - position: absolute; - left: 5px; - top: 5px; - margin: 0; -} + #map { + height: 100%; + } + } -/* Rules for greeting bar in the top right corner */ + #map-ui { + z-index: 9999; + width: 100%; + overflow-y: scroll; + } +} -#browse_map ul.secondary-actions { - float: right; - font-size: 10px; +#sidebar .welcome { + display: none; } -#map { - border: 0; +.leaflet-top.leaflet-right { + top: 10px !important; + z-index: 0; } .content_map { @@ -102,69 +139,6 @@ h2, h3, h4 { min-height: auto; } -.content_map #small_map { - height: 300px; - border: 1px solid #ccc; -} - -.leaflet-control-pan, .leaflet-control-zoomslider { - display: none; -} - -.site-index .leaflet-top, -.site-export .leaflet-top { - top: 10px !important; -} - -/* Rules for the main content area */ - -#content { - margin-left: 0px; - margin-right: 0px; - border-left: 0px; - border-right: 0px; -} - -.site-export #content, -.site-edit #content, -.site-index #content { - margin-top: 21px; -} - -/* Rules for search sidebar when shown */ - -#sidebar { - border: 0px; - margin: 0px; - width: 50% !important; - border-right: 1px solid #ccccdd; -} - -p.search_results_entry { - padding: 2px 0px; -} - -/* Rules for the map UI */ - -.layers-ui { - .leaflet-container { - display: none; - } - - li { - border-radius: 0; - margin-bottom: 0; - - &:first-child { - border-radius: 4px 4px 0 0; - } - - &:last-child { - border-radius: 0 0 4px 4px; - } - } -} - /* Rules for the login form */ #login_login input#user_email { @@ -200,55 +174,6 @@ p.search_results_entry { top: auto; } -/* Rules for the user settings page */ - -#user_new_email { - width: 60% !important; -} - -#user_description, #user_preferred_editor { - width: 90% !important; -} - -.minorNote { - display: block; -} - -/* Rules for the browse pages */ - -.browse-section.common div{ - clear: both; -} - -#changeset_list_map { - position: relative; - width: 100%; - right: 0; - left: 0; - top: 0px; - margin-bottom: 20px; - float: none; - height: 300px !important; - max-height: auto; - min-height: auto; -} - -/* Rules for the diary entries pages */ - -#diary_entry_title, #diary_entry_body, #diary_entry_language_code, #diary_comment_body { - width: 100% !important; -} - -#usemap { - display: block; -} - -/* Rules for the messaging pages */ - -#message_title, #message_body { - width: 100% !important; -} - /* Rules for the sign-up page */ .user-new, @@ -261,3 +186,7 @@ p.search_results_entry { display: none; } } + +.site-about #content .attr h1 { + font-size: 28px; +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index fec202ca5..67e25c6a7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -418,6 +418,10 @@ class ApplicationController < ActionController::Base request.body.rewind end + def map_layout + request.xhr? ? false : 'map' + end + def preferred_editor editor = if params[:editor] params[:editor] diff --git a/app/controllers/browse_controller.rb b/app/controllers/browse_controller.rb index 119792167..29cd6707f 100644 --- a/app/controllers/browse_controller.rb +++ b/app/controllers/browse_controller.rb @@ -1,78 +1,65 @@ class BrowseController < ApplicationController - layout 'site', :except => [ :start ] + layout :map_layout before_filter :authorize_web before_filter :set_locale before_filter { |c| c.check_database_readable(true) } - around_filter :web_timeout, :except => [:start] + around_filter :web_timeout - def start - end - def relation @type = "relation" - @relation = Relation.find(params[:id]) - @next = Relation.visible.where("id > ?", @relation.id).order(:id => :asc).first - @prev = Relation.visible.where("id < ?", @relation.id).order(:id => :desc).first + @feature = Relation.find(params[:id]) + render 'feature' rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end - + def relation_history @type = "relation" - @relation = Relation.find(params[:id]) + @feature = Relation.find(params[:id]) + render 'history' rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end - + def way @type = "way" - @way = Way.preload(:way_tags, :containing_relation_members, :changeset => :user, :nodes => [:node_tags, :ways => :way_tags]).find(params[:id]) - @next = Way.visible.where("id > ?", @way.id).order(:id => :asc).first - @prev = Way.visible.where("id < ?", @way.id).order(:id => :desc).first + @feature = Way.preload(:way_tags, :containing_relation_members, :changeset => :user, :nodes => [:node_tags, :ways => :way_tags]).find(params[:id]) + render 'feature' rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end - + def way_history @type = "way" - @way = Way.preload(:way_tags, :old_ways => { :changeset => :user }).find(params[:id]) + @feature = Way.preload(:way_tags, :old_ways => { :changeset => :user }).find(params[:id]) + render 'history' rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end def node @type = "node" - @node = Node.find(params[:id]) - @next = Node.visible.where("id > ?", @node.id).order(:id => :asc).first - @prev = Node.visible.where("id < ?", @node.id).order(:id => :desc).first + @feature = Node.find(params[:id]) + render 'feature' rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end - + def node_history @type = "node" - @node = Node.find(params[:id]) + @feature = Node.find(params[:id]) + render 'history' rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end - + def changeset @type = "changeset" - @changeset = Changeset.find(params[:id]) @node_pages, @nodes = paginate(:old_nodes, :conditions => {:changeset_id => @changeset.id}, :per_page => 20, :parameter => 'node_page') @way_pages, @ways = paginate(:old_ways, :conditions => {:changeset_id => @changeset.id}, :per_page => 20, :parameter => 'way_page') @relation_pages, @relations = paginate(:old_relations, :conditions => {:changeset_id => @changeset.id}, :per_page => 20, :parameter => 'relation_page') - - @title = "#{I18n.t('browse.changeset.title')} | #{@changeset.id}" - @next = Changeset.where("id > ?", @changeset.id).order(:id => :asc).first - @prev = Changeset.where("id < ?", @changeset.id).order(:id => :desc).first - - if @changeset.user.data_public? - @next_by_user = @changeset.user.changesets.where("id > ?", @changeset.id).reorder(:id => :asc).first - @prev_by_user = @changeset.user.changesets.where("id < ?", @changeset.id).reorder(:id => :desc).first - end rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end @@ -80,9 +67,6 @@ class BrowseController < ApplicationController def note @type = "note" @note = Note.find(params[:id]) - @title = "#{I18n.t('browse.note.title')} | #{@note.id}" - @next = Note.visible.where("id > ?", @note.id).order(:id => :asc).first - @prev = Note.visible.where("id < ?", @note.id).order(:id => :desc).first rescue ActiveRecord::RecordNotFound render :action => "not_found", :status => :not_found end diff --git a/app/controllers/changeset_controller.rb b/app/controllers/changeset_controller.rb index 36b3b5124..bd908879f 100644 --- a/app/controllers/changeset_controller.rb +++ b/app/controllers/changeset_controller.rb @@ -252,6 +252,8 @@ class ChangesetController < ApplicationController def list if request.format == :atom and params[:page] redirect_to params.merge({ :page => nil }), :status => :moved_permanently + elsif request.format == :html and !params[:bbox] + render :action => :history, :layout => map_layout else changesets = conditions_nonempty(Changeset.all) @@ -289,52 +291,16 @@ class ChangesetController < ApplicationController end if params[:bbox] - bbox = BoundingBox.from_bbox_params(params) - elsif params[:minlon] and params[:minlat] and params[:maxlon] and params[:maxlat] - bbox = BoundingBox.from_lon_lat_params(params) + changesets = conditions_bbox(changesets, BoundingBox.from_bbox_params(params)) end - if bbox - changesets = conditions_bbox(changesets, bbox) - bbox_link = render_to_string :partial => "bbox", :object => bbox + if params[:max_id] + changesets = changesets.where("changesets.id <= ?", params[:max_id]) end - if user - user_link = render_to_string :partial => "user", :object => user - end - - if params[:friends] and @user - @title = t 'changeset.list.title_friend' - @heading = t 'changeset.list.heading_friend' - @description = t 'changeset.list.description_friend' - elsif params[:nearby] and @user - @title = t 'changeset.list.title_nearby' - @heading = t 'changeset.list.heading_nearby' - @description = t 'changeset.list.description_nearby' - elsif user and bbox - @title = t 'changeset.list.title_user_bbox', :user => user.display_name, :bbox => bbox.to_s - @heading = t 'changeset.list.heading_user_bbox', :user => user.display_name, :bbox => bbox.to_s - @description = t 'changeset.list.description_user_bbox', :user => user_link, :bbox => bbox_link - elsif user - @title = t 'changeset.list.title_user', :user => user.display_name - @heading = t 'changeset.list.heading_user', :user => user.display_name - @description = t 'changeset.list.description_user', :user => user_link - elsif bbox - @title = t 'changeset.list.title_bbox', :bbox => bbox.to_s - @heading = t 'changeset.list.heading_bbox', :bbox => bbox.to_s - @description = t 'changeset.list.description_bbox', :bbox => bbox_link - else - @title = t 'changeset.list.title' - @heading = t 'changeset.list.heading' - @description = t 'changeset.list.description' - end - - @page = (params[:page] || 1).to_i - @page_size = 20 - - @edits = changesets.order("changesets.created_at DESC").offset((@page - 1) * @page_size).limit(@page_size).preload(:user, :changeset_tags) + @edits = changesets.order("changesets.created_at DESC").limit(20).preload(:user, :changeset_tags) - render :action => :list + render :action => :list, :layout => false end end diff --git a/app/controllers/export_controller.rb b/app/controllers/export_controller.rb index b37810ca9..00eba741f 100644 --- a/app/controllers/export_controller.rb +++ b/app/controllers/export_controller.rb @@ -5,9 +5,6 @@ class ExportController < ApplicationController caches_page :embed - def start - end - #When the user clicks 'Export' we redirect to a URL which generates the export download def finish bbox = BoundingBox.from_lon_lat_params(params) diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index 6db70a6f3..87eb329ab 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -29,6 +29,8 @@ class GeocoderController < ApplicationController @sources.push "osm_nominatim" @sources.push "geonames" if defined?(GEONAMES_USERNAME) end + + render :layout => map_layout end def search_latlon diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index cea37fbf3..1757e771a 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -1,9 +1,10 @@ class SiteController < ApplicationController - layout 'site', :except => [:key, :permalink] - layout false, :only => [:key, :permalink] + layout 'site' + layout :map_layout, :only => [:index, :export] before_filter :authorize_web before_filter :set_locale + before_filter :redirect_browse_params, :only => :index before_filter :redirect_map_params, :only => [:index, :edit, :export] before_filter :require_user, :only => [:edit, :welcome] before_filter :require_oauth, :only => [:index] @@ -33,6 +34,7 @@ class SiteController < ApplicationController def key expires_in 7.days, :public => true + render :layout => false end def edit @@ -44,8 +46,6 @@ class SiteController < ApplicationController return end - @extra_body_class = "site-edit-#{editor}" - if params[:node] bbox = Node.find(params[:node]).bbox.to_unscaled @lat = bbox.centre_lat @@ -72,6 +72,12 @@ class SiteController < ApplicationController def welcome end + def help + end + + def about + end + def preview render :text => RichText.new(params[:format], params[:text]).to_html end @@ -82,6 +88,18 @@ class SiteController < ApplicationController private + def redirect_browse_params + if params[:node] + redirect_to node_path(params[:node]) + elsif params[:way] + redirect_to way_path(params[:way]) + elsif params[:relation] + redirect_to relation_path(params[:relation]) + elsif params[:note] + redirect_to browse_note_path(params[:note]) + end + end + def redirect_map_params anchor = [] diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 4765cb35b..5d61e8c63 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -94,6 +94,14 @@ module ApplicationHelper end def body_class - [params[:controller], "#{params[:controller]}-#{params[:action]}", @extra_body_class].compact.join(" ") + if content_for? :body_class + content_for :body_class + else + "#{params[:controller]} #{params[:controller]}-#{params[:action]}" + end + end + + def current_page_class(path) + :current if current_page?(path) end end diff --git a/app/helpers/browse_helper.rb b/app/helpers/browse_helper.rb index c4e4d425a..cf13c2795 100644 --- a/app/helpers/browse_helper.rb +++ b/app/helpers/browse_helper.rb @@ -1,8 +1,4 @@ module BrowseHelper - def link_to_page(page, page_param) - return link_to(page, page_param => page) - end - def printable_name(object, version=false) if object.id.is_a?(Array) id = object.id[0] @@ -61,6 +57,18 @@ module BrowseHelper end end + def type_and_paginated_count(type, pages) + if pages.page_count == 1 + t "browse.changeset.#{type}", + :count => pages.item_count + else + t "browse.changeset.#{type}_paginated", + :x => pages.current_page.first_item, + :y => pages.current_page.last_item, + :count => pages.item_count + end + end + private ICON_TAGS = [ diff --git a/app/helpers/changeset_helper.rb b/app/helpers/changeset_helper.rb new file mode 100644 index 000000000..cae1335c4 --- /dev/null +++ b/app/helpers/changeset_helper.rb @@ -0,0 +1,32 @@ +module ChangesetHelper + def changeset_user_link(changeset) + if changeset.user.data_public? + link_to(changeset.user.display_name, user_path(changeset.user.display_name)) + else + t('browse.anonymous') + end + end + + def changeset_details(changeset) + if changeset.closed_at > DateTime.now + action = :created + time = distance_of_time_in_words_to_now(changeset.created_at) + title = l(changeset.created_at) + else + action = :closed + time = distance_of_time_in_words_to_now(changeset.closed_at) + title = "#{t('browse.created')}: #{l(changeset.created_at)} #{t('browse.closed')}: #{l(changeset.closed_at)}".html_safe + end + + if params.key?(:display_name) + t "browse.#{action}_html", + :time => time, + :title => title + else + t "browse.#{action}_by_html", + :time => time, + :title => title, + :user => changeset_user_link(changeset) + end + end +end diff --git a/app/helpers/geocoder_helper.rb b/app/helpers/geocoder_helper.rb index c74cba28e..ce6c7eafa 100644 --- a/app/helpers/geocoder_helper.rb +++ b/app/helpers/geocoder_helper.rb @@ -2,7 +2,9 @@ module GeocoderHelper def result_to_html(result) html_options = { :class => "set_position", :data => {} } - if result[:min_lon] and result[:min_lat] and result[:max_lon] and result[:max_lat] + if result[:type] and result[:id] + url = url_for(:controller => :browse, :action => result[:type], :id => result[:id]) + elsif result[:min_lon] and result[:min_lat] and result[:max_lon] and result[:max_lat] url = "?minlon=#{result[:min_lon]}&minlat=#{result[:min_lat]}&maxlon=#{result[:max_lon]}&maxlat=#{result[:max_lat]}" else url = "?mlat=#{result[:lat]}&mlon=#{result[:lon]}&zoom=#{result[:zoom]}" @@ -17,14 +19,7 @@ module GeocoderHelper html << " " if result[:prefix] and result[:name] html << link_to(result[:name], url, html_options) if result[:name] html << result[:suffix] if result[:suffix] - - if result[:type] and result[:id] - html << content_tag(:small, :class => ["deemphasize", "search_details"]) do - link_to(t("browse.#{result[:type]}_history.view_details"), :controller => :browse, :action => result[:type], :id => result[:id]) - end - end - - return raw(html) + html.html_safe end def describe_location(lat, lon, zoom = nil, language = nil) diff --git a/app/helpers/note_helper.rb b/app/helpers/note_helper.rb index f2bff861f..e0eef269b 100644 --- a/app/helpers/note_helper.rb +++ b/app/helpers/note_helper.rb @@ -1,9 +1,16 @@ module NoteHelper - def note_event(at, by) + def note_event(event, at, by) if by.nil? - I18n.t("browse.note.at_html", :when => friendly_date(at)).html_safe + I18n.t("browse.note." + event + "_by_anonymous", + :when => friendly_date(at), + :exact_time => l(at) + ).html_safe else - I18n.t("browse.note.at_by_html", :when => friendly_date(at), :user => note_author(by)).html_safe + I18n.t("browse.note." + event + "_by", + :when => friendly_date(at), + :exact_time => l(at), + :user => note_author(by) + ).html_safe end end @@ -14,4 +21,5 @@ module NoteHelper link_to h(author.display_name), link_options.merge({:controller => "user", :action => "view", :display_name => author.display_name}) end end + end diff --git a/app/helpers/title_helper.rb b/app/helpers/title_helper.rb new file mode 100644 index 000000000..c9b979ad5 --- /dev/null +++ b/app/helpers/title_helper.rb @@ -0,0 +1,11 @@ +module TitleHelper + def set_title(title = false) + if title + title = t('layouts.project_name.title') + ' | ' + title + else + title = t('layouts.project_name.title') + end + response.headers["X-Page-Title"] = title + @title = title + end +end diff --git a/app/views/browse/_changeset_details.html.erb b/app/views/browse/_changeset_details.html.erb deleted file mode 100644 index 7a0deac50..000000000 --- a/app/views/browse/_changeset_details.html.erb +++ /dev/null @@ -1,78 +0,0 @@ -
    - -
    -
    -

    <%= t 'browse.changeset_details.created_at' %>

    -

    <%= l changeset_details.created_at %>

    -
    - -
    -

    <%= t 'browse.changeset_details.closed_at' %>

    -

    <%= l changeset_details.closed_at %>

    -
    - - <% if changeset_details.user.data_public? %> -
    -

    <%= t 'browse.changeset_details.belongs_to' %>

    -

    <%= link_to h(changeset_details.user.display_name), :controller => "user", :action => "view", :display_name => changeset_details.user.display_name %>

    -
    - <% end %> -
    - - <%= render :partial => "tag_details", :object => changeset_details %> - -
    -

    <%= t 'browse.changeset_details.bounding_box' %>

    - <% unless changeset_details.has_valid_bbox? %> -

    <%= t 'browse.changeset_details.no_bounding_box' %>

    - <% else bbox = changeset_details.bbox.to_unscaled %> -
    -
    <%=bbox.max_lat -%>
    -
    <%=bbox.min_lon -%>
    -
    (<%= link_to t('browse.changeset_details.box'), root_path(:minlon => bbox.min_lon, :minlat => bbox.min_lat, :maxlon => bbox.max_lon, :maxlat => bbox.max_lat, :box => 'yes'), :title => t('browse.changeset_details.show_area_box') %>)
    -
    <%=bbox.max_lon -%>
    -
    <%= bbox.min_lat -%>
    -
    - <% end %> -
    - - <% unless @nodes.empty? %> -
    -

    <%= t 'browse.changeset_details.has_nodes', :count => @node_pages.item_count %>

    -
      - <% @nodes.each do |node| %> -
    • <%= link_to h(printable_name(node, true)), { :action => "node", :id => node.node_id.to_s }, :class => link_class('node', node), :title => link_title(node) %>
    • - <% end %> -
    -
    - <%= render :partial => 'paging_nav', :locals => { :pages => @node_pages, :page_param => "node_page"} %> - <% end %> - - <% unless @ways.empty? %> -
    -

    <%= t 'browse.changeset_details.has_ways', :count => @way_pages.item_count %>

    -
      - <% @ways.each do |way| %> -
    • <%= link_to h(printable_name(way, true)), { :action => "way", :id => way.way_id.to_s }, :class => link_class('way', way), :title => link_title(way) %>
    • - <% end %> - <%= - #render :partial => "containing_relation", :collection => changeset_details.containing_relation_members - %> -
    -
    - <%= render :partial => 'paging_nav', :locals => { :pages => @way_pages, :page_param => "way_page" } %> - <% end %> - - <% unless @relations.empty? %> -
    -

    <%= t 'browse.changeset_details.has_relations', :count => @relation_pages.item_count %>

    -
      - <% @relations.each do |relation| %> -
    • <%= link_to h(printable_name(relation, true)), { :action => "relation", :id => relation.relation_id.to_s }, :class => link_class('relation', relation), :title => link_title(relation) %>
    • - <% end %> -
    -
    - <%= render :partial => 'paging_nav', :locals => { :pages => @relation_pages, :page_param => "relation_page" } %> - <% end %> - -
    \ No newline at end of file diff --git a/app/views/browse/_common_details.html.erb b/app/views/browse/_common_details.html.erb index 7c8165c67..959820bfd 100644 --- a/app/views/browse/_common_details.html.erb +++ b/app/views/browse/_common_details.html.erb @@ -1,39 +1,26 @@ -
    -
    - <% if common_details.visible? %> -

    <%= t 'browse.common_details.edited_at' %>

    - <% else %> -

    <%= t 'browse.common_details.deleted_at' %>

    - <% end %> -

    <%= l common_details.timestamp %>

    -
    - - <% if common_details.changeset.user.data_public? %> -
    - <% if common_details.visible? %> -

    <%= t 'browse.common_details.edited_by' %>

    - <% else %> -

    <%= t 'browse.common_details.deleted_by' %>

    - <% end %> -

    <%= link_to h(common_details.changeset.user.display_name), :controller => "user", :action => "view", :display_name => common_details.changeset.user.display_name %>

    -
    +

    + <% if common_details.changeset.tags['comment'].present? %> + <%= linkify(h(common_details.changeset.tags['comment'])) %> + <% else %> + <%= t 'browse.no_comment' %> <% end %> +

    -
    -

    <%= t 'browse.common_details.version' %>

    -

    <%= h(common_details.version) %>

    -
    - -
    -

    <%= t 'browse.common_details.in_changeset' %>

    -

    <%= link_to common_details.changeset_id, :action => :changeset, :id => common_details.changeset_id %>

    -
    +
    + <%= + t "browse.#{common_details.visible? ? :edited : :deleted}_by_html", + :time => distance_of_time_in_words_to_now(common_details.timestamp), + :user => changeset_user_link(common_details.changeset), + :title => l(common_details.timestamp) + %> +
    - <% if common_details.changeset.tags['comment'].present? %> -
    -

    <%= t 'browse.common_details.changeset_comment' %>

    -

    <%= linkify(h(common_details.changeset.tags['comment'])) %>

    -
    - <% end %> +
    + <%= t 'browse.version' %> + #<%= h(common_details.version) %> + · + <%= t 'browse.in_changeset' %> + #<%= link_to common_details.changeset_id, :action => :changeset, :id => common_details.changeset_id %>
    -<%= render :partial => "tag_details", :object => common_details %> + +<%= render :partial => "tag_details", :object => common_details.tags %> diff --git a/app/views/browse/_map.html.erb b/app/views/browse/_map.html.erb deleted file mode 100644 index ed703665d..000000000 --- a/app/views/browse/_map.html.erb +++ /dev/null @@ -1,78 +0,0 @@ -
    - <% if map.instance_of? Changeset or (map.instance_of? Node and map.version > 1) or map.visible? %> - - <% content_for :head do %> - <%= javascript_include_tag "browse" %> - <% end %> - - <% - if map.instance_of? Changeset - bbox = map.bbox.to_unscaled - data = { - :type => "changeset", - :id => map.id, - :minlon => bbox.min_lon, - :minlat => bbox.min_lat, - :maxlon => bbox.max_lon, - :maxlat => bbox.max_lat - } - elsif map.instance_of? Note - data = { - :type => "note", - :id => map.id, - :lon => map.lon, - :lat => map.lat - } - else - data = { - :type => map.class.name.downcase, - :id => map.id, - :version => map.version, - :visible => map.visible - } - end - %> - <%= content_tag "div", "", :id => "small_map", :data => data %> - <%= t 'browse.map.loading' %> - -
      -
    • - <% if map.instance_of? Note -%> - <%= link_to t("browse.map.larger.area"), - root_path(:notes => "yes"), - :id => "area_larger_map", - :class => "geolink bbox" %> - <% else -%> - <%= link_to t("browse.map.larger.area"), - root_path(:box => "yes"), - :id => "area_larger_map", - :class => "geolink bbox" %> - <% end -%> -
    • -
    • - <%= render :partial => 'layouts/edit_menu', - :locals => { :link_text => t("browse.map.edit.area"), - :link_class => 'bbox' } %> -
    • -
    - - <% unless map.instance_of? Changeset %> -
      -
    • - <%= link_to t("browse.map.larger." + map.class.to_s.downcase), - root_path, - :id => "object_larger_map", - :class => "geolink object" %> -
    • -
    • - <%= render :partial => 'layouts/edit_menu', - :locals => { :link_text => t("browse.map.edit." + map.class.to_s.downcase), - :link_class => 'object' } %> -
    • -
    - <% end %> - - <% else %> - <%= t 'browse.map.deleted' %> - <% end %> -
    diff --git a/app/views/browse/_navigation.html.erb b/app/views/browse/_navigation.html.erb deleted file mode 100644 index 0856044c8..000000000 --- a/app/views/browse/_navigation.html.erb +++ /dev/null @@ -1,43 +0,0 @@ -<% type = (@next || @prev).class.name.downcase %> -
      - <% if @prev %> -
    • - <%= link_to t('browse.navigation.paging.all.prev', :id => @prev.id.to_s), - { :id => @prev.id }, - { :title => t("browse.navigation.all.prev_#{type}_tooltip") } %> -
    • - <% end %> - <% if @next %> -
    • - <%= link_to t('browse.navigation.paging.all.next', :id => @next.id.to_s), - { :id => @next.id }, - { :title => t("browse.navigation.all.next_#{type}_tooltip") } %> -
    • - <% end %> -
    - <% if @next_by_user or @prev_by_user %> -
      - <% if @prev_by_user %> -
    • - <%= link_to t('browse.navigation.paging.user.prev', :id => @prev_by_user.id.to_s), - { :id => @prev_by_user.id }, - { :title => t("browse.navigation.user.prev_#{type}_tooltip", :user => @prev_by_user.user.display_name) } %> -
    • - <% end %> -
    • - <%= - user = (@prev_by_user || @next_by_user).user.display_name - link_to h(user), - { :controller => "changeset", :action => "list", :display_name => user }, - { :title => t("browse.navigation.user.name_#{type}_tooltip", :user => h(user)) } - %> -
    • - <% if @next_by_user %> -
    • - <%= link_to t('browse.navigation.paging.user.next', :id => @next_by_user.id.to_s), - { :id => @next_by_user.id }, - { :title => t("browse.navigation.user.next_#{type}_tooltip", :user => @next_by_user.user.display_name) } %> -
    • - <% end %> -
    - <% end %> diff --git a/app/views/browse/_node.html.erb b/app/views/browse/_node.html.erb new file mode 100644 index 000000000..5b29865db --- /dev/null +++ b/app/views/browse/_node.html.erb @@ -0,0 +1,21 @@ +
    + <% if node.redacted? %> + <%= t 'browse.redacted.message_html', + :type => t('browse.redacted.type.node'), + :version => node.version, + :redaction_link => link_to(t('browse.redacted.redaction', + :id => node.redaction.id), node.redaction) %> + <% else %> + <%= render :partial => "common_details", :object => node %> + + <% unless node.ways.empty? and node.containing_relation_members.empty? %> +

    <%= t 'browse.part_of' %>

    +
      + <% node.ways.each do |way| %> +
    • <%= link_to h(printable_name(way)), { :action => "way", :id => way.id.to_s }, :class => link_class('way', way), :title => link_title(way) %>
    • + <% end %> + <%= render :partial => "containing_relation", :collection => node.containing_relation_members %> +
    + <% end %> + <% end %> +
    diff --git a/app/views/browse/_node_details.html.erb b/app/views/browse/_node_details.html.erb deleted file mode 100644 index 8dec338d6..000000000 --- a/app/views/browse/_node_details.html.erb +++ /dev/null @@ -1,28 +0,0 @@ -
    -<% if node_details.redacted? %> -
    - <%= t 'browse.redacted.message_html', :type => t('browse.redacted.type.node'), :redaction_link => link_to(t('browse.redacted.redaction', :id => node_details.redaction.id), node_details.redaction), :version => node_details.version %> -
    -<% else %> - <%= render :partial => "common_details", :object => node_details %> - - <% if node_details.visible -%> -
    -

    <%= t 'browse.node_details.coordinates' %>

    -
    <%= link_to(content_tag(:span, number_with_delimiter(node_details.lat), :class => "latitude") + ", " + content_tag(:span, number_with_delimiter(node_details.lon), :class => "longitude"), {:controller => 'site', :action => 'index', :lat => h(node_details.lat), :lon => h(node_details.lon), :zoom => "18"}) %>
    -
    - <% end -%> - - <% unless node_details.ways.empty? and node_details.containing_relation_members.empty? %> -
    -

    <%= t 'browse.node_details.part_of' %>

    -
      - <% node_details.ways.each do |way| %> -
    • <%= link_to h(printable_name(way)), { :action => "way", :id => way.id.to_s }, :class => link_class('way', way), :title => link_title(way) %>
    • - <% end %> - <%= render :partial => "containing_relation", :collection => node_details.containing_relation_members %> -
    -
    - <% end %> -<% end %> -
    diff --git a/app/views/browse/_paging_nav.html.erb b/app/views/browse/_paging_nav.html.erb index f236b4465..67f1c75a3 100644 --- a/app/views/browse/_paging_nav.html.erb +++ b/app/views/browse/_paging_nav.html.erb @@ -1,14 +1,5 @@ -
    -<% current_page = pages.current_page %> - -<%= t'browse.paging_nav.showing_page' %> -<%= current_page.number %> (<%= current_page.first_item %><% -if (current_page.first_item < current_page.last_item) # if more than 1 trace on page - %>-<%= current_page.last_item %><% -end %> -<%= t'browse.paging_nav.of'%> <%= pages.item_count %>) - <% if pages.page_count > 1 %> -| <%= raw pagination_links_each(pages, {}) { |n| link_to_page(n, page_param) } %> + + <%= raw pagination_links_each(pages, {}) { |n| link_to(n, page_param => n) } %> + <% end %> -
    \ No newline at end of file diff --git a/app/views/browse/_relation.html.erb b/app/views/browse/_relation.html.erb new file mode 100644 index 000000000..e8f9a4f51 --- /dev/null +++ b/app/views/browse/_relation.html.erb @@ -0,0 +1,21 @@ +
    + <% if relation.redacted? %> + <%= t 'browse.redacted.message_html', + :type => t('browse.redacted.type.relation'), + :version => relation.version, + :redaction_link => link_to(t('browse.redacted.redaction', + :id => relation.redaction.id), relation.redaction) %>< + <% else %> + <%= render :partial => "common_details", :object => relation %> + + <% unless relation.relation_members.empty? %> +

    <%= t'browse.relation.members' %>

    +
      <%= render :partial => "relation_member", :collection => relation.relation_members %>
    + <% end %> + + <% unless relation.containing_relation_members.empty? %> +

    <%= t'browse.part_of' %>

    +
      <%= render :partial => "containing_relation", :collection => relation.containing_relation_members %>
    + <% end %> + <% end %> +
    diff --git a/app/views/browse/_relation_details.html.erb b/app/views/browse/_relation_details.html.erb deleted file mode 100644 index 1c0f4c93c..000000000 --- a/app/views/browse/_relation_details.html.erb +++ /dev/null @@ -1,23 +0,0 @@ -
    -<% if relation_details.redacted? %> -
    - <%= t 'browse.redacted.message_html', :type => t('browse.redacted.type.relation'), :redaction_link => link_to(t('browse.redacted.redaction', :id => relation_details.redaction.id), relation_details.redaction), :version => relation_details.version %>< -
    -<% else %> - <%= render :partial => "common_details", :object => relation_details %> - - <% unless relation_details.relation_members.empty? %> -
    -

    <%= t'browse.relation_details.members' %>

    -
      <%= render :partial => "relation_member", :collection => relation_details.relation_members %>
    -
    - <% end %> - - <% unless relation_details.containing_relation_members.empty? %> -
    -

    <%= t'browse.relation_details.part_of' %>

    -
      <%= render :partial => "containing_relation", :collection => relation_details.containing_relation_members %>
    -
    - <% end %> -<% end %> -
    diff --git a/app/views/browse/_tag.html.erb b/app/views/browse/_tag.html.erb index 298331832..b9296fa48 100644 --- a/app/views/browse/_tag.html.erb +++ b/app/views/browse/_tag.html.erb @@ -1 +1,4 @@ -
  • <%= format_key(tag[0]) %> = <%= format_value(tag[0], tag[1]) %>
  • \ No newline at end of file +
  • + <%= format_key(tag[0]) %> + <%= format_value(tag[0], tag[1]) %> +
  • diff --git a/app/views/browse/_tag_details.html.erb b/app/views/browse/_tag_details.html.erb index 9d0a2af54..090a23e7c 100644 --- a/app/views/browse/_tag_details.html.erb +++ b/app/views/browse/_tag_details.html.erb @@ -1,6 +1,6 @@ -<% unless tag_details.tags.empty? %> -
    -

    <%= t'browse.tag_details.tags' %>

    -
      <%= render :partial => "tag", :collection => tag_details.tags.sort %>
    -
    -<% end %> \ No newline at end of file +<% unless tag_details.empty? %> +

    <%= t 'browse.tag_details.tags' %>

    +
      + <%= render :partial => "tag", :collection => tag_details.sort %> +
    +<% end %> diff --git a/app/views/browse/_way.html.erb b/app/views/browse/_way.html.erb new file mode 100644 index 000000000..9156d2399 --- /dev/null +++ b/app/views/browse/_way.html.erb @@ -0,0 +1,33 @@ +
    + <% if way.redacted? %> + <%= t 'browse.redacted.message_html', + :type => t('browse.redacted.type.way'), + :version => way.version, + :redaction_link => link_to(t('browse.redacted.redaction', + :id => way.redaction.id), way.redaction) %> + <% else %> + <%= render :partial => "common_details", :object => way %> + + <% unless way.way_nodes.empty? %> +

    <%= t'browse.way.nodes' %>

    +
      + <% way.way_nodes.each do |wn| %> +
    • + <%= link_to h(printable_name(wn.node)), { :action => "node", :id => wn.node_id.to_s }, :class => link_class('node', wn.node), :title => link_title(wn.node) %> + <% related_ways = wn.node.ways.reject { |w| w.id == wn.way_id } %> + <% if related_ways.size > 0 then %> + (<%= raw t 'browse.way.also_part_of', :count => related_ways.size, :related_ways => related_ways.map { |w| link_to(h(printable_name(w)), { :action => "way", :id => w.id.to_s }, :class => link_class('way', w), :title => link_title(w) ) }.to_sentence %>) + <% end %> +
    • + <% end %> +
    + <% end %> + + <% unless way.containing_relation_members.empty? %> +

    <%= t'browse.part_of' %>

    +
      + <%= render :partial => "containing_relation", :collection => way.containing_relation_members %> +
    + <% end %> + <% end %> +
    diff --git a/app/views/browse/_way_details.html.erb b/app/views/browse/_way_details.html.erb deleted file mode 100644 index 6bff887b3..000000000 --- a/app/views/browse/_way_details.html.erb +++ /dev/null @@ -1,34 +0,0 @@ -
    -<% if way_details.redacted? %> -
    - <%= t 'browse.redacted.message_html', :type => t('browse.redacted.type.way'), :redaction_link => link_to(t('browse.redacted.redaction', :id => way_details.redaction.id), way_details.redaction), :version => way_details.version %> -
    -<% else %> - <%= render :partial => "common_details", :object => way_details %> - - <% unless way_details.way_nodes.empty? %> -
    -

    <%= t'browse.way_details.nodes' %>

    -
      - <% way_details.way_nodes.each do |wn| %> -
    • - <%= link_to h(printable_name(wn.node)), { :action => "node", :id => wn.node_id.to_s }, :class => link_class('node', wn.node), :title => link_title(wn.node) %> - <% related_ways = wn.node.ways.reject { |w| w.id == wn.way_id } %> - <% if related_ways.size > 0 then %> - (<%= raw t 'browse.way_details.also_part_of', :count => related_ways.size, :related_ways => related_ways.map { |w| link_to(h(printable_name(w)), { :action => "way", :id => w.id.to_s }, :class => link_class('way', w), :title => link_title(w) ) }.to_sentence %>) - <% end %> -
    • - <% end %> -
    -
    - <% end %> - - <% unless way_details.containing_relation_members.empty? %> -
    -

    <%= t'browse.way_details.part_of' %>

    -
      - <%= render :partial => "containing_relation", :collection => way_details.containing_relation_members %> -
    - <% end %> -<% end %> -
    diff --git a/app/views/browse/changeset.html.erb b/app/views/browse/changeset.html.erb index 96a5280a5..aa333cfff 100644 --- a/app/views/browse/changeset.html.erb +++ b/app/views/browse/changeset.html.erb @@ -1,18 +1,55 @@ -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> +<% set_title(t('browse.changeset.title', :id => @changeset.id)) %> -<% content_for :heading do %> -

    <%= t 'browse.changeset.changeset', :id => @changeset.id %>

    -
      -
    • <%= link_to(t('browse.changeset.changesetxml'), :controller => "changeset", :action => "read") %>
    • -
    • <%= link_to(t('browse.changeset.osmchangexml'), :controller => "changeset", :action => "download") %>
    • -
    -<% end %> +

    + + <%= t('browse.changeset.title', :id => @changeset.id) %> +

    -<%= render :partial => "navigation" %> +
    +

    <%= @changeset.tags['comment'].to_s.presence || t('browse.no_comment') %>

    +
    <%= changeset_details(@changeset) %>
    -<% if @changeset.has_valid_bbox? %> -<%= render :partial => "map", :object => @changeset %> -<% end %> -<%= render :partial => "changeset_details", :object => @changeset %> \ No newline at end of file + <%= render :partial => "tag_details", :object => @changeset.tags.except('comment') %> + + <% unless @ways.empty? %> +

    + <%= type_and_paginated_count('way', @way_pages) %> + <%= render :partial => 'paging_nav', :locals => { :pages => @way_pages, :page_param => "way_page" } %> +

    +
      + <% @ways.each do |way| %> +
    • <%= link_to h(printable_name(way, true)), { :action => "way", :id => way.way_id.to_s }, :class => link_class('way', way), :title => link_title(way) %>
    • + <% end %> +
    + <% end %> + + <% unless @relations.empty? %> +

    + <%= type_and_paginated_count('relation', @relation_pages) %> + <%= render :partial => 'paging_nav', :locals => { :pages => @relation_pages, :page_param => "relation_page" } %> +

    +
      + <% @relations.each do |relation| %> +
    • <%= link_to h(printable_name(relation, true)), { :action => "relation", :id => relation.relation_id.to_s }, :class => link_class('relation', relation), :title => link_title(relation) %>
    • + <% end %> +
    + <% end %> + + <% unless @nodes.empty? %> +

    + <%= type_and_paginated_count('node', @node_pages) %> + <%= render :partial => 'paging_nav', :locals => { :pages => @node_pages, :page_param => "node_page"} %> +

    +
      + <% @nodes.each do |node| %> +
    • <%= link_to h(printable_name(node, true)), { :action => "node", :id => node.node_id.to_s }, :class => link_class('node', node), :title => link_title(node) %>
    • + <% end %> +
    + <% end %> +
    + +
    + <%= link_to(t('browse.changeset.changesetxml'), :controller => "changeset", :action => "read") %> + · + <%= link_to(t('browse.changeset.osmchangexml'), :controller => "changeset", :action => "download") %> +
    diff --git a/app/views/browse/feature.html.erb b/app/views/browse/feature.html.erb new file mode 100644 index 000000000..1e0f118d8 --- /dev/null +++ b/app/views/browse/feature.html.erb @@ -0,0 +1,14 @@ +<% set_title(t("browse.#{@type}.title", :name => printable_name(@feature))) %> + +

    + + <%= t("browse.#{@type}.title", :name => printable_name(@feature)) %> +

    + +<%= render :partial => @type, :object => @feature %> + +
    + <%= link_to(t('browse.download_xml'), :controller => @type, :action => "read") %> + · + <%= link_to(t('browse.view_history'), :action => "#{@type}_history") %> +
    diff --git a/app/views/browse/history.html.erb b/app/views/browse/history.html.erb new file mode 100644 index 000000000..fa483bfb0 --- /dev/null +++ b/app/views/browse/history.html.erb @@ -0,0 +1,14 @@ +<% set_title(t("browse.#{@type}.history_title", :name => printable_name(@feature))) %> + +

    + + <%= t("browse.#{@type}.history_title", :name => printable_name(@feature)) %> +

    + +<%= render :partial => @type, :collection => @feature.send("old_#{@type}s").reverse %> + +
    + <%= link_to(t('browse.download_xml'), :controller => "old_#{@type}", :action => "history") %> + · + <%= link_to(t('browse.view_details'), :action => @type) %> +
    diff --git a/app/views/browse/new_note.html.erb b/app/views/browse/new_note.html.erb new file mode 100644 index 000000000..49922494e --- /dev/null +++ b/app/views/browse/new_note.html.erb @@ -0,0 +1,18 @@ +<% set_title(t "browse.note.new_note") %> + +

    + + <%= t "browse.note.new_note" %> +

    + +
    +

    <%= t('javascripts.notes.new.intro') %>

    +
    + + + +
    + +
    +
    +
    diff --git a/app/views/browse/node.html.erb b/app/views/browse/node.html.erb deleted file mode 100644 index f41562a7f..000000000 --- a/app/views/browse/node.html.erb +++ /dev/null @@ -1,27 +0,0 @@ -<% -@name = printable_name @node -@title = t('browse.node.node') + ' | ' + @name -%> -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> - -<% content_for :heading do %> -

    <%= t'browse.node.node_title', :node_name => @name %>

    -
      -
    • <%= link_to(t('browse.node.download_xml'), :controller => "node", :action => "read") %>
    • -
    • <%= link_to(t('browse.node.view_history'), :action => "node_history") %>
    • - <% if @node.visible -%> -
    • <%= link_to(t('browse.node.edit'), :controller => "site", :action => "edit", :lat => @node.lat, :lon => @node.lon, :zoom => 18, :node => @node.id) %>
    • - <% end -%> -
    -<% end %> -<%= render :partial => "navigation" %> - -<% if @node.visible -%> -<%= render :partial => "map", :object => @node %> -<% end -%> - -
    - <%= render :partial => "node_details", :object => @node %> -
    \ No newline at end of file diff --git a/app/views/browse/node_history.html.erb b/app/views/browse/node_history.html.erb deleted file mode 100644 index e37f0e037..000000000 --- a/app/views/browse/node_history.html.erb +++ /dev/null @@ -1,25 +0,0 @@ -<% -@name = printable_name @node -@title = t('browse.node_history.node_history') + ' | ' + @name -%> -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> - -<% content_for :heading do %> -

    <%= raw t'browse.node_history.node_history_title', :node_name => link_to(h(@name), :action => "node", :id => @node.id) %>

    -
      -
    • <%= link_to(t('browse.node_history.download_xml'), :controller => "old_node", :action => "history") %>
    • -
    • <%= link_to(t('browse.node_history.view_details'), :action => "node") %>
    • -
    -<% end %> - -<% if @node.visible -%> - <%= render :partial => "map", :object => @node %> -<% end -%> - -
    - <% @node.old_nodes.reverse.each do |node| %> - <%= render :partial => "node_details", :object => node %> - <% end %> -
    diff --git a/app/views/browse/not_found.html.erb b/app/views/browse/not_found.html.erb index f536ef9ff..a8974b474 100644 --- a/app/views/browse/not_found.html.erb +++ b/app/views/browse/not_found.html.erb @@ -6,4 +6,7 @@ 'changeset' => I18n.t('browse.not_found.type.changeset'), }; %> -

    <%= t'browse.not_found.sorry', :type=> browse_not_found_type[@type] , :id => params[:id] %>

    + +

    + + <%= t'browse.not_found.sorry', :type=> browse_not_found_type[@type] , :id => params[:id] %>

    diff --git a/app/views/browse/note.html.erb b/app/views/browse/note.html.erb index 31fd00f01..90d34b574 100644 --- a/app/views/browse/note.html.erb +++ b/app/views/browse/note.html.erb @@ -1,67 +1,57 @@ -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> +<% set_title("#{t('browse.note.title')} | #{@note.id}") %> -<% content_for :heading do %> -

    - <%= image_tag "#{@note.status}_note_marker.png", :alt => @note.status %> - <%= t "browse.note.#{@note.status}_title", :note_name => @note.id %> -

    -<% end %> +

    + + <%= t "browse.note.#{@note.status}_title", :note_name => @note.id %> +

    -<%= render :partial => "navigation" %> - -<%= render :partial => "map", :object => @note %> - -
    - - <% if @note.comments.find { |comment| comment.author.nil? } -%> -
    -

    <%= t "javascripts.notes.show.anonymous_warning" %>

    +
    +

    <%= t('browse.note.mine.description') %>

    +
    + <%= h(@note.comments.first.body.to_html) %>
    - <% end -%> - -
    -
    -

    <%= t "browse.note.opened" %>

    -

    <%= note_event(@note.created_at, @note.author) %>

    -
    +
    + <%= note_event('open', @note.created_at, @note.author) %> <% if @note.status == "closed" %> -
    -

    <%= t "browse.note.closed" %>

    -

    <%= note_event(@note.closed_at, @note.comments.last.author) %>

    -
    - <% elsif @note.comments.length > 1 %> -
    -

    <%= t "browse.note.last_modified" %>

    -

    <%= note_event(@note.updated_at, @note.comments.last.author) %>

    -
    +
    + <%= note_event(@note.status, @note.closed_at, @note.comments.last.author) %> <% end %> - -
    -

    <%= t "browse.note.description" %>

    -

    <%= h(@note.comments.first.body.to_html) %>

    -
    - -
    -

    <%= t "browse.node_details.coordinates" %>

    -

    <%= link_to ("#{number_with_delimiter(@note.lat)}, #{number_with_delimiter(@note.lon)}".html_safe), {:controller => 'site', :action => 'index', :lat => h(@note.lat), :lon => h(@note.lon), :zoom => "18"} %>

    -
    + <% if @note.comments.find { |comment| comment.author.nil? } -%> +

    <%= t "javascripts.notes.show.anonymous_warning" %>

    + <% end -%> + <% if @note.comments.length > 1 %> -
    -

    <%= t "browse.note.comments" %>

    +
      <% @note.comments[1..-1].each do |comment| %>
    • + <%= note_event(comment.event, comment.created_at, comment.author) %> <%= comment.body.to_html %> - <%= note_event(comment.created_at, comment.author) %>
    • <% end %>
    <% end %> + <% if @note.status == "open" %> +
    + +
    + + + +
    +
    + <% else %> +
    + +
    + + +
    +
    + <% end %>
    diff --git a/app/views/browse/relation.html.erb b/app/views/browse/relation.html.erb deleted file mode 100644 index 3ba355054..000000000 --- a/app/views/browse/relation.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -<% -@name = printable_name @relation -@title = t('browse.relation.relation') + ' | ' + @name -%> -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> - -<% content_for :heading do %> -

    <%= t'browse.relation.relation_title', :relation_name => @name %>

    -
      -
    • <%= link_to(t('browse.relation.download_xml'), :controller => "relation", :action => "read") %>
    • -
    • <%= link_to(t('browse.relation.view_history'), :action => "relation_history") %>
    • -
    -<% end %> -<%= render :partial => "navigation" %> -<%= render :partial => "map", :object => @relation %> - -
    - <%= render :partial => "relation_details", :object => @relation %> -
    \ No newline at end of file diff --git a/app/views/browse/relation_history.html.erb b/app/views/browse/relation_history.html.erb deleted file mode 100644 index e0640d900..000000000 --- a/app/views/browse/relation_history.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -<% -@name = printable_name @relation -@title = t('browse.relation_history.relation_history') + ' | ' + @name -%> -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> - -<% content_for :heading do %> -

    <%= raw t'browse.relation_history.relation_history_title', :relation_name => link_to(h(@name), :action => "relation", :id => @relation.id) %>

    -
      -
    • <%= link_to(t('browse.relation_history.download_xml'), :controller => "old_relation", :action => "history") %>
    • -
    • <%= link_to(t('browse.relation_history.view_details'), :action => "relation") %>
    • -
    -<% end %> - -<%= render :partial => "map", :object => @relation %> -
    -<% @relation.old_relations.reverse.each do |relation| %> - <%= render :partial => "relation_details", :object => relation %> -<% end %> -
    \ No newline at end of file diff --git a/app/views/browse/start.html.erb b/app/views/browse/start.html.erb deleted file mode 100644 index 12012a029..000000000 --- a/app/views/browse/start.html.erb +++ /dev/null @@ -1,6 +0,0 @@ - -
    -
    diff --git a/app/views/browse/way.html.erb b/app/views/browse/way.html.erb deleted file mode 100644 index 15a0dcad8..000000000 --- a/app/views/browse/way.html.erb +++ /dev/null @@ -1,23 +0,0 @@ -<% -@name = printable_name @way -@title = t('browse.way.way') + ' | ' + @name -%> -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> - -<% content_for :heading do %> -

    <%= t'browse.way.way_title', :way_name => @name %>

    -
      -
    • <%= link_to(t('browse.way.download_xml'), :controller => "way", :action => "read") %>
    • -
    • <%= link_to(t('browse.way.view_history'), :action => "way_history") %>
    • -
    • <%= link_to(t('browse.way.edit'), :controller => "site", :action => "edit", :way => @way.id) %>
    • -
    -<% end %> - -<%= render :partial => "navigation" %> -<%= render :partial => "map", :object => @way %> - -
    - <%= render :partial => "way_details", :object => @way %> -
    \ No newline at end of file diff --git a/app/views/browse/way_history.html.erb b/app/views/browse/way_history.html.erb deleted file mode 100644 index 49058edc1..000000000 --- a/app/views/browse/way_history.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -<% -@name = printable_name @way -@title = t('browse.way_history.way_history') + ' | ' + @name -%> -<% content_for :head do %> -<%= stylesheet_link_tag 'browse' %> -<% end %> - -<% content_for :heading do %> -

    <%= raw t'browse.way_history.way_history_title', :way_name => link_to(h(@name), :action => "way", :id => @way.id) %>

    -
      -
    • <%= link_to(t('browse.way_history.download_xml'), :controller => "old_way", :action => "history") %>
    • -
    • <%= link_to(t('browse.way_history.view_details'), :action => "way") %>
    • -
    -<% end %> - -<%= render :partial => "map", :object => @way %> -
    -<% @way.old_ways.reverse.each do |way| %> - <%= render :partial => "way_details", :object => way %> -<% end %> -
    \ No newline at end of file diff --git a/app/views/changeset/_changeset.html.erb b/app/views/changeset/_changeset.html.erb index 3e4871ec0..5c5ad670b 100644 --- a/app/views/changeset/_changeset.html.erb +++ b/app/views/changeset/_changeset.html.erb @@ -12,39 +12,19 @@ end %> -<%= content_tag "ul", :class => 'changeset_item', :id => "changeset_#{changeset.id}", :data => {:changeset => changeset_data} do %> -
  • - - - <%= - link_to(changeset.id, - {:controller => 'browse', :action => 'changeset', :id => changeset.id}, - {:title => t('changeset.changeset.view_changeset_details')}) - %> - - - - <% if changeset.closed_at > DateTime.now %> <%= t'changeset.changeset.still_editing' %> - <% else %><%= l changeset.closed_at, :format => :long %><% end %> - - - <%if showusername %> - - <% if changeset.user.data_public? %> - <%= link_to h(changeset.user.display_name), :controller => "changeset", :action => "list", :display_name => changeset.user.display_name %> - <% else %> - <%= t'changeset.changeset.anonymous' %> - <% end %> - - <% end %> -
  • - -
  • - <% if changeset.tags['comment'].to_s != '' %> - <%= linkify(h(changeset.tags['comment'])) %> - <% else %> - <%= t'changeset.changeset.no_comment' %> - <% end %> -
  • - +<%= content_tag "li", :id => "changeset_#{changeset.id}", :data => {:changeset => changeset_data} do %> +

    + + <% if changeset.tags['comment'].to_s != '' %> + <%= linkify(h(changeset.tags['comment'])) %> + <% else %> + <%= t 'browse.no_comment' %> + <% end %> + +

    +
    + <%= changeset_details(changeset) %> + · + #<%= changeset.id %> +
    <% end %> diff --git a/app/views/changeset/_changeset_paging_nav.html.erb b/app/views/changeset/_changeset_paging_nav.html.erb deleted file mode 100644 index 46b4635c8..000000000 --- a/app/views/changeset/_changeset_paging_nav.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -
      - <% if @page > 1 %> -
    • <%= link_to t('changeset.changeset_paging_nav.previous'), params.merge({ :page => @page - 1 }) %>
    • - <% else %> -
    • <%= t('changeset.changeset_paging_nav.previous') %>
    • - <% end %> - -
    • <%= t('changeset.changeset_paging_nav.showing_page', :page => @page) %>
    • - - <% if @edits.size < @page_size %> -
    • <%= t('changeset.changeset_paging_nav.next') %>
    • - <% else %> -
    • <%= link_to t('changeset.changeset_paging_nav.next'), params.merge({ :page => @page + 1 }) %>
    • - <% end %> -
    \ No newline at end of file diff --git a/app/views/changeset/_changesets.html.erb b/app/views/changeset/_changesets.html.erb deleted file mode 100644 index fe8da2b38..000000000 --- a/app/views/changeset/_changesets.html.erb +++ /dev/null @@ -1,4 +0,0 @@ -<% showusername = true if showusername.nil? %> -
    - <%= render :partial => 'changeset', :locals => {:showusername => showusername}, :collection => @edits unless @edits.nil? %> -
    diff --git a/app/views/changeset/_map.html.erb b/app/views/changeset/_map.html.erb deleted file mode 100644 index 9730059ee..000000000 --- a/app/views/changeset/_map.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -
    -
    diff --git a/app/views/changeset/_user.html.erb b/app/views/changeset/_user.html.erb deleted file mode 100644 index 0e9507650..000000000 --- a/app/views/changeset/_user.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= link_to user.display_name, :controller => "user", :action => "view", :display_name => user.display_name %> diff --git a/app/views/changeset/history.html.erb b/app/views/changeset/history.html.erb new file mode 100644 index 000000000..23fee589c --- /dev/null +++ b/app/views/changeset/history.html.erb @@ -0,0 +1,30 @@ +<% content_for :head do -%> + <% unless params[:friends] or params[:nearby] -%> + <%= auto_discovery_link_tag :atom, params.merge({ :page => nil, :action => :feed }) %> + <% end -%> +<% end -%> + +<% + if params[:friends] and @user + set_title(t 'changeset.list.title_friend') + @heading = t 'changeset.list.title_friend' + elsif params[:nearby] and @user + set_title(t 'changeset.list.title_nearby') + @heading = t 'changeset.list.title_nearby' + elsif params[:display_name] + set_title(t 'changeset.list.title_user', :user => params[:display_name]) + @heading = t('changeset.list.title_user', :user => link_to(params[:display_name], :controller => "user", :action => "view", :display_name => params[:display_name])).html_safe + else + set_title(t 'changeset.list.title') + @heading = t 'changeset.list.title' + end +%> + +

    + + <%= @heading %> +

    + +
    + <%= image_tag "searching.gif", :class => "loader" %> +
    diff --git a/app/views/changeset/list.atom.builder b/app/views/changeset/list.atom.builder index 591f269b6..619dc4a08 100644 --- a/app/views/changeset/list.atom.builder +++ b/app/views/changeset/list.atom.builder @@ -4,12 +4,6 @@ atom_feed(:language => I18n.locale, :schema_date => 2009, "xmlns:georss" => "http://www.georss.org/georss") do |feed| feed.title @title - feed.subtitle :type => 'xhtml' do |xhtml| - xhtml.p do |p| - p << @description - end - end - feed.updated @edits.map {|e| [e.created_at, e.closed_at].max }.max feed.icon "http://#{SERVER_URL}/favicon.ico" feed.logo "http://#{SERVER_URL}/images/mag_map-rss2.0.png" @@ -46,16 +40,16 @@ atom_feed(:language => I18n.locale, :schema_date => 2009, xhtml.style "th { text-align: left } tr { vertical-align: top }" xhtml.table do |table| table.tr do |tr| - tr.th t("browse.changeset_details.created_at") + tr.th t("browse.created") tr.td l(changeset.created_at) end table.tr do |tr| - tr.th t("browse.changeset_details.closed_at") + tr.th t("browse.closed") tr.td l(changeset.closed_at) end if changeset.user.data_public? table.tr do |tr| - tr.th t("browse.changeset_details.belongs_to") + tr.th t("browse.changeset.belongs_to") tr.td do |td| td.a h(changeset.user.display_name), :href => url_for(:controller => "user", :action => "view", :display_name => changeset.user.display_name, :only_path => false) end diff --git a/app/views/changeset/list.html.erb b/app/views/changeset/list.html.erb index ee8610574..b0ccf67dc 100644 --- a/app/views/changeset/list.html.erb +++ b/app/views/changeset/list.html.erb @@ -1,37 +1,13 @@ -<% content_for :head do -%> - <%= javascript_include_tag "changeset" %> -<% end -%> - -<% content_for :heading do %> - -

    <%= @heading %>

    -
      -
    • <%= raw(@description) %>
    • - <% unless params[:friends] or params[:nearby] -%> -
    • <%= atom_link_to params.merge({ :page => nil, :action => :feed }) %>
    • - <% end -%> -
    - -<% end %> - -<%= render :partial => 'changeset_paging_nav' %> - -<% if @edits.size > 0 %> -
    - <%= render :partial => 'map' %> -
    -
    - <%= render :partial => 'changesets', :locals => { :showusername => !params.has_key?(:display_name) } %> +<% if @edits.present? %> +
      + <%= render :partial => 'changeset', :collection => @edits %> +
    +
    + <%= link_to t('changeset.list.load_more'), url_for(params.merge(:max_id => @edits.last.id - 1)), :class => "button load_more" %> + <%= image_tag "searching.gif", :class => "loader", :style => "display: none;" %>
    - <%= render :partial => 'changeset_paging_nav' %> -<% elsif @user and @user.display_name == params[:display_name] %> -

    <%= t('changeset.list.empty_user_html') %>

    +<% elsif params[:max_id] %> +
    <%= t('changeset.list.no_more') %>
    <% else %> -

    <%= t('changeset.list.empty_anon_html') %>

    +
    <%= t('changeset.list.empty') %>
    <% end %> - -<% unless params[:friends] or params[:nearby] -%> - <% content_for :head do -%> - <%= auto_discovery_link_tag :atom, params.merge({ :page => nil, :action => :feed }) %> - <% end -%> -<% end -%> \ No newline at end of file diff --git a/app/views/diary_entry/comments.html.erb b/app/views/diary_entry/comments.html.erb index fd90b7501..9dc800cff 100644 --- a/app/views/diary_entry/comments.html.erb +++ b/app/views/diary_entry/comments.html.erb @@ -18,7 +18,7 @@ <% end -%> -
      -
    • <%= link_to t('diary_entry.comments.older_comments') , { :page => @comment_pages.current.next} if @comment_pages.current.next %>
    • -
    • <%= link_to t('diary_entry.comments.newer_comments'), { :page => @comment_pages.current.previous } if @comment_pages.current.previous %>
    • -
    +
    + <%= link_to t('diary_entry.comments.older_comments') , { :page => @comment_pages.current.next} if @comment_pages.current.next %> + <%= link_to t('diary_entry.comments.newer_comments'), { :page => @comment_pages.current.previous } if @comment_pages.current.previous %> +
    diff --git a/app/views/diary_entry/list.html.erb b/app/views/diary_entry/list.html.erb index 2939ec7e6..0767bd402 100644 --- a/app/views/diary_entry/list.html.erb +++ b/app/views/diary_entry/list.html.erb @@ -3,7 +3,7 @@ <% if @this_user %> <%= user_image @this_user %> <% end %> -

    <%= h(@title) %>

    +

    <%= h(@title) %>

      <% unless params[:friends] or params[:nearby] -%> diff --git a/app/views/export/start.html.erb b/app/views/export/start.html.erb deleted file mode 100644 index 0bc1ac5bb..000000000 --- a/app/views/export/start.html.erb +++ /dev/null @@ -1,48 +0,0 @@ -<%= form_tag :controller => "export", :action => "finish" do %> - <%= hidden_field_tag 'format', 'osm' %> - -
      -
      - <%= text_field_tag('maxlat', nil, :size => 10, :class => "export_bound") %> -
      - <%= text_field_tag('minlon', nil, :size => 10, :class => "export_bound") %> - <%= text_field_tag('maxlon', nil, :size => 10, :class => "export_bound") %> -
      - <%= text_field_tag('minlat', nil, :size => 10, :class => "export_bound") %> -
      - <%= t'export.start.manually_select' %> -
      - -
      -

      <%= t'export.start.licence' %>

      - -
      -

      <%= raw t'export.start.export_details' %>

      -
      - -
      -

      <%= t'export.start.too_large.heading' %>

      - -
      -

      <%= t'export.start.too_large.body' %>

      -
      -
      <%= t'export.start.too_large.planet.title' %>
      -
      <%= t'export.start.too_large.planet.description' %>
      - -
      <%= t'export.start.too_large.geofabrik.title' %>
      -
      <%= t'export.start.too_large.geofabrik.description' %>
      - -
      <%= t'export.start.too_large.metro.title' %>
      -
      <%= t'export.start.too_large.metro.description' %>
      - -
      <%= t'export.start.too_large.other.title' %>
      -
      <%= t'export.start.too_large.other.description' %>
      -
      -
      -
      -
      - -
      - <%= submit_tag t('export.start.export_button'), :id => "export_commit" %> -
      -<% end %> diff --git a/app/views/geocoder/results.html.erb b/app/views/geocoder/results.html.erb index 3c471076c..d990b7f0e 100644 --- a/app/views/geocoder/results.html.erb +++ b/app/views/geocoder/results.html.erb @@ -2,16 +2,14 @@

      <%= t 'geocoder.results.no_results' %>

      <% else %>
        - <% @results.each do |result| %> -
      • <%= result_to_html(result) %>

      • - <% end %> -
      + <% @results.each do |result| %> +
    • <%= result_to_html(result) %>

    • + <% end %> +
    <% if @more_params %>
    -
    - <%= link_to t('geocoder.results.more_results'), url_for(@more_params), :class => "button" %> -
    - <%= image_tag "searching.gif", :class => ["search_searching", "hidden"] %> + <%= link_to t('geocoder.results.more_results'), url_for(@more_params), :class => "button load_more" %> + <%= image_tag "searching.gif", :class => "loader", :style => "display: none;" %>
    <% end %> <% end %> diff --git a/app/views/geocoder/search.html.erb b/app/views/geocoder/search.html.erb index 6e25588b6..ac655147a 100644 --- a/app/views/geocoder/search.html.erb +++ b/app/views/geocoder/search.html.erb @@ -1,9 +1,10 @@ +

    + + <%= t('site.sidebar.search_results') %> +

    <% @sources.each do |source| %> -

    <%= raw(t "geocoder.search.title.#{source}") %>

    -
    "> - <%= image_tag "searching.gif", :class => "search_searching" %> +

    <%= raw(t "geocoder.search.title.#{source}") %>

    +
    "> + <%= image_tag "searching.gif", :class => "loader" %>
    - <% end %> diff --git a/app/views/layouts/_content.html.erb b/app/views/layouts/_content.html.erb new file mode 100644 index 000000000..a4d93cc0e --- /dev/null +++ b/app/views/layouts/_content.html.erb @@ -0,0 +1,19 @@ +
    + <% if content_for? :content %> + <%= yield :content %> + <% else %> + <%= render :partial => "layouts/flash", :locals => { :flash => flash } %> + <% if content_for? :heading %> +
    +
    + <%= yield :heading %> +
    +
    + <% end %> +
    +
    + <%= yield %> +
    +
    + <% end %> +
    diff --git a/app/views/layouts/_edit_menu.html.erb b/app/views/layouts/_edit_menu.html.erb deleted file mode 100644 index b7d9d7fdf..000000000 --- a/app/views/layouts/_edit_menu.html.erb +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/app/views/layouts/_flash.html.erb b/app/views/layouts/_flash.html.erb index a3cbbc207..51ef3fe41 100644 --- a/app/views/layouts/_flash.html.erb +++ b/app/views/layouts/_flash.html.erb @@ -1,11 +1,20 @@ <% if flash[:error] %> -
    <%=image_tag("notice.png", :class => "small_icon", :border=>0)%><%= raw flash[:error] %>
    +

    + <%= image_tag("notice.png", :class => "small_icon", :border => 0) %> + <%= raw flash[:error] %> +

    <% end %> <% if flash[:warning] %> -
    <%=image_tag("notice.png", :class => "small_icon", :border=>0)%><%= raw flash[:warning] %>
    +

    + <%= image_tag("notice.png", :class => "small_icon", :border => 0) %> + <%= raw flash[:warning] %> +

    <% end %> <% if flash[:notice] %> -
    <%=image_tag("notice.png", :class => "small_icon", :border=>0)%><%= raw flash[:notice] %>
    +

    + <%= image_tag("notice.png", :class => "small_icon", :border => 0) %> + <%= raw flash[:notice] %> +

    <% end %> diff --git a/app/views/layouts/_head.html.erb b/app/views/layouts/_head.html.erb index 0a4fb143f..1897cfff3 100644 --- a/app/views/layouts/_head.html.erb +++ b/app/views/layouts/_head.html.erb @@ -1,9 +1,10 @@ + <%= javascript_include_tag "application" %> - <%= stylesheet_link_tag "small-#{dir}", :media => "only screen and (max-width:641px)" %> - <%= stylesheet_link_tag "large-#{dir}", :media => "screen and (min-width: 642px)" %> + <%= stylesheet_link_tag "small-#{dir}", :media => "only screen and (max-width:721px)" %> + <%= stylesheet_link_tag "large-#{dir}", :media => "screen and (min-width: 722px)" %> <%= stylesheet_link_tag "print-#{dir}", :media => "print" %> <%= stylesheet_link_tag "leaflet-all", :media => "screen, print" %> <% if t('license_page.legal_babble', :locale => I18n.locale) != t('license_page.legal_babble', :locale => :en) %> -

    <%= t 'license_page.native.title' %>

    +

    <%= t 'license_page.native.title' %>

    <%= raw t 'license_page.native.text', :native_link => link_to(t('license_page.native.native_link'), @@ -19,7 +19,7 @@ <% else %> <% if t('license_page.legal_babble', :locale => @locale) != t('license_page.legal_babble', :locale => :en) %> -

    <%= t 'license_page.foreign.title' %>

    +

    <%= t 'license_page.foreign.title' %>

    <%= raw t 'license_page.foreign.text', :english_original_link => link_to(t('license_page.foreign.english_link'), @@ -31,7 +31,7 @@ <% end %> <% end %> -

    <%= t "license_page.legal_babble.title_html", :locale => @locale %>

    +

    <%= t "license_page.legal_babble.title_html", :locale => @locale %>

    <% end %> diff --git a/app/views/site/edit.html.erb b/app/views/site/edit.html.erb index 761975466..ae313e1f2 100644 --- a/app/views/site/edit.html.erb +++ b/app/views/site/edit.html.erb @@ -1,21 +1,13 @@ -<% if STATUS == :database_offline or STATUS == :api_offline %> -

    <%= t 'layouts.osm_offline' %> -

    -<% elsif STATUS == :database_readonly or STATUS == :api_readonly %> -

    <%= t 'layouts.osm_read_only' %> -

    -<% elsif !@user.data_public? %> -

    <%= t 'site.edit.not_public' %>

    -

    <%= raw t 'site.edit.not_public_description', :user_page => (link_to t('site.edit.user_page_link'), {:controller => 'user', :action => 'account', :display_name => @user.display_name, :anchor => 'public'}) %>

    -

    <%= raw t 'site.edit.anon_edits', :link => link_to(t('site.edit.anon_edits_link_text'), t('site.edit.anon_edits_link')) %>

    -<% else %> -<% content_for :head do %> - <%= javascript_include_tag "edit" %> -<% end %> - -<%= render :partial => 'home_link' %> -<%= render :partial => 'sidebar' %> -<%= render :partial => 'search' %> - -<%= render :partial => preferred_editor %> +<% content_for :content do %> + <% if STATUS == :database_offline or STATUS == :api_offline %> +

    <%= t 'layouts.osm_offline' %>

    + <% elsif STATUS == :database_readonly or STATUS == :api_readonly %> +

    <%= t 'layouts.osm_read_only' %>

    + <% elsif !@user.data_public? %> +

    <%= t 'site.edit.not_public' %>

    +

    <%= raw t 'site.edit.not_public_description', :user_page => (link_to t('site.edit.user_page_link'), {:controller => 'user', :action => 'account', :display_name => @user.display_name, :anchor => 'public'}) %>

    +

    <%= raw t 'site.edit.anon_edits', :link => link_to(t('site.edit.anon_edits_link_text'), t('site.edit.anon_edits_link')) %>

    + <% else %> + <%= render :partial => preferred_editor %> + <% end %> <% end %> diff --git a/app/views/site/export.html.erb b/app/views/site/export.html.erb new file mode 100644 index 000000000..4ac5ec4d9 --- /dev/null +++ b/app/views/site/export.html.erb @@ -0,0 +1,47 @@ +<% set_title(t('export.title')) %> + +

    + + <%= t 'export.title' %> +

    + +<%= form_tag({:controller => "export", :action => "finish"}, :class => "export_form") do %> + <%= hidden_field_tag 'format', 'osm' %> + +
    +
    + <%= text_field_tag('maxlat', nil, :size => 10, :class => "export_bound") %> +
    + <%= text_field_tag('minlon', nil, :size => 10, :class => "export_bound") %> + <%= text_field_tag('maxlon', nil, :size => 10, :class => "export_bound") %> +

    + <%= text_field_tag('minlat', nil, :size => 10, :class => "export_bound") %> +
    + <%= t'export.start.manually_select' %> +
    + +

    <%= t'export.start.licence' %>

    +

    <%= raw t 'export.start.export_details' %>

    + +
    +

    <%= t'export.start.too_large.heading' %>

    +

    <%= t'export.start.too_large.body' %>

    +
    +
    <%= t'export.start.too_large.planet.title' %>
    +
    <%= t'export.start.too_large.planet.description' %>
    + +
    <%= t'export.start.too_large.geofabrik.title' %>
    +
    <%= t'export.start.too_large.geofabrik.description' %>
    + +
    <%= t'export.start.too_large.metro.title' %>
    +
    <%= t'export.start.too_large.metro.description' %>
    + +
    <%= t'export.start.too_large.other.title' %>
    +
    <%= t'export.start.too_large.other.description' %>
    +
    +
    + +
    + <%= submit_tag t('export.start.export_button'), :id => "export_commit" %> +
    +<% end %> diff --git a/app/views/site/help.html.erb b/app/views/site/help.html.erb new file mode 100644 index 000000000..a1b1adb92 --- /dev/null +++ b/app/views/site/help.html.erb @@ -0,0 +1,18 @@ +<% content_for :heading do %> +

    <%= t "help_page.title" %>

    +<% end %> + +

    <%= t "help_page.introduction" %>

    + +<% ['welcome', 'help', 'wiki'].each do |site| %> + <% unless site == 'welcome' && !@user %> +
    +

    + + <%= t "help_page.#{site}.title" %> + +

    +

    <%= t "help_page.#{site}.description" %>

    +
    + <% end %> +<% end %> diff --git a/app/views/site/id.html.erb b/app/views/site/id.html.erb index fde4a07cd..fa47bb00c 100644 --- a/app/views/site/id.html.erb +++ b/app/views/site/id.html.erb @@ -33,24 +33,15 @@ }); id.map().on('move.embed', parent.$.throttle(250, function() { - var extent = id.map().extent(), - zoom = ~~id.map().zoom(), - center = id.map().center(); + var zoom = ~~id.map().zoom(), + center = id.map().center(), + llz = { lon: center[0], lat: center[1], zoom: zoom }; - parent.updatelinks({ - lon: center[0], - lat: center[1] - }, - zoom, - null, - [[extent[0][1], - extent[0][0]], - [extent[1][1], - extent[1][0]]]); + parent.updatelinks(llz, zoom); // Manually resolve URL to avoid iframe JS context weirdness. // http://bl.ocks.org/jfirebaugh/5439412 - var hash = parent.OSM.formatHash({ lon: center[0], lat: center[1], zoom: zoom }); + var hash = parent.OSM.formatHash(llz); if (hash !== parent.location.hash) { parent.location.replace(parent.location.href.replace(/(#.*|$)/, hash)); } diff --git a/app/views/site/index.html.erb b/app/views/site/index.html.erb index 73e1382d3..6f215235c 100644 --- a/app/views/site/index.html.erb +++ b/app/views/site/index.html.erb @@ -1,33 +1,13 @@ -<% content_for :head do %> - <%= javascript_include_tag "index" %> -<% end %> - -<%= render :partial => 'home_link' %> -<%= render :partial => 'sidebar' %> -<%= render :partial => 'search' %> - -
    diff --git a/app/views/user/_contact.html.erb b/app/views/user/_contact.html.erb index 9d719b52f..4811389f1 100644 --- a/app/views/user/_contact.html.erb +++ b/app/views/user/_contact.html.erb @@ -24,7 +24,7 @@ <% changeset = contact.changesets.first %> <% if changeset %> <%= t('user.view.latest edit', :ago => t('user.view.ago', :time_in_words_ago => time_ago_in_words(changeset.created_at))) %> - <% comment = changeset.tags['comment'].to_s != '' ? changeset.tags['comment'] : t('changeset.changeset.no_comment') %> + <% comment = changeset.tags['comment'].to_s != '' ? changeset.tags['comment'] : t('browse.no_comment') %> "<%= link_to(comment, {:controller => 'browse', :action => 'changeset', :id => changeset.id}, {:title => t('changeset.changeset.view_changeset_details')}) diff --git a/app/views/user/account.html.erb b/app/views/user/account.html.erb index e5cbe22b5..94183ff42 100644 --- a/app/views/user/account.html.erb +++ b/app/views/user/account.html.erb @@ -1,5 +1,5 @@ <% content_for :heading do %> -

    <%= t 'user.account.my settings' %>

    +

    <%= t 'user.account.my settings' %>

    • <%= link_to t('user.account.return to profile'), :controller => 'user', :action => 'view', :display_name => @user.display_name %>
    • <%= link_to t('user.view.oauth settings'), :controller => 'oauth_clients', :action => 'index' %>
    • diff --git a/app/views/user/confirm.html.erb b/app/views/user/confirm.html.erb index 31f29eb64..9fc33094e 100644 --- a/app/views/user/confirm.html.erb +++ b/app/views/user/confirm.html.erb @@ -1,5 +1,5 @@ <% content_for :heading do %> -

      <%= t 'user.confirm.heading' %>

      +

      <%= t 'user.confirm.heading' %>

      <% end %> diff --git a/app/views/user/no_such_user.html.erb b/app/views/user/no_such_user.html.erb index d472f96b0..062d18fb5 100644 --- a/app/views/user/no_such_user.html.erb +++ b/app/views/user/no_such_user.html.erb @@ -1,4 +1,4 @@ <% content_for :heading do %> -

      <%= t 'user.no_such_user.heading', :user => h(@not_found_user) %>

      +

      <%= t 'user.no_such_user.heading', :user => h(@not_found_user) %>

      <% end %>

      <%= t 'user.no_such_user.body', :user => h(@not_found_user) %>

      diff --git a/app/views/user/view.html.erb b/app/views/user/view.html.erb index fc7b59929..f39bafec7 100644 --- a/app/views/user/view.html.erb +++ b/app/views/user/view.html.erb @@ -2,9 +2,9 @@
      <%= user_image @this_user %>
      -

      <%= @this_user.display_name %><%= role_icons(@this_user) %>

      +

      <%= @this_user.display_name %><%= role_icons(@this_user) %>

      <% if @user and @this_user.id == @user.id %> - +
      • <%= link_to t('user.view.my edits'), :controller => 'changeset', :action => 'list', :display_name => @user.display_name %> @@ -45,7 +45,7 @@
      <% else %> - +
      • diff --git a/config/environments/production.rb b/config/environments/production.rb index 47358b387..2db9f2366 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -69,12 +69,13 @@ OpenStreetMap::Application.configure do # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. - config.assets.precompile += %w( index.js edit.js browse.js changeset.js welcome.js ) + config.assets.precompile += %w( index.js browse.js welcome.js ) config.assets.precompile += %w( user.js diary_entry.js swfobject.js ) config.assets.precompile += %w( large-ltr.css small-ltr.css print-ltr.css ) config.assets.precompile += %w( large-rtl.css small-rtl.css print-rtl.css ) - config.assets.precompile += %w( browse.css leaflet-all.css leaflet.ie.css ) + config.assets.precompile += %w( leaflet-all.css leaflet.ie.css ) config.assets.precompile += %w( embed.js embed.css ) + config.assets.precompile += %w( html5shiv.js ) config.assets.precompile += %w( images/marker-*.png img/*-handle.png ) config.assets.precompile += %w( potlatch2.swf ) config.assets.precompile += %w( potlatch2/assets.zip ) diff --git a/config/locales/en.yml b/config/locales/en.yml index d7411e997..3fc045865 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -95,96 +95,62 @@ en: name: "Remote Control" description: "Remote Control (JOSM or Merkaartor)" browse: + created: "Created" + closed: "Closed" + created_html: "Created %{time} ago" + closed_html: "Closed %{time} ago" + created_by_html: "Created %{time} ago by %{user}" + deleted_by_html: "Deleted %{time} ago by %{user}" + edited_by_html: "Edited %{time} ago by %{user}" + closed_by_html: "Closed %{time} ago by %{user}" + version: "Version" + in_changeset: "Changeset" + anonymous: "anonymous" + no_comment: "(no comment)" + part_of: "Part of" + download_xml: "Download XML" + view_history: "View History" + view_details: "View Details" changeset: - title: "Changeset" - changeset: "Changeset: %{id}" + title: "Changeset %{id}" + belongs_to: "Author" + node: "Nodes (%{count})" + node_paginated: "Nodes (%{x}-%{y} of %{count})" + way: "Ways (%{count})" + way_paginated: "Ways (%{x}-%{y} of %{count})" + relation: "Relations (%{count})" + relation_paginated: "Relations (%{x}-%{y} of %{count})" changesetxml: "Changeset XML" osmchangexml: "osmChange XML" feed: title: "Changeset %{id}" title_comment: "Changeset %{id} - %{comment}" - navigation: - paging: - user: - prev: "« %{id}" - next: "%{id} »" - all: - prev: "« %{id}" - next: "%{id} »" - user: - name_changeset_tooltip: "View edits by %{user}" - prev_changeset_tooltip: "Previous edit by %{user}" - next_changeset_tooltip: "Next edit by %{user}" - all: - prev_node_tooltip: "Previous node" - next_node_tooltip: "Next node" - prev_way_tooltip: "Previous way" - next_way_tooltip: "Next way" - prev_relation_tooltip: "Previous relation" - next_relation_tooltip: "Next relation" - prev_changeset_tooltip: "Previous changeset" - next_changeset_tooltip: "Next changeset" - prev_note_tooltip: "Previous note" - next_note_tooltip: "Next note" - changeset_details: - created_at: "Created at:" - closed_at: "Closed at:" - belongs_to: "Belongs to:" - bounding_box: "Bounding box:" - no_bounding_box: "No bounding box has been stored for this changeset." - show_area_box: "Show Area Box" - box: "box" - has_nodes: - one: "Has the following %{count} node:" - other: "Has the following %{count} nodes:" - has_ways: - one: "Has the following %{count} way:" - other: "Has the following %{count} ways:" - has_relations: - one: "Has the following %{count} relation:" - other: "Has the following %{count} relations:" - common_details: - edited_at: "Edited at:" - edited_by: "Edited by:" - deleted_at: "Deleted at:" - deleted_by: "Deleted by:" - version: "Version:" - in_changeset: "In changeset:" - changeset_comment: "Comment:" + node: + title: "Node: %{name}" + history_title: "Node History: %{name}" + way: + title: "Way: %{name}" + history_title: "Way History: %{name}" + nodes: "Nodes" + also_part_of: + one: "part of way %{related_ways}" + other: "part of ways %{related_ways}" + relation: + title: "Relation: %{name}" + history_title: "Relation History: %{name}" + members: "Members" + relation_member: + entry: "%{type} %{name}" + entry_role: "%{type} %{name} as %{role}" + type: + node: "Node" + way: "Way" + relation: "Relation" containing_relation: entry: "Relation %{relation_name}" entry_role: "Relation %{relation_name} (as %{relation_role})" - map: - loading: "Loading..." - deleted: "Deleted" - larger: - area: "View area on larger map" - node: "View node on larger map" - way: "View way on larger map" - relation: "View relation on larger map" - note: "View note on larger map" - edit: - area: "Edit area" - node: "Edit node" - way: "Edit way" - relation: "Edit relation" - note: "Edit note" - node_details: - coordinates: "Coordinates:" - part_of: "Part of:" - node_history: - node_history: "Node History" - node_history_title: "Node History: %{node_name}" - download_xml: "Download XML" - view_details: "View details" - node: - node: "Node" - node_title: "Node: %{node_name}" - download_xml: "Download XML" - view_history: "View history" - edit: "Edit node" not_found: - sorry: "Sorry, the %{type} with the id %{id}, could not be found." + sorry: "Sorry, %{type} #%{id} could not be found." type: node: node way: way @@ -197,9 +163,6 @@ en: way: way relation: relation changeset: changeset - paging_nav: - showing_page: "page" - of: "of" redacted: redaction: "Redaction %{id}" message_html: "Version %{version} of this %{type} cannot be shown as it has been redacted. Please see %{redaction_link} for details." @@ -207,110 +170,38 @@ en: node: "node" way: "way" relation: "relation" - relation_details: - members: "Members:" - part_of: "Part of:" - relation_history: - relation_history: "Relation History" - relation_history_title: "Relation History: %{relation_name}" - download_xml: "Download XML" - view_details: "View details" - relation_member: - entry: "%{type} %{name}" - entry_role: "%{type} %{name} as %{role}" - type: - node: "Node" - way: "Way" - relation: "Relation" - relation: - relation: "Relation" - relation_title: "Relation: %{relation_name}" - download_xml: "Download XML" - view_history: "View history" start_rjs: - notes_layer_name: "Browse Notes" - data_layer_name: "Browse Map Data" - data_frame_title: "Data" - zoom_or_select: "Zoom in or select an area of the map to view" - view_data: "View data for current map view" - manually_select: "Manually select a different area" - hide_areas: "Hide areas" - show_areas: "Show areas" - loaded_an_area_with_num_features: "You have loaded an area which contains %{num_features} features. In general, some browsers may not cope well with displaying this quantity of data. Generally, browsers work best at displaying less than %{max_features} features at a time: doing anything else may make your browser slow/unresponsive. If you are sure you want to display this data, you may do so by clicking the button below." + loaded_an_area_with_num_features: "Loading %{num_features} features, which may make your browser slow or unresponsive. Are sure you want to display this data?" load_data: "Load Data" - unable_to_load_size: "Unable to load: Bounding box size of %{bbox_size} is too large (must be smaller than %{max_bbox_size})" + unable_to_load_size: "Unable to load map data, too large of an area (%{bbox_size}). Area must be smaller than %{max_bbox_size} square degrees." loading: "Loading..." - show_history: "Show History" - wait: "Wait..." - history_for_feature: "History for %{feature}" - details: "Details" - private_user: "private user" - edited_by_user_at_timestamp: "Edited by %{user} at %{timestamp}" - object_list: - heading: "Object list" - back: "Back to object list" - type: - node: "Node" - way: "Way" - # There is no 'relation' type because it is not represented in OpenLayers - api: "Retrieve this area from the API" - details: "Details" - selected: - type: - node: "Node %{id}" - way: "Way %{id}" - # There is no 'relation' type because it is not represented in OpenLayers - history: - type: - node: "Node %{id}" - way: "Way %{id}" - # There is no 'relation' type because it is not represented in OpenLayers tag_details: - tags: "Tags:" + tags: "Tags" wiki_link: key: "The wiki description page for the %{key} tag" tag: "The wiki description page for the %{key}=%{value} tag" wikipedia_link: "The %{page} article on Wikipedia" - way_details: - nodes: "Nodes:" - part_of: "Part of:" - also_part_of: - one: "part of way %{related_ways}" - other: "part of ways %{related_ways}" - way_history: - way_history: "Way History" - way_history_title: "Way History: %{way_name}" - download_xml: "Download XML" - view_details: "View details" - way: - way: "Way" - way_title: "Way: %{way_name}" - download_xml: "Download XML" - view_history: "View history" - edit: "Edit way" note: title: "Note" - open_title: "Unresolved note: %{note_name}" - closed_title: "Resolved note: %{note_name}" - opened: "Opened:" - last_modified: "Last modified:" - closed: "Closed:" - at_html: "%{when} ago" - at_by_html: "%{when} ago by %{user}" - description: "Description:" - comments: "Comments:" + new_note: "New Note" + open_title: "Unresolved note #%{note_name}" + closed_title: "Resolved note #%{note_name}" + open_by: "Created by %{user} %{when} ago" + open_by_anonymous: "Created by anonymous %{when} ago" + commented_by: "Comment from %{user} %{when} ago" + commented_by_anonymous: "Comment from anonymous %{when} ago" + closed_by: "Resolved by %{user} %{when} ago" + closed_by_anonymous: "Resolved by anonymous %{when} ago" + reopened_by: "Reactivated by %{user} %{when} ago" + reopened_by_anonymous: "Reactivated by anonymous %{when} ago" changeset: changeset_paging_nav: showing_page: "Page %{page}" next: "Next »" previous: "« Previous" changeset: - still_editing: "(still editing)" anonymous: "Anonymous" - no_comment: "(none)" no_edits: "(no edits)" - show_area_box: "show area box" - big_area: "(big)" view_changeset_details: "View changeset details" changesets: id: "ID" @@ -321,24 +212,11 @@ en: list: title: "Changesets" title_user: "Changesets by %{user}" - title_bbox: "Changesets within %{bbox}" - title_user_bbox: "Changesets by %{user} within %{bbox}" title_friend: "Changesets by your friends" title_nearby: "Changesets by nearby users" - heading: "Changesets" - heading_user: "Changesets" - heading_bbox: "Changesets" - heading_user_bbox: "Changesets" - heading_friend: "Changesets" - heading_nearby: "Changesets" - description: "Browse recent contributions to the map" - description_user: "Changesets by %{user}" - description_bbox: "Changesets within %{bbox}" - description_user_bbox: "Changesets by %{user} within %{bbox}" - description_friend: "Changesets by your friends" - description_nearby: "Changesets by nearby users" - empty_user_html: "It looks you haven't made any edits yet. To get started, check out the Beginners Guide." - empty_anon_html: "No edits made yet." + empty: "No changesets in this area." + no_more: "No more changesets in this area." + load_more: "Load more" timeout: sorry: "Sorry, the list of changesets you requested took too long to retrieve." diary_entry: @@ -416,6 +294,7 @@ en: newer_comments: "Newer Comments" older_comments: "Older Comments" export: + title: "Export" start: area_to_export: "Area to Export" manually_select: "Manually select a different area" @@ -452,13 +331,6 @@ en: output: "Output" paste_html: "Paste HTML to embed in website" export_button: "Export" - start_rjs: - export: "Export" - drag_a_box: "Drag a box on the map to select an area" - manually_select: "Manually select a different area" - click_add_marker: "Click on the map to add a marker" - change_marker: "Change marker position" - add_marker: "Add a marker to the map" geocoder: search: title: @@ -1000,14 +872,13 @@ en: alt_text: OpenStreetMap logo home: Go to Home Location logout: Logout - log_in: log in + log_in: Log In log_in_tooltip: Log in with an existing account - sign_up: sign up + sign_up: Sign Up sign_up_tooltip: Create an account for editing - view: View - view_tooltip: View the map edit: Edit history: History + export: Export data: Data export_data: Export Data gps_traces: GPS Traces @@ -1016,13 +887,9 @@ en: user_diaries_tooltip: View user diaries edit_with: Edit with %{editor} tag_line: The Free Wiki World Map - intro_1: "OpenStreetMap is a free worldwide map, created by people like you." - intro_2_html: "The data is free to %{download} and %{use} under its %{license}. %{create_account} to improve the map." + intro_header: Welcome to OpenStreetMap! + intro_text: OpenStreetMap is an editable map of the world created by people like you and free to use under an open license. intro_2_create_account: "Create a user account" - intro_2_license: "open license" - intro_2_use: "use" - intro_2_download: "download" - intro_2_use_url: "http://wiki.openstreetmap.org/wiki/Using_OpenStreetMap" partners_html: "Hosting is supported by %{ucl}, %{ic} and %{bytemark}, and other %{partners}." partners_ucl: "the UCL VR Centre" partners_ic: "Imperial College London" @@ -1032,16 +899,8 @@ en: osm_offline: "The OpenStreetMap database is currently offline while essential database maintenance work is carried out." osm_read_only: "The OpenStreetMap database is currently in read-only mode while essential database maintenance work is carried out." donate: "Support OpenStreetMap by %{link} to the Hardware Upgrade Fund." - donate_link_text: donating help: Help - help_centre: Help Centre - help_url: http://help.openstreetmap.org/ - help_title: Help site for the project - wiki: Wiki - wiki_url: http://wiki.openstreetmap.org/ - wiki_title: Wiki site for the project - documentation: Documentation - documentation_title: Documentation for the project + about: About copyright: "Copyright & License" community: Community community_blogs: "Community Blogs" @@ -1051,7 +910,7 @@ en: make_a_donation: title: Support OpenStreetMap with a monetary donation text: Make a Donation - + learn_more: "Learn More" license_page: foreign: title: About this translation @@ -1197,8 +1056,9 @@ en: questions: title: Any questions? paragraph_1_html: | - Need help mapping, or not clear on how to use OpenStreetMap? Get your questions answered - on the help website. + OpenStreetMap has several resources for learning about the project, asking and answering + questions, and collaboratively discussing and documenting mapping topics. + Get help here. start_mapping: Start Mapping add_a_note: title: No Time To Edit? Add a Note! @@ -1209,6 +1069,52 @@ en: Just go to the map and click the note icon: . This will add a marker to the map, which you can move by dragging. Add your message, then click save, and other mappers will investigate. + help_page: + title: Getting Help + introduction: | + OpenStreetMap has several resources for learning about the project, asking and answering questions, + and collaboratively discussing and documenting mapping topics. + welcome: + url: /welcome + title: Welcome to OSM + description: Start with this quick guide covering the OpenStreetMap basics. + help: + url: https://help.openstreetmap.org/ + title: help.openstreetmap.org + description: Ask a question or look up answers on OSM's question-and-answer site. + wiki: + url: http://wiki.openstreetmap.org/ + title: wiki.openstreetmap.org + description: Browse the wiki for in-depth OSM documentation. + about_page: + next: Next + copyright_html: ©OpenStreetMap
        contributors + used_by: "%{name} powers map data on hundreds of web sites, mobile apps, and hardware devices" + lede_text: | + OpenStreetMap is built by a community of mappers that contribute and maintain data + about roads, trails, cafés, railway stations, and much more, all over the world. + local_knowledge_title: Local Knowledge + local_knowledge_html: | + OpenStreetMap emphasizes local knowledge. Contributors use + aerial imagery, GPS devices, and low-tech field maps to verify that OSM + is accurate and up to date. + community_driven_title: Community Driven + community_driven_html: | + OpenStreetMap's community is diverse, passionate, and growing every day. + Our contributors include enthusiast mappers, GIS professionals, engineers + running the OSM servers, humanitarians mapping disaster-affected areas, + and many more. + To learn more about the community, see the user diaries, + community blogs, and + the OSM Foundation website. + open_data_title: Open Data + open_data_html: | + OpenStreetMap is open data: you are free to use it for any purpose + as long as you credit OpenStreetMap and its contributors. If you alter or + build upon the data in certain ways, you may distribute the result only + under the same licence. See the Copyright and + License page for details. + partners_title: Partners notifier: diary_comment_notification: subject: "[OpenStreetMap] %{user} commented on your diary entry" @@ -1385,7 +1291,6 @@ en: where_am_i: "Where am I?" where_am_i_title: Describe the current location using the search engine submit_text: "Go" - search_help: "examples: 'Alkmaar', 'Regent Street, Cambridge', 'CB2 5AQ', or 'post offices near Lünen' more examples..." key: table: entry: @@ -2141,13 +2046,14 @@ en: overlays: Enable overlays for troubleshooting the map title: "Layers" copyright: "© OpenStreetMap contributors" + donate_link_text: "" site: edit_tooltip: Edit the map edit_disabled_tooltip: Zoom in to edit the map - history_tooltip: View edits for this area - history_disabled_tooltip: Zoom in to view edits for this area createnote_tooltip: Add a note to the map createnote_disabled_tooltip: Zoom in to add a note to the map + map_notes_zoom_in_tooltip: Zoom in to see map notes + map_data_zoom_in_tooltip: Zoom in to see map data notes: new: intro: "In order to improve the map the information you enter is shown to other mappers, so please be as descriptive and precise as possible when moving the marker to the correct position and entering your note below." diff --git a/config/routes.rb b/config/routes.rb index 81548af12..59c5b6803 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -102,23 +102,24 @@ OpenStreetMap::Application.routes.draw do end # Data browsing - match '/browse/start' => 'browse#start', :via => :get - match '/browse/way/:id' => 'browse#way', :via => :get, :id => /\d+/ + match '/browse/way/:id' => 'browse#way', :via => :get, :id => /\d+/, :as => :way match '/browse/way/:id/history' => 'browse#way_history', :via => :get, :id => /\d+/ - match '/browse/node/:id' => 'browse#node', :via => :get, :id => /\d+/ + match '/browse/node/:id' => 'browse#node', :via => :get, :id => /\d+/, :as => :node match '/browse/node/:id/history' => 'browse#node_history', :via => :get, :id => /\d+/ - match '/browse/relation/:id' => 'browse#relation', :via => :get, :id => /\d+/ + match '/browse/relation/:id' => 'browse#relation', :via => :get, :id => /\d+/, :as => :relation match '/browse/relation/:id/history' => 'browse#relation_history', :via => :get, :id => /\d+/ match '/browse/changeset/:id' => 'browse#changeset', :via => :get, :as => :changeset, :id => /\d+/ match '/browse/note/:id' => 'browse#note', :via => :get, :id => /\d+/, :as => "browse_note" + match '/new_note' => 'browse#new_note', :via => :get match '/user/:display_name/edits' => 'changeset#list', :via => :get match '/user/:display_name/edits/feed' => 'changeset#feed', :via => :get, :defaults => { :format => :atom } match '/user/:display_name/notes' => 'notes#mine', :via => :get match '/browse/friends' => 'changeset#list', :via => :get, :friends => true, :as => "friend_changesets" match '/browse/nearby' => 'changeset#list', :via => :get, :nearby => true, :as => "nearby_changesets" - match '/browse/changesets' => 'changeset#list', :via => :get - match '/browse/changesets/feed' => 'changeset#feed', :via => :get, :defaults => { :format => :atom } - match '/browse' => 'changeset#list', :via => :get + + get '/browse/changesets/feed', :to => redirect('/history/feed') + get '/browse/changesets', :to => redirect('/history') + get '/browse', :to => redirect('/history') # web site root :to => 'site#index', :via => [:get, :post] @@ -126,9 +127,11 @@ OpenStreetMap::Application.routes.draw do match '/copyright/:copyright_locale' => 'site#copyright', :via => :get match '/copyright' => 'site#copyright', :via => :get match '/welcome' => 'site#welcome', :via => :get, :as => :welcome + match '/help' => 'site#help', :via => :get, :as => :help + match '/about' => 'site#about', :via => :get, :as => :about match '/history' => 'changeset#list', :via => :get match '/history/feed' => 'changeset#feed', :via => :get, :defaults => { :format => :atom } - match '/export' => 'site#index', :export => true, :via => :get + match '/export' => 'site#export', :via => :get match '/login' => 'user#login', :via => [:get, :post] match '/logout' => 'user#logout', :via => [:get, :post] match '/offline' => 'site#offline', :via => :get @@ -213,7 +216,7 @@ OpenStreetMap::Application.routes.draw do match '/users/:status' => 'user#list', :via => [:get, :post] # geocoder - match '/geocoder/search' => 'geocoder#search', :via => :post + match '/search' => 'geocoder#search', :via => :get, :as => :search match '/geocoder/search_latlon' => 'geocoder#search_latlon', :via => :get match '/geocoder/search_us_postcode' => 'geocoder#search_us_postcode', :via => :get match '/geocoder/search_uk_postcode' => 'geocoder#search_uk_postcode', :via => :get @@ -224,7 +227,6 @@ OpenStreetMap::Application.routes.draw do match '/geocoder/search_geonames_reverse' => 'geocoder#search_geonames_reverse', :via => :get # export - match '/export/start' => 'export#start', :via => :get match '/export/finish' => 'export#finish', :via => :post match '/export/embed' => 'export#embed', :via => :get diff --git a/test/functional/browse_controller_test.rb b/test/functional/browse_controller_test.rb index e2937c5d8..0f1ff6855 100644 --- a/test/functional/browse_controller_test.rb +++ b/test/functional/browse_controller_test.rb @@ -7,10 +7,6 @@ class BrowseControllerTest < ActionController::TestCase ## # test all routes which lead to this controller def test_routes - assert_routing( - { :path => "/browse/start", :method => :get }, - { :controller => "browse", :action => "start" } - ) assert_routing( { :path => "/browse/node/1", :method => :get }, { :controller => "browse", :action => "node", :id => "1" } diff --git a/test/functional/export_controller_test.rb b/test/functional/export_controller_test.rb index 0e7529b77..d36f0cfd8 100644 --- a/test/functional/export_controller_test.rb +++ b/test/functional/export_controller_test.rb @@ -5,10 +5,6 @@ class ExportControllerTest < ActionController::TestCase ## # test all routes which lead to this controller def test_routes - assert_routing( - { :path => "/export/start", :method => :get }, - { :controller => "export", :action => "start" } - ) assert_routing( { :path => "/export/finish", :method => :post }, { :controller => "export", :action => "finish" } @@ -19,14 +15,6 @@ class ExportControllerTest < ActionController::TestCase ) end - ## - # test the start action - def test_start - xhr :get, :start - assert_response :success - assert_template "export/start" - end - ### # test the finish action for raw OSM data def test_finish_osm diff --git a/vendor/assets/javascripts/html5shiv.js b/vendor/assets/javascripts/html5shiv.js new file mode 100644 index 000000000..94324d7c8 --- /dev/null +++ b/vendor/assets/javascripts/html5shiv.js @@ -0,0 +1,301 @@ +/** +* @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +;(function(window, document) { +/*jshint evil:true */ + /** version */ + var version = '3.7.0'; + + /** Preset options */ + var options = window.html5 || {}; + + /** Used to skip problem elements */ + var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; + + /** Not all elements can be cloned in IE **/ + var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; + + /** Detect whether the browser supports default html5 styles */ + var supportsHtml5Styles; + + /** Name of the expando, to work with multiple documents or to re-shiv one document */ + var expando = '_html5shiv'; + + /** The id for the the documents expando */ + var expanID = 0; + + /** Cached data for each document */ + var expandoData = {}; + + /** Detect whether the browser supports unknown elements */ + var supportsUnknownElements; + + (function() { + try { + var a = document.createElement('a'); + a.innerHTML = ''; + //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles + supportsHtml5Styles = ('hidden' in a); + + supportsUnknownElements = a.childNodes.length == 1 || (function() { + // assign a false positive if unable to shiv + (document.createElement)('a'); + var frag = document.createDocumentFragment(); + return ( + typeof frag.cloneNode == 'undefined' || + typeof frag.createDocumentFragment == 'undefined' || + typeof frag.createElement == 'undefined' + ); + }()); + } catch(e) { + // assign a false positive if detection fails => unable to shiv + supportsHtml5Styles = true; + supportsUnknownElements = true; + } + + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a style sheet with the given CSS text and adds it to the document. + * @private + * @param {Document} ownerDocument The document. + * @param {String} cssText The CSS text. + * @returns {StyleSheet} The style element. + */ + function addStyleSheet(ownerDocument, cssText) { + var p = ownerDocument.createElement('p'), + parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; + + p.innerHTML = 'x'; + return parent.insertBefore(p.lastChild, parent.firstChild); + } + + /** + * Returns the value of `html5.elements` as an array. + * @private + * @returns {Array} An array of shived element node names. + */ + function getElements() { + var elements = html5.elements; + return typeof elements == 'string' ? elements.split(' ') : elements; + } + + /** + * Returns the data associated to the given document + * @private + * @param {Document} ownerDocument The document. + * @returns {Object} An object of data. + */ + function getExpandoData(ownerDocument) { + var data = expandoData[ownerDocument[expando]]; + if (!data) { + data = {}; + expanID++; + ownerDocument[expando] = expanID; + expandoData[expanID] = data; + } + return data; + } + + /** + * returns a shived element for the given nodeName and document + * @memberOf html5 + * @param {String} nodeName name of the element + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived element. + */ + function createElement(nodeName, ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createElement(nodeName); + } + if (!data) { + data = getExpandoData(ownerDocument); + } + var node; + + if (data.cache[nodeName]) { + node = data.cache[nodeName].cloneNode(); + } else if (saveClones.test(nodeName)) { + node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); + } else { + node = data.createElem(nodeName); + } + + // Avoid adding some elements to fragments in IE < 9 because + // * Attributes like `name` or `type` cannot be set/changed once an element + // is inserted into a document/fragment + // * Link elements with `src` attributes that are inaccessible, as with + // a 403 response, will cause the tab/window to crash + // * Script elements appended to fragments will execute when their `src` + // or `text` property is set + return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; + } + + /** + * returns a shived DocumentFragment for the given document + * @memberOf html5 + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived DocumentFragment. + */ + function createDocumentFragment(ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createDocumentFragment(); + } + data = data || getExpandoData(ownerDocument); + var clone = data.frag.cloneNode(), + i = 0, + elems = getElements(), + l = elems.length; + for(;i 7); - })(); - - L.Hash = function(map) { - this.onHashChange = L.Util.bind(this.onHashChange, this); - - if (map) { - this.init(map); - } - }; - - L.Hash.parseHash = function(hash) { - if(hash.indexOf('#') === 0) { - hash = hash.substr(1); - } - var args = hash.split("/"); - if (args.length == 3) { - var zoom = parseInt(args[0], 10), - lat = parseFloat(args[1]), - lon = parseFloat(args[2]); - if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) { - return false; - } else { - return { - center: new L.LatLng(lat, lon), - zoom: zoom - }; - } - } else { - return false; - } - }; - - L.Hash.formatHash = function(map) { - var center = map.getCenter(), - zoom = map.getZoom(), - precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)); - - return "#" + [zoom, - center.lat.toFixed(precision), - center.lng.toFixed(precision) - ].join("/"); - }, - - L.Hash.prototype = { - map: null, - lastHash: null, - - parseHash: L.Hash.parseHash, - formatHash: L.Hash.formatHash, - - init: function(map) { - this.map = map; - - // reset the hash - this.lastHash = null; - this.onHashChange(); - - if (!this.isListening) { - this.startListening(); - } - }, - - removeFrom: function(map) { - if (this.changeTimeout) { - clearTimeout(this.changeTimeout); - } - - if (this.isListening) { - this.stopListening(); - } - - this.map = null; - }, - - onMapMove: function() { - // bail if we're moving the map (updating from a hash), - // or if the map is not yet loaded - - if (this.movingMap || !this.map._loaded) { - return false; - } - - var hash = this.formatHash(this.map); - if (this.lastHash != hash) { - location.replace(hash); - this.lastHash = hash; - } - }, - - movingMap: false, - update: function() { - var hash = location.hash; - if (hash === this.lastHash) { - return; - } - var parsed = this.parseHash(hash); - if (parsed) { - this.movingMap = true; - - this.map.setView(parsed.center, parsed.zoom); - - this.movingMap = false; - } else { - this.onMapMove(this.map); - } - }, - - // defer hash change updates every 100ms - changeDefer: 100, - changeTimeout: null, - onHashChange: function() { - // throttle calls to update() so that they only happen every - // `changeDefer` ms - if (!this.changeTimeout) { - var that = this; - this.changeTimeout = setTimeout(function() { - that.update(); - that.changeTimeout = null; - }, this.changeDefer); - } - }, - - isListening: false, - hashChangeInterval: null, - startListening: function() { - this.map.on("moveend", this.onMapMove, this); - - if (HAS_HASHCHANGE) { - L.DomEvent.addListener(window, "hashchange", this.onHashChange); - } else { - clearInterval(this.hashChangeInterval); - this.hashChangeInterval = setInterval(this.onHashChange, 50); - } - this.isListening = true; - }, - - stopListening: function() { - this.map.off("moveend", this.onMapMove, this); - - if (HAS_HASHCHANGE) { - L.DomEvent.removeListener(window, "hashchange", this.onHashChange); - } else { - clearInterval(this.hashChangeInterval); - } - this.isListening = false; - } - }; - L.hash = function(map) { - return new L.Hash(map); - }; - L.Map.prototype.addHash = function() { - this._hash = L.hash(this); - }; - L.Map.prototype.removeHash = function() { - this._hash.removeFrom(); - }; -})(window); diff --git a/vendor/assets/leaflet/leaflet.js b/vendor/assets/leaflet/leaflet.js index fa26f6e2c..2b66295fc 100644 --- a/vendor/assets/leaflet/leaflet.js +++ b/vendor/assets/leaflet/leaflet.js @@ -9188,4 +9188,4 @@ L.Map.include({ }); -}(window, document)); \ No newline at end of file +}(window, document));